Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
This branch was successfully deployed
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.
Follows #3147, which rewrote column validation in the same function.
Root cause
StructureChangeManager.validate()grouped index names and check constraint names over every working row, filtered only onisValid. A row struck through for deletion kept its name in the group. So each of these saves was refused withDuplicate index name: idx_aunder "Some Changes Are Incomplete":Check constraints behaved the same way. The generator never needed that caution:
sortByDependencyruns every index drop and every check constraint drop before any add or rename. #3147 already stopped counting deleted columns.The same grouping also blocked saves that left the group alone. SQLite accepts
CONSTRAINT c CHECK (a > 0), CONSTRAINT c CHECK (a < 10)and the tab lists both, so every Structure save on such a table was refused."A deleted name is free" is not the whole answer, because three paths relied on the old check without knowing it:
DROP CONSTRAINT cremoves the first constraint named c in the table's text, and names compare without case: on a table holdingcandC,DROP CONSTRAINT "C"droppedc. Once deletions stop counting, deleting one of two same-named constraints could drop the other.UpdateTableand refuses another request while the table isUPDATING. The driver sends one request per change. A delete and a same-name add were refused by the duplicate check by accident; without it, the delete would run and the add would fail.PRIMARY: they refuse it with ERROR 1280, in any letter case. Duplicating the PRIMARY row and deleting the original was also refused by accident. Without that, a save that also changes a column splits the replacement:DROP INDEX PRIMARYcommits, the add fails, and the table has no key. Editing the PRIMARY row in place alongside a column change already did this on main.Fix
flagDuplicateNamesreplaces both hand-written blocks, at the same positions. It groups the rows the table keeps, leaving out pending deletions. A group blocks the save only when the save staged one of its rows, the rule fix(structure): hold only the columns a save changes to having a name and a type #3147 uses for columns.flagChangesToASharedConstraintNamegroups loaded check constraints by name, ignoring case. When some but not all of a group are changed or deleted, it refuses the changed ones with "More than one check constraint is named %@. Change or delete all of them in the same save." Changing every one of them saves, because each is dropped by name and added back from its own definition. This check covers check constraints only: no engine lists two indexes under one name, and folding case there would only refuse PostgreSQL's case-distinct names.SchemaStatementGenerator.replacingIndexesInPlacepairs a.deleteIndexand an.addIndexof the same name into.modifyIndex(old:new:), which is whatPluginSchemaOperation.modifyIndexdescribes.sortByDependencypairs through it and the refusal loop reads the same list, so what the driver is asked about matches what it writes. Results by engine:ALTER TABLE … DROP INDEX idx_a, ADD INDEX idx_a (…), which keeps the old index if the server rejects the new one..modifyIndexrefusal answers the same-name case before anything runs.SchemaOperationRefusalasks about.dropIndex(old)before.modifyIndexand.addIndex(new), so DynamoDB's primary key and local indexes get their real reason instead of "delete it and save".PRIMARYin any letter case, before anything runs.SchemaStatementGenerator.inNameOrderorders renames and one-statement index replacements so none takes a name before the change holding it has let it go, keeping staging order otherwise. Two or more that hold each other's names in a cycle, such as a swap, are each split into a drop, run with the other drops, and an add. Names compare without case for this, as MySQL, MariaDB and SQLite resolve them.candCare one name to SQLite and MariaDB, so the duplicate check groups constraint names without case and refuses the pair before anything runs.CLUSTEREDindex added by Duplicate or paste is re-decided after every change:CLUSTEREDwhen no index the table keeps holds the place,NONCLUSTEREDbeside one that does. So Duplicate, edit, then delete the original ends with a clustered index, and undoing the delete hands the place back. A copy whose type the user picks keeps it.PRIMARY, reusing a constraint name and SQLite's same-named constraints. dynamodb.mdx covers one index change per save.Verified
PRIMARY.StructureIndexNameReuseUITestspassed, and it failed against the base validator with "Some Changes Are Incomplete Duplicate index name: idx_tag". It seedsidx_bodyon body andidx_tagon tag, deletes one, renames the other onto its name, saves, and assertssqlite_masterholds only the deleted name, now defined on the other column.DROP CONSTRAINT ctakes the first of two constraints named c, andDROP CONSTRAINT "C"takesc. Two drops remove both. Drop, drop, then add leaves exactly the rewritten constraint.CREATE INDEX idx_aworks straight afterDROP INDEX idx_a.DROP INDEX idx_athenCREATE INDEX idx_a,DROP CONSTRAINT cthenADD CONSTRAINT c, andDROP CONSTRAINT cthenRENAME CONSTRAINT d TO call work."c"and"C"coexist on one table.ADD INDEX PRIMARY,primaryandPrimaryeach fail with 1280.DROP INDEX PRIMARYthenADD UNIQUE INDEX PRIMARY, the table is left with no key.DROP INDEX idx_a, ADD UNIQUE INDEX idx_a (b)over duplicate values fails with 1062 and keeps idx_a. The split form loses it.ctob, deletea,btoa) ran in staging order and failed partway on MySQL and MariaDB, a P2 thatcandCpassed as two constraint names, and a P2 that a duplicated clustered index stayedNONCLUSTEREDafter its original was deleted, leaving the table with none. All three are fixed above. 12 of the new cases fail against the round-0 sources, and all pass with the fix.mainatc21dc512e. 7 unit suites plusStringCatalogIntegrityTests: 134 of 134.StructureIndexNameReuseUITests: 2 of 2.verify.sh docspasses.Deliberately not fixed here
UpdateTablerequests, and the second fails after the first has run, as on main. The rule belongs in a save-level review, which feat/mongodb-structure-field-edits adds asreviewSchemaChange. A second batch refusal in PluginKit here would compete with it. The docs now say to save one index change at a time.CONSTRAINT name CHECKclauses. A column-level check, UNIQUE or foreign key sharing the name is invisible to the Structure tab. A complete guard belongs in the SQLite driver.idx_abesideIDX_Ais refused by the server at save time. PostgreSQL keeps the two apart, so folding case for indexes would refuse a valid save there.