@quereus/quereus 4.20.1 → 4.20.3
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/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +17 -69
- package/dist/src/schema/schema-differ.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 +210 -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,217 @@
|
|
|
1
|
+
-- 28.2-set-op-branch-types.sqllogic
|
|
2
|
+
-- Cross-branch type merge for set operations (ticket
|
|
3
|
+
-- union-branch-value-not-converted-on-write): a set operation advertises a type
|
|
4
|
+
-- it actually produces, merged symmetrically across both operands, so a branch
|
|
5
|
+
-- stores exactly what it would have stored on its own — in either arm order.
|
|
6
|
+
-- No `using memory`, so store mode exercises the same rules on the store path.
|
|
7
|
+
|
|
8
|
+
-- ============================================================
|
|
9
|
+
-- DATE branch vs TEXT branch. No common concrete type exists (temporal parse is
|
|
10
|
+
-- normalizing), so the merge advertises ANY and every cell converts at the DML —
|
|
11
|
+
-- the raw literal normalizes and the already-stored value survives
|
|
12
|
+
-- re-conversion (temporal conversion is idempotent).
|
|
13
|
+
-- ============================================================
|
|
14
|
+
|
|
15
|
+
create table sobt_d (id integer primary key, d date);
|
|
16
|
+
create table sobt_d2 (id integer primary key, d date);
|
|
17
|
+
insert into sobt_d values (1, '2024-06-05');
|
|
18
|
+
-- run
|
|
19
|
+
|
|
20
|
+
-- Single-arm baseline: the literal normalizes to a plain date.
|
|
21
|
+
insert into sobt_d2 select 2, '2024-01-02T00:00:00Z';
|
|
22
|
+
-- run
|
|
23
|
+
|
|
24
|
+
select id, d from sobt_d2;
|
|
25
|
+
→ [{"id":2,"d":"2024-01-02"}]
|
|
26
|
+
|
|
27
|
+
-- DATE arm on the LEFT: the TEXT literal in the right arm must STILL normalize
|
|
28
|
+
-- (it used to ride the advertised DATE type unconverted — raw timestamp text
|
|
29
|
+
-- silently stored in a DATE column).
|
|
30
|
+
delete from sobt_d2;
|
|
31
|
+
insert into sobt_d2 select id, d from sobt_d union all select 2, '2024-01-02T00:00:00Z';
|
|
32
|
+
-- run
|
|
33
|
+
|
|
34
|
+
select id, d from sobt_d2 order by id;
|
|
35
|
+
→ [{"id":1,"d":"2024-06-05"},{"id":2,"d":"2024-01-02"}]
|
|
36
|
+
|
|
37
|
+
-- DATE arm on the RIGHT: same result — the merge is order-independent.
|
|
38
|
+
delete from sobt_d2;
|
|
39
|
+
insert into sobt_d2 select 2, '2024-01-02T00:00:00Z' union all select id, d from sobt_d;
|
|
40
|
+
-- run
|
|
41
|
+
|
|
42
|
+
select id, d from sobt_d2 order by id;
|
|
43
|
+
→ [{"id":1,"d":"2024-06-05"},{"id":2,"d":"2024-01-02"}]
|
|
44
|
+
|
|
45
|
+
-- ============================================================
|
|
46
|
+
-- Must-keep-working cases: pairs whose conversion is total and idempotent keep
|
|
47
|
+
-- their current behavior, and the numeric merge must promote (NOT collapse to
|
|
48
|
+
-- TEXT the way CASE branch typing does).
|
|
49
|
+
-- ============================================================
|
|
50
|
+
|
|
51
|
+
-- Mixed INTEGER/TEXT values pass through a bag union unchanged.
|
|
52
|
+
select 1 as v union all select 'a';
|
|
53
|
+
→ [{"v":1},{"v":"a"}]
|
|
54
|
+
|
|
55
|
+
-- INTEGER ∪ REAL promotes numerically: both values stay numbers.
|
|
56
|
+
select 1 as v union all select 2.5;
|
|
57
|
+
→ [{"v":1},{"v":2.5}]
|
|
58
|
+
|
|
59
|
+
create table sobt_i (id integer primary key, n integer);
|
|
60
|
+
|
|
61
|
+
-- TEXT numeral in either arm still converts on insert.
|
|
62
|
+
insert into sobt_i select 1, 5 union all select 2, '7';
|
|
63
|
+
-- run
|
|
64
|
+
|
|
65
|
+
select id, n from sobt_i order by id;
|
|
66
|
+
→ [{"id":1,"n":5},{"id":2,"n":7}]
|
|
67
|
+
|
|
68
|
+
delete from sobt_i;
|
|
69
|
+
insert into sobt_i select 1, '7' union all select 2, 5;
|
|
70
|
+
-- run
|
|
71
|
+
|
|
72
|
+
select id, n from sobt_i order by id;
|
|
73
|
+
→ [{"id":1,"n":7},{"id":2,"n":5}]
|
|
74
|
+
|
|
75
|
+
-- ============================================================
|
|
76
|
+
-- A `select null` branch must not poison a well-typed union: NULL is a member
|
|
77
|
+
-- of every type, so the other branch's type stands and its values are
|
|
78
|
+
-- untouched.
|
|
79
|
+
-- ============================================================
|
|
80
|
+
|
|
81
|
+
create table sobt_n (id integer primary key, d date null);
|
|
82
|
+
insert into sobt_n select 3, null union all select 4, d from sobt_d;
|
|
83
|
+
-- run
|
|
84
|
+
|
|
85
|
+
select id, d from sobt_n order by id;
|
|
86
|
+
→ [{"id":3,"d":null},{"id":4,"d":"2024-06-05"}]
|
|
87
|
+
|
|
88
|
+
-- ...and in the other arm order: the NULL branch on the right must not poison
|
|
89
|
+
-- the DATE claim either.
|
|
90
|
+
delete from sobt_n;
|
|
91
|
+
insert into sobt_n select 4, d from sobt_d union all select 3, null;
|
|
92
|
+
-- run
|
|
93
|
+
|
|
94
|
+
select id, d from sobt_n order by id;
|
|
95
|
+
→ [{"id":3,"d":null},{"id":4,"d":"2024-06-05"}]
|
|
96
|
+
|
|
97
|
+
-- ============================================================
|
|
98
|
+
-- DIFF (symmetric difference) expands to (A except B) union (B except A); the
|
|
99
|
+
-- operands are aligned ONCE before the expansion, so both inner EXCEPTs — and
|
|
100
|
+
-- the outer UNION — see the same merged column type.
|
|
101
|
+
-- ============================================================
|
|
102
|
+
|
|
103
|
+
create table sobt_j (id integer primary key, j json);
|
|
104
|
+
insert into sobt_j values (1, '"abc"');
|
|
105
|
+
-- run
|
|
106
|
+
|
|
107
|
+
-- The TEXT branch is cast to JSON, so the shared value cancels and only the
|
|
108
|
+
-- symmetric difference remains — in either arm order.
|
|
109
|
+
select j from sobt_j diff select '"xyz"';
|
|
110
|
+
→ [{"j":"abc"},{"j":"xyz"}]
|
|
111
|
+
|
|
112
|
+
select '"xyz"' as j diff select j from sobt_j;
|
|
113
|
+
→ [{"j":"xyz"},{"j":"abc"}]
|
|
114
|
+
|
|
115
|
+
select j from sobt_j diff select '"abc"';
|
|
116
|
+
→ []
|
|
117
|
+
|
|
118
|
+
-- ============================================================
|
|
119
|
+
-- ORDER BY over a set operation, a view over one, and a nested set operation
|
|
120
|
+
-- all still resolve after branch alignment (the aligned branch republishes its
|
|
121
|
+
-- columns; the compound scope resolves against the set operation's output).
|
|
122
|
+
-- ============================================================
|
|
123
|
+
|
|
124
|
+
select j as x from sobt_j union all select '"9"' order by x;
|
|
125
|
+
→ [{"x":"9"},{"x":"abc"}]
|
|
126
|
+
|
|
127
|
+
create view sobt_v as select j as x from sobt_j union all select '"9"';
|
|
128
|
+
-- run
|
|
129
|
+
|
|
130
|
+
select json_quote(x) as q from sobt_v order by 1;
|
|
131
|
+
→ [{"q":"\"9\""},{"q":"\"abc\""}]
|
|
132
|
+
|
|
133
|
+
select j from sobt_j union select '"9"' union select '"abc"';
|
|
134
|
+
→ [{"j":"abc"},{"j":"9"}]
|
|
135
|
+
|
|
136
|
+
-- ============================================================
|
|
137
|
+
-- Mixed whole-number/decimal branches (ticket
|
|
138
|
+
-- set-op-numeric-promotion-skips-conversion). Neither branch is converted, so
|
|
139
|
+
-- the merge advertises NUMERIC — a type the mixed stream genuinely inhabits —
|
|
140
|
+
-- rather than REAL, which the DML write pass would have believed and skipped
|
|
141
|
+
-- conversion for. Small integers cannot discriminate (both internal forms
|
|
142
|
+
-- coincide) and the harness normalizes BigInt to Number before comparing rows,
|
|
143
|
+
-- so the stored-form assertions all go through `cast(v as text)`.
|
|
144
|
+
-- ============================================================
|
|
145
|
+
|
|
146
|
+
create table sobt_r (id integer primary key, v real);
|
|
147
|
+
|
|
148
|
+
-- Baseline: a direct insert converts to the REAL (floating point) form, which
|
|
149
|
+
-- rounds 2^53+1 down to 2^53.
|
|
150
|
+
insert into sobt_r values (1, 9007199254740993);
|
|
151
|
+
-- run
|
|
152
|
+
|
|
153
|
+
select cast(v as text) as t from sobt_r;
|
|
154
|
+
→ [{"t":"9007199254740992"}]
|
|
155
|
+
|
|
156
|
+
-- Whole-number arm on the LEFT: the REAL column must store exactly what the
|
|
157
|
+
-- direct insert stored.
|
|
158
|
+
delete from sobt_r;
|
|
159
|
+
insert into sobt_r (id, v) select 1, 9007199254740993 union all select 2, 2.5;
|
|
160
|
+
-- run
|
|
161
|
+
|
|
162
|
+
select cast(v as text) as t from sobt_r order by id;
|
|
163
|
+
→ [{"t":"9007199254740992"},{"t":"2.5"}]
|
|
164
|
+
|
|
165
|
+
-- Whole-number arm on the RIGHT: same result — the merge is order-independent.
|
|
166
|
+
delete from sobt_r;
|
|
167
|
+
insert into sobt_r (id, v) select 2, 2.5 union all select 1, 9007199254740993;
|
|
168
|
+
-- run
|
|
169
|
+
|
|
170
|
+
select cast(v as text) as t from sobt_r order by id;
|
|
171
|
+
→ [{"t":"9007199254740992"},{"t":"2.5"}]
|
|
172
|
+
|
|
173
|
+
-- A REAL-declared KEY fed by the same mix: an unconverted bigint used to reach
|
|
174
|
+
-- REAL_TYPE.compare and throw ("Cannot convert a BigInt value to a number").
|
|
175
|
+
create table sobt_rk (v real primary key);
|
|
176
|
+
insert into sobt_rk (v) select 9007199254740993 union all select 2.5;
|
|
177
|
+
-- run
|
|
178
|
+
|
|
179
|
+
select cast(v as text) as t from sobt_rk order by v;
|
|
180
|
+
→ [{"t":"2.5"},{"t":"9007199254740992"}]
|
|
181
|
+
|
|
182
|
+
-- A NUMERIC-declared KEY: conversion IS legitimately skipped here (NUMERIC holds
|
|
183
|
+
-- both forms), so the bigint reaches NUMERIC_TYPE.compare and must be ordered,
|
|
184
|
+
-- not rejected (ticket numeric-comparator-rejects-bigint), and stored intact.
|
|
185
|
+
create table sobt_nk (v numeric primary key);
|
|
186
|
+
insert into sobt_nk (v) select 9007199254740993 union all select 2.5;
|
|
187
|
+
-- run
|
|
188
|
+
|
|
189
|
+
select cast(v as text) as t from sobt_nk order by v;
|
|
190
|
+
→ [{"t":"2.5"},{"t":"9007199254740993"}]
|
|
191
|
+
|
|
192
|
+
-- READ side is untouched by this fix: each row keeps its own storage class
|
|
193
|
+
-- through a compound select (as SQLite does), so a big whole number does NOT
|
|
194
|
+
-- get rounded on the way out.
|
|
195
|
+
select cast(v as text) as t from (select 9007199254740993 as v union all select 2.5) as s;
|
|
196
|
+
→ [{"t":"9007199254740993"},{"t":"2.5"}]
|
|
197
|
+
|
|
198
|
+
-- Three or more `union all` arms collapse into AsyncGatherNode, which folds the
|
|
199
|
+
-- same merge across every branch — the mixed pair must still reach NUMERIC there.
|
|
200
|
+
create table sobt_g (v real primary key);
|
|
201
|
+
insert into sobt_g (v) select 2.5 union all select 9007199254740993 union all select 7;
|
|
202
|
+
-- run
|
|
203
|
+
|
|
204
|
+
select cast(v as text) as t from sobt_g order by v;
|
|
205
|
+
→ [{"t":"2.5"},{"t":"7"},{"t":"9007199254740992"}]
|
|
206
|
+
|
|
207
|
+
-- Deduplicating set operations compare across branches under the merged type, so
|
|
208
|
+
-- the whole-number and decimal spellings of one value must collapse (and not
|
|
209
|
+
-- throw out of the comparator on the bigint operand).
|
|
210
|
+
select v from (select 1 as v union select 1.0) as s;
|
|
211
|
+
→ [{"v":1}]
|
|
212
|
+
|
|
213
|
+
select v from (select 3 as v intersect select 3.0) as s;
|
|
214
|
+
→ [{"v":3}]
|
|
215
|
+
|
|
216
|
+
select v from (select 3 as v except select 3.0) as s;
|
|
217
|
+
→ []
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
-- constraint-edge-cases.sqllogic - Edge-case interactions between constraints, FK cascades, and assertions
|
|
2
|
+
|
|
3
|
+
PRAGMA foreign_keys = true;
|
|
4
|
+
|
|
5
|
+
-- ===================================================================
|
|
6
|
+
-- Multi-row DELETE with cascading FKs
|
|
7
|
+
-- Delete multiple parent rows in a single statement where each parent
|
|
8
|
+
-- has children — verify all children are cascaded correctly.
|
|
9
|
+
-- ===================================================================
|
|
10
|
+
|
|
11
|
+
CREATE TABLE mr_parent (
|
|
12
|
+
id INTEGER PRIMARY KEY,
|
|
13
|
+
name TEXT
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE TABLE mr_child (
|
|
17
|
+
id INTEGER PRIMARY KEY,
|
|
18
|
+
parent_id INTEGER,
|
|
19
|
+
info TEXT,
|
|
20
|
+
FOREIGN KEY (parent_id) REFERENCES mr_parent(id) ON DELETE CASCADE
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
INSERT INTO mr_parent VALUES (1, 'P1'), (2, 'P2'), (3, 'P3');
|
|
24
|
+
INSERT INTO mr_child VALUES (10, 1, 'C1a'), (11, 1, 'C1b'), (20, 2, 'C2a'), (21, 2, 'C2b'), (30, 3, 'C3a');
|
|
25
|
+
|
|
26
|
+
SELECT count(*) FROM mr_child;
|
|
27
|
+
→ [{"count(*)":5}]
|
|
28
|
+
|
|
29
|
+
-- Delete two parents at once — children of both should be cascaded
|
|
30
|
+
DELETE FROM mr_parent WHERE id IN (1, 2);
|
|
31
|
+
|
|
32
|
+
SELECT count(*) FROM mr_parent;
|
|
33
|
+
→ [{"count(*)":1}]
|
|
34
|
+
|
|
35
|
+
SELECT count(*) FROM mr_child;
|
|
36
|
+
→ [{"count(*)":1}]
|
|
37
|
+
|
|
38
|
+
-- Only P3's child remains
|
|
39
|
+
SELECT id, parent_id FROM mr_child;
|
|
40
|
+
→ [{"id":30,"parent_id":3}]
|
|
41
|
+
|
|
42
|
+
DROP TABLE mr_child;
|
|
43
|
+
DROP TABLE mr_parent;
|
|
44
|
+
|
|
45
|
+
-- ===================================================================
|
|
46
|
+
-- CASCADE across three levels
|
|
47
|
+
-- grandparent → parent → child FK chain with CASCADE DELETE
|
|
48
|
+
-- ===================================================================
|
|
49
|
+
|
|
50
|
+
CREATE TABLE gp (
|
|
51
|
+
id INTEGER PRIMARY KEY,
|
|
52
|
+
name TEXT
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
CREATE TABLE par (
|
|
56
|
+
id INTEGER PRIMARY KEY,
|
|
57
|
+
gp_id INTEGER,
|
|
58
|
+
FOREIGN KEY (gp_id) REFERENCES gp(id) ON DELETE CASCADE
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
CREATE TABLE ch (
|
|
62
|
+
id INTEGER PRIMARY KEY,
|
|
63
|
+
par_id INTEGER,
|
|
64
|
+
FOREIGN KEY (par_id) REFERENCES par(id) ON DELETE CASCADE
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
INSERT INTO gp VALUES (1, 'G1'), (2, 'G2');
|
|
68
|
+
INSERT INTO par VALUES (10, 1), (11, 1), (20, 2);
|
|
69
|
+
INSERT INTO ch VALUES (100, 10), (101, 10), (110, 11), (200, 20);
|
|
70
|
+
|
|
71
|
+
SELECT count(*) FROM ch;
|
|
72
|
+
→ [{"count(*)":4}]
|
|
73
|
+
|
|
74
|
+
-- Delete grandparent — should cascade through parent to child
|
|
75
|
+
DELETE FROM gp WHERE id = 1;
|
|
76
|
+
|
|
77
|
+
SELECT count(*) FROM gp;
|
|
78
|
+
→ [{"count(*)":1}]
|
|
79
|
+
|
|
80
|
+
SELECT count(*) FROM par;
|
|
81
|
+
→ [{"count(*)":1}]
|
|
82
|
+
|
|
83
|
+
-- Only children of G2's parent (par id=20) remain
|
|
84
|
+
SELECT count(*) FROM ch;
|
|
85
|
+
→ [{"count(*)":1}]
|
|
86
|
+
|
|
87
|
+
SELECT id, par_id FROM ch;
|
|
88
|
+
→ [{"id":200,"par_id":20}]
|
|
89
|
+
|
|
90
|
+
DROP TABLE ch;
|
|
91
|
+
DROP TABLE par;
|
|
92
|
+
DROP TABLE gp;
|
|
93
|
+
|
|
94
|
+
-- ===================================================================
|
|
95
|
+
-- SET NULL cascade on multi-row delete
|
|
96
|
+
-- Delete multiple parents with SET NULL children — verify all affected
|
|
97
|
+
-- children have NULLed FK columns.
|
|
98
|
+
-- ===================================================================
|
|
99
|
+
|
|
100
|
+
CREATE TABLE snm_parent (
|
|
101
|
+
id INTEGER PRIMARY KEY,
|
|
102
|
+
name TEXT
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
CREATE TABLE snm_child (
|
|
106
|
+
id INTEGER PRIMARY KEY,
|
|
107
|
+
parent_id INTEGER NULL,
|
|
108
|
+
FOREIGN KEY (parent_id) REFERENCES snm_parent(id) ON DELETE SET NULL
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
INSERT INTO snm_parent VALUES (1, 'X'), (2, 'Y'), (3, 'Z');
|
|
112
|
+
INSERT INTO snm_child VALUES (10, 1), (11, 1), (20, 2), (30, 3);
|
|
113
|
+
|
|
114
|
+
-- Delete two parents at once
|
|
115
|
+
DELETE FROM snm_parent WHERE id IN (1, 2);
|
|
116
|
+
|
|
117
|
+
SELECT id, parent_id FROM snm_child ORDER BY id;
|
|
118
|
+
→ [{"id":10,"parent_id":null},{"id":11,"parent_id":null},{"id":20,"parent_id":null},{"id":30,"parent_id":3}]
|
|
119
|
+
|
|
120
|
+
DROP TABLE snm_child;
|
|
121
|
+
DROP TABLE snm_parent;
|
|
122
|
+
|
|
123
|
+
-- ===================================================================
|
|
124
|
+
-- Multiple assertions in same transaction
|
|
125
|
+
-- Two independent assertions, one passes and one fails — verify the
|
|
126
|
+
-- failing one prevents COMMIT and the error identifies which assertion.
|
|
127
|
+
-- ===================================================================
|
|
128
|
+
|
|
129
|
+
CREATE TABLE ma_data (id INTEGER PRIMARY KEY, a INTEGER, b INTEGER);
|
|
130
|
+
INSERT INTO ma_data VALUES (1, 10, 20);
|
|
131
|
+
-- run
|
|
132
|
+
|
|
133
|
+
CREATE ASSERTION ma_a_positive CHECK (NOT EXISTS (SELECT 1 FROM ma_data WHERE a < 0));
|
|
134
|
+
CREATE ASSERTION ma_b_small CHECK (NOT EXISTS (SELECT 1 FROM ma_data WHERE b > 100));
|
|
135
|
+
-- run
|
|
136
|
+
|
|
137
|
+
-- Both pass: valid insert
|
|
138
|
+
BEGIN;
|
|
139
|
+
INSERT INTO ma_data VALUES (2, 5, 50);
|
|
140
|
+
COMMIT;
|
|
141
|
+
-- run
|
|
142
|
+
|
|
143
|
+
SELECT count(*) FROM ma_data;
|
|
144
|
+
→ [{"count(*)":2}]
|
|
145
|
+
|
|
146
|
+
-- a passes, b fails → should identify ma_b_small
|
|
147
|
+
BEGIN;
|
|
148
|
+
INSERT INTO ma_data VALUES (3, 1, 200);
|
|
149
|
+
COMMIT;
|
|
150
|
+
-- error: Integrity assertion failed: ma_b_small
|
|
151
|
+
|
|
152
|
+
-- a fails → should identify ma_a_positive
|
|
153
|
+
BEGIN;
|
|
154
|
+
INSERT INTO ma_data VALUES (4, -5, 10);
|
|
155
|
+
COMMIT;
|
|
156
|
+
-- error: Integrity assertion failed: ma_a_positive
|
|
157
|
+
|
|
158
|
+
-- Verify only original 2 rows
|
|
159
|
+
SELECT count(*) FROM ma_data;
|
|
160
|
+
→ [{"count(*)":2}]
|
|
161
|
+
|
|
162
|
+
DROP ASSERTION ma_a_positive;
|
|
163
|
+
DROP ASSERTION ma_b_small;
|
|
164
|
+
DROP TABLE ma_data;
|
|
165
|
+
-- run
|
|
166
|
+
|
|
167
|
+
-- ===================================================================
|
|
168
|
+
-- Deferred CHECK + assertion in same transaction
|
|
169
|
+
-- A deferred row-level CHECK and a global assertion both evaluated at
|
|
170
|
+
-- COMMIT — verify both are checked and the first failure is reported.
|
|
171
|
+
-- ===================================================================
|
|
172
|
+
|
|
173
|
+
CREATE TABLE ref_lookup (id TEXT PRIMARY KEY, label TEXT);
|
|
174
|
+
INSERT INTO ref_lookup VALUES ('valid', 'Valid Ref');
|
|
175
|
+
-- run
|
|
176
|
+
|
|
177
|
+
CREATE TABLE da_data (
|
|
178
|
+
id INTEGER PRIMARY KEY,
|
|
179
|
+
ref_id TEXT,
|
|
180
|
+
val INTEGER,
|
|
181
|
+
CONSTRAINT ref_exists CHECK ON INSERT, UPDATE (
|
|
182
|
+
EXISTS (SELECT 1 FROM ref_lookup WHERE ref_lookup.id = NEW.ref_id)
|
|
183
|
+
)
|
|
184
|
+
);
|
|
185
|
+
-- run
|
|
186
|
+
|
|
187
|
+
CREATE ASSERTION da_val_positive CHECK (NOT EXISTS (SELECT 1 FROM da_data WHERE val < 0));
|
|
188
|
+
-- run
|
|
189
|
+
|
|
190
|
+
-- Both pass
|
|
191
|
+
BEGIN;
|
|
192
|
+
INSERT INTO da_data VALUES (1, 'valid', 10);
|
|
193
|
+
COMMIT;
|
|
194
|
+
-- run
|
|
195
|
+
|
|
196
|
+
SELECT count(*) FROM da_data;
|
|
197
|
+
→ [{"count(*)":1}]
|
|
198
|
+
|
|
199
|
+
-- Deferred CHECK fails (bad ref_id)
|
|
200
|
+
BEGIN;
|
|
201
|
+
INSERT INTO da_data VALUES (2, 'missing', 5);
|
|
202
|
+
COMMIT;
|
|
203
|
+
-- error: CHECK constraint failed: ref_exists
|
|
204
|
+
|
|
205
|
+
-- Assertion fails (negative val, valid ref)
|
|
206
|
+
BEGIN;
|
|
207
|
+
INSERT INTO da_data VALUES (3, 'valid', -10);
|
|
208
|
+
COMMIT;
|
|
209
|
+
-- error: Integrity assertion failed: da_val_positive
|
|
210
|
+
|
|
211
|
+
-- Verify only original row exists
|
|
212
|
+
SELECT count(*) FROM da_data;
|
|
213
|
+
→ [{"count(*)":1}]
|
|
214
|
+
|
|
215
|
+
DROP ASSERTION da_val_positive;
|
|
216
|
+
DROP TABLE da_data;
|
|
217
|
+
DROP TABLE ref_lookup;
|
|
218
|
+
-- run
|
|
219
|
+
|
|
220
|
+
-- ===================================================================
|
|
221
|
+
-- Multiple child tables with different cascade actions on same parent
|
|
222
|
+
-- One child uses CASCADE, another uses SET NULL — both should fire
|
|
223
|
+
-- correctly on parent delete.
|
|
224
|
+
-- ===================================================================
|
|
225
|
+
|
|
226
|
+
CREATE TABLE mc_parent (
|
|
227
|
+
id INTEGER PRIMARY KEY,
|
|
228
|
+
name TEXT
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
CREATE TABLE mc_cascade_child (
|
|
232
|
+
id INTEGER PRIMARY KEY,
|
|
233
|
+
parent_id INTEGER,
|
|
234
|
+
FOREIGN KEY (parent_id) REFERENCES mc_parent(id) ON DELETE CASCADE
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
CREATE TABLE mc_setnull_child (
|
|
238
|
+
id INTEGER PRIMARY KEY,
|
|
239
|
+
parent_id INTEGER NULL,
|
|
240
|
+
FOREIGN KEY (parent_id) REFERENCES mc_parent(id) ON DELETE SET NULL
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
INSERT INTO mc_parent VALUES (1, 'P1'), (2, 'P2');
|
|
244
|
+
INSERT INTO mc_cascade_child VALUES (10, 1), (11, 1), (20, 2);
|
|
245
|
+
INSERT INTO mc_setnull_child VALUES (100, 1), (101, 1), (200, 2);
|
|
246
|
+
|
|
247
|
+
-- Delete parent 1 — cascade child rows deleted, setnull child rows nulled
|
|
248
|
+
DELETE FROM mc_parent WHERE id = 1;
|
|
249
|
+
|
|
250
|
+
-- CASCADE child: rows for parent 1 gone
|
|
251
|
+
SELECT count(*) FROM mc_cascade_child WHERE parent_id = 1;
|
|
252
|
+
→ [{"count(*)":0}]
|
|
253
|
+
|
|
254
|
+
-- CASCADE child: parent 2 rows untouched
|
|
255
|
+
SELECT count(*) FROM mc_cascade_child WHERE parent_id = 2;
|
|
256
|
+
→ [{"count(*)":1}]
|
|
257
|
+
|
|
258
|
+
-- SET NULL child: rows for parent 1 have null FK
|
|
259
|
+
SELECT id, parent_id FROM mc_setnull_child ORDER BY id;
|
|
260
|
+
→ [{"id":100,"parent_id":null},{"id":101,"parent_id":null},{"id":200,"parent_id":2}]
|
|
261
|
+
|
|
262
|
+
DROP TABLE mc_cascade_child;
|
|
263
|
+
DROP TABLE mc_setnull_child;
|
|
264
|
+
DROP TABLE mc_parent;
|
|
265
|
+
|
|
266
|
+
-- ===================================================================
|
|
267
|
+
-- Savepoint interaction with deferred constraints
|
|
268
|
+
-- Insert violating row, create savepoint, fix the violation, rollback
|
|
269
|
+
-- savepoint (restoring violation), then attempt COMMIT — should fail.
|
|
270
|
+
-- ===================================================================
|
|
271
|
+
|
|
272
|
+
CREATE TABLE sp_ref (id TEXT PRIMARY KEY, name TEXT);
|
|
273
|
+
INSERT INTO sp_ref VALUES ('ok', 'OK');
|
|
274
|
+
-- run
|
|
275
|
+
|
|
276
|
+
CREATE TABLE sp_data (
|
|
277
|
+
id INTEGER PRIMARY KEY,
|
|
278
|
+
ref_id TEXT,
|
|
279
|
+
CONSTRAINT sp_ref_exists CHECK ON INSERT, UPDATE (
|
|
280
|
+
EXISTS (SELECT 1 FROM sp_ref WHERE sp_ref.id = NEW.ref_id)
|
|
281
|
+
)
|
|
282
|
+
);
|
|
283
|
+
-- run
|
|
284
|
+
|
|
285
|
+
BEGIN;
|
|
286
|
+
-- Insert violating row (bad ref_id) — deferred until COMMIT
|
|
287
|
+
INSERT INTO sp_data VALUES (1, 'bad');
|
|
288
|
+
-- Create savepoint
|
|
289
|
+
SAVEPOINT sp1;
|
|
290
|
+
-- Fix the violation by adding the missing ref
|
|
291
|
+
INSERT INTO sp_ref VALUES ('bad', 'Now Valid');
|
|
292
|
+
-- Rollback savepoint — restoring the violation (ref 'bad' no longer exists)
|
|
293
|
+
ROLLBACK TO SAVEPOINT sp1;
|
|
294
|
+
-- Attempt COMMIT — should fail because 'bad' ref doesn't exist
|
|
295
|
+
COMMIT;
|
|
296
|
+
-- error: CHECK constraint failed: sp_ref_exists
|
|
297
|
+
|
|
298
|
+
-- Verify nothing was committed
|
|
299
|
+
SELECT count(*) FROM sp_data;
|
|
300
|
+
→ [{"count(*)":0}]
|
|
301
|
+
|
|
302
|
+
DROP TABLE sp_data;
|
|
303
|
+
DROP TABLE sp_ref;
|
|
304
|
+
-- run
|
|
305
|
+
|
|
306
|
+
-- ===================================================================
|
|
307
|
+
-- Constraint violation in multi-statement transaction
|
|
308
|
+
-- First statement valid, second violates a deferred constraint, third
|
|
309
|
+
-- fixes it — COMMIT should succeed since end-state is valid.
|
|
310
|
+
-- ===================================================================
|
|
311
|
+
|
|
312
|
+
CREATE TABLE fix_ref (id TEXT PRIMARY KEY, name TEXT);
|
|
313
|
+
INSERT INTO fix_ref VALUES ('a', 'Alpha'), ('b', 'Beta');
|
|
314
|
+
-- run
|
|
315
|
+
|
|
316
|
+
CREATE TABLE fix_data (
|
|
317
|
+
id INTEGER PRIMARY KEY,
|
|
318
|
+
ref_id TEXT,
|
|
319
|
+
CONSTRAINT fix_ref_exists CHECK ON INSERT, UPDATE (
|
|
320
|
+
EXISTS (SELECT 1 FROM fix_ref WHERE fix_ref.id = NEW.ref_id)
|
|
321
|
+
)
|
|
322
|
+
);
|
|
323
|
+
-- run
|
|
324
|
+
|
|
325
|
+
BEGIN;
|
|
326
|
+
-- Valid insert
|
|
327
|
+
INSERT INTO fix_data VALUES (1, 'a');
|
|
328
|
+
-- Violating insert (ref 'missing' doesn't exist yet)
|
|
329
|
+
INSERT INTO fix_data VALUES (2, 'missing');
|
|
330
|
+
-- Fix violation by adding the missing reference
|
|
331
|
+
INSERT INTO fix_ref VALUES ('missing', 'Now Exists');
|
|
332
|
+
-- COMMIT should succeed because end-state is valid
|
|
333
|
+
COMMIT;
|
|
334
|
+
-- run
|
|
335
|
+
|
|
336
|
+
SELECT count(*) FROM fix_data;
|
|
337
|
+
→ [{"count(*)":2}]
|
|
338
|
+
|
|
339
|
+
SELECT ref_id FROM fix_data ORDER BY id;
|
|
340
|
+
→ [{"ref_id":"a"},{"ref_id":"missing"}]
|
|
341
|
+
|
|
342
|
+
DROP TABLE fix_data;
|
|
343
|
+
DROP TABLE fix_ref;
|
|
344
|
+
-- run
|
|
345
|
+
|
|
346
|
+
-- ===================================================================
|
|
347
|
+
-- FK cascade triggering a CHECK violation
|
|
348
|
+
-- Parent delete cascades SET NULL to child, but the child table has a
|
|
349
|
+
-- NOT NULL constraint on the FK column — the cascade cannot satisfy the
|
|
350
|
+
-- constraint, so the operation should fail.
|
|
351
|
+
-- ===================================================================
|
|
352
|
+
|
|
353
|
+
CREATE TABLE fkc_parent (
|
|
354
|
+
id INTEGER PRIMARY KEY,
|
|
355
|
+
name TEXT
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
CREATE TABLE fkc_child (
|
|
359
|
+
id INTEGER PRIMARY KEY,
|
|
360
|
+
parent_id INTEGER NOT NULL,
|
|
361
|
+
FOREIGN KEY (parent_id) REFERENCES fkc_parent(id) ON DELETE SET NULL
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
INSERT INTO fkc_parent VALUES (1, 'P1'), (2, 'P2');
|
|
365
|
+
INSERT INTO fkc_child VALUES (10, 1), (20, 2);
|
|
366
|
+
|
|
367
|
+
-- Commit setup
|
|
368
|
+
SELECT count(*) FROM fkc_child;
|
|
369
|
+
→ [{"count(*)":2}]
|
|
370
|
+
|
|
371
|
+
-- Delete parent — cascade tries SET NULL but column is NOT NULL → should fail
|
|
372
|
+
DELETE FROM fkc_parent WHERE id = 1;
|
|
373
|
+
-- error: NOT NULL constraint failed: fkc_child.parent_id
|
|
374
|
+
|
|
375
|
+
-- Verify nothing was deleted
|
|
376
|
+
SELECT count(*) FROM fkc_parent;
|
|
377
|
+
→ [{"count(*)":2}]
|
|
378
|
+
|
|
379
|
+
SELECT count(*) FROM fkc_child;
|
|
380
|
+
→ [{"count(*)":2}]
|
|
381
|
+
|
|
382
|
+
DROP TABLE fkc_child;
|
|
383
|
+
DROP TABLE fkc_parent;
|
|
384
|
+
|
|
385
|
+
-- ===================================================================
|
|
386
|
+
-- Assertion referencing multiple tables
|
|
387
|
+
-- CREATE ASSERTION checking that count(*) from table a equals
|
|
388
|
+
-- count(*) from table b — verify evaluation across tables at commit.
|
|
389
|
+
-- ===================================================================
|
|
390
|
+
|
|
391
|
+
CREATE TABLE tbl_a (id INTEGER PRIMARY KEY, val TEXT);
|
|
392
|
+
CREATE TABLE tbl_b (id INTEGER PRIMARY KEY, val TEXT);
|
|
393
|
+
-- run
|
|
394
|
+
|
|
395
|
+
CREATE ASSERTION counts_equal CHECK (
|
|
396
|
+
(SELECT count(*) FROM tbl_a) = (SELECT count(*) FROM tbl_b)
|
|
397
|
+
);
|
|
398
|
+
-- run
|
|
399
|
+
|
|
400
|
+
-- Both empty: OK
|
|
401
|
+
BEGIN;
|
|
402
|
+
COMMIT;
|
|
403
|
+
-- run
|
|
404
|
+
|
|
405
|
+
-- Insert into both equally: OK
|
|
406
|
+
BEGIN;
|
|
407
|
+
INSERT INTO tbl_a VALUES (1, 'a1');
|
|
408
|
+
INSERT INTO tbl_b VALUES (1, 'b1');
|
|
409
|
+
COMMIT;
|
|
410
|
+
-- run
|
|
411
|
+
|
|
412
|
+
SELECT count(*) FROM tbl_a;
|
|
413
|
+
→ [{"count(*)":1}]
|
|
414
|
+
|
|
415
|
+
-- Insert into a only → counts diverge → fails
|
|
416
|
+
BEGIN;
|
|
417
|
+
INSERT INTO tbl_a VALUES (2, 'a2');
|
|
418
|
+
COMMIT;
|
|
419
|
+
-- error: Integrity assertion failed: counts_equal
|
|
420
|
+
|
|
421
|
+
-- Insert into b only → counts diverge → fails
|
|
422
|
+
BEGIN;
|
|
423
|
+
INSERT INTO tbl_b VALUES (2, 'b2');
|
|
424
|
+
COMMIT;
|
|
425
|
+
-- error: Integrity assertion failed: counts_equal
|
|
426
|
+
|
|
427
|
+
-- Insert into both → counts match again → OK
|
|
428
|
+
BEGIN;
|
|
429
|
+
INSERT INTO tbl_a VALUES (2, 'a2');
|
|
430
|
+
INSERT INTO tbl_b VALUES (2, 'b2');
|
|
431
|
+
COMMIT;
|
|
432
|
+
-- run
|
|
433
|
+
|
|
434
|
+
SELECT count(*) FROM tbl_a;
|
|
435
|
+
→ [{"count(*)":2}]
|
|
436
|
+
SELECT count(*) FROM tbl_b;
|
|
437
|
+
→ [{"count(*)":2}]
|
|
438
|
+
|
|
439
|
+
DROP ASSERTION counts_equal;
|
|
440
|
+
DROP TABLE tbl_b;
|
|
441
|
+
DROP TABLE tbl_a;
|
|
442
|
+
-- run
|