@quereus/quereus 4.20.0 → 4.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/src/common/types.d.ts +4 -4
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/schema/catalog-rendering.js +13 -1
- package/dist/src/schema/catalog-rendering.js.map +1 -1
- package/dist/src/schema/catalog.d.ts +35 -2
- package/dist/src/schema/catalog.d.ts.map +1 -1
- package/dist/src/schema/catalog.js +42 -33
- package/dist/src/schema/catalog.js.map +1 -1
- package/dist/src/schema/schema-differ.d.ts +1 -1
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +195 -33
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/schema/unique-enforcement.d.ts +23 -1
- package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
- package/dist/src/schema/unique-enforcement.js +43 -1
- package/dist/src/schema/unique-enforcement.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +15 -12
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +87 -100
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/package.json +7 -4
- package/test/README.md +173 -0
- package/test/logic/01-basic.sqllogic +39 -0
- package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
- package/test/logic/01.2-strings.sqllogic +43 -0
- package/test/logic/01.5-insert-select.sqllogic +237 -0
- package/test/logic/01.6-update-extras.sqllogic +118 -0
- package/test/logic/01.7-update-from.sqllogic +67 -0
- package/test/logic/01.8-delete-extras.sqllogic +122 -0
- package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
- package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
- package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
- package/test/logic/01.9-query-expr-values.sqllogic +111 -0
- package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
- package/test/logic/02-filters.sqllogic +54 -0
- package/test/logic/02-smoke.sqllogic +62 -0
- package/test/logic/02.1-bind-parameters.sqllogic +223 -0
- package/test/logic/03-expressions.sqllogic +190 -0
- package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
- package/test/logic/03.4-defaults.sqllogic +554 -0
- package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
- package/test/logic/03.5-tvf.sqllogic +61 -0
- package/test/logic/03.6-type-system.sqllogic +544 -0
- package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
- package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
- package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
- package/test/logic/03.8-not-precedence.sqllogic +255 -0
- package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
- package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
- package/test/logic/04-order-by.sqllogic +38 -0
- package/test/logic/04-transactions.sqllogic +239 -0
- package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
- package/test/logic/05-vtab_memory.sqllogic +50 -0
- package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
- package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
- package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
- package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
- package/test/logic/06-builtin_functions.sqllogic +149 -0
- package/test/logic/06.1-string-functions.sqllogic +92 -0
- package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
- package/test/logic/06.2-math-functions.sqllogic +82 -0
- package/test/logic/06.3-schema.sqllogic +48 -0
- package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
- package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
- package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
- package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
- package/test/logic/06.3.4-view-info.sqllogic +378 -0
- package/test/logic/06.3.5-column-info.sqllogic +347 -0
- package/test/logic/06.3.6-schema-views.sqllogic +29 -0
- package/test/logic/06.4-schema-search-path.sqllogic +354 -0
- package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
- package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
- package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
- package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
- package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
- package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
- package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
- package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
- package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
- package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
- package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
- package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
- package/test/logic/06.7-json-extended.sqllogic +53 -0
- package/test/logic/06.8-json-path-operators.sqllogic +99 -0
- package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
- package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
- package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
- package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
- package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
- package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
- package/test/logic/07-aggregates.sqllogic +193 -0
- package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
- package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
- package/test/logic/07.3-group-by-extras.sqllogic +602 -0
- package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
- package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
- package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
- package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
- package/test/logic/07.5-window.sqllogic +1941 -0
- package/test/logic/07.5.1-window-named.sqllogic +13 -0
- package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
- package/test/logic/07.6-subqueries.sqllogic +78 -0
- package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
- package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
- package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
- package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
- package/test/logic/07.7.1-in-extras.sqllogic +158 -0
- package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
- package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
- package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
- package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
- package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
- package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
- package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
- package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
- package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
- package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
- package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
- package/test/logic/07.9-in-value-list.sqllogic +154 -0
- package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
- package/test/logic/08-views.sqllogic +64 -0
- package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
- package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
- package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
- package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
- package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
- package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
- package/test/logic/09-set_operations.sqllogic +244 -0
- package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
- package/test/logic/10-distinct_datatypes.sqllogic +127 -0
- package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
- package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
- package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
- package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
- package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
- package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
- package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
- package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
- package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
- package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
- package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
- package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
- package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
- package/test/logic/10.2-column-features.sqllogic +365 -0
- package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
- package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
- package/test/logic/10.3-function-features.sqllogic +247 -0
- package/test/logic/10.4-schema-scale.sqllogic +168 -0
- package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
- package/test/logic/10.5-indexes.sqllogic +164 -0
- package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
- package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
- package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
- package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
- package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
- package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
- package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
- package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
- package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
- package/test/logic/100.1-where-extras.sqllogic +163 -0
- package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
- package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
- package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
- package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
- package/test/logic/102-unique-constraints.sqllogic +145 -0
- package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
- package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
- package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
- package/test/logic/102.2-unique-collation.sqllogic +181 -0
- package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
- package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
- package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
- package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
- package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
- package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
- package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
- package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
- package/test/logic/108-cardinality-estimation.sqllogic +146 -0
- package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
- package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
- package/test/logic/11-joins.sqllogic +86 -0
- package/test/logic/11.1-join-using.sqllogic +267 -0
- package/test/logic/11.2-comma-join.sqllogic +35 -0
- package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
- package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
- package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
- package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
- package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
- package/test/logic/12-empty-primary-key.sqllogic +124 -0
- package/test/logic/12-join_padding_order.sqllogic +58 -0
- package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
- package/test/logic/13-cte.sqllogic +137 -0
- package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
- package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
- package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
- package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
- package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
- package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
- package/test/logic/13.4-cte-extras.sqllogic +98 -0
- package/test/logic/13.5-cte-join-order.sqllogic +166 -0
- package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
- package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
- package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
- package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
- package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
- package/test/logic/14-utilities.sqllogic +168 -0
- package/test/logic/15-timespan.sqllogic +279 -0
- package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
- package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
- package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
- package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
- package/test/logic/16-epoch.sqllogic +187 -0
- package/test/logic/17-weekday-modifier.sqllogic +78 -0
- package/test/logic/18-json-string-escapes.sqllogic +86 -0
- package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
- package/test/logic/20-empty-single-row.sqllogic +261 -0
- package/test/logic/21-null-edge-cases.sqllogic +227 -0
- package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
- package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
- package/test/logic/21.2-between-edges.sqllogic +157 -0
- package/test/logic/22-boundary-values.sqllogic +175 -0
- package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
- package/test/logic/24-builtin-branches.sqllogic +611 -0
- package/test/logic/24.1-substr-extras.sqllogic +75 -0
- package/test/logic/24.2-random-extras.sqllogic +39 -0
- package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
- package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
- package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
- package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
- package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
- package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
- package/test/logic/26-join-edge-cases.sqllogic +333 -0
- package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
- package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
- package/test/logic/26.3-join-on-constants.sqllogic +61 -0
- package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
- package/test/logic/27-window-edge-cases.sqllogic +206 -0
- package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
- package/test/logic/27.2-window-exclude.sqllogic +13 -0
- package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
- package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
- package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
- package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
- package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
- package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
- package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
- package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
- package/test/logic/40-constraints.sqllogic +418 -0
- package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
- package/test/logic/40.2-check-extras.sqllogic +683 -0
- package/test/logic/41-alter-table.sqllogic +191 -0
- package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
- package/test/logic/41-fk-cross-schema.sqllogic +155 -0
- package/test/logic/41-fk-extended-targets.sqllogic +173 -0
- package/test/logic/41-foreign-keys.sqllogic +1001 -0
- package/test/logic/41-generated-column-errors.sqllogic +225 -0
- package/test/logic/41-generated-column-extras.sqllogic +598 -0
- package/test/logic/41-generated-column-scope.sqllogic +329 -0
- package/test/logic/41-generated-columns.sqllogic +361 -0
- package/test/logic/41.1-alter-pk.sqllogic +230 -0
- package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
- package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
- package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
- package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
- package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
- package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
- package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
- package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
- package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
- package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
- package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
- package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
- package/test/logic/41.2-alter-column.sqllogic +382 -0
- package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
- package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
- package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
- package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
- package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
- package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
- package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
- package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
- package/test/logic/41.5-alter-misc.sqllogic +48 -0
- package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
- package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
- package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
- package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
- package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
- package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
- package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
- package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
- package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
- package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
- package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
- package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
- package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
- package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
- package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
- package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
- package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
- package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
- package/test/logic/42-committed-snapshot.sqllogic +254 -0
- package/test/logic/42-returning.sqllogic +159 -0
- package/test/logic/42.1-returning-extras.sqllogic +232 -0
- package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
- package/test/logic/43-default-nullability.sqllogic +131 -0
- package/test/logic/43-transition-constraints.sqllogic +341 -0
- package/test/logic/43.1-default-collation.sqllogic +140 -0
- package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
- package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
- package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
- package/test/logic/44-determinism-validation.sqllogic +164 -0
- package/test/logic/44-orthogonality.sqllogic +146 -0
- package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
- package/test/logic/45-udf-determinism.sqllogic +39 -0
- package/test/logic/46-mutation-context.sqllogic +595 -0
- package/test/logic/47-upsert.sqllogic +255 -0
- package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
- package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
- package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
- package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
- package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
- package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
- package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
- package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
- package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
- package/test/logic/49-reference-graph.sqllogic +84 -0
- package/test/logic/50-declarative-schema.sqllogic +2550 -0
- package/test/logic/50-metadata-tags.sqllogic +1033 -0
- package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
- package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
- package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
- package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
- package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
- package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
- package/test/logic/51-lens-foundation.sqllogic +147 -0
- package/test/logic/51-materialized-views.sqllogic +376 -0
- package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
- package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
- package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
- package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
- package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
- package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
- package/test/logic/52-lens-overrides.sqllogic +566 -0
- package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
- package/test/logic/53-reserved-tags.sqllogic +252 -0
- package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
- package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
- package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
- package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
- package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
- package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
- package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
- package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
- package/test/logic/55-lens-prover.sqllogic +202 -0
- package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
- package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
- package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
- package/test/logic/81-quickpick.sqllogic +24 -0
- package/test/logic/82-bloom-join.sqllogic +185 -0
- package/test/logic/83-merge-join.sqllogic +280 -0
- package/test/logic/84-asof-scan.sqllogic +238 -0
- package/test/logic/84-key-cardinality.sqllogic +50 -0
- package/test/logic/85-relational-const-folding.sqllogic +51 -0
- package/test/logic/86-scalar-cse.sqllogic +42 -0
- package/test/logic/90-error_paths.sqllogic +114 -0
- package/test/logic/90.1-parse-errors.sqllogic +77 -0
- package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
- package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
- package/test/logic/90.3-expression-errors.sqllogic +43 -0
- package/test/logic/90.4-dml-errors.sqllogic +47 -0
- package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
- package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
- package/test/logic/90.6-select-error-paths.sqllogic +57 -0
- package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
- package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
- package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
- package/test/logic/93.1-view-error-paths.sqllogic +74 -0
- package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
- package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
- package/test/logic/93.4-view-mutation.sqllogic +4881 -0
- package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
- package/test/logic/93.5-authored-inverse.sqllogic +415 -0
- package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
- package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
- package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
- package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
- package/test/logic/95-assertions.sqllogic +1417 -0
- package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
- package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
- package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
- package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
- package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
- package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
- package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
- package/test/logic/drop-unique-index.sqllogic +88 -0
- package/test/logic/pushdown-test.sqllogic +36 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
-- 13.9.1-schema-authored-schema-path-isolation.sqllogic - a table's own DDL resolves bare
|
|
2
|
+
-- relation names against the table's OWN schema, never the writer's search path
|
|
3
|
+
--
|
|
4
|
+
-- Sibling of 13.9-schema-authored-cte-isolation.sqllogic: same four schema-authored
|
|
5
|
+
-- expression kinds (a column DEFAULT, a generated-column expression, a CHECK constraint,
|
|
6
|
+
-- a synthesized foreign-key probe), the other leak channel. A DEFAULT used to be built on
|
|
7
|
+
-- a planning context still carrying the WRITING statement's schema search path (the
|
|
8
|
+
-- session `pragma schema_path`, or a per-statement `insert … with schema …`), while the
|
|
9
|
+
-- CHECK beside it narrowed to the table's own schema — so one table definition could
|
|
10
|
+
-- disagree with itself about what a bare `c` meant. `schemaAuthoredContext`
|
|
11
|
+
-- (planner/building/schema-authored-context.ts) now narrows the path in ONE place, to the
|
|
12
|
+
-- owning table's schema exactly, with no fallback to the session default path.
|
|
13
|
+
--
|
|
14
|
+
-- Every arm is written so the WRONG binding is observable: the DECOY relation lives in the
|
|
15
|
+
-- schema the writer is pointed at, the real one lives beside the table, the two disagree,
|
|
16
|
+
-- and the assertion pins the owning schema's answer.
|
|
17
|
+
|
|
18
|
+
pragma foreign_keys = true;
|
|
19
|
+
pragma schema_path = 'main';
|
|
20
|
+
|
|
21
|
+
-- The decoy `main.c` has 1 row; the real `temp.c` beside every table below has 3.
|
|
22
|
+
create table main.c (k integer primary key);
|
|
23
|
+
insert into main.c values (1);
|
|
24
|
+
create table temp.c (k integer primary key);
|
|
25
|
+
insert into temp.c values (1), (2), (3);
|
|
26
|
+
-- run
|
|
27
|
+
|
|
28
|
+
-- ===== Column DEFAULT (session schema path) =====
|
|
29
|
+
|
|
30
|
+
create table temp.sp_def (id integer primary key, w integer default (select count(*) from c));
|
|
31
|
+
-- run
|
|
32
|
+
|
|
33
|
+
insert into temp.sp_def (id) values (1);
|
|
34
|
+
|
|
35
|
+
-- 3 (temp.c, beside the table), not 1 (main.c, on the writer's path).
|
|
36
|
+
select id, w from temp.sp_def order by id;
|
|
37
|
+
→ [{"id":1,"w":3}]
|
|
38
|
+
|
|
39
|
+
-- ===== Generated column, all four write sites =====
|
|
40
|
+
-- One stored body, four statements that compile it (the INSERT row expansion, the
|
|
41
|
+
-- `on conflict do update` recompute, the UPDATE recompute, and the ADD COLUMN
|
|
42
|
+
-- backfill), one shared builder (`planner/building/generated-column-scope.ts`) that
|
|
43
|
+
-- wraps every one of them in `schemaAuthoredContext`. All four must read `temp.c`
|
|
44
|
+
-- (3 rows, beside the table), never the decoy `main.c` on the writer's path.
|
|
45
|
+
|
|
46
|
+
create table temp.sp_gen (id integer primary key, v integer, g integer generated always as ((select count(*) from c)));
|
|
47
|
+
-- run
|
|
48
|
+
|
|
49
|
+
insert into temp.sp_gen (id, v) values (1, 1);
|
|
50
|
+
|
|
51
|
+
select id, v, g from temp.sp_gen order by id;
|
|
52
|
+
→ [{"id":1,"v":1,"g":3}]
|
|
53
|
+
|
|
54
|
+
update temp.sp_gen set v = 2 where id = 1;
|
|
55
|
+
|
|
56
|
+
select id, v, g from temp.sp_gen order by id;
|
|
57
|
+
→ [{"id":1,"v":2,"g":3}]
|
|
58
|
+
|
|
59
|
+
insert into temp.sp_gen (id, v) values (1, 5) on conflict (id) do update set v = 5;
|
|
60
|
+
|
|
61
|
+
select id, v, g from temp.sp_gen order by id;
|
|
62
|
+
→ [{"id":1,"v":5,"g":3}]
|
|
63
|
+
|
|
64
|
+
-- the ADD COLUMN backfill, and a write through the ordinary path afterwards
|
|
65
|
+
create table temp.sp_gen_alter (id integer primary key, v integer);
|
|
66
|
+
insert into temp.sp_gen_alter values (1, 1);
|
|
67
|
+
-- run
|
|
68
|
+
|
|
69
|
+
alter table temp.sp_gen_alter add column g integer generated always as ((select count(*) from c));
|
|
70
|
+
-- run
|
|
71
|
+
|
|
72
|
+
insert into temp.sp_gen_alter (id, v) values (2, 2);
|
|
73
|
+
|
|
74
|
+
select id, v, g from temp.sp_gen_alter order by id;
|
|
75
|
+
→ [{"id":1,"v":1,"g":3},{"id":2,"v":2,"g":3}]
|
|
76
|
+
|
|
77
|
+
-- ===== UPDATE-path schema-authored build (`building/update.ts`) =====
|
|
78
|
+
-- `building/update.ts` narrows on its own context (`schemaAuthoredUpdateCtx`), shared by
|
|
79
|
+
-- the CHECK build and the NOT NULL defaults. (The generated-column recompute no longer
|
|
80
|
+
-- rides on that context — it narrows inside the shared generated-expression builder,
|
|
81
|
+
-- pinned by the arm above.)
|
|
82
|
+
|
|
83
|
+
create table temp.sp_cku (id integer primary key, v integer, check ((select count(*) from c) = 3));
|
|
84
|
+
insert into temp.sp_cku values (1, 1);
|
|
85
|
+
-- run
|
|
86
|
+
|
|
87
|
+
update temp.sp_cku set v = 2 where id = 1;
|
|
88
|
+
|
|
89
|
+
select id, v from temp.sp_cku order by id;
|
|
90
|
+
→ [{"id":1,"v":2}]
|
|
91
|
+
|
|
92
|
+
-- and the other direction on the UPDATE path: an update-only CHECK that only the decoy
|
|
93
|
+
-- satisfies must still reject
|
|
94
|
+
create table temp.sp_ckux (id integer primary key, v integer, check on update ((select count(*) from c) = 1));
|
|
95
|
+
insert into temp.sp_ckux values (1, 1);
|
|
96
|
+
-- run
|
|
97
|
+
|
|
98
|
+
update temp.sp_ckux set v = 2 where id = 1;
|
|
99
|
+
-- error: CHECK
|
|
100
|
+
|
|
101
|
+
select id, v from temp.sp_ckux order by id;
|
|
102
|
+
→ [{"id":1,"v":1}]
|
|
103
|
+
|
|
104
|
+
-- ===== NOT NULL column DEFAULT (REPLACE substitution) =====
|
|
105
|
+
-- `buildNotNullDefaults` pre-builds the DEFAULT evaluator the constraint runtime
|
|
106
|
+
-- substitutes when REPLACE meets an explicit NULL.
|
|
107
|
+
|
|
108
|
+
create table temp.sp_nnd (id integer primary key, w integer not null default (select count(*) from c));
|
|
109
|
+
-- run
|
|
110
|
+
|
|
111
|
+
insert or replace into temp.sp_nnd (id, w) values (1, null);
|
|
112
|
+
|
|
113
|
+
select id, w from temp.sp_nnd order by id;
|
|
114
|
+
→ [{"id":1,"w":3}]
|
|
115
|
+
|
|
116
|
+
-- ===== Per-statement WITH SCHEMA (distinct from the session pragma) =====
|
|
117
|
+
-- Session path is `temp` here, so only the statement's own `with schema main` points the
|
|
118
|
+
-- writer at the decoy. The default must still read temp.c.
|
|
119
|
+
|
|
120
|
+
pragma schema_path = 'temp';
|
|
121
|
+
|
|
122
|
+
create table temp.sp_ws (id integer primary key, w integer default (select count(*) from c));
|
|
123
|
+
-- run
|
|
124
|
+
|
|
125
|
+
insert into temp.sp_ws (id) values (1) with schema main;
|
|
126
|
+
|
|
127
|
+
select id, w from temp.sp_ws order by id;
|
|
128
|
+
→ [{"id":1,"w":3}]
|
|
129
|
+
|
|
130
|
+
pragma schema_path = 'main';
|
|
131
|
+
|
|
132
|
+
-- ===== Controls: CHECK and child-side FK were already correct, and must stay so =====
|
|
133
|
+
-- The narrowing used to be duplicated inside `buildConstraintChecks` and both foreign-key
|
|
134
|
+
-- builders; collapsing it into the shared helper must not change either one's answer.
|
|
135
|
+
|
|
136
|
+
-- (a) a CHECK that holds against temp.c (3 rows) and fails against main.c (1 row)
|
|
137
|
+
create table temp.sp_ck (id integer primary key, check ((select count(*) from c) = 3));
|
|
138
|
+
-- run
|
|
139
|
+
|
|
140
|
+
insert into temp.sp_ck values (1);
|
|
141
|
+
|
|
142
|
+
select id from temp.sp_ck order by id;
|
|
143
|
+
→ [{"id":1}]
|
|
144
|
+
|
|
145
|
+
-- (b) the other direction: a CHECK only the DECOY would satisfy must still reject
|
|
146
|
+
create table temp.sp_ckx (id integer primary key, check ((select count(*) from c) = 1));
|
|
147
|
+
-- run
|
|
148
|
+
|
|
149
|
+
insert into temp.sp_ckx values (1);
|
|
150
|
+
-- error: CHECK
|
|
151
|
+
|
|
152
|
+
select count(*) as n from temp.sp_ckx;
|
|
153
|
+
→ [{"n":0}]
|
|
154
|
+
|
|
155
|
+
-- (c) child-side FK probe on a table in the non-default schema. The parent exists only in
|
|
156
|
+
-- `temp` and holds the referenced row, so a broken probe shows up as a spurious
|
|
157
|
+
-- `CHECK constraint failed: _fk_…`.
|
|
158
|
+
create table temp.sp_fkp (id integer primary key);
|
|
159
|
+
insert into temp.sp_fkp values (1);
|
|
160
|
+
create table temp.sp_fkc (id integer primary key, pid integer references sp_fkp(id));
|
|
161
|
+
-- run
|
|
162
|
+
|
|
163
|
+
insert into temp.sp_fkc values (1, 1);
|
|
164
|
+
|
|
165
|
+
select id, pid from temp.sp_fkc order by id;
|
|
166
|
+
→ [{"id":1,"pid":1}]
|
|
167
|
+
|
|
168
|
+
-- ===== Write-through a view whose base table lives in the non-default schema =====
|
|
169
|
+
-- The base op is re-planned through `buildInsertStmt`, so it inherits the narrowing.
|
|
170
|
+
|
|
171
|
+
create table temp.sp_vt (id integer primary key, w integer default (select count(*) from c));
|
|
172
|
+
create view temp.sp_v as select id, w from sp_vt;
|
|
173
|
+
-- run
|
|
174
|
+
|
|
175
|
+
insert into temp.sp_v (id) values (1);
|
|
176
|
+
|
|
177
|
+
select id, w from temp.sp_vt order by id;
|
|
178
|
+
→ [{"id":1,"w":3}]
|
|
179
|
+
|
|
180
|
+
-- ===== Multi-source view INSERT: the anchor key column's declared DEFAULT =====
|
|
181
|
+
-- The shared surrogate is minted ONCE per produced row at the envelope, from the anchor
|
|
182
|
+
-- key column's own `default` — the one schema-authored expression the decomposition
|
|
183
|
+
-- lowering builds itself rather than delegating to `buildInsertStmt` (`buildKeyDefault`
|
|
184
|
+
-- in planner/building/view-mutation-builder.ts). Its owner is the ANCHOR BASE TABLE's
|
|
185
|
+
-- schema, which is why the analyses carry `keyDefaultSchemaName` alongside the
|
|
186
|
+
-- expression. `main.kd_core` is a decoy with a much higher water mark.
|
|
187
|
+
|
|
188
|
+
create table main.kd_core (rid integer primary key, name text);
|
|
189
|
+
insert into main.kd_core values (500, 'decoy');
|
|
190
|
+
create table temp.kd_core (rid integer primary key default (coalesce((select max(rid) from kd_core), 0) + mutation_ordinal()), name text);
|
|
191
|
+
create table temp.kd_contact (rid integer primary key, email text);
|
|
192
|
+
create view temp.kd_v as select c.name as name, k.email as email
|
|
193
|
+
from kd_core c join kd_contact k on k.rid = c.rid;
|
|
194
|
+
insert into temp.kd_core values (100, 'seed');
|
|
195
|
+
-- run
|
|
196
|
+
|
|
197
|
+
insert into temp.kd_v (name, email) values ('Ada', 'ada@x.io');
|
|
198
|
+
|
|
199
|
+
-- 101 (above temp.kd_core's real high-water mark 100), not 501 (above the main decoy).
|
|
200
|
+
select rid, name from temp.kd_core order by rid;
|
|
201
|
+
→ [{"rid":100,"name":"seed"},{"rid":101,"name":"Ada"}]
|
|
202
|
+
|
|
203
|
+
select rid, email from temp.kd_contact order by rid;
|
|
204
|
+
→ [{"rid":101,"email":"ada@x.io"}]
|
|
205
|
+
|
|
206
|
+
select rid, name from main.kd_core order by rid;
|
|
207
|
+
→ [{"rid":500,"name":"decoy"}]
|
|
208
|
+
|
|
209
|
+
-- And the owner is the ANCHOR BASE TABLE's schema, not the VIEW's — they can differ.
|
|
210
|
+
-- Here the view lives in `main` (with the session path) while the anchor lives in `temp`,
|
|
211
|
+
-- and the anchor's default reads a bare `ks_seq` that exists in both. Reading it as the
|
|
212
|
+
-- view's schema would take main.ks_seq's mark (500) instead of temp.ks_seq's (100).
|
|
213
|
+
|
|
214
|
+
create table temp.ks_seq (n integer primary key);
|
|
215
|
+
insert into temp.ks_seq values (100);
|
|
216
|
+
create table main.ks_seq (n integer primary key);
|
|
217
|
+
insert into main.ks_seq values (500);
|
|
218
|
+
create table temp.ks_core (rid integer primary key default (coalesce((select max(n) from ks_seq), 0) + mutation_ordinal()), name text);
|
|
219
|
+
create table temp.ks_contact (rid integer primary key, email text);
|
|
220
|
+
create view main.ks_v as select c.name as name, k.email as email
|
|
221
|
+
from temp.ks_core c join temp.ks_contact k on k.rid = c.rid;
|
|
222
|
+
-- run
|
|
223
|
+
|
|
224
|
+
insert into main.ks_v (name, email) values ('Bea', 'bea@x.io');
|
|
225
|
+
|
|
226
|
+
select rid, name from temp.ks_core order by rid;
|
|
227
|
+
→ [{"rid":101,"name":"Bea"}]
|
|
228
|
+
|
|
229
|
+
-- ===== Control: a QUALIFIED reference inside a default is unaffected =====
|
|
230
|
+
|
|
231
|
+
create table temp.sp_q (id integer primary key, w integer default (select count(*) from main.c));
|
|
232
|
+
-- run
|
|
233
|
+
|
|
234
|
+
insert into temp.sp_q (id) values (1);
|
|
235
|
+
|
|
236
|
+
select id, w from temp.sp_q order by id;
|
|
237
|
+
→ [{"id":1,"w":1}]
|
|
238
|
+
|
|
239
|
+
-- ===== The rule is strict: no fallback to the session default path =====
|
|
240
|
+
-- A schema-authored expression naming a relation that lives ONLY in another schema, and
|
|
241
|
+
-- not qualifying it, does not resolve — the same rule CHECK and FK bodies have always
|
|
242
|
+
-- had. (docs/schema.md § Stored bodies resolve against their home schema.)
|
|
243
|
+
|
|
244
|
+
create table main.sp_only (k integer primary key);
|
|
245
|
+
insert into main.sp_only values (1);
|
|
246
|
+
create table temp.sp_cross (id integer primary key, w integer default (select count(*) from sp_only));
|
|
247
|
+
-- run
|
|
248
|
+
|
|
249
|
+
insert into temp.sp_cross (id) values (1);
|
|
250
|
+
-- error: sp_only
|
|
251
|
+
|
|
252
|
+
select count(*) as n from temp.sp_cross;
|
|
253
|
+
→ [{"n":0}]
|
|
254
|
+
|
|
255
|
+
-- ===== ALTER TABLE ADD COLUMN's CHECK, validated over the existing rows =====
|
|
256
|
+
-- The new column's CHECK is enforced against rows already in the table by a scan
|
|
257
|
+
-- re-prepared from the constraint's own SQL text (`validateBackfillAgainstChecks` in
|
|
258
|
+
-- runtime/emit/alter-table.ts). A freshly-prepared statement carries the SESSION path,
|
|
259
|
+
-- so that scan needs the owning schema pinned on it explicitly — the planning-context
|
|
260
|
+
-- helper never sees it. Both directions, since one alone cannot tell a narrowed path
|
|
261
|
+
-- from a scan that silently did nothing.
|
|
262
|
+
--
|
|
263
|
+
-- The per-row backfill / CHECK path below covers the same rule for a non-foldable
|
|
264
|
+
-- (subquery) DEFAULT and the CHECK predicates that ride alongside it — untestable until
|
|
265
|
+
-- bug-alter-add-column-relation-default-fails-to-emit, since before that fix a subquery
|
|
266
|
+
-- inside either reached the runtime unphysicalized and the whole ALTER errored outright.
|
|
267
|
+
|
|
268
|
+
create table temp.sp_ac (id integer primary key);
|
|
269
|
+
insert into temp.sp_ac values (1);
|
|
270
|
+
create table temp.sp_acx (id integer primary key);
|
|
271
|
+
insert into temp.sp_acx values (1);
|
|
272
|
+
-- run
|
|
273
|
+
|
|
274
|
+
-- true only against the main.c decoy (1 row) ⇒ must be REJECTED
|
|
275
|
+
alter table temp.sp_acx add column x integer default 0 check ((select count(*) from c) = 1);
|
|
276
|
+
-- error: CHECK
|
|
277
|
+
|
|
278
|
+
-- true against temp.c (3 rows), beside the table ⇒ must be ACCEPTED
|
|
279
|
+
alter table temp.sp_ac add column x integer default 0 check ((select count(*) from c) = 3);
|
|
280
|
+
-- run
|
|
281
|
+
|
|
282
|
+
select id, x from temp.sp_ac order by id;
|
|
283
|
+
→ [{"id":1,"x":0}]
|
|
284
|
+
|
|
285
|
+
-- ===== ALTER TABLE ADD COLUMN's per-row backfill / CHECK, same rule =====
|
|
286
|
+
|
|
287
|
+
create table temp.sp_acbf (id integer primary key);
|
|
288
|
+
insert into temp.sp_acbf values (1);
|
|
289
|
+
-- run
|
|
290
|
+
|
|
291
|
+
-- A non-foldable (subquery) DEFAULT compiles to a per-row backfill node — 3 (temp.c,
|
|
292
|
+
-- beside the table), not 1 (main.c, on the writer's path).
|
|
293
|
+
alter table temp.sp_acbf add column n integer default (select count(*) from c);
|
|
294
|
+
-- run
|
|
295
|
+
|
|
296
|
+
select id, n from temp.sp_acbf order by id;
|
|
297
|
+
→ [{"id":1,"n":3}]
|
|
298
|
+
|
|
299
|
+
-- A per-row DEFAULT (`new.id`) with an inline CHECK reading `c` — true against temp.c
|
|
300
|
+
-- (3 rows), beside the table ⇒ accepted.
|
|
301
|
+
alter table temp.sp_acbf add column m integer default (new.id) check ((select count(*) from c) = 3);
|
|
302
|
+
-- run
|
|
303
|
+
|
|
304
|
+
select id, m from temp.sp_acbf order by id;
|
|
305
|
+
→ [{"id":1,"m":1}]
|
|
306
|
+
|
|
307
|
+
-- Same shape, but the CHECK is only true against the main.c decoy (1 row) ⇒ rejected —
|
|
308
|
+
-- distinguishes a narrowed path from a CHECK that silently did nothing.
|
|
309
|
+
alter table temp.sp_acbf add column mm integer default (new.id) check ((select count(*) from c) = 1);
|
|
310
|
+
-- error: CHECK
|
|
311
|
+
|
|
312
|
+
select * from temp.sp_acbf order by id;
|
|
313
|
+
→ [{"id":1,"n":3,"m":1}]
|
|
314
|
+
|
|
315
|
+
-- ===== A maintained table's declared CHECK, both when it is created and when it derives =====
|
|
316
|
+
-- `create table … maintained as` reaches the same CHECK bodies by two routes that neither
|
|
317
|
+
-- INSERT nor UPDATE uses: the create-time scan over the already-derived rows
|
|
318
|
+
-- (`validateChecksOverExistingRows`, schema/constraint-builder.ts — again a re-prepared
|
|
319
|
+
-- statement, so the path is pinned on the statement) and the per-derived-row validator
|
|
320
|
+
-- (`core/derived-row-validator.ts`, which builds on its OWN fresh planning context — the
|
|
321
|
+
-- one call site that would have lost the narrowing when the constraint and foreign-key
|
|
322
|
+
-- builders stopped narrowing internally).
|
|
323
|
+
|
|
324
|
+
create table temp.mt_src (id integer primary key, n integer);
|
|
325
|
+
insert into temp.mt_src values (1, 2);
|
|
326
|
+
-- run
|
|
327
|
+
|
|
328
|
+
-- Created while `temp.mt_src` already holds n = 2: passes against temp.c (2 <= 3),
|
|
329
|
+
-- would fail against the main.c decoy (2 <= 1).
|
|
330
|
+
create table temp.mt (id integer primary key, n integer not null check (n <= (select count(*) from c)))
|
|
331
|
+
maintained as select id, n from mt_src;
|
|
332
|
+
-- run
|
|
333
|
+
|
|
334
|
+
select id, n from temp.mt order by id;
|
|
335
|
+
→ [{"id":1,"n":2}]
|
|
336
|
+
|
|
337
|
+
-- and a row derived AFTER creation goes through the derived-row validator instead
|
|
338
|
+
insert into temp.mt_src values (2, 3);
|
|
339
|
+
|
|
340
|
+
select id, n from temp.mt order by id;
|
|
341
|
+
→ [{"id":1,"n":2},{"id":2,"n":3}]
|
|
342
|
+
|
|
343
|
+
-- the same validator must still REJECT: 9 > 3, against temp.c
|
|
344
|
+
insert into temp.mt_src values (3, 9);
|
|
345
|
+
-- error: CHECK
|
|
346
|
+
|
|
347
|
+
-- ===== A user-declared schema behaves identically (not a `temp`-only special case) =====
|
|
348
|
+
|
|
349
|
+
declare schema spapp {
|
|
350
|
+
table c {
|
|
351
|
+
k INTEGER PRIMARY KEY
|
|
352
|
+
}
|
|
353
|
+
table t {
|
|
354
|
+
id INTEGER PRIMARY KEY,
|
|
355
|
+
w INTEGER DEFAULT (select count(*) from c)
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
apply schema spapp;
|
|
360
|
+
-- run
|
|
361
|
+
|
|
362
|
+
insert into spapp.c values (1), (2), (3), (4), (5);
|
|
363
|
+
|
|
364
|
+
insert into spapp.t (id) values (1);
|
|
365
|
+
|
|
366
|
+
-- 5 (spapp.c), not 1 (main.c, the session path).
|
|
367
|
+
select id, w from spapp.t order by id;
|
|
368
|
+
→ [{"id":1,"w":5}]
|
|
369
|
+
|
|
370
|
+
-- Cleanup
|
|
371
|
+
drop table spapp.t;
|
|
372
|
+
drop table spapp.c;
|
|
373
|
+
drop table temp.mt;
|
|
374
|
+
drop table temp.mt_src;
|
|
375
|
+
drop table temp.sp_acx;
|
|
376
|
+
drop table temp.sp_ac;
|
|
377
|
+
drop table temp.sp_cross;
|
|
378
|
+
drop table main.sp_only;
|
|
379
|
+
drop table temp.sp_q;
|
|
380
|
+
drop view main.ks_v;
|
|
381
|
+
drop table temp.ks_contact;
|
|
382
|
+
drop table temp.ks_core;
|
|
383
|
+
drop table main.ks_seq;
|
|
384
|
+
drop table temp.ks_seq;
|
|
385
|
+
drop view temp.kd_v;
|
|
386
|
+
drop table temp.kd_contact;
|
|
387
|
+
drop table temp.kd_core;
|
|
388
|
+
drop table main.kd_core;
|
|
389
|
+
drop view temp.sp_v;
|
|
390
|
+
drop table temp.sp_vt;
|
|
391
|
+
drop table temp.sp_fkc;
|
|
392
|
+
drop table temp.sp_fkp;
|
|
393
|
+
drop table temp.sp_ckx;
|
|
394
|
+
drop table temp.sp_ck;
|
|
395
|
+
drop table temp.sp_ckux;
|
|
396
|
+
drop table temp.sp_cku;
|
|
397
|
+
drop table temp.sp_ws;
|
|
398
|
+
drop table temp.sp_nnd;
|
|
399
|
+
drop table temp.sp_gen;
|
|
400
|
+
drop table temp.sp_gen_alter;
|
|
401
|
+
drop table temp.sp_def;
|
|
402
|
+
-- sp_acbf's added CHECK reads `c` through a subquery (resolving, from temp, to temp.c),
|
|
403
|
+
-- so it has to go before it: dropping a table a stored expression still names is refused
|
|
404
|
+
-- (41.10.4-drop-object-expression-dependents).
|
|
405
|
+
drop table temp.sp_acbf;
|
|
406
|
+
drop table temp.c;
|
|
407
|
+
drop table main.c;
|
|
408
|
+
-- run
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
-- utilities.sqllogic - Edge cases for NULL handling, coercion, collation, truthiness, and aggregates
|
|
2
|
+
|
|
3
|
+
-- === NULL comparison semantics ===
|
|
4
|
+
|
|
5
|
+
select null = null;
|
|
6
|
+
→ [{"null = null":null}]
|
|
7
|
+
|
|
8
|
+
select null < 1;
|
|
9
|
+
→ [{"null < 1":null}]
|
|
10
|
+
|
|
11
|
+
select null > 1;
|
|
12
|
+
→ [{"null > 1":null}]
|
|
13
|
+
|
|
14
|
+
select null != null;
|
|
15
|
+
→ [{"null != null":null}]
|
|
16
|
+
|
|
17
|
+
select null >= 0;
|
|
18
|
+
→ [{"null >= 0":null}]
|
|
19
|
+
|
|
20
|
+
-- === NULL sorting (total ordering: NULL first in ASC by default) ===
|
|
21
|
+
|
|
22
|
+
CREATE TABLE null_sort_t (id INTEGER PRIMARY KEY, v INTEGER NULL);
|
|
23
|
+
INSERT INTO null_sort_t VALUES (1, null), (2, 3), (3, 1), (4, null), (5, 2);
|
|
24
|
+
|
|
25
|
+
select v from null_sort_t order by v;
|
|
26
|
+
→ [{"v":null},{"v":null},{"v":1},{"v":2},{"v":3}]
|
|
27
|
+
|
|
28
|
+
select v from null_sort_t order by v desc;
|
|
29
|
+
→ [{"v":null},{"v":null},{"v":3},{"v":2},{"v":1}]
|
|
30
|
+
|
|
31
|
+
-- NULLS LAST moves nulls to end in ASC
|
|
32
|
+
select v from null_sort_t order by v nulls last;
|
|
33
|
+
→ [{"v":1},{"v":2},{"v":3},{"v":null},{"v":null}]
|
|
34
|
+
|
|
35
|
+
-- NULLS FIRST in DESC keeps nulls at the start
|
|
36
|
+
select v from null_sort_t order by v desc nulls first;
|
|
37
|
+
→ [{"v":null},{"v":null},{"v":3},{"v":2},{"v":1}]
|
|
38
|
+
|
|
39
|
+
-- NULLS LAST in DESC moves nulls to the end
|
|
40
|
+
select v from null_sort_t order by v desc nulls last;
|
|
41
|
+
→ [{"v":3},{"v":2},{"v":1},{"v":null},{"v":null}]
|
|
42
|
+
|
|
43
|
+
DROP TABLE null_sort_t;
|
|
44
|
+
|
|
45
|
+
-- === Storage class ordering ===
|
|
46
|
+
-- Type ordering: NULL < NUMERIC < TEXT < BLOB
|
|
47
|
+
|
|
48
|
+
CREATE TABLE mixed_t (id INTEGER PRIMARY KEY, v ANY NULL);
|
|
49
|
+
INSERT INTO mixed_t VALUES (1, null), (2, 42), (3, 'hello'), (4, 3.14), (5, x'FF');
|
|
50
|
+
|
|
51
|
+
-- Verify cross-type ordering via typeof
|
|
52
|
+
select typeof(v) from mixed_t order by v;
|
|
53
|
+
→ [{"typeof(v)":"null"},{"typeof(v)":"real"},{"typeof(v)":"integer"},{"typeof(v)":"text"},{"typeof(v)":"blob"}]
|
|
54
|
+
|
|
55
|
+
DROP TABLE mixed_t;
|
|
56
|
+
|
|
57
|
+
-- === Collation tests ===
|
|
58
|
+
|
|
59
|
+
-- Default (BINARY) collation: case-sensitive
|
|
60
|
+
select 'ABC' = 'abc';
|
|
61
|
+
→ [{"'ABC' = 'abc'":false}]
|
|
62
|
+
|
|
63
|
+
-- NOCASE collation on column definition
|
|
64
|
+
CREATE TABLE nocase_t (id INTEGER PRIMARY KEY, name TEXT COLLATE NOCASE);
|
|
65
|
+
INSERT INTO nocase_t VALUES (1, 'Alice'), (2, 'alice'), (3, 'BOB'), (4, 'bob');
|
|
66
|
+
|
|
67
|
+
-- Case-insensitive ordering (secondary sort by id for stability)
|
|
68
|
+
select name from nocase_t order by name, id;
|
|
69
|
+
→ [{"name":"Alice"},{"name":"alice"},{"name":"BOB"},{"name":"bob"}]
|
|
70
|
+
|
|
71
|
+
-- Case-insensitive equality
|
|
72
|
+
select id from nocase_t where name = 'alice' order by id;
|
|
73
|
+
→ [{"id":1},{"id":2}]
|
|
74
|
+
|
|
75
|
+
DROP TABLE nocase_t;
|
|
76
|
+
|
|
77
|
+
-- RTRIM collation on column definition
|
|
78
|
+
CREATE TABLE rtrim_t (id INTEGER PRIMARY KEY, name TEXT COLLATE RTRIM);
|
|
79
|
+
INSERT INTO rtrim_t VALUES (1, 'hello'), (2, 'hello '), (3, 'world'), (4, 'world ');
|
|
80
|
+
|
|
81
|
+
-- RTRIM equality: 'hello' and 'hello ' are equal
|
|
82
|
+
select id from rtrim_t where name = 'hello' order by id;
|
|
83
|
+
→ [{"id":1},{"id":2}]
|
|
84
|
+
|
|
85
|
+
select id from rtrim_t where name = 'world' order by id;
|
|
86
|
+
→ [{"id":3},{"id":4}]
|
|
87
|
+
|
|
88
|
+
DROP TABLE rtrim_t;
|
|
89
|
+
|
|
90
|
+
-- === Coercion edge cases ===
|
|
91
|
+
|
|
92
|
+
-- Numeric string coercion in comparisons
|
|
93
|
+
select 42 = '42';
|
|
94
|
+
→ [{"42 = '42'":true}]
|
|
95
|
+
|
|
96
|
+
select 42 < '43';
|
|
97
|
+
→ [{"42 < '43'":true}]
|
|
98
|
+
|
|
99
|
+
-- Non-numeric string stays as text (cross-type comparison: number != text)
|
|
100
|
+
select 42 = 'hello';
|
|
101
|
+
→ [{"42 = 'hello'":false}]
|
|
102
|
+
|
|
103
|
+
-- Scientific notation coercion
|
|
104
|
+
select 1000 = '1e3';
|
|
105
|
+
→ [{"1000 = '1e3'":true}]
|
|
106
|
+
|
|
107
|
+
-- Arithmetic with mixed types
|
|
108
|
+
select 1 + '2';
|
|
109
|
+
→ [{"1 + '2'":3}]
|
|
110
|
+
|
|
111
|
+
-- Non-numeric string coerces to 0 in arithmetic
|
|
112
|
+
select 1 + 'hello';
|
|
113
|
+
→ [{"1 + 'hello'":1}]
|
|
114
|
+
|
|
115
|
+
select 'abc' + 0;
|
|
116
|
+
→ [{"'abc' + 0":0}]
|
|
117
|
+
|
|
118
|
+
select '' + 0;
|
|
119
|
+
→ [{"'' + 0":0}]
|
|
120
|
+
|
|
121
|
+
-- === Truthiness (isTruthy) edge cases ===
|
|
122
|
+
|
|
123
|
+
CREATE TABLE bool_t (id INTEGER PRIMARY KEY, v ANY NULL);
|
|
124
|
+
INSERT INTO bool_t VALUES (1, 0), (2, 1), (3, ''), (4, 'text'), (5, null);
|
|
125
|
+
|
|
126
|
+
-- WHERE uses numeric truthiness: strings are coerced to numbers; non-numeric strings are falsy
|
|
127
|
+
select id from bool_t where v;
|
|
128
|
+
→ [{"id":2}]
|
|
129
|
+
|
|
130
|
+
DROP TABLE bool_t;
|
|
131
|
+
|
|
132
|
+
-- CASE WHEN uses isTruthy
|
|
133
|
+
select case when 0 then 'yes' else 'no' end as r;
|
|
134
|
+
→ [{"r":"no"}]
|
|
135
|
+
|
|
136
|
+
select case when 1 then 'yes' else 'no' end as r;
|
|
137
|
+
→ [{"r":"yes"}]
|
|
138
|
+
|
|
139
|
+
select case when '' then 'yes' else 'no' end as r;
|
|
140
|
+
→ [{"r":"no"}]
|
|
141
|
+
|
|
142
|
+
select case when 'nonempty' then 'yes' else 'no' end as r;
|
|
143
|
+
→ [{"r":"no"}]
|
|
144
|
+
|
|
145
|
+
select case when null then 'yes' else 'no' end as r;
|
|
146
|
+
→ [{"r":"no"}]
|
|
147
|
+
|
|
148
|
+
-- === Aggregate coercion ===
|
|
149
|
+
|
|
150
|
+
-- SUM with numeric strings (coerced to numbers)
|
|
151
|
+
CREATE TABLE agg_t (id INTEGER PRIMARY KEY, amount TEXT);
|
|
152
|
+
INSERT INTO agg_t VALUES (1, '10'), (2, '20'), (3, '30');
|
|
153
|
+
|
|
154
|
+
select sum(amount) from agg_t;
|
|
155
|
+
→ [{"sum(amount)":60}]
|
|
156
|
+
|
|
157
|
+
-- MIN/MAX with mixed coerced values
|
|
158
|
+
-- Numeric strings are coerced to numbers; non-numeric stay as text
|
|
159
|
+
-- Storage class ordering: NUMERIC < TEXT, so min = smallest number, max = largest text
|
|
160
|
+
INSERT INTO agg_t VALUES (4, 'z'), (5, 'a');
|
|
161
|
+
|
|
162
|
+
select min(amount) from agg_t;
|
|
163
|
+
→ [{"min(amount)":10}]
|
|
164
|
+
|
|
165
|
+
select max(amount) from agg_t;
|
|
166
|
+
→ [{"max(amount)":"z"}]
|
|
167
|
+
|
|
168
|
+
DROP TABLE agg_t;
|