sql: support IF NOT EXISTS for CREATE CLUSTER and CREATE CLUSTER REPLICA - #38061
Open
aljoscha wants to merge 1 commit into
Open
sql: support IF NOT EXISTS for CREATE CLUSTER and CREATE CLUSTER REPLICA#38061aljoscha wants to merge 1 commit into
aljoscha wants to merge 1 commit into
Conversation
Both statements now accept an `IF NOT EXISTS` clause, matching the 13 other `CREATE` statements that already support it. A name that is already taken yields an "already exists, skipping" notice and success instead of an error, leaving the existing object untouched. The skip happens where every sibling path puts it, at the catalog transaction, so the statement is still validated in full first. A typo'd `SIZE` does not pass silently just because the cluster happens to exist. A bare `if` identifier now renders quoted, since the `IF [NOT] EXISTS` clause sits exactly where the object name goes and an unquoted `if` name would no longer reparse. Fixes SQL-601
aljoscha
force-pushed
the
sql-601-cluster-if-not-exists
branch
from
August 5, 2026 17:31
f9f363d to
0d7238c
Compare
aljoscha
marked this pull request as ready for review
August 5, 2026 17:42
mgree
approved these changes
Aug 5, 2026
mgree
left a comment
Contributor
There was a problem hiding this comment.
LGTM. It's worth confirming that nobody has an existing cluster named if, which will get borked by this change.
Comment on lines
+465
to
+468
| // `IF NOT EXISTS` is a property of the statement that created the | ||
| // cluster, not of the cluster itself, so the reconstructed plan | ||
| // never carries it. | ||
| if_not_exists: false, |
Contributor
There was a problem hiding this comment.
Reading this, I don't have the context to know what a "reconstructed plan" is. Someone who knows this file might, though!
Comment on lines
+364
to
+369
| // The `IF [NOT] EXISTS` clauses of CREATE/DROP/ALTER sit | ||
| // exactly where the object name goes, so a bare `if` name | ||
| // is consumed as the start of such a clause on reparse | ||
| // (`CREATE CLUSTER if (SIZE …)` -> "expected NOT, found | ||
| // left parenthesis"). | ||
| || kw == IF |
Contributor
There was a problem hiding this comment.
Could this be breaking for existing customers' queries? (Feels crazy to me to use if as a name for something, but that's programmer bias I'm sure.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CREATE CLUSTERandCREATE CLUSTER REPLICAnow accept anIF NOT EXISTSclause, matching the 13 other
CREATEstatements that already support it.With it, creating a cluster or replica whose name is already taken succeeds and
emits a
cluster "c" already exists, skippingnotice (SQLSTATE 42710) insteadof failing, so idempotent provisioning scripts no longer need a pre-flight
existence check.
Skipping leaves the existing object completely untouched. The configuration in
the statement is not applied, so this is not an upsert.
Previously these two statements produced a misleading parse error, because
IFwas consumed as the object name and the failure surfaced one token later:
Implementation
The machinery already exists end to end, so this is mostly threading a flag:
if_not_existson the two AST nodes and the two plans, aparse_if_not_exists()call in each parse function, and the established "turn the catalog's
already-exists error into a notice" arm in the sequencer.
Two things worth calling out:
The skip happens at the catalog transaction, where every sibling path puts
it, rather than short-circuiting early on the in-memory catalog. That means
the statement is validated in full first, so
CREATE CLUSTER IF NOT EXISTS c (SIZE 'typo')still reports the bad size rather than silently succeedingbecause
chappens to exist. The cost is that a skipped statement stillallocates (and discards) a cluster id, which is a durable catalog write. That
is the same cost every other
CREATE ... IF NOT EXISTSalready pays, andsilently accepting a typo'd config in a provisioning script is the worse
failure mode.
A bare
ifidentifier now renders quoted. TheIF [NOT] EXISTSclause sitsexactly where the object name goes, so a rendered
CREATE CLUSTER if (SIZE …)no longer reparses, which breaks both the plan/unplan roundtrip assertion in
plan_create_clusterandSHOW CREATE CLUSTERfor a cluster namedif.This joins the existing list of keywords quoted for exactly this reason
(
PREPARE,INTO,WHEN, …), and it covers the same hazard for every otherstatement whose
IF EXISTSclause sits where the name goes. Note the flipside:
CREATE CLUSTER if …andCREATE CLUSTER REPLICA if.r …used to parse(the parser accepts keywords as identifiers) and now do not. Quoting still
works, and
DROP CLUSTER ifwas already broken the same way.SHOW CREATE CLUSTERdoes not renderIF NOT EXISTS. It is a property of thestatement, not of the cluster.
Tests
src/sql-parser/tests/testdata/ddl: syntax for both statements, theIF EXISTStypo, and a cluster literally namedif.test/sqllogictest/cluster.slt: idempotence, that the existing object is leftuntouched, that a bad
SIZEis still reported, the managed and unmanagedcluster variants,
FEATURES, reserved names, case sensitivity, fullSHOW CREATE CLUSTERoutput, that the replica form still requires the clusterto exist, and that it does not soften the managed-cluster rejection.
test/pgtest-mz/notice.pt: the wire-level notice for both statements.Fixes SQL-601