@quereus/quereus 4.20.0 → 4.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/src/common/types.d.ts +4 -4
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/schema/catalog-rendering.js +13 -1
- package/dist/src/schema/catalog-rendering.js.map +1 -1
- package/dist/src/schema/catalog.d.ts +35 -2
- package/dist/src/schema/catalog.d.ts.map +1 -1
- package/dist/src/schema/catalog.js +42 -33
- package/dist/src/schema/catalog.js.map +1 -1
- package/dist/src/schema/schema-differ.d.ts +1 -1
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +195 -33
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/schema/unique-enforcement.d.ts +23 -1
- package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
- package/dist/src/schema/unique-enforcement.js +43 -1
- package/dist/src/schema/unique-enforcement.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +15 -12
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +87 -100
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/package.json +7 -4
- package/test/README.md +173 -0
- package/test/logic/01-basic.sqllogic +39 -0
- package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
- package/test/logic/01.2-strings.sqllogic +43 -0
- package/test/logic/01.5-insert-select.sqllogic +237 -0
- package/test/logic/01.6-update-extras.sqllogic +118 -0
- package/test/logic/01.7-update-from.sqllogic +67 -0
- package/test/logic/01.8-delete-extras.sqllogic +122 -0
- package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
- package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
- package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
- package/test/logic/01.9-query-expr-values.sqllogic +111 -0
- package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
- package/test/logic/02-filters.sqllogic +54 -0
- package/test/logic/02-smoke.sqllogic +62 -0
- package/test/logic/02.1-bind-parameters.sqllogic +223 -0
- package/test/logic/03-expressions.sqllogic +190 -0
- package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
- package/test/logic/03.4-defaults.sqllogic +554 -0
- package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
- package/test/logic/03.5-tvf.sqllogic +61 -0
- package/test/logic/03.6-type-system.sqllogic +544 -0
- package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
- package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
- package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
- package/test/logic/03.8-not-precedence.sqllogic +255 -0
- package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
- package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
- package/test/logic/04-order-by.sqllogic +38 -0
- package/test/logic/04-transactions.sqllogic +239 -0
- package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
- package/test/logic/05-vtab_memory.sqllogic +50 -0
- package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
- package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
- package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
- package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
- package/test/logic/06-builtin_functions.sqllogic +149 -0
- package/test/logic/06.1-string-functions.sqllogic +92 -0
- package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
- package/test/logic/06.2-math-functions.sqllogic +82 -0
- package/test/logic/06.3-schema.sqllogic +48 -0
- package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
- package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
- package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
- package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
- package/test/logic/06.3.4-view-info.sqllogic +378 -0
- package/test/logic/06.3.5-column-info.sqllogic +347 -0
- package/test/logic/06.3.6-schema-views.sqllogic +29 -0
- package/test/logic/06.4-schema-search-path.sqllogic +354 -0
- package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
- package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
- package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
- package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
- package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
- package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
- package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
- package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
- package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
- package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
- package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
- package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
- package/test/logic/06.7-json-extended.sqllogic +53 -0
- package/test/logic/06.8-json-path-operators.sqllogic +99 -0
- package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
- package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
- package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
- package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
- package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
- package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
- package/test/logic/07-aggregates.sqllogic +193 -0
- package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
- package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
- package/test/logic/07.3-group-by-extras.sqllogic +602 -0
- package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
- package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
- package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
- package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
- package/test/logic/07.5-window.sqllogic +1941 -0
- package/test/logic/07.5.1-window-named.sqllogic +13 -0
- package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
- package/test/logic/07.6-subqueries.sqllogic +78 -0
- package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
- package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
- package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
- package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
- package/test/logic/07.7.1-in-extras.sqllogic +158 -0
- package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
- package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
- package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
- package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
- package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
- package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
- package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
- package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
- package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
- package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
- package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
- package/test/logic/07.9-in-value-list.sqllogic +154 -0
- package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
- package/test/logic/08-views.sqllogic +64 -0
- package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
- package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
- package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
- package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
- package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
- package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
- package/test/logic/09-set_operations.sqllogic +244 -0
- package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
- package/test/logic/10-distinct_datatypes.sqllogic +127 -0
- package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
- package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
- package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
- package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
- package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
- package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
- package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
- package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
- package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
- package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
- package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
- package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
- package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
- package/test/logic/10.2-column-features.sqllogic +365 -0
- package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
- package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
- package/test/logic/10.3-function-features.sqllogic +247 -0
- package/test/logic/10.4-schema-scale.sqllogic +168 -0
- package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
- package/test/logic/10.5-indexes.sqllogic +164 -0
- package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
- package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
- package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
- package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
- package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
- package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
- package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
- package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
- package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
- package/test/logic/100.1-where-extras.sqllogic +163 -0
- package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
- package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
- package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
- package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
- package/test/logic/102-unique-constraints.sqllogic +145 -0
- package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
- package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
- package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
- package/test/logic/102.2-unique-collation.sqllogic +181 -0
- package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
- package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
- package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
- package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
- package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
- package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
- package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
- package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
- package/test/logic/108-cardinality-estimation.sqllogic +146 -0
- package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
- package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
- package/test/logic/11-joins.sqllogic +86 -0
- package/test/logic/11.1-join-using.sqllogic +267 -0
- package/test/logic/11.2-comma-join.sqllogic +35 -0
- package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
- package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
- package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
- package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
- package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
- package/test/logic/12-empty-primary-key.sqllogic +124 -0
- package/test/logic/12-join_padding_order.sqllogic +58 -0
- package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
- package/test/logic/13-cte.sqllogic +137 -0
- package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
- package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
- package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
- package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
- package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
- package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
- package/test/logic/13.4-cte-extras.sqllogic +98 -0
- package/test/logic/13.5-cte-join-order.sqllogic +166 -0
- package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
- package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
- package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
- package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
- package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
- package/test/logic/14-utilities.sqllogic +168 -0
- package/test/logic/15-timespan.sqllogic +279 -0
- package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
- package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
- package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
- package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
- package/test/logic/16-epoch.sqllogic +187 -0
- package/test/logic/17-weekday-modifier.sqllogic +78 -0
- package/test/logic/18-json-string-escapes.sqllogic +86 -0
- package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
- package/test/logic/20-empty-single-row.sqllogic +261 -0
- package/test/logic/21-null-edge-cases.sqllogic +227 -0
- package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
- package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
- package/test/logic/21.2-between-edges.sqllogic +157 -0
- package/test/logic/22-boundary-values.sqllogic +175 -0
- package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
- package/test/logic/24-builtin-branches.sqllogic +611 -0
- package/test/logic/24.1-substr-extras.sqllogic +75 -0
- package/test/logic/24.2-random-extras.sqllogic +39 -0
- package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
- package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
- package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
- package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
- package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
- package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
- package/test/logic/26-join-edge-cases.sqllogic +333 -0
- package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
- package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
- package/test/logic/26.3-join-on-constants.sqllogic +61 -0
- package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
- package/test/logic/27-window-edge-cases.sqllogic +206 -0
- package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
- package/test/logic/27.2-window-exclude.sqllogic +13 -0
- package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
- package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
- package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
- package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
- package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
- package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
- package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
- package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
- package/test/logic/40-constraints.sqllogic +418 -0
- package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
- package/test/logic/40.2-check-extras.sqllogic +683 -0
- package/test/logic/41-alter-table.sqllogic +191 -0
- package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
- package/test/logic/41-fk-cross-schema.sqllogic +155 -0
- package/test/logic/41-fk-extended-targets.sqllogic +173 -0
- package/test/logic/41-foreign-keys.sqllogic +1001 -0
- package/test/logic/41-generated-column-errors.sqllogic +225 -0
- package/test/logic/41-generated-column-extras.sqllogic +598 -0
- package/test/logic/41-generated-column-scope.sqllogic +329 -0
- package/test/logic/41-generated-columns.sqllogic +361 -0
- package/test/logic/41.1-alter-pk.sqllogic +230 -0
- package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
- package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
- package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
- package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
- package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
- package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
- package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
- package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
- package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
- package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
- package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
- package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
- package/test/logic/41.2-alter-column.sqllogic +382 -0
- package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
- package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
- package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
- package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
- package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
- package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
- package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
- package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
- package/test/logic/41.5-alter-misc.sqllogic +48 -0
- package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
- package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
- package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
- package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
- package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
- package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
- package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
- package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
- package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
- package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
- package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
- package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
- package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
- package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
- package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
- package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
- package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
- package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
- package/test/logic/42-committed-snapshot.sqllogic +254 -0
- package/test/logic/42-returning.sqllogic +159 -0
- package/test/logic/42.1-returning-extras.sqllogic +232 -0
- package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
- package/test/logic/43-default-nullability.sqllogic +131 -0
- package/test/logic/43-transition-constraints.sqllogic +341 -0
- package/test/logic/43.1-default-collation.sqllogic +140 -0
- package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
- package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
- package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
- package/test/logic/44-determinism-validation.sqllogic +164 -0
- package/test/logic/44-orthogonality.sqllogic +146 -0
- package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
- package/test/logic/45-udf-determinism.sqllogic +39 -0
- package/test/logic/46-mutation-context.sqllogic +595 -0
- package/test/logic/47-upsert.sqllogic +255 -0
- package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
- package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
- package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
- package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
- package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
- package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
- package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
- package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
- package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
- package/test/logic/49-reference-graph.sqllogic +84 -0
- package/test/logic/50-declarative-schema.sqllogic +2550 -0
- package/test/logic/50-metadata-tags.sqllogic +1033 -0
- package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
- package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
- package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
- package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
- package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
- package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
- package/test/logic/51-lens-foundation.sqllogic +147 -0
- package/test/logic/51-materialized-views.sqllogic +376 -0
- package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
- package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
- package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
- package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
- package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
- package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
- package/test/logic/52-lens-overrides.sqllogic +566 -0
- package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
- package/test/logic/53-reserved-tags.sqllogic +252 -0
- package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
- package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
- package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
- package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
- package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
- package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
- package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
- package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
- package/test/logic/55-lens-prover.sqllogic +202 -0
- package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
- package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
- package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
- package/test/logic/81-quickpick.sqllogic +24 -0
- package/test/logic/82-bloom-join.sqllogic +185 -0
- package/test/logic/83-merge-join.sqllogic +280 -0
- package/test/logic/84-asof-scan.sqllogic +238 -0
- package/test/logic/84-key-cardinality.sqllogic +50 -0
- package/test/logic/85-relational-const-folding.sqllogic +51 -0
- package/test/logic/86-scalar-cse.sqllogic +42 -0
- package/test/logic/90-error_paths.sqllogic +114 -0
- package/test/logic/90.1-parse-errors.sqllogic +77 -0
- package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
- package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
- package/test/logic/90.3-expression-errors.sqllogic +43 -0
- package/test/logic/90.4-dml-errors.sqllogic +47 -0
- package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
- package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
- package/test/logic/90.6-select-error-paths.sqllogic +57 -0
- package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
- package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
- package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
- package/test/logic/93.1-view-error-paths.sqllogic +74 -0
- package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
- package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
- package/test/logic/93.4-view-mutation.sqllogic +4881 -0
- package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
- package/test/logic/93.5-authored-inverse.sqllogic +415 -0
- package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
- package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
- package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
- package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
- package/test/logic/95-assertions.sqllogic +1417 -0
- package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
- package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
- package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
- package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
- package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
- package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
- package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
- package/test/logic/drop-unique-index.sqllogic +88 -0
- package/test/logic/pushdown-test.sqllogic +36 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
-- A write that collides on the PRIMARY KEY and resolves it by REPLACE must still
|
|
2
|
+
-- enforce every other UNIQUE constraint, each under its own conflict action
|
|
3
|
+
-- (statement OR > per-constraint default > ABORT). Expected results match
|
|
4
|
+
-- SQLite except cases G and M2, which pin a deliberate divergence (see
|
|
5
|
+
-- docs/sql-dml.md § Conflict Resolution): the row displaced at the PK counts as
|
|
6
|
+
-- already gone, so its UNIQUE values are free for the new row. Previously the
|
|
7
|
+
-- memory table wrote the row and returned on the PK-REPLACE branch, leaving a
|
|
8
|
+
-- secondary UNIQUE column duplicated.
|
|
9
|
+
|
|
10
|
+
-- ===================================
|
|
11
|
+
-- A. INSERT OR REPLACE — PK and secondary UNIQUE conflicts both resolved by deletion
|
|
12
|
+
-- ===================================
|
|
13
|
+
|
|
14
|
+
create table pr_a (id integer primary key, v text unique);
|
|
15
|
+
create table pr_a_child (id integer primary key, parent_id integer references pr_a(id) on delete cascade);
|
|
16
|
+
insert into pr_a values (1, 'a'), (2, 'b');
|
|
17
|
+
insert into pr_a_child values (20, 2);
|
|
18
|
+
|
|
19
|
+
insert or replace into pr_a values (1, 'b');
|
|
20
|
+
|
|
21
|
+
select * from pr_a order by id;
|
|
22
|
+
→ [{"id":1,"v":"b"}]
|
|
23
|
+
|
|
24
|
+
-- The row evicted on the secondary UNIQUE (id=2) runs the full delete pipeline.
|
|
25
|
+
select * from pr_a_child;
|
|
26
|
+
→ []
|
|
27
|
+
|
|
28
|
+
drop table pr_a_child;
|
|
29
|
+
drop table pr_a;
|
|
30
|
+
|
|
31
|
+
-- ===================================
|
|
32
|
+
-- B. PK-level REPLACE; UNIQUE keeps its own default (ABORT) → error
|
|
33
|
+
-- ===================================
|
|
34
|
+
|
|
35
|
+
create table pr_b (id integer primary key on conflict replace, v text unique);
|
|
36
|
+
insert into pr_b values (1, 'a'), (2, 'b');
|
|
37
|
+
|
|
38
|
+
insert into pr_b values (1, 'b');
|
|
39
|
+
-- error: UNIQUE constraint failed
|
|
40
|
+
|
|
41
|
+
select * from pr_b order by id;
|
|
42
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
43
|
+
|
|
44
|
+
drop table pr_b;
|
|
45
|
+
|
|
46
|
+
-- ===================================
|
|
47
|
+
-- C. Key-changing UPDATE under PK-level REPLACE, UNIQUE default ABORT → error, table unchanged
|
|
48
|
+
-- ===================================
|
|
49
|
+
|
|
50
|
+
create table pr_c (id integer primary key on conflict replace, v text unique);
|
|
51
|
+
insert into pr_c values (1, 'a'), (2, 'b'), (3, 'c');
|
|
52
|
+
|
|
53
|
+
update pr_c set id = 1, v = 'b' where id = 3;
|
|
54
|
+
-- error: UNIQUE constraint failed
|
|
55
|
+
|
|
56
|
+
select * from pr_c order by id;
|
|
57
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"},{"id":3,"v":"c"}]
|
|
58
|
+
|
|
59
|
+
drop table pr_c;
|
|
60
|
+
|
|
61
|
+
-- ===================================
|
|
62
|
+
-- D. Key-changing UPDATE, both constraints REPLACE
|
|
63
|
+
-- ===================================
|
|
64
|
+
|
|
65
|
+
create table pr_d (id integer primary key on conflict replace, v text unique on conflict replace);
|
|
66
|
+
insert into pr_d values (1, 'a'), (2, 'b'), (3, 'c');
|
|
67
|
+
|
|
68
|
+
update pr_d set id = 1, v = 'b' where id = 3;
|
|
69
|
+
|
|
70
|
+
select * from pr_d order by id;
|
|
71
|
+
→ [{"id":1,"v":"b"}]
|
|
72
|
+
|
|
73
|
+
drop table pr_d;
|
|
74
|
+
|
|
75
|
+
-- ===================================
|
|
76
|
+
-- E. INSERT, both constraints REPLACE
|
|
77
|
+
-- ===================================
|
|
78
|
+
|
|
79
|
+
create table pr_e (id integer primary key on conflict replace, v text unique on conflict replace);
|
|
80
|
+
insert into pr_e values (1, 'a'), (2, 'b');
|
|
81
|
+
|
|
82
|
+
insert into pr_e values (1, 'b');
|
|
83
|
+
|
|
84
|
+
select * from pr_e order by id;
|
|
85
|
+
→ [{"id":1,"v":"b"}]
|
|
86
|
+
|
|
87
|
+
drop table pr_e;
|
|
88
|
+
|
|
89
|
+
-- ===================================
|
|
90
|
+
-- F. PK-level REPLACE, UNIQUE IGNORE — the secondary IGNORE skips the whole insert
|
|
91
|
+
-- ===================================
|
|
92
|
+
|
|
93
|
+
create table pr_f (id integer primary key on conflict replace, v text unique on conflict ignore);
|
|
94
|
+
insert into pr_f values (1, 'a'), (2, 'b');
|
|
95
|
+
|
|
96
|
+
insert into pr_f values (1, 'b');
|
|
97
|
+
|
|
98
|
+
select * from pr_f order by id;
|
|
99
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
100
|
+
|
|
101
|
+
drop table pr_f;
|
|
102
|
+
|
|
103
|
+
-- ===================================
|
|
104
|
+
-- G. PK REPLACE whose new value equals the replaced row's own value — no self-conflict
|
|
105
|
+
-- (SQLite reports a UNIQUE error here: it checks v against the not-yet-displaced row)
|
|
106
|
+
-- ===================================
|
|
107
|
+
|
|
108
|
+
create table pr_g (id integer primary key on conflict replace, v text unique, w text);
|
|
109
|
+
insert into pr_g values (1, 'a', 'x'), (2, 'b', 'y');
|
|
110
|
+
|
|
111
|
+
insert into pr_g values (1, 'a', 'z');
|
|
112
|
+
|
|
113
|
+
select * from pr_g order by id;
|
|
114
|
+
→ [{"id":1,"v":"a","w":"z"},{"id":2,"v":"b","w":"y"}]
|
|
115
|
+
|
|
116
|
+
drop table pr_g;
|
|
117
|
+
|
|
118
|
+
-- ===================================
|
|
119
|
+
-- H. Same as A inside an explicit transaction, rows written earlier in that transaction
|
|
120
|
+
-- ===================================
|
|
121
|
+
|
|
122
|
+
create table pr_h (id integer primary key, v text unique);
|
|
123
|
+
insert into pr_h values (1, 'a');
|
|
124
|
+
|
|
125
|
+
begin;
|
|
126
|
+
insert into pr_h values (2, 'b');
|
|
127
|
+
insert or replace into pr_h values (1, 'b');
|
|
128
|
+
select * from pr_h order by id;
|
|
129
|
+
→ [{"id":1,"v":"b"}]
|
|
130
|
+
commit;
|
|
131
|
+
|
|
132
|
+
select * from pr_h order by id;
|
|
133
|
+
→ [{"id":1,"v":"b"}]
|
|
134
|
+
|
|
135
|
+
drop table pr_h;
|
|
136
|
+
|
|
137
|
+
-- ===================================
|
|
138
|
+
-- I. Row at the replaced PK written earlier in the transaction; the secondary
|
|
139
|
+
-- UNIQUE conflict is a committed row
|
|
140
|
+
-- ===================================
|
|
141
|
+
|
|
142
|
+
create table pr_i (id integer primary key, v text unique);
|
|
143
|
+
insert into pr_i values (2, 'b');
|
|
144
|
+
|
|
145
|
+
begin;
|
|
146
|
+
insert into pr_i values (1, 'a');
|
|
147
|
+
insert or replace into pr_i values (1, 'b');
|
|
148
|
+
select * from pr_i order by id;
|
|
149
|
+
→ [{"id":1,"v":"b"}]
|
|
150
|
+
commit;
|
|
151
|
+
|
|
152
|
+
select * from pr_i order by id;
|
|
153
|
+
→ [{"id":1,"v":"b"}]
|
|
154
|
+
|
|
155
|
+
drop table pr_i;
|
|
156
|
+
|
|
157
|
+
-- ===================================
|
|
158
|
+
-- J. PK-level REPLACE, UNIQUE default ABORT, every row written in the transaction
|
|
159
|
+
-- ===================================
|
|
160
|
+
|
|
161
|
+
create table pr_j (id integer primary key on conflict replace, v text unique);
|
|
162
|
+
|
|
163
|
+
begin;
|
|
164
|
+
insert into pr_j values (1, 'a'), (2, 'b');
|
|
165
|
+
insert into pr_j values (1, 'b');
|
|
166
|
+
-- error: UNIQUE constraint failed
|
|
167
|
+
select * from pr_j order by id;
|
|
168
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
169
|
+
commit;
|
|
170
|
+
|
|
171
|
+
select * from pr_j order by id;
|
|
172
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
173
|
+
|
|
174
|
+
drop table pr_j;
|
|
175
|
+
|
|
176
|
+
-- ===================================
|
|
177
|
+
-- K. PK-level REPLACE, UNIQUE default ABORT; row at the replaced PK written in the
|
|
178
|
+
-- transaction, the secondary conflict is a committed row
|
|
179
|
+
-- ===================================
|
|
180
|
+
|
|
181
|
+
create table pr_k (id integer primary key on conflict replace, v text unique);
|
|
182
|
+
insert into pr_k values (2, 'b');
|
|
183
|
+
|
|
184
|
+
begin;
|
|
185
|
+
insert into pr_k values (1, 'a');
|
|
186
|
+
insert into pr_k values (1, 'b');
|
|
187
|
+
-- error: UNIQUE constraint failed
|
|
188
|
+
commit;
|
|
189
|
+
|
|
190
|
+
select * from pr_k order by id;
|
|
191
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
192
|
+
|
|
193
|
+
drop table pr_k;
|
|
194
|
+
|
|
195
|
+
-- ===================================
|
|
196
|
+
-- L. Key-changing UPDATE inside a transaction over rows written in that transaction
|
|
197
|
+
-- ===================================
|
|
198
|
+
|
|
199
|
+
create table pr_l (id integer primary key on conflict replace, v text unique);
|
|
200
|
+
create table pr_l2 (id integer primary key on conflict replace, v text unique on conflict replace);
|
|
201
|
+
|
|
202
|
+
begin;
|
|
203
|
+
insert into pr_l values (1, 'a'), (2, 'b'), (3, 'c');
|
|
204
|
+
update pr_l set id = 1, v = 'b' where id = 3;
|
|
205
|
+
-- error: UNIQUE constraint failed
|
|
206
|
+
select * from pr_l order by id;
|
|
207
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"},{"id":3,"v":"c"}]
|
|
208
|
+
|
|
209
|
+
insert into pr_l2 values (1, 'a'), (2, 'b'), (3, 'c');
|
|
210
|
+
update pr_l2 set id = 1, v = 'b' where id = 3;
|
|
211
|
+
select * from pr_l2 order by id;
|
|
212
|
+
→ [{"id":1,"v":"b"}]
|
|
213
|
+
commit;
|
|
214
|
+
|
|
215
|
+
select * from pr_l order by id;
|
|
216
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"},{"id":3,"v":"c"}]
|
|
217
|
+
select * from pr_l2 order by id;
|
|
218
|
+
→ [{"id":1,"v":"b"}]
|
|
219
|
+
|
|
220
|
+
drop table pr_l2;
|
|
221
|
+
drop table pr_l;
|
|
222
|
+
|
|
223
|
+
-- ===================================
|
|
224
|
+
-- M. Key-changing UPDATE onto an occupied PK; the moving row keeps its own UNIQUE
|
|
225
|
+
-- value — neither the slot it vacates nor the displaced row may self-conflict
|
|
226
|
+
-- ===================================
|
|
227
|
+
|
|
228
|
+
create table pr_m (id integer primary key on conflict replace, v text unique);
|
|
229
|
+
insert into pr_m values (1, 'a'), (2, 'b'), (3, 'c');
|
|
230
|
+
|
|
231
|
+
update pr_m set id = 1 where id = 3;
|
|
232
|
+
|
|
233
|
+
select * from pr_m order by id;
|
|
234
|
+
→ [{"id":1,"v":"c"},{"id":2,"v":"b"}]
|
|
235
|
+
|
|
236
|
+
-- M2. The displaced row's own UNIQUE value is free for the mover to take
|
|
237
|
+
-- (SQLite reports a UNIQUE error here, as in G).
|
|
238
|
+
update pr_m set id = 2, v = 'b' where id = 1;
|
|
239
|
+
|
|
240
|
+
select * from pr_m order by id;
|
|
241
|
+
→ [{"id":2,"v":"b"}]
|
|
242
|
+
|
|
243
|
+
drop table pr_m;
|
|
244
|
+
|
|
245
|
+
-- ===================================
|
|
246
|
+
-- N. Composite primary key — PK REPLACE plus secondary UNIQUE, insert and key-changing update
|
|
247
|
+
-- ===================================
|
|
248
|
+
|
|
249
|
+
create table pr_n (a integer, b integer, v text unique on conflict replace, primary key (a, b) on conflict replace);
|
|
250
|
+
insert into pr_n values (1, 1, 'x'), (1, 2, 'y'), (2, 1, 'z');
|
|
251
|
+
|
|
252
|
+
insert or replace into pr_n values (1, 1, 'y');
|
|
253
|
+
|
|
254
|
+
select * from pr_n order by a, b;
|
|
255
|
+
→ [{"a":1,"b":1,"v":"y"},{"a":2,"b":1,"v":"z"}]
|
|
256
|
+
|
|
257
|
+
update pr_n set b = 1, a = 1 where a = 2 and b = 1;
|
|
258
|
+
|
|
259
|
+
select * from pr_n order by a, b;
|
|
260
|
+
→ [{"a":1,"b":1,"v":"z"}]
|
|
261
|
+
|
|
262
|
+
update pr_n set a = 3 where a = 1 and b = 1;
|
|
263
|
+
|
|
264
|
+
select * from pr_n order by a, b;
|
|
265
|
+
→ [{"a":3,"b":1,"v":"z"}]
|
|
266
|
+
|
|
267
|
+
drop table pr_n;
|
|
268
|
+
|
|
269
|
+
-- ===================================
|
|
270
|
+
-- O. Both channels on one write: the PK-replaced row and the UNIQUE-evicted row
|
|
271
|
+
-- each cascade to their own children
|
|
272
|
+
-- ===================================
|
|
273
|
+
|
|
274
|
+
create table pr_o (id integer primary key, v text unique);
|
|
275
|
+
create table pr_o_child (id integer primary key, parent_id integer references pr_o(id) on delete cascade);
|
|
276
|
+
insert into pr_o values (1, 'a'), (2, 'b'), (3, 'c');
|
|
277
|
+
insert into pr_o_child values (10, 1), (20, 2), (30, 3);
|
|
278
|
+
|
|
279
|
+
insert or replace into pr_o values (1, 'b');
|
|
280
|
+
|
|
281
|
+
select * from pr_o order by id;
|
|
282
|
+
→ [{"id":1,"v":"b"},{"id":3,"v":"c"}]
|
|
283
|
+
|
|
284
|
+
select * from pr_o_child order by id;
|
|
285
|
+
→ [{"id":30,"parent_id":3}]
|
|
286
|
+
|
|
287
|
+
drop table pr_o_child;
|
|
288
|
+
drop table pr_o;
|
|
289
|
+
|
|
290
|
+
-- ===================================
|
|
291
|
+
-- P. Same-PK UPDATE of a row written earlier in the transaction onto a committed
|
|
292
|
+
-- row's UNIQUE value — UNIQUE default ABORT → error, nothing reaches the commit
|
|
293
|
+
-- ===================================
|
|
294
|
+
|
|
295
|
+
create table pr_p (id integer primary key, v text unique);
|
|
296
|
+
insert into pr_p values (2, 'b');
|
|
297
|
+
|
|
298
|
+
begin;
|
|
299
|
+
insert into pr_p values (1, 'a');
|
|
300
|
+
update pr_p set v = 'b' where id = 1;
|
|
301
|
+
-- error: UNIQUE constraint failed
|
|
302
|
+
select * from pr_p order by id;
|
|
303
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
304
|
+
commit;
|
|
305
|
+
|
|
306
|
+
select * from pr_p order by id;
|
|
307
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
308
|
+
|
|
309
|
+
drop table pr_p;
|
|
310
|
+
|
|
311
|
+
-- ===================================
|
|
312
|
+
-- Q. Same-PK UPDATE under a PK-level REPLACE, rows written in the transaction — the
|
|
313
|
+
-- PK's action does not apply to the UNIQUE, which keeps its default ABORT
|
|
314
|
+
-- ===================================
|
|
315
|
+
|
|
316
|
+
create table pr_q (id integer primary key on conflict replace, v text unique);
|
|
317
|
+
|
|
318
|
+
begin;
|
|
319
|
+
insert into pr_q values (1, 'a'), (2, 'b');
|
|
320
|
+
update pr_q set v = 'b' where id = 1;
|
|
321
|
+
-- error: UNIQUE constraint failed
|
|
322
|
+
commit;
|
|
323
|
+
|
|
324
|
+
select * from pr_q order by id;
|
|
325
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
326
|
+
|
|
327
|
+
drop table pr_q;
|
|
328
|
+
|
|
329
|
+
-- ===================================
|
|
330
|
+
-- R. Same-PK UPDATE, UNIQUE IGNORE, conflict with a committed row — the update is
|
|
331
|
+
-- skipped and the row written in the transaction survives the commit
|
|
332
|
+
-- ===================================
|
|
333
|
+
|
|
334
|
+
create table pr_r (id integer primary key, v text unique on conflict ignore);
|
|
335
|
+
insert into pr_r values (2, 'b');
|
|
336
|
+
|
|
337
|
+
begin;
|
|
338
|
+
insert into pr_r values (1, 'a');
|
|
339
|
+
update pr_r set v = 'b' where id = 1;
|
|
340
|
+
select * from pr_r order by id;
|
|
341
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
342
|
+
commit;
|
|
343
|
+
|
|
344
|
+
select * from pr_r order by id;
|
|
345
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
346
|
+
|
|
347
|
+
drop table pr_r;
|
|
348
|
+
|
|
349
|
+
-- ===================================
|
|
350
|
+
-- S. Same-PK UPDATE, UNIQUE REPLACE, conflict with a committed row — the committed
|
|
351
|
+
-- row is evicted through the full delete pipeline (its child cascades)
|
|
352
|
+
-- ===================================
|
|
353
|
+
|
|
354
|
+
create table pr_s (id integer primary key, v text unique on conflict replace);
|
|
355
|
+
create table pr_s_child (id integer primary key, parent_id integer references pr_s(id) on delete cascade);
|
|
356
|
+
insert into pr_s values (2, 'b');
|
|
357
|
+
insert into pr_s_child values (20, 2);
|
|
358
|
+
|
|
359
|
+
begin;
|
|
360
|
+
insert into pr_s values (1, 'a');
|
|
361
|
+
update pr_s set v = 'b' where id = 1;
|
|
362
|
+
select * from pr_s order by id;
|
|
363
|
+
→ [{"id":1,"v":"b"}]
|
|
364
|
+
select * from pr_s_child;
|
|
365
|
+
→ []
|
|
366
|
+
commit;
|
|
367
|
+
|
|
368
|
+
select * from pr_s order by id;
|
|
369
|
+
→ [{"id":1,"v":"b"}]
|
|
370
|
+
select * from pr_s_child;
|
|
371
|
+
→ []
|
|
372
|
+
|
|
373
|
+
drop table pr_s_child;
|
|
374
|
+
drop table pr_s;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
-- INSERT OR FAIL combined with engine-level constraints (NOT NULL / CHECK).
|
|
2
|
+
-- The 47.2 case 7 covers OR FAIL + UNIQUE; this fills in the engine-level
|
|
3
|
+
-- constraints so we know the FAIL→commit-prior-rows path applies uniformly.
|
|
4
|
+
|
|
5
|
+
-- ===================================
|
|
6
|
+
-- 1. OR FAIL on NOT NULL violation — earlier rows remain
|
|
7
|
+
-- ===================================
|
|
8
|
+
|
|
9
|
+
create table t_nn (id integer primary key, name text);
|
|
10
|
+
insert into t_nn values (10, 'pre');
|
|
11
|
+
|
|
12
|
+
insert or fail into t_nn values (1, 'a'), (2, 'b'), (3, null), (4, 'd');
|
|
13
|
+
-- error: NOT NULL
|
|
14
|
+
|
|
15
|
+
select id, name from t_nn order by id;
|
|
16
|
+
→ [{"id":1,"name":"a"},{"id":2,"name":"b"},{"id":10,"name":"pre"}]
|
|
17
|
+
|
|
18
|
+
drop table t_nn;
|
|
19
|
+
|
|
20
|
+
-- ===================================
|
|
21
|
+
-- 2. OR FAIL on CHECK violation — earlier rows remain
|
|
22
|
+
-- ===================================
|
|
23
|
+
|
|
24
|
+
create table t_ck (id integer primary key, n integer check (n > 0));
|
|
25
|
+
insert into t_ck values (10, 100);
|
|
26
|
+
|
|
27
|
+
insert or fail into t_ck values (1, 1), (2, 2), (3, -1), (4, 4);
|
|
28
|
+
-- error: CHECK
|
|
29
|
+
|
|
30
|
+
select id, n from t_ck order by id;
|
|
31
|
+
→ [{"id":1,"n":1},{"id":2,"n":2},{"id":10,"n":100}]
|
|
32
|
+
|
|
33
|
+
drop table t_ck;
|
|
34
|
+
|
|
35
|
+
-- ===================================
|
|
36
|
+
-- 3. OR ROLLBACK on engine-level CHECK rolls back the enclosing transaction
|
|
37
|
+
-- ===================================
|
|
38
|
+
|
|
39
|
+
create table t_rb (id integer primary key, n integer check (n > 0));
|
|
40
|
+
insert into t_rb values (1, 10);
|
|
41
|
+
-- run
|
|
42
|
+
|
|
43
|
+
begin;
|
|
44
|
+
insert into t_rb values (2, 20);
|
|
45
|
+
insert or rollback into t_rb values (3, -5);
|
|
46
|
+
-- error: CHECK
|
|
47
|
+
|
|
48
|
+
-- The enclosing transaction was auto-rolled-back; only the pre-tx insert remains.
|
|
49
|
+
select id, n from t_rb order by id;
|
|
50
|
+
→ [{"id":1,"n":10}]
|
|
51
|
+
|
|
52
|
+
drop table t_rb;
|
|
53
|
+
|
|
54
|
+
-- ===================================
|
|
55
|
+
-- 4. OR FAIL nested under a user-level SAVEPOINT — ROLLBACK TO must work
|
|
56
|
+
-- ===================================
|
|
57
|
+
-- The per-row OR FAIL savepoint (`__or_fail_N`) is created and released
|
|
58
|
+
-- inside the bracket. After the bracket ends, the user-level savepoint
|
|
59
|
+
-- stack must remain aligned with TxnMgr's. If the per-row create/release
|
|
60
|
+
-- did not broadcast to connections (the bug this exercises), per-connection
|
|
61
|
+
-- stacks would drift relative to TxnMgr and ROLLBACK TO sp would restore
|
|
62
|
+
-- the wrong layer.
|
|
63
|
+
|
|
64
|
+
create table t_sp (id integer primary key, name text);
|
|
65
|
+
insert into t_sp values (10, 'pre');
|
|
66
|
+
-- run
|
|
67
|
+
|
|
68
|
+
begin;
|
|
69
|
+
savepoint sp1;
|
|
70
|
+
-- OR FAIL succeeds for all rows: per-row create/release brackets must
|
|
71
|
+
-- compose cleanly with the surrounding user savepoint.
|
|
72
|
+
insert or fail into t_sp values (1, 'a'), (2, 'b'), (3, 'c');
|
|
73
|
+
select id, name from t_sp order by id;
|
|
74
|
+
→ [{"id":1,"name":"a"},{"id":2,"name":"b"},{"id":3,"name":"c"},{"id":10,"name":"pre"}]
|
|
75
|
+
|
|
76
|
+
-- ROLLBACK TO sp1: must undo all three OR-FAIL rows, leaving only `pre`.
|
|
77
|
+
rollback to savepoint sp1;
|
|
78
|
+
select id, name from t_sp order by id;
|
|
79
|
+
→ [{"id":10,"name":"pre"}]
|
|
80
|
+
|
|
81
|
+
-- Re-INSERT under the same sp1 to verify the stack is still well-formed.
|
|
82
|
+
insert or fail into t_sp values (4, 'd'), (5, 'e');
|
|
83
|
+
select id, name from t_sp order by id;
|
|
84
|
+
→ [{"id":4,"name":"d"},{"id":5,"name":"e"},{"id":10,"name":"pre"}]
|
|
85
|
+
|
|
86
|
+
release savepoint sp1;
|
|
87
|
+
commit;
|
|
88
|
+
|
|
89
|
+
select id, name from t_sp order by id;
|
|
90
|
+
→ [{"id":4,"name":"d"},{"id":5,"name":"e"},{"id":10,"name":"pre"}]
|
|
91
|
+
|
|
92
|
+
drop table t_sp;
|
|
93
|
+
|
|
94
|
+
-- ===================================
|
|
95
|
+
-- 5. OR FAIL whose middle row fails, nested under a SAVEPOINT
|
|
96
|
+
-- ===================================
|
|
97
|
+
-- When OR FAIL aborts mid-statement, the per-row __or_fail_N savepoint for
|
|
98
|
+
-- the failing row is rolled back + released. Earlier rows commit. The
|
|
99
|
+
-- surrounding sp1 must still be reachable for a follow-on rollback.
|
|
100
|
+
|
|
101
|
+
create table t_spf (id integer primary key, n integer check (n > 0));
|
|
102
|
+
insert into t_spf values (100, 99);
|
|
103
|
+
-- run
|
|
104
|
+
|
|
105
|
+
begin;
|
|
106
|
+
savepoint sp1;
|
|
107
|
+
insert or fail into t_spf values (1, 1), (2, 2), (3, -1), (4, 4);
|
|
108
|
+
-- error: CHECK
|
|
109
|
+
|
|
110
|
+
-- Rows 1,2 survive; 3,4 do not. Pre-row 100 also survives.
|
|
111
|
+
select id, n from t_spf order by id;
|
|
112
|
+
→ [{"id":1,"n":1},{"id":2,"n":2},{"id":100,"n":99}]
|
|
113
|
+
|
|
114
|
+
-- The user-level sp1 is still aligned: rollback wipes the OR-FAIL survivors.
|
|
115
|
+
rollback to savepoint sp1;
|
|
116
|
+
select id, n from t_spf order by id;
|
|
117
|
+
→ [{"id":100,"n":99}]
|
|
118
|
+
|
|
119
|
+
release savepoint sp1;
|
|
120
|
+
commit;
|
|
121
|
+
|
|
122
|
+
drop table t_spf;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
-- ON CONFLICT (cols) DO UPDATE / DO NOTHING must match a conflict the targeted
|
|
2
|
+
-- constraint *enforces* — a collation-equal conflict (NOCASE case-variant, RTRIM
|
|
3
|
+
-- trailing-space) — and route it to the UPSERT arm instead of aborting with a
|
|
4
|
+
-- UNIQUE error. Ticket bug-upsert-conflict-target-collation-match.
|
|
5
|
+
-- Pre-fix, matchUpsertClause compared proposed vs stored by byte identity
|
|
6
|
+
-- (sqlValueIdentical), so every collation-variant scenario below wrongly aborted.
|
|
7
|
+
--
|
|
8
|
+
-- The affinity-coercion corner ('1' vs stored INTEGER 1) lives in the sibling
|
|
9
|
+
-- memory-only file 47.4-upsert-conflict-target-affinity.sqllogic — it exposes a
|
|
10
|
+
-- separate isolation-layer defect under the store backend (see that file's header
|
|
11
|
+
-- and fix/bug-store-isolation-upsert-affinity-coerced-pk).
|
|
12
|
+
-- The index-derived-collation scenario (UNIQUE via a standalone `create unique
|
|
13
|
+
-- index` with a per-column COLLATE) lives in the sibling file
|
|
14
|
+
-- 47.3.1-upsert-conflict-index-derived-collation.sqllogic.
|
|
15
|
+
|
|
16
|
+
-- ===================================
|
|
17
|
+
-- 1. NOCASE single-column UNIQUE — DO UPDATE runs on a case-variant conflict.
|
|
18
|
+
-- Proposed 'alice' collides with stored 'Alice' under NOCASE; the existing
|
|
19
|
+
-- row is updated (a new row is NOT inserted, and no UNIQUE abort).
|
|
20
|
+
-- ===================================
|
|
21
|
+
|
|
22
|
+
create table nc_u (id integer primary key, name text collate nocase unique, hits integer);
|
|
23
|
+
insert into nc_u values (1, 'Alice', 1);
|
|
24
|
+
|
|
25
|
+
insert into nc_u values (2, 'alice', 99) on conflict (name) do update set hits = hits + 1;
|
|
26
|
+
select id, name, hits from nc_u order by id;
|
|
27
|
+
→ [{"id":1,"name":"Alice","hits":2}]
|
|
28
|
+
|
|
29
|
+
-- ===================================
|
|
30
|
+
-- 2. NOCASE DO NOTHING arm — a case-variant conflict is SKIPPED, not aborted.
|
|
31
|
+
-- ===================================
|
|
32
|
+
|
|
33
|
+
insert into nc_u values (3, 'ALICE', 5) on conflict (name) do nothing;
|
|
34
|
+
select count(*) as cnt from nc_u;
|
|
35
|
+
→ [{"cnt":1}]
|
|
36
|
+
select id, name, hits from nc_u order by id;
|
|
37
|
+
→ [{"id":1,"name":"Alice","hits":2}]
|
|
38
|
+
|
|
39
|
+
-- Control: a genuinely different NOCASE value is NOT a conflict — it inserts.
|
|
40
|
+
insert into nc_u values (4, 'Bob', 1) on conflict (name) do update set hits = hits + 1;
|
|
41
|
+
select id, name, hits from nc_u order by id;
|
|
42
|
+
→ [{"id":1,"name":"Alice","hits":2},{"id":4,"name":"Bob","hits":1}]
|
|
43
|
+
|
|
44
|
+
drop table nc_u;
|
|
45
|
+
|
|
46
|
+
-- ===================================
|
|
47
|
+
-- 3. RTRIM UNIQUE — a trailing-space variant matches under RTRIM.
|
|
48
|
+
-- ===================================
|
|
49
|
+
|
|
50
|
+
create table rt_u (id integer primary key, code text collate rtrim unique, n integer);
|
|
51
|
+
insert into rt_u values (1, 'abc', 10);
|
|
52
|
+
|
|
53
|
+
insert into rt_u values (2, 'abc ', 0) on conflict (code) do update set n = n + 1;
|
|
54
|
+
select id, code, n from rt_u order by id;
|
|
55
|
+
→ [{"id":1,"code":"abc","n":11}]
|
|
56
|
+
|
|
57
|
+
drop table rt_u;
|
|
58
|
+
|
|
59
|
+
-- ===================================
|
|
60
|
+
-- 4. Byte-identical regression control + different-constraint-still-aborts.
|
|
61
|
+
-- A BINARY key conflict still matches; a conflict on a DIFFERENT unique
|
|
62
|
+
-- constraint than the one named still aborts (the fix must not widen matching).
|
|
63
|
+
-- ===================================
|
|
64
|
+
|
|
65
|
+
create table scoped2 (id integer primary key, email text unique);
|
|
66
|
+
insert into scoped2 values (1, 'a@x');
|
|
67
|
+
|
|
68
|
+
-- byte-identical PK conflict still skipped (no regression)
|
|
69
|
+
insert into scoped2 values (1, 'a@x') on conflict (id) do nothing;
|
|
70
|
+
select count(*) as cnt from scoped2;
|
|
71
|
+
→ [{"cnt":1}]
|
|
72
|
+
|
|
73
|
+
-- conflict is on `email` (different PK), but the clause targets `id` → abort
|
|
74
|
+
insert into scoped2 values (2, 'a@x') on conflict (id) do nothing;
|
|
75
|
+
-- error: UNIQUE constraint failed
|
|
76
|
+
|
|
77
|
+
select id, email from scoped2 order by id;
|
|
78
|
+
→ [{"id":1,"email":"a@x"}]
|
|
79
|
+
|
|
80
|
+
drop table scoped2;
|
|
81
|
+
|
|
82
|
+
-- ===================================
|
|
83
|
+
-- 5. Composite target with per-column collations — each target column is
|
|
84
|
+
-- compared under its OWN column's collation. `a` matches exactly, `b`
|
|
85
|
+
-- matches under NOCASE.
|
|
86
|
+
-- ===================================
|
|
87
|
+
|
|
88
|
+
create table comp_coll (a integer, b text collate nocase, note text, unique (a, b));
|
|
89
|
+
insert into comp_coll values (1, 'Xy', 'orig');
|
|
90
|
+
|
|
91
|
+
insert into comp_coll values (1, 'XY', 'ignored') on conflict (a, b) do update set note = 'updated';
|
|
92
|
+
select a, b, note from comp_coll order by a;
|
|
93
|
+
→ [{"a":1,"b":"Xy","note":"updated"}]
|
|
94
|
+
|
|
95
|
+
-- A composite where only `a` collides (different `b` under NOCASE) is NOT a
|
|
96
|
+
-- conflict on (a, b) — it inserts as a new row.
|
|
97
|
+
insert into comp_coll values (1, 'Zz', 'second') on conflict (a, b) do update set note = 'updated';
|
|
98
|
+
select a, b, note from comp_coll order by b;
|
|
99
|
+
→ [{"a":1,"b":"Xy","note":"updated"},{"a":1,"b":"Zz","note":"second"}]
|
|
100
|
+
|
|
101
|
+
drop table comp_coll;
|
|
102
|
+
|
|
103
|
+
-- ===================================
|
|
104
|
+
-- 6. WHERE guard on DO UPDATE combined with a collation-variant conflict. The
|
|
105
|
+
-- conflict is matched (NOCASE case-variant) so no new row inserts and no
|
|
106
|
+
-- UNIQUE abort, but the WHERE guard governs whether the update runs — a
|
|
107
|
+
-- false guard skips (DO NOTHING equivalent), a true guard updates.
|
|
108
|
+
-- ===================================
|
|
109
|
+
|
|
110
|
+
create table wg (id integer primary key, name text collate nocase unique, hits integer);
|
|
111
|
+
insert into wg values (1, 'Kite', 5);
|
|
112
|
+
|
|
113
|
+
-- guard false: conflict matched but update skipped, existing row untouched, no insert
|
|
114
|
+
insert into wg values (2, 'KITE', 0) on conflict (name) do update set hits = hits + 1 where hits > 100;
|
|
115
|
+
select id, name, hits from wg order by id;
|
|
116
|
+
→ [{"id":1,"name":"Kite","hits":5}]
|
|
117
|
+
|
|
118
|
+
-- guard true: same collation-variant conflict now updates
|
|
119
|
+
insert into wg values (3, 'kite', 0) on conflict (name) do update set hits = hits + 1 where hits < 100;
|
|
120
|
+
select id, name, hits from wg order by id;
|
|
121
|
+
→ [{"id":1,"name":"Kite","hits":6}]
|
|
122
|
+
|
|
123
|
+
drop table wg;
|
|
124
|
+
|
|
125
|
+
-- ===================================
|
|
126
|
+
-- 7. Multi-row INSERT mixing a collation-variant conflict row with clean rows
|
|
127
|
+
-- under a single statement — the variant row routes to DO UPDATE, the clean
|
|
128
|
+
-- rows insert, none abort.
|
|
129
|
+
-- ===================================
|
|
130
|
+
|
|
131
|
+
create table multi (id integer primary key, name text collate nocase unique, hits integer);
|
|
132
|
+
insert into multi values (1, 'Ada', 1);
|
|
133
|
+
|
|
134
|
+
insert into multi values (2, 'Bea', 1), (3, 'ADA', 0), (4, 'Cid', 1)
|
|
135
|
+
on conflict (name) do update set hits = hits + 10;
|
|
136
|
+
select id, name, hits from multi order by id;
|
|
137
|
+
→ [{"id":1,"name":"Ada","hits":11},{"id":2,"name":"Bea","hits":1},{"id":4,"name":"Cid","hits":1}]
|
|
138
|
+
|
|
139
|
+
drop table multi;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- Index-derived UNIQUE enforcement collation via ON CONFLICT upsert.
|
|
2
|
+
--
|
|
3
|
+
-- requires-capability: standalone-index-ddl
|
|
4
|
+
--
|
|
5
|
+
-- Carved out of 47.3-upsert-conflict-target-collation: every other section of
|
|
6
|
+
-- 47.3 enforces UNIQUE through a column- or table-level constraint, but this
|
|
7
|
+
-- scenario derives its UNIQUE from a standalone `create unique index` whose key
|
|
8
|
+
-- expression carries a per-column COLLATE. Backends that retire first-class
|
|
9
|
+
-- CREATE [UNIQUE] INDEX cannot run it, so it lives in its own file to keep 47.3's
|
|
10
|
+
-- collation-variant upsert-matching subject portable across backends.
|
|
11
|
+
--
|
|
12
|
+
-- Subject: the enforcement collation is the INDEX's NOCASE, not the column's
|
|
13
|
+
-- declared BINARY — so proposed 'HELLO' matches stored 'Hello' and routes to the
|
|
14
|
+
-- DO UPDATE arm. Sibling: unique-enforcement-collation.spec.ts covers the same
|
|
15
|
+
-- index-derived-collation resolution directly.
|
|
16
|
+
|
|
17
|
+
create table idx_coll (id integer primary key, tag text);
|
|
18
|
+
create unique index idx_tag_nc on idx_coll (tag collate nocase);
|
|
19
|
+
insert into idx_coll values (1, 'Hello');
|
|
20
|
+
|
|
21
|
+
insert into idx_coll values (2, 'HELLO') on conflict (tag) do update set tag = 'seen';
|
|
22
|
+
select id, tag from idx_coll order by id;
|
|
23
|
+
→ [{"id":1,"tag":"seen"}]
|
|
24
|
+
|
|
25
|
+
drop table idx_coll;
|