-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sql: Add IF NOT EXISTS modifier to ALTER TABLE ... ADD CONSTRAINT #71257
sql: Add IF NOT EXISTS modifier to ALTER TABLE ... ADD CONSTRAINT #71257
Conversation
@ekalinin I'm very sorry that I did not realize you already had a pull request up for this issue, #53095, and furthermore that you had recently intended to rebase it. It was right there in github, but I didn't notice until right now, my apologies. I looked at your pull request and found it reassuring that we essentially took the same approach in implementing this. My only significant point of contention pertains to the handling the IF NOT EXISTS in the I also wasn't sure about changing the grammar for |
Hey @postamar! I just closed my PR as i think your PR is better ;) |
I'm converting this PR back to draft mode to rebase it. Now that #70604 has been merged to master, I've been able to find a few more subtle bugs. |
ca916db
to
d59d9ea
Compare
20bdaca
to
49f2c5e
Compare
@@ -2222,6 +2222,17 @@ alter_table_cmd: | |||
ValidationBehavior: $3.validationBehavior(), | |||
} | |||
} | |||
// ALTER TABLE <name> ADD CONSTRAINT IF NOT EXISTS ... | |||
| ADD CONSTRAINT IF NOT EXISTS constraint_name constraint_elem opt_validate_behavior |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if instead of another parser case we added an opt_if_not_exist to the existing rule?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
last time i tried something like that i got shift reduce'd to oblivion, but i didnt figure out why. you can try but i think that's why even in pg IF EXISTS / NOT EXISTS are always a separate clause.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The presence of IF NOT EXISTS makes the constraint_name mandatory instead of optional. There were several ways to deal with this awkwardness and because I don't have taste in these matters I picked the one which made for the smallest diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry had this in pending for ages
pkg/sql/alter_table.go
Outdated
@@ -194,6 +194,12 @@ func (n *alterTableNode) startExec(params runParams) error { | |||
return err | |||
} | |||
case *tree.AlterTableAddConstraint: | |||
skip, err := validateConstraintNameIsNotUsed(n.tableDesc, t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: pedantically:
if skip, err := validateConstraintNameIsNotUsed(n.tableDesc, t); err != nil {
...
} else if skip {
....
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -578,7 +578,7 @@ t CREATE TABLE public.t ( | |||
statement ok | |||
CREATE INDEX i ON t (x); | |||
|
|||
statement error pq: constraint with name i already exists | |||
statement error pgcode 42P07 an index named "i" already exists or is being dropped |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i wonder if we should keep "constraint" here instead of "index" in the error message. seems more postgres-like
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My rationale for this was that since I'm returning pgcode.DuplicateRelation
I might as well reference a relation. I don't know what the right thing to do is here and I'm not familiar with postgres. Should I change the message to s/constraint/index only, or should I also change the pgcode to something else? I'll defer to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm having looked into this further, it turns out that we sometimes return pgcode.DuplicateObject
and a duplicate constraint name
message, depending on which statements are executed.
For the sake of uniformity perhaps we should always return pgcode.DuplicateObject
and not talk about indexes.
@@ -2222,6 +2222,17 @@ alter_table_cmd: | |||
ValidationBehavior: $3.validationBehavior(), | |||
} | |||
} | |||
// ALTER TABLE <name> ADD CONSTRAINT IF NOT EXISTS ... | |||
| ADD CONSTRAINT IF NOT EXISTS constraint_name constraint_elem opt_validate_behavior |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
last time i tried something like that i got shift reduce'd to oblivion, but i didnt figure out why. you can try but i think that's why even in pg IF EXISTS / NOT EXISTS are always a separate clause.
49f2c5e
to
b8bee29
Compare
Previously, it was not possible to execute ALTER TABLE ... ADD CONSTRAINT IF NOT EXISTS ... statements. This commit adds this IF NOT EXISTS modifier to the ADD CONSTRAINT command of the ALTER TABLE statement. When the modifier is present and the defined constraint name already exists in the table, the statement no-ops instead of erroring. Note that this syntax is not supported in PostgreSQL, however PostgreSQL has transactional schema changes and PL/pgSQL which make it possible to achieve the same thing. CockroachDB has none of that yet. This commit also fixes some minor bugs or inconsistencies in the handling of duplicate index names. Fixes cockroachdb#53007. Release note (sql change): added ALTER TABLE ... ADD CONSTRAINT IF NOT EXISTS.
b8bee29
to
e89093f
Compare
Thanks for the review! bors r+ |
Build succeeded: |
Previously, it was not possible to execute ALTER TABLE ... ADD
CONSTRAINT IF NOT EXISTS ... statements. This commit adds this IF NOT
EXISTS modifier to the ADD CONSTRAINT command of the ALTER TABLE
statement. When the modifier is present and the defined constraint name
already exists in the table, the statement no-ops instead of erroring.
Note that this syntax is not supported in PostgreSQL, however PostgreSQL
has transactional schema changes and PL/pgSQL which make it possible to
achieve the same thing. CockroachDB has none of that yet.
Fixes #53007.
Release note (sql change): added ALTER TABLE ... ADD CONSTRAINT IF NOT
EXISTS.