@quereus/quereus 4.20.1 → 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/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,171 @@
|
|
|
1
|
+
-- Column-level ON CONFLICT directives in DDL (e.g.
|
|
2
|
+
-- `... PRIMARY KEY ON CONFLICT REPLACE`). Quereus now honors these as the
|
|
3
|
+
-- per-constraint default conflict resolution. Statement-level OR clauses
|
|
4
|
+
-- still take precedence over the column-level default.
|
|
5
|
+
|
|
6
|
+
-- ===================================
|
|
7
|
+
-- 1. PRIMARY KEY ON CONFLICT REPLACE — duplicate insert silently replaces
|
|
8
|
+
-- ===================================
|
|
9
|
+
|
|
10
|
+
create table pk_replace (a integer primary key on conflict replace, b text);
|
|
11
|
+
insert into pk_replace values (1, 'first');
|
|
12
|
+
|
|
13
|
+
insert into pk_replace values (1, 'second');
|
|
14
|
+
|
|
15
|
+
select a, b from pk_replace;
|
|
16
|
+
→ [{"a":1,"b":"second"}]
|
|
17
|
+
|
|
18
|
+
drop table pk_replace;
|
|
19
|
+
|
|
20
|
+
-- ===================================
|
|
21
|
+
-- 2. PRIMARY KEY ON CONFLICT IGNORE — duplicate insert silently dropped
|
|
22
|
+
-- ===================================
|
|
23
|
+
|
|
24
|
+
create table pk_ignore (a integer primary key on conflict ignore, b text);
|
|
25
|
+
insert into pk_ignore values (10, 'data');
|
|
26
|
+
|
|
27
|
+
insert into pk_ignore values (10, 'conflict');
|
|
28
|
+
|
|
29
|
+
select a, b from pk_ignore;
|
|
30
|
+
→ [{"a":10,"b":"data"}]
|
|
31
|
+
|
|
32
|
+
drop table pk_ignore;
|
|
33
|
+
|
|
34
|
+
-- ===================================
|
|
35
|
+
-- 3. UNIQUE ON CONFLICT REPLACE — second insert replaces existing row
|
|
36
|
+
-- ===================================
|
|
37
|
+
|
|
38
|
+
create table uniq_replace (id integer primary key, email text unique on conflict replace);
|
|
39
|
+
insert into uniq_replace values (1, 'a@x');
|
|
40
|
+
|
|
41
|
+
insert into uniq_replace values (2, 'a@x');
|
|
42
|
+
|
|
43
|
+
-- The new row (id=2) wins; the old one is replaced.
|
|
44
|
+
select id, email from uniq_replace order by id;
|
|
45
|
+
→ [{"id":2,"email":"a@x"}]
|
|
46
|
+
|
|
47
|
+
drop table uniq_replace;
|
|
48
|
+
|
|
49
|
+
-- ===================================
|
|
50
|
+
-- 4. NOT NULL ON CONFLICT IGNORE — violating row silently skipped
|
|
51
|
+
-- ===================================
|
|
52
|
+
|
|
53
|
+
create table nn_ignore (id integer primary key, name text not null on conflict ignore);
|
|
54
|
+
insert into nn_ignore values (1, 'valid');
|
|
55
|
+
|
|
56
|
+
insert into nn_ignore (id) values (2);
|
|
57
|
+
|
|
58
|
+
select id, name from nn_ignore order by id;
|
|
59
|
+
→ [{"id":1,"name":"valid"}]
|
|
60
|
+
|
|
61
|
+
drop table nn_ignore;
|
|
62
|
+
|
|
63
|
+
-- ===================================
|
|
64
|
+
-- 5. CHECK ON CONFLICT IGNORE — parser accepts; violations silently skipped
|
|
65
|
+
-- ===================================
|
|
66
|
+
|
|
67
|
+
create table ck_ignore (id integer primary key, n integer check (n > 0) on conflict ignore);
|
|
68
|
+
insert into ck_ignore values (1, 10);
|
|
69
|
+
|
|
70
|
+
-- CHECK violation under column-level IGNORE: row dropped.
|
|
71
|
+
insert into ck_ignore values (2, -5);
|
|
72
|
+
|
|
73
|
+
select id, n from ck_ignore order by id;
|
|
74
|
+
→ [{"id":1,"n":10}]
|
|
75
|
+
|
|
76
|
+
drop table ck_ignore;
|
|
77
|
+
|
|
78
|
+
-- ===================================
|
|
79
|
+
-- 6. Statement-level OR clause overrides column-level ON CONFLICT directive
|
|
80
|
+
-- ===================================
|
|
81
|
+
|
|
82
|
+
create table override_t (a integer primary key on conflict ignore, b text);
|
|
83
|
+
insert into override_t values (1, 'first');
|
|
84
|
+
|
|
85
|
+
-- statement-level OR ABORT must beat the column-level IGNORE directive.
|
|
86
|
+
insert or abort into override_t values (1, 'second');
|
|
87
|
+
-- error: UNIQUE constraint failed
|
|
88
|
+
|
|
89
|
+
-- only original row remains
|
|
90
|
+
select a, b from override_t;
|
|
91
|
+
→ [{"a":1,"b":"first"}]
|
|
92
|
+
|
|
93
|
+
drop table override_t;
|
|
94
|
+
|
|
95
|
+
-- ===================================
|
|
96
|
+
-- 7. UPDATE path honors PRIMARY KEY ON CONFLICT REPLACE
|
|
97
|
+
-- ===================================
|
|
98
|
+
|
|
99
|
+
create table pk_upd_replace (id integer primary key on conflict replace, v text);
|
|
100
|
+
insert into pk_upd_replace values (1, 'a'), (2, 'b');
|
|
101
|
+
|
|
102
|
+
-- No OR clause on UPDATE — column-level REPLACE should apply.
|
|
103
|
+
update pk_upd_replace set id = 2 where id = 1;
|
|
104
|
+
|
|
105
|
+
select id, v from pk_upd_replace order by id;
|
|
106
|
+
→ [{"id":2,"v":"a"}]
|
|
107
|
+
|
|
108
|
+
drop table pk_upd_replace;
|
|
109
|
+
|
|
110
|
+
-- ===================================
|
|
111
|
+
-- 8. UPDATE path honors PRIMARY KEY ON CONFLICT IGNORE
|
|
112
|
+
-- ===================================
|
|
113
|
+
|
|
114
|
+
create table pk_upd_ignore (id integer primary key on conflict ignore, v text);
|
|
115
|
+
insert into pk_upd_ignore values (1, 'a'), (2, 'b');
|
|
116
|
+
|
|
117
|
+
update pk_upd_ignore set id = 2 where id = 1;
|
|
118
|
+
|
|
119
|
+
select id, v from pk_upd_ignore order by id;
|
|
120
|
+
→ [{"id":1,"v":"a"},{"id":2,"v":"b"}]
|
|
121
|
+
|
|
122
|
+
drop table pk_upd_ignore;
|
|
123
|
+
|
|
124
|
+
-- ===================================
|
|
125
|
+
-- 9. UPDATE-with-PK-change under REPLACE cascades FK ON DELETE for evicted row
|
|
126
|
+
-- ===================================
|
|
127
|
+
-- Quereus's default `on update` is `restrict`, so any child of the moved row
|
|
128
|
+
-- would block the update before the eviction can happen. To isolate the
|
|
129
|
+
-- evicted row's cascade, only the row that gets evicted has a child here.
|
|
130
|
+
|
|
131
|
+
create table parent_evict (id integer primary key on conflict replace, v text);
|
|
132
|
+
create table child_evict (
|
|
133
|
+
id integer primary key,
|
|
134
|
+
parent_id integer references parent_evict(id) on delete cascade
|
|
135
|
+
);
|
|
136
|
+
insert into parent_evict values (1, 'one'), (2, 'two');
|
|
137
|
+
insert into child_evict values (20, 2);
|
|
138
|
+
|
|
139
|
+
-- Move parent id=1 onto id=2; column-level REPLACE evicts the row at id=2.
|
|
140
|
+
update parent_evict set id = 2 where id = 1;
|
|
141
|
+
|
|
142
|
+
-- The row formerly at id=2 was evicted, so its child (id=20) must be cascaded.
|
|
143
|
+
select id, parent_id from child_evict;
|
|
144
|
+
→ []
|
|
145
|
+
|
|
146
|
+
select id, v from parent_evict order by id;
|
|
147
|
+
→ [{"id":2,"v":"one"}]
|
|
148
|
+
|
|
149
|
+
drop table child_evict;
|
|
150
|
+
drop table parent_evict;
|
|
151
|
+
|
|
152
|
+
-- ===================================
|
|
153
|
+
-- 10. UPDATE-with-PK-change under REPLACE applies ON DELETE SET NULL for evicted row
|
|
154
|
+
-- ===================================
|
|
155
|
+
|
|
156
|
+
create table p_set_null (id integer primary key on conflict replace, v text);
|
|
157
|
+
create table c_set_null (
|
|
158
|
+
id integer primary key,
|
|
159
|
+
parent_id integer null references p_set_null(id) on delete set null
|
|
160
|
+
);
|
|
161
|
+
insert into p_set_null values (1, 'a'), (2, 'b');
|
|
162
|
+
insert into c_set_null values (200, 2);
|
|
163
|
+
|
|
164
|
+
update p_set_null set id = 2 where id = 1;
|
|
165
|
+
|
|
166
|
+
-- Evicted parent (2, 'b') triggers SET NULL on its child (200).
|
|
167
|
+
select id, parent_id from c_set_null;
|
|
168
|
+
→ [{"id":200,"parent_id":null}]
|
|
169
|
+
|
|
170
|
+
drop table c_set_null;
|
|
171
|
+
drop table p_set_null;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
-- Table-level `PRIMARY KEY (...) ON CONFLICT <action>` directive. Mirrors 29.1
|
|
2
|
+
-- (column-level) but exercises the constraint on a composite PK declared as a
|
|
3
|
+
-- table-level constraint, which previously parsed correctly but had its
|
|
4
|
+
-- `ON CONFLICT` action silently dropped (resolving to ABORT).
|
|
5
|
+
|
|
6
|
+
-- ===================================
|
|
7
|
+
-- 1. PRIMARY KEY (...) ON CONFLICT IGNORE — duplicate insert silently dropped
|
|
8
|
+
-- ===================================
|
|
9
|
+
|
|
10
|
+
create table tpk_ignore (a integer, b integer, v text, primary key (a, b) on conflict ignore);
|
|
11
|
+
insert into tpk_ignore values (1, 1, 'first');
|
|
12
|
+
|
|
13
|
+
insert into tpk_ignore values (1, 1, 'second');
|
|
14
|
+
|
|
15
|
+
select a, b, v from tpk_ignore;
|
|
16
|
+
→ [{"a":1,"b":1,"v":"first"}]
|
|
17
|
+
|
|
18
|
+
drop table tpk_ignore;
|
|
19
|
+
|
|
20
|
+
-- ===================================
|
|
21
|
+
-- 2. PRIMARY KEY (...) ON CONFLICT REPLACE — duplicate insert silently replaces
|
|
22
|
+
-- ===================================
|
|
23
|
+
|
|
24
|
+
create table tpk_replace (a integer, b integer, v text, primary key (a, b) on conflict replace);
|
|
25
|
+
insert into tpk_replace values (1, 1, 'first');
|
|
26
|
+
|
|
27
|
+
insert into tpk_replace values (1, 1, 'second');
|
|
28
|
+
|
|
29
|
+
select a, b, v from tpk_replace;
|
|
30
|
+
→ [{"a":1,"b":1,"v":"second"}]
|
|
31
|
+
|
|
32
|
+
drop table tpk_replace;
|
|
33
|
+
|
|
34
|
+
-- ===================================
|
|
35
|
+
-- 3. PRIMARY KEY (...) ON CONFLICT FAIL — duplicate insert errors
|
|
36
|
+
-- ===================================
|
|
37
|
+
|
|
38
|
+
create table tpk_fail (a integer, b integer, v text, primary key (a, b) on conflict fail);
|
|
39
|
+
insert into tpk_fail values (1, 1, 'first');
|
|
40
|
+
|
|
41
|
+
insert into tpk_fail values (1, 1, 'second');
|
|
42
|
+
-- error: UNIQUE constraint failed
|
|
43
|
+
|
|
44
|
+
-- The original row is still there; the conflicting insert errored out.
|
|
45
|
+
select a, b, v from tpk_fail;
|
|
46
|
+
→ [{"a":1,"b":1,"v":"first"}]
|
|
47
|
+
|
|
48
|
+
drop table tpk_fail;
|
|
49
|
+
|
|
50
|
+
-- ===================================
|
|
51
|
+
-- 4. PRIMARY KEY (...) ON CONFLICT ROLLBACK — duplicate insert errors
|
|
52
|
+
-- ===================================
|
|
53
|
+
-- The per-constraint ROLLBACK action surfaces as a constraint failure at the
|
|
54
|
+
-- helper layer (statement aborts). Translation into a tx-wide rollback of the
|
|
55
|
+
-- enclosing transaction would require additional runtime wiring beyond the
|
|
56
|
+
-- schema-build + helper scope of this change; see implementer notes.
|
|
57
|
+
|
|
58
|
+
create table tpk_rb (a integer, b integer, v text, primary key (a, b) on conflict rollback);
|
|
59
|
+
insert into tpk_rb values (1, 1, 'first');
|
|
60
|
+
|
|
61
|
+
insert into tpk_rb values (1, 1, 'second');
|
|
62
|
+
-- error: UNIQUE constraint failed
|
|
63
|
+
|
|
64
|
+
select a, b, v from tpk_rb;
|
|
65
|
+
→ [{"a":1,"b":1,"v":"first"}]
|
|
66
|
+
|
|
67
|
+
drop table tpk_rb;
|
|
68
|
+
|
|
69
|
+
-- ===================================
|
|
70
|
+
-- 5. Statement-level OR clause overrides table-level ON CONFLICT directive
|
|
71
|
+
-- ===================================
|
|
72
|
+
|
|
73
|
+
create table tpk_override (a integer, b integer, v text, primary key (a, b) on conflict ignore);
|
|
74
|
+
insert into tpk_override values (1, 1, 'first');
|
|
75
|
+
|
|
76
|
+
-- statement-level OR ABORT must beat the table-level IGNORE directive.
|
|
77
|
+
insert or abort into tpk_override values (1, 1, 'second');
|
|
78
|
+
-- error: UNIQUE constraint failed
|
|
79
|
+
|
|
80
|
+
-- only the original row remains
|
|
81
|
+
select a, b, v from tpk_override;
|
|
82
|
+
→ [{"a":1,"b":1,"v":"first"}]
|
|
83
|
+
|
|
84
|
+
drop table tpk_override;
|
|
85
|
+
|
|
86
|
+
-- ===================================
|
|
87
|
+
-- 6. UPDATE path honors table-level PRIMARY KEY ON CONFLICT REPLACE
|
|
88
|
+
-- ===================================
|
|
89
|
+
|
|
90
|
+
create table tpk_upd_replace (a integer, b integer, v text, primary key (a, b) on conflict replace);
|
|
91
|
+
insert into tpk_upd_replace values (1, 1, 'a'), (2, 2, 'b');
|
|
92
|
+
|
|
93
|
+
-- No OR clause on UPDATE — table-level REPLACE should apply.
|
|
94
|
+
update tpk_upd_replace set a = 2, b = 2 where a = 1 and b = 1;
|
|
95
|
+
|
|
96
|
+
select a, b, v from tpk_upd_replace order by a, b;
|
|
97
|
+
→ [{"a":2,"b":2,"v":"a"}]
|
|
98
|
+
|
|
99
|
+
drop table tpk_upd_replace;
|
|
100
|
+
|
|
101
|
+
-- ===================================
|
|
102
|
+
-- 7. UPDATE path honors table-level PRIMARY KEY ON CONFLICT IGNORE
|
|
103
|
+
-- ===================================
|
|
104
|
+
|
|
105
|
+
create table tpk_upd_ignore (a integer, b integer, v text, primary key (a, b) on conflict ignore);
|
|
106
|
+
insert into tpk_upd_ignore values (1, 1, 'a'), (2, 2, 'b');
|
|
107
|
+
|
|
108
|
+
update tpk_upd_ignore set a = 2, b = 2 where a = 1 and b = 1;
|
|
109
|
+
|
|
110
|
+
select a, b, v from tpk_upd_ignore order by a, b;
|
|
111
|
+
→ [{"a":1,"b":1,"v":"a"},{"a":2,"b":2,"v":"b"}]
|
|
112
|
+
|
|
113
|
+
drop table tpk_upd_ignore;
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
-- constraints.sqllogic - Testing integrity constraints
|
|
2
|
+
|
|
3
|
+
-- Basic table creation (without constraint enforcement)
|
|
4
|
+
CREATE TABLE t_basic (
|
|
5
|
+
id INTEGER PRIMARY KEY,
|
|
6
|
+
name TEXT,
|
|
7
|
+
value INTEGER
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
INSERT INTO t_basic VALUES (1, 'test', 100);
|
|
11
|
+
SELECT * FROM t_basic;
|
|
12
|
+
→ [{"id":1,"name":"test","value":100}]
|
|
13
|
+
|
|
14
|
+
DROP TABLE t_basic;
|
|
15
|
+
|
|
16
|
+
-- === NOT NULL Constraints ===
|
|
17
|
+
|
|
18
|
+
CREATE TABLE t_notnull (
|
|
19
|
+
id INTEGER PRIMARY KEY,
|
|
20
|
+
req TEXT NOT NULL,
|
|
21
|
+
opt TEXT NULL
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
-- Insert valid row
|
|
25
|
+
INSERT INTO t_notnull (id, req, opt) VALUES (1, 'required', 'optional');
|
|
26
|
+
SELECT req, opt FROM t_notnull WHERE id = 1;
|
|
27
|
+
→ [{"req":"required","opt":"optional"}]
|
|
28
|
+
|
|
29
|
+
-- Insert omitting NOT NULL column (no default)
|
|
30
|
+
INSERT INTO t_notnull (id, opt) VALUES (2, 'no_req');
|
|
31
|
+
-- error: NOT NULL constraint failed: t_notnull.req
|
|
32
|
+
|
|
33
|
+
-- Insert explicit NULL into NOT NULL column
|
|
34
|
+
INSERT INTO t_notnull (id, req) VALUES (3, NULL);
|
|
35
|
+
-- error: NOT NULL constraint failed: t_notnull.req
|
|
36
|
+
|
|
37
|
+
-- Update optional to NULL (allowed)
|
|
38
|
+
UPDATE t_notnull SET opt = NULL WHERE id = 1;
|
|
39
|
+
SELECT opt FROM t_notnull WHERE id = 1;
|
|
40
|
+
→ [{"opt":null}]
|
|
41
|
+
|
|
42
|
+
-- Update required to NULL (fail)
|
|
43
|
+
UPDATE t_notnull SET req = NULL WHERE id = 1;
|
|
44
|
+
-- error: NOT NULL constraint failed: t_notnull.req
|
|
45
|
+
|
|
46
|
+
-- Verify state after failed update
|
|
47
|
+
SELECT req FROM t_notnull WHERE id = 1;
|
|
48
|
+
→ [{"req":"required"}]
|
|
49
|
+
|
|
50
|
+
DROP TABLE t_notnull;
|
|
51
|
+
|
|
52
|
+
-- === Simple CHECK Constraints (Default ON INSERT, UPDATE) ===
|
|
53
|
+
|
|
54
|
+
CREATE TABLE t_check (
|
|
55
|
+
id INTEGER PRIMARY KEY,
|
|
56
|
+
pos INT CHECK(pos > 0),
|
|
57
|
+
bal REAL CHECK(bal >= 0)
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
-- Insert valid
|
|
61
|
+
INSERT INTO t_check VALUES (1, 10, 100.5);
|
|
62
|
+
SELECT pos, bal FROM t_check WHERE id = 1;
|
|
63
|
+
→ [{"pos":10,"bal":100.5}]
|
|
64
|
+
|
|
65
|
+
-- Insert invalid pos
|
|
66
|
+
INSERT INTO t_check VALUES (2, -5, 50);
|
|
67
|
+
-- error: CHECK constraint failed: _check_pos
|
|
68
|
+
|
|
69
|
+
-- Insert invalid bal
|
|
70
|
+
INSERT INTO t_check VALUES (3, 5, -0.01);
|
|
71
|
+
-- error: CHECK constraint failed: _check_bal
|
|
72
|
+
|
|
73
|
+
-- Update valid to valid
|
|
74
|
+
UPDATE t_check SET pos = 20, bal = 99.9 WHERE id = 1;
|
|
75
|
+
SELECT pos, bal FROM t_check WHERE id = 1;
|
|
76
|
+
→ [{"pos":20,"bal":99.9}]
|
|
77
|
+
|
|
78
|
+
-- Update valid to invalid pos
|
|
79
|
+
UPDATE t_check SET pos = 0 WHERE id = 1;
|
|
80
|
+
-- error: CHECK constraint failed: _check_pos
|
|
81
|
+
|
|
82
|
+
-- Update valid to invalid bal
|
|
83
|
+
UPDATE t_check SET bal = -10 WHERE id = 1;
|
|
84
|
+
-- error: CHECK constraint failed: _check_bal
|
|
85
|
+
|
|
86
|
+
-- Verify state after failed updates
|
|
87
|
+
SELECT pos, bal FROM t_check WHERE id = 1;
|
|
88
|
+
→ [{"pos":20,"bal":99.9}]
|
|
89
|
+
|
|
90
|
+
DROP TABLE t_check;
|
|
91
|
+
|
|
92
|
+
-- === Row-Level CHECK ON ... Constraints ===
|
|
93
|
+
|
|
94
|
+
CREATE TABLE t_check_on (
|
|
95
|
+
id INTEGER PRIMARY KEY,
|
|
96
|
+
status TEXT CHECK ON INSERT (status IN ('active', 'inactive')),
|
|
97
|
+
val INTEGER,
|
|
98
|
+
CONSTRAINT positive_val CHECK ON UPDATE (NEW.val >= 0),
|
|
99
|
+
CONSTRAINT no_delete CHECK ON DELETE (FALSE)
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
-- Insert valid (status check applies)
|
|
103
|
+
INSERT INTO t_check_on (id, status, val) VALUES (1, 'active', 100);
|
|
104
|
+
SELECT status, val FROM t_check_on WHERE id = 1;
|
|
105
|
+
→ [{"status":"active","val":100}]
|
|
106
|
+
|
|
107
|
+
-- Insert invalid status
|
|
108
|
+
INSERT INTO t_check_on (id, status, val) VALUES (2, 'pending', 200);
|
|
109
|
+
-- error: CHECK constraint failed: _check_status
|
|
110
|
+
|
|
111
|
+
-- Update status (check does NOT apply on UPDATE)
|
|
112
|
+
UPDATE t_check_on SET status = 'archived' WHERE id = 1;
|
|
113
|
+
SELECT status FROM t_check_on WHERE id = 1;
|
|
114
|
+
→ [{"status":"archived"}]
|
|
115
|
+
|
|
116
|
+
-- Update val valid (positive_val check applies)
|
|
117
|
+
UPDATE t_check_on SET val = 50 WHERE id = 1;
|
|
118
|
+
SELECT val FROM t_check_on WHERE id = 1;
|
|
119
|
+
→ [{"val":50}]
|
|
120
|
+
|
|
121
|
+
-- Update val invalid (positive_val check applies)
|
|
122
|
+
UPDATE t_check_on SET val = -1 WHERE id = 1;
|
|
123
|
+
-- error: CHECK constraint failed: positive_val
|
|
124
|
+
|
|
125
|
+
-- Verify state after failed update
|
|
126
|
+
SELECT val FROM t_check_on WHERE id = 1;
|
|
127
|
+
→ [{"val":50}]
|
|
128
|
+
|
|
129
|
+
-- Attempt DELETE (no_delete check applies)
|
|
130
|
+
DELETE FROM t_check_on WHERE id = 1;
|
|
131
|
+
-- error: CHECK constraint failed: no_delete
|
|
132
|
+
|
|
133
|
+
-- Verify state after failed delete
|
|
134
|
+
SELECT count(*) FROM t_check_on WHERE id = 1;
|
|
135
|
+
→ [{"count(*)":1}]
|
|
136
|
+
|
|
137
|
+
DROP TABLE t_check_on;
|
|
138
|
+
|
|
139
|
+
-- === CHECK ON with NEW/OLD aliases ===
|
|
140
|
+
|
|
141
|
+
CREATE TABLE t_check_alias (
|
|
142
|
+
id INTEGER PRIMARY KEY,
|
|
143
|
+
version INTEGER DEFAULT 1,
|
|
144
|
+
payload TEXT,
|
|
145
|
+
CONSTRAINT version_increase CHECK ON UPDATE (NEW.version > OLD.version)
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
INSERT INTO t_check_alias (id, payload) VALUES (10, 'initial data');
|
|
149
|
+
SELECT version FROM t_check_alias WHERE id = 10;
|
|
150
|
+
→ [{"version":1}]
|
|
151
|
+
|
|
152
|
+
-- Valid update (increasing version)
|
|
153
|
+
UPDATE t_check_alias SET version = 2, payload = 'updated data' WHERE id = 10;
|
|
154
|
+
SELECT version, payload FROM t_check_alias WHERE id = 10;
|
|
155
|
+
→ [{"version":2,"payload":"updated data"}]
|
|
156
|
+
|
|
157
|
+
-- Invalid update (same version)
|
|
158
|
+
UPDATE t_check_alias SET version = 2, payload = 'no change' WHERE id = 10;
|
|
159
|
+
-- error: CHECK constraint failed: version_increase
|
|
160
|
+
|
|
161
|
+
-- Invalid update (decreasing version)
|
|
162
|
+
UPDATE t_check_alias SET version = 1, payload = 'revert?' WHERE id = 10;
|
|
163
|
+
-- error: CHECK constraint failed: version_increase
|
|
164
|
+
|
|
165
|
+
-- Verify state after failed updates
|
|
166
|
+
SELECT version, payload FROM t_check_alias WHERE id = 10;
|
|
167
|
+
→ [{"version":2,"payload":"updated data"}]
|
|
168
|
+
|
|
169
|
+
DROP TABLE t_check_alias;
|
|
170
|
+
|
|
171
|
+
-- === CHECK ON with Subquery ===
|
|
172
|
+
|
|
173
|
+
CREATE TABLE products (sku TEXT PRIMARY KEY, price REAL);
|
|
174
|
+
CREATE TABLE inventory (loc TEXT, sku TEXT, qty INTEGER CHECK(qty >= 0) /* Simple check */,
|
|
175
|
+
FOREIGN KEY (sku) REFERENCES products(sku));
|
|
176
|
+
ALTER TABLE inventory ADD CONSTRAINT enough_stock CHECK ON UPDATE (
|
|
177
|
+
new.qty <= (SELECT sum(s.qty) FROM inventory s WHERE s.sku = NEW.sku)
|
|
178
|
+
);
|
|
179
|
+
ALTER TABLE inventory ADD CONSTRAINT no_delete_if_positive CHECK ON DELETE (
|
|
180
|
+
old.qty <= 0
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
INSERT INTO products VALUES ('A1', 10.0), ('B2', 20.0);
|
|
184
|
+
INSERT INTO inventory VALUES ('W1', 'A1', 50), ('W2', 'A1', 30), ('W1', 'B2', 100);
|
|
185
|
+
|
|
186
|
+
SELECT sku, sum(qty) FROM inventory GROUP BY sku ORDER BY sku;
|
|
187
|
+
→ [{"sku":"A1","sum(qty)":80},{"sku":"B2","sum(qty)":100}]
|
|
188
|
+
|
|
189
|
+
-- Valid update (decreasing stock is allowed by enough_stock on update)
|
|
190
|
+
UPDATE inventory SET qty = 25 WHERE loc = 'W1' AND sku = 'A1';
|
|
191
|
+
SELECT qty FROM inventory WHERE loc = 'W1' AND sku = 'A1';
|
|
192
|
+
→ [{"qty":25}]
|
|
193
|
+
|
|
194
|
+
-- Invalid update (cannot set negative simple check)
|
|
195
|
+
UPDATE inventory SET qty = -5 WHERE loc = 'W1' AND sku = 'A1';
|
|
196
|
+
-- error: CHECK constraint failed: _check_qty
|
|
197
|
+
|
|
198
|
+
-- Attempt to delete row with positive quantity
|
|
199
|
+
DELETE FROM inventory WHERE loc = 'W1' AND sku = 'A1';
|
|
200
|
+
-- error: CHECK constraint failed: no_delete_if_positive
|
|
201
|
+
|
|
202
|
+
-- Set quantity to 0
|
|
203
|
+
UPDATE inventory SET qty = 0 WHERE loc = 'W1' AND sku = 'A1';
|
|
204
|
+
SELECT qty FROM inventory WHERE loc = 'W1' AND sku = 'A1';
|
|
205
|
+
→ [{"qty":0}]
|
|
206
|
+
|
|
207
|
+
-- Now delete should work
|
|
208
|
+
DELETE FROM inventory WHERE loc = 'W1' AND sku = 'A1';
|
|
209
|
+
SELECT count(*) FROM inventory WHERE loc = 'W1' AND sku = 'A1';
|
|
210
|
+
→ [{"count(*)":0}]
|
|
211
|
+
|
|
212
|
+
DROP TABLE inventory;
|
|
213
|
+
DROP TABLE products;
|
|
214
|
+
|
|
215
|
+
-- === CHECK with EXISTS subquery referencing another table (INSERT/UPDATE) ===
|
|
216
|
+
|
|
217
|
+
CREATE TABLE ref_table (
|
|
218
|
+
id TEXT PRIMARY KEY,
|
|
219
|
+
name TEXT
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
CREATE TABLE dependent (
|
|
223
|
+
id INTEGER PRIMARY KEY,
|
|
224
|
+
ref_id TEXT,
|
|
225
|
+
CONSTRAINT ref_must_exist CHECK ON INSERT, UPDATE (
|
|
226
|
+
EXISTS (SELECT 1 FROM ref_table WHERE ref_table.id = NEW.ref_id)
|
|
227
|
+
)
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
-- Insert into empty dependent table should fail (ref_table is empty)
|
|
231
|
+
INSERT INTO dependent (id, ref_id) VALUES (1, 'abc');
|
|
232
|
+
-- error: CHECK constraint failed: ref_must_exist
|
|
233
|
+
|
|
234
|
+
-- Populate ref_table
|
|
235
|
+
INSERT INTO ref_table VALUES ('abc', 'Valid Reference');
|
|
236
|
+
SELECT * FROM ref_table;
|
|
237
|
+
→ [{"id":"abc","name":"Valid Reference"}]
|
|
238
|
+
|
|
239
|
+
-- Now insert should succeed
|
|
240
|
+
INSERT INTO dependent (id, ref_id) VALUES (1, 'abc');
|
|
241
|
+
SELECT * FROM dependent;
|
|
242
|
+
→ [{"id":1,"ref_id":"abc"}]
|
|
243
|
+
|
|
244
|
+
-- Try to update to non-existent reference
|
|
245
|
+
UPDATE dependent SET ref_id = 'xyz' WHERE id = 1;
|
|
246
|
+
-- error: CHECK constraint failed: ref_must_exist
|
|
247
|
+
|
|
248
|
+
-- Verify state unchanged
|
|
249
|
+
SELECT ref_id FROM dependent WHERE id = 1;
|
|
250
|
+
→ [{"ref_id":"abc"}]
|
|
251
|
+
|
|
252
|
+
-- Add another valid reference
|
|
253
|
+
INSERT INTO ref_table VALUES ('xyz', 'Another Valid');
|
|
254
|
+
|
|
255
|
+
-- Now update should succeed
|
|
256
|
+
UPDATE dependent SET ref_id = 'xyz' WHERE id = 1;
|
|
257
|
+
SELECT ref_id FROM dependent WHERE id = 1;
|
|
258
|
+
→ [{"ref_id":"xyz"}]
|
|
259
|
+
|
|
260
|
+
DROP TABLE dependent;
|
|
261
|
+
DROP TABLE ref_table;
|
|
262
|
+
|
|
263
|
+
-- === Deferred row-level CHECK (EXISTS) commit-time enforcement ===
|
|
264
|
+
|
|
265
|
+
-- Recreate tables
|
|
266
|
+
CREATE TABLE ref_table (
|
|
267
|
+
id TEXT PRIMARY KEY,
|
|
268
|
+
name TEXT
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
CREATE TABLE dependent (
|
|
272
|
+
id INTEGER PRIMARY KEY,
|
|
273
|
+
ref_id TEXT,
|
|
274
|
+
CONSTRAINT ref_must_exist CHECK ON INSERT, UPDATE (
|
|
275
|
+
EXISTS (SELECT 1 FROM ref_table WHERE ref_table.id = NEW.ref_id)
|
|
276
|
+
)
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
-- Case A: Violation allowed within transaction, rejected at COMMIT
|
|
280
|
+
BEGIN;
|
|
281
|
+
INSERT INTO dependent (id, ref_id) VALUES (100, 'missing');
|
|
282
|
+
COMMIT;
|
|
283
|
+
-- error: CHECK constraint failed: ref_must_exist
|
|
284
|
+
|
|
285
|
+
-- Ensure nothing was committed
|
|
286
|
+
SELECT count(*) FROM dependent WHERE id = 100;
|
|
287
|
+
→ [{"count(*)":0}]
|
|
288
|
+
|
|
289
|
+
-- Case B: Fix violation before COMMIT → succeeds
|
|
290
|
+
BEGIN;
|
|
291
|
+
INSERT INTO dependent (id, ref_id) VALUES (101, 'later');
|
|
292
|
+
INSERT INTO ref_table VALUES ('later', 'OK');
|
|
293
|
+
COMMIT;
|
|
294
|
+
SELECT ref_id FROM dependent WHERE id = 101;
|
|
295
|
+
→ [{"ref_id":"later"}]
|
|
296
|
+
|
|
297
|
+
-- Case C: Savepoint rollback of violating change → COMMIT succeeds
|
|
298
|
+
BEGIN;
|
|
299
|
+
SAVEPOINT sp;
|
|
300
|
+
INSERT INTO dependent (id, ref_id) VALUES (102, 'nope');
|
|
301
|
+
ROLLBACK TO SAVEPOINT sp;
|
|
302
|
+
COMMIT;
|
|
303
|
+
SELECT count(*) FROM dependent WHERE id = 102;
|
|
304
|
+
→ [{"count(*)":0}]
|
|
305
|
+
|
|
306
|
+
DROP TABLE dependent;
|
|
307
|
+
DROP TABLE ref_table;
|
|
308
|
+
|
|
309
|
+
-- === ALTER TABLE ADD CONSTRAINT ===
|
|
310
|
+
|
|
311
|
+
CREATE TABLE t_alter(x INT, y TEXT);
|
|
312
|
+
|
|
313
|
+
-- Add a simple CHECK constraint
|
|
314
|
+
ALTER TABLE t_alter ADD CONSTRAINT positive_x CHECK (x > 0);
|
|
315
|
+
|
|
316
|
+
-- Test that the constraint is enforced on INSERT
|
|
317
|
+
INSERT INTO t_alter VALUES (5, 'valid');
|
|
318
|
+
SELECT * FROM t_alter;
|
|
319
|
+
→ [{"x":5,"y":"valid"}]
|
|
320
|
+
|
|
321
|
+
-- Test constraint failure
|
|
322
|
+
INSERT INTO t_alter VALUES (-1, 'invalid');
|
|
323
|
+
-- error: CHECK constraint failed: positive_x
|
|
324
|
+
|
|
325
|
+
-- Verify state after failed insert
|
|
326
|
+
SELECT * FROM t_alter;
|
|
327
|
+
→ [{"x":5,"y":"valid"}]
|
|
328
|
+
|
|
329
|
+
-- Add constraint with operation specifier
|
|
330
|
+
ALTER TABLE t_alter ADD CONSTRAINT y_on_update CHECK ON UPDATE (length(y) > 2);
|
|
331
|
+
|
|
332
|
+
-- Test UPDATE constraint
|
|
333
|
+
UPDATE t_alter SET y = 'good' WHERE x = 5;
|
|
334
|
+
SELECT * FROM t_alter;
|
|
335
|
+
→ [{"x":5,"y":"good"}]
|
|
336
|
+
|
|
337
|
+
-- Test UPDATE constraint failure
|
|
338
|
+
UPDATE t_alter SET y = 'no' WHERE x = 5;
|
|
339
|
+
-- error: CHECK constraint failed: y_on_update
|
|
340
|
+
|
|
341
|
+
-- Verify state after failed update
|
|
342
|
+
SELECT * FROM t_alter;
|
|
343
|
+
→ [{"x":5,"y":"good"}]
|
|
344
|
+
|
|
345
|
+
-- Test that INSERT is not affected by UPDATE-only constraint
|
|
346
|
+
INSERT INTO t_alter VALUES (10, 'hi');
|
|
347
|
+
SELECT * FROM t_alter ORDER BY x;
|
|
348
|
+
→ [{"x":5,"y":"good"},{"x":10,"y":"hi"}]
|
|
349
|
+
|
|
350
|
+
DROP TABLE t_alter;
|
|
351
|
+
|
|
352
|
+
-- === NOT EXISTS constraint (lowercase operators) ===
|
|
353
|
+
|
|
354
|
+
CREATE TABLE other_table (
|
|
355
|
+
id INTEGER PRIMARY KEY,
|
|
356
|
+
value TEXT
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
CREATE TABLE main_table (
|
|
360
|
+
id INTEGER PRIMARY KEY,
|
|
361
|
+
name TEXT
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
-- Add constraint with lowercase 'not exists'
|
|
365
|
+
ALTER TABLE main_table ADD CONSTRAINT is_valid CHECK (not exists (select 1 from other_table));
|
|
366
|
+
|
|
367
|
+
-- Insert should succeed when other_table is empty
|
|
368
|
+
INSERT INTO main_table VALUES (1, 'first');
|
|
369
|
+
SELECT * FROM main_table;
|
|
370
|
+
→ [{"id":1,"name":"first"}]
|
|
371
|
+
|
|
372
|
+
-- Insert into other_table
|
|
373
|
+
INSERT INTO other_table VALUES (1, 'data');
|
|
374
|
+
|
|
375
|
+
-- Now insert into main_table should fail (other_table is not empty)
|
|
376
|
+
INSERT INTO main_table VALUES (2, 'second');
|
|
377
|
+
-- error: CHECK constraint failed: is_valid
|
|
378
|
+
|
|
379
|
+
-- Clear other_table
|
|
380
|
+
DELETE FROM other_table WHERE id = 1;
|
|
381
|
+
|
|
382
|
+
-- Now insert should succeed again
|
|
383
|
+
INSERT INTO main_table VALUES (2, 'second');
|
|
384
|
+
SELECT count(*) FROM main_table;
|
|
385
|
+
→ [{"count(*)":2}]
|
|
386
|
+
|
|
387
|
+
DROP TABLE main_table;
|
|
388
|
+
DROP TABLE other_table;
|
|
389
|
+
|
|
390
|
+
-- === Lowercase logical operators in constraints ===
|
|
391
|
+
|
|
392
|
+
CREATE TABLE t_lowercase (
|
|
393
|
+
id INTEGER PRIMARY KEY,
|
|
394
|
+
value INTEGER,
|
|
395
|
+
name TEXT,
|
|
396
|
+
CONSTRAINT check_and CHECK (value > 0 and value < 100),
|
|
397
|
+
CONSTRAINT check_like CHECK (name like 'test%')
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
-- Test AND constraint
|
|
401
|
+
INSERT INTO t_lowercase VALUES (1, 50, 'test1');
|
|
402
|
+
|
|
403
|
+
-- Test AND constraint failure (value too high)
|
|
404
|
+
INSERT INTO t_lowercase VALUES (2, 150, 'test2');
|
|
405
|
+
-- error: CHECK constraint failed: check_and (value > 0 and value < 100)
|
|
406
|
+
|
|
407
|
+
-- Test AND constraint failure (value too low)
|
|
408
|
+
INSERT INTO t_lowercase VALUES (3, -5, 'test3');
|
|
409
|
+
-- error: CHECK constraint failed: check_and (value > 0 and value < 100)
|
|
410
|
+
|
|
411
|
+
-- Test LIKE constraint
|
|
412
|
+
INSERT INTO t_lowercase VALUES (5, 75, 'testing');
|
|
413
|
+
|
|
414
|
+
-- Test LIKE constraint failure
|
|
415
|
+
INSERT INTO t_lowercase VALUES (6, 30, 'invalid');
|
|
416
|
+
-- error: CHECK constraint failed: check_like (name like 'test%')
|
|
417
|
+
|
|
418
|
+
DROP TABLE t_lowercase;
|