@quereus/quereus 4.20.1 → 4.20.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +17 -69
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/package.json +7 -4
- package/test/README.md +173 -0
- package/test/logic/01-basic.sqllogic +39 -0
- package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
- package/test/logic/01.2-strings.sqllogic +43 -0
- package/test/logic/01.5-insert-select.sqllogic +237 -0
- package/test/logic/01.6-update-extras.sqllogic +118 -0
- package/test/logic/01.7-update-from.sqllogic +67 -0
- package/test/logic/01.8-delete-extras.sqllogic +122 -0
- package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
- package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
- package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
- package/test/logic/01.9-query-expr-values.sqllogic +111 -0
- package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
- package/test/logic/02-filters.sqllogic +54 -0
- package/test/logic/02-smoke.sqllogic +62 -0
- package/test/logic/02.1-bind-parameters.sqllogic +223 -0
- package/test/logic/03-expressions.sqllogic +190 -0
- package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
- package/test/logic/03.4-defaults.sqllogic +554 -0
- package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
- package/test/logic/03.5-tvf.sqllogic +61 -0
- package/test/logic/03.6-type-system.sqllogic +544 -0
- package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
- package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
- package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
- package/test/logic/03.8-not-precedence.sqllogic +255 -0
- package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
- package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
- package/test/logic/04-order-by.sqllogic +38 -0
- package/test/logic/04-transactions.sqllogic +239 -0
- package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
- package/test/logic/05-vtab_memory.sqllogic +50 -0
- package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
- package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
- package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
- package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
- package/test/logic/06-builtin_functions.sqllogic +149 -0
- package/test/logic/06.1-string-functions.sqllogic +92 -0
- package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
- package/test/logic/06.2-math-functions.sqllogic +82 -0
- package/test/logic/06.3-schema.sqllogic +48 -0
- package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
- package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
- package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
- package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
- package/test/logic/06.3.4-view-info.sqllogic +378 -0
- package/test/logic/06.3.5-column-info.sqllogic +347 -0
- package/test/logic/06.3.6-schema-views.sqllogic +29 -0
- package/test/logic/06.4-schema-search-path.sqllogic +354 -0
- package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
- package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
- package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
- package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
- package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
- package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
- package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
- package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
- package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
- package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
- package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
- package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
- package/test/logic/06.7-json-extended.sqllogic +53 -0
- package/test/logic/06.8-json-path-operators.sqllogic +99 -0
- package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
- package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
- package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
- package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
- package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
- package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
- package/test/logic/07-aggregates.sqllogic +193 -0
- package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
- package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
- package/test/logic/07.3-group-by-extras.sqllogic +602 -0
- package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
- package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
- package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
- package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
- package/test/logic/07.5-window.sqllogic +1941 -0
- package/test/logic/07.5.1-window-named.sqllogic +13 -0
- package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
- package/test/logic/07.6-subqueries.sqllogic +78 -0
- package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
- package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
- package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
- package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
- package/test/logic/07.7.1-in-extras.sqllogic +158 -0
- package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
- package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
- package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
- package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
- package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
- package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
- package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
- package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
- package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
- package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
- package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
- package/test/logic/07.9-in-value-list.sqllogic +154 -0
- package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
- package/test/logic/08-views.sqllogic +64 -0
- package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
- package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
- package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
- package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
- package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
- package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
- package/test/logic/09-set_operations.sqllogic +244 -0
- package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
- package/test/logic/10-distinct_datatypes.sqllogic +127 -0
- package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
- package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
- package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
- package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
- package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
- package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
- package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
- package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
- package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
- package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
- package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
- package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
- package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
- package/test/logic/10.2-column-features.sqllogic +365 -0
- package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
- package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
- package/test/logic/10.3-function-features.sqllogic +247 -0
- package/test/logic/10.4-schema-scale.sqllogic +168 -0
- package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
- package/test/logic/10.5-indexes.sqllogic +164 -0
- package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
- package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
- package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
- package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
- package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
- package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
- package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
- package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
- package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
- package/test/logic/100.1-where-extras.sqllogic +163 -0
- package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
- package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
- package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
- package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
- package/test/logic/102-unique-constraints.sqllogic +145 -0
- package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
- package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
- package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
- package/test/logic/102.2-unique-collation.sqllogic +181 -0
- package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
- package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
- package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
- package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
- package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
- package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
- package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
- package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
- package/test/logic/108-cardinality-estimation.sqllogic +146 -0
- package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
- package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
- package/test/logic/11-joins.sqllogic +86 -0
- package/test/logic/11.1-join-using.sqllogic +267 -0
- package/test/logic/11.2-comma-join.sqllogic +35 -0
- package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
- package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
- package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
- package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
- package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
- package/test/logic/12-empty-primary-key.sqllogic +124 -0
- package/test/logic/12-join_padding_order.sqllogic +58 -0
- package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
- package/test/logic/13-cte.sqllogic +137 -0
- package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
- package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
- package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
- package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
- package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
- package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
- package/test/logic/13.4-cte-extras.sqllogic +98 -0
- package/test/logic/13.5-cte-join-order.sqllogic +166 -0
- package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
- package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
- package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
- package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
- package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
- package/test/logic/14-utilities.sqllogic +168 -0
- package/test/logic/15-timespan.sqllogic +279 -0
- package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
- package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
- package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
- package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
- package/test/logic/16-epoch.sqllogic +187 -0
- package/test/logic/17-weekday-modifier.sqllogic +78 -0
- package/test/logic/18-json-string-escapes.sqllogic +86 -0
- package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
- package/test/logic/20-empty-single-row.sqllogic +261 -0
- package/test/logic/21-null-edge-cases.sqllogic +227 -0
- package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
- package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
- package/test/logic/21.2-between-edges.sqllogic +157 -0
- package/test/logic/22-boundary-values.sqllogic +175 -0
- package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
- package/test/logic/24-builtin-branches.sqllogic +611 -0
- package/test/logic/24.1-substr-extras.sqllogic +75 -0
- package/test/logic/24.2-random-extras.sqllogic +39 -0
- package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
- package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
- package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
- package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
- package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
- package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
- package/test/logic/26-join-edge-cases.sqllogic +333 -0
- package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
- package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
- package/test/logic/26.3-join-on-constants.sqllogic +61 -0
- package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
- package/test/logic/27-window-edge-cases.sqllogic +206 -0
- package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
- package/test/logic/27.2-window-exclude.sqllogic +13 -0
- package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
- package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
- package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
- package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
- package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
- package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
- package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
- package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
- package/test/logic/40-constraints.sqllogic +418 -0
- package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
- package/test/logic/40.2-check-extras.sqllogic +683 -0
- package/test/logic/41-alter-table.sqllogic +191 -0
- package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
- package/test/logic/41-fk-cross-schema.sqllogic +155 -0
- package/test/logic/41-fk-extended-targets.sqllogic +173 -0
- package/test/logic/41-foreign-keys.sqllogic +1001 -0
- package/test/logic/41-generated-column-errors.sqllogic +225 -0
- package/test/logic/41-generated-column-extras.sqllogic +598 -0
- package/test/logic/41-generated-column-scope.sqllogic +329 -0
- package/test/logic/41-generated-columns.sqllogic +361 -0
- package/test/logic/41.1-alter-pk.sqllogic +230 -0
- package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
- package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
- package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
- package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
- package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
- package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
- package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
- package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
- package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
- package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
- package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
- package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
- package/test/logic/41.2-alter-column.sqllogic +382 -0
- package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
- package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
- package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
- package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
- package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
- package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
- package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
- package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
- package/test/logic/41.5-alter-misc.sqllogic +48 -0
- package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
- package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
- package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
- package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
- package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
- package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
- package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
- package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
- package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
- package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
- package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
- package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
- package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
- package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
- package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
- package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
- package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
- package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
- package/test/logic/42-committed-snapshot.sqllogic +254 -0
- package/test/logic/42-returning.sqllogic +159 -0
- package/test/logic/42.1-returning-extras.sqllogic +232 -0
- package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
- package/test/logic/43-default-nullability.sqllogic +131 -0
- package/test/logic/43-transition-constraints.sqllogic +341 -0
- package/test/logic/43.1-default-collation.sqllogic +140 -0
- package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
- package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
- package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
- package/test/logic/44-determinism-validation.sqllogic +164 -0
- package/test/logic/44-orthogonality.sqllogic +146 -0
- package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
- package/test/logic/45-udf-determinism.sqllogic +39 -0
- package/test/logic/46-mutation-context.sqllogic +595 -0
- package/test/logic/47-upsert.sqllogic +255 -0
- package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
- package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
- package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
- package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
- package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
- package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
- package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
- package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
- package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
- package/test/logic/49-reference-graph.sqllogic +84 -0
- package/test/logic/50-declarative-schema.sqllogic +2550 -0
- package/test/logic/50-metadata-tags.sqllogic +1033 -0
- package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
- package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
- package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
- package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +210 -0
- package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
- package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
- package/test/logic/51-lens-foundation.sqllogic +147 -0
- package/test/logic/51-materialized-views.sqllogic +376 -0
- package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
- package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
- package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
- package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
- package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
- package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
- package/test/logic/52-lens-overrides.sqllogic +566 -0
- package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
- package/test/logic/53-reserved-tags.sqllogic +252 -0
- package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
- package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
- package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
- package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
- package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
- package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
- package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
- package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
- package/test/logic/55-lens-prover.sqllogic +202 -0
- package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
- package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
- package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
- package/test/logic/81-quickpick.sqllogic +24 -0
- package/test/logic/82-bloom-join.sqllogic +185 -0
- package/test/logic/83-merge-join.sqllogic +280 -0
- package/test/logic/84-asof-scan.sqllogic +238 -0
- package/test/logic/84-key-cardinality.sqllogic +50 -0
- package/test/logic/85-relational-const-folding.sqllogic +51 -0
- package/test/logic/86-scalar-cse.sqllogic +42 -0
- package/test/logic/90-error_paths.sqllogic +114 -0
- package/test/logic/90.1-parse-errors.sqllogic +77 -0
- package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
- package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
- package/test/logic/90.3-expression-errors.sqllogic +43 -0
- package/test/logic/90.4-dml-errors.sqllogic +47 -0
- package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
- package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
- package/test/logic/90.6-select-error-paths.sqllogic +57 -0
- package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
- package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
- package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
- package/test/logic/93.1-view-error-paths.sqllogic +74 -0
- package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
- package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
- package/test/logic/93.4-view-mutation.sqllogic +4881 -0
- package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
- package/test/logic/93.5-authored-inverse.sqllogic +415 -0
- package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
- package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
- package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
- package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
- package/test/logic/95-assertions.sqllogic +1417 -0
- package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
- package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
- package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
- package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
- package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
- package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
- package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
- package/test/logic/drop-unique-index.sqllogic +88 -0
- package/test/logic/pushdown-test.sqllogic +36 -0
|
@@ -0,0 +1,855 @@
|
|
|
1
|
+
-- adapted from SQLite test/alter3.test, test/alter4.test, test/alter.test
|
|
2
|
+
-- ADD COLUMN with various constraints. Existing 41-alter-table covers
|
|
3
|
+
-- NULL backfill, text DEFAULT, NOT NULL+DEFAULT — this fills in CHECK,
|
|
4
|
+
-- REFERENCES, COLLATE, UNIQUE rejection, and various default literal types.
|
|
5
|
+
|
|
6
|
+
pragma foreign_keys = true;
|
|
7
|
+
|
|
8
|
+
-- ===================================
|
|
9
|
+
-- 1. ADD COLUMN with CHECK constraint
|
|
10
|
+
-- ===================================
|
|
11
|
+
|
|
12
|
+
create table t_chk (id integer primary key, a integer not null);
|
|
13
|
+
insert into t_chk values (1, 10);
|
|
14
|
+
|
|
15
|
+
alter table t_chk add column b integer null check (b is null or b > 0);
|
|
16
|
+
|
|
17
|
+
-- existing rows backfilled with NULL (allowed by CHECK)
|
|
18
|
+
select b from t_chk where id = 1;
|
|
19
|
+
→ [{"b":null}]
|
|
20
|
+
|
|
21
|
+
-- valid insert
|
|
22
|
+
insert into t_chk values (2, 20, 5);
|
|
23
|
+
|
|
24
|
+
-- CHECK violation
|
|
25
|
+
insert into t_chk values (3, 30, -1);
|
|
26
|
+
-- error: CHECK
|
|
27
|
+
|
|
28
|
+
drop table t_chk;
|
|
29
|
+
-- run
|
|
30
|
+
|
|
31
|
+
-- 1b. Engine-bug guard (CHECK analogue of altered-column-not-exists-antijoin-misread).
|
|
32
|
+
-- The literal-default CHECK post-scan runs `select 1 from <t> where not (<check>)`. A
|
|
33
|
+
-- DECLARED CHECK seeds a domain constraint on the scan, so if the new CHECK were live
|
|
34
|
+
-- during validation, `ruleFilterContradiction` would fold the scan's own `not (<check>)`
|
|
35
|
+
-- to EmptyRelation and silently admit a violating backfilled row. The fix validates
|
|
36
|
+
-- against a schema carrying the new COLUMN but NOT the new CHECK, committing the CHECK
|
|
37
|
+
-- only after the scan passes. Existing row 1 backfilled with 0 violates `v > 0` → abort.
|
|
38
|
+
create table t_chk2 (id integer primary key);
|
|
39
|
+
insert into t_chk2 values (1);
|
|
40
|
+
-- run
|
|
41
|
+
|
|
42
|
+
alter table t_chk2 add column v integer default 0 check (v > 0);
|
|
43
|
+
-- error: CHECK
|
|
44
|
+
|
|
45
|
+
-- Reverted: the column was dropped and no stale CHECK left declared.
|
|
46
|
+
select * from t_chk2 order by id;
|
|
47
|
+
→ [{"id":1}]
|
|
48
|
+
|
|
49
|
+
-- A satisfying literal default succeeds and backfills.
|
|
50
|
+
alter table t_chk2 add column v integer default 7 check (v > 0);
|
|
51
|
+
-- run
|
|
52
|
+
|
|
53
|
+
select * from t_chk2 order by id;
|
|
54
|
+
→ [{"id":1,"v":7}]
|
|
55
|
+
|
|
56
|
+
drop table t_chk2;
|
|
57
|
+
|
|
58
|
+
-- ===================================
|
|
59
|
+
-- 2. ADD COLUMN with REFERENCES (column-level FK)
|
|
60
|
+
--
|
|
61
|
+
-- Adding a column-level FK validates the EXISTING (backfilled) rows against the
|
|
62
|
+
-- referenced parent — MATCH SIMPLE, pragma-gated — via the same post-scan the
|
|
63
|
+
-- ADD CONSTRAINT path uses (validateForeignKeyOverExistingRows), for BOTH the
|
|
64
|
+
-- literal-default and per-row (evaluator) default paths. A fully-non-NULL orphan
|
|
65
|
+
-- aborts the ALTER and leaves the table unchanged (column not added); a NULL
|
|
66
|
+
-- backfill satisfies the FK.
|
|
67
|
+
-- ===================================
|
|
68
|
+
|
|
69
|
+
-- 2a. NULL backfill is allowed (MATCH SIMPLE), and forward enforcement fires.
|
|
70
|
+
create table t_parent (pid integer primary key);
|
|
71
|
+
insert into t_parent values (1), (2);
|
|
72
|
+
|
|
73
|
+
create table t_child (id integer primary key, name text);
|
|
74
|
+
insert into t_child values (1, 'x');
|
|
75
|
+
|
|
76
|
+
alter table t_child add column parent integer null references t_parent(pid);
|
|
77
|
+
|
|
78
|
+
-- backfilled NULL is allowed (MATCH SIMPLE)
|
|
79
|
+
select parent from t_child where id = 1;
|
|
80
|
+
→ [{"parent":null}]
|
|
81
|
+
|
|
82
|
+
-- valid FK insert
|
|
83
|
+
insert into t_child values (2, 'y', 1);
|
|
84
|
+
|
|
85
|
+
-- FK violation (forward enforcement via merged table-level FK)
|
|
86
|
+
insert into t_child values (3, 'z', 99);
|
|
87
|
+
-- error:
|
|
88
|
+
|
|
89
|
+
drop table t_child;
|
|
90
|
+
drop table t_parent;
|
|
91
|
+
-- run
|
|
92
|
+
|
|
93
|
+
-- 2b. Literal-default ORPHAN over populated rows → ALTER aborts, table unchanged.
|
|
94
|
+
create table t_parent (pid integer primary key);
|
|
95
|
+
insert into t_parent values (1), (2);
|
|
96
|
+
create table t_child (id integer primary key, name text);
|
|
97
|
+
insert into t_child values (1, 'x');
|
|
98
|
+
-- run
|
|
99
|
+
|
|
100
|
+
alter table t_child add column parent integer default 99 references t_parent(pid);
|
|
101
|
+
-- error: foreign key
|
|
102
|
+
|
|
103
|
+
-- the column was NOT added (revert dropped it + restored the catalog)
|
|
104
|
+
select count(*) as c from table_info('t_child') where name = 'parent';
|
|
105
|
+
→ [{"c":0}]
|
|
106
|
+
|
|
107
|
+
-- ...and the FK was never installed: forward enforcement is absent and a plain
|
|
108
|
+
-- insert over the original (id, name) shape still succeeds.
|
|
109
|
+
insert into t_child values (2, 'y');
|
|
110
|
+
select count(*) as c from t_child;
|
|
111
|
+
→ [{"c":2}]
|
|
112
|
+
|
|
113
|
+
drop table t_child;
|
|
114
|
+
drop table t_parent;
|
|
115
|
+
-- run
|
|
116
|
+
|
|
117
|
+
-- 2c. Literal-default SATISFIED → ALTER succeeds, backfills, forward enforcement active.
|
|
118
|
+
create table t_parent (pid integer primary key);
|
|
119
|
+
insert into t_parent values (1), (2);
|
|
120
|
+
create table t_child (id integer primary key, name text);
|
|
121
|
+
insert into t_child values (1, 'x');
|
|
122
|
+
-- run
|
|
123
|
+
|
|
124
|
+
alter table t_child add column parent integer default 1 references t_parent(pid);
|
|
125
|
+
-- run
|
|
126
|
+
|
|
127
|
+
-- backfilled value present and satisfied
|
|
128
|
+
select parent from t_child where id = 1;
|
|
129
|
+
→ [{"parent":1}]
|
|
130
|
+
|
|
131
|
+
-- the FK is installed (introspection)
|
|
132
|
+
select count(*) as c from foreign_key_info('t_child') where referenced_table = 't_parent';
|
|
133
|
+
→ [{"c":1}]
|
|
134
|
+
|
|
135
|
+
-- forward enforcement: an orphan insert is now rejected
|
|
136
|
+
insert into t_child values (2, 'y', 99);
|
|
137
|
+
-- error:
|
|
138
|
+
|
|
139
|
+
drop table t_child;
|
|
140
|
+
drop table t_parent;
|
|
141
|
+
-- run
|
|
142
|
+
|
|
143
|
+
-- 2d. Per-row (evaluator) default ORPHAN → ALTER aborts, table unchanged.
|
|
144
|
+
-- The default (new.a + 100) lands each row on a value with no parent row.
|
|
145
|
+
create table t_parent (pid integer primary key);
|
|
146
|
+
insert into t_parent values (1), (2);
|
|
147
|
+
create table t_child (id integer primary key, a integer);
|
|
148
|
+
insert into t_child values (1, 1), (2, 2);
|
|
149
|
+
-- run
|
|
150
|
+
|
|
151
|
+
alter table t_child add column parent integer default (new.a + 100) references t_parent(pid);
|
|
152
|
+
-- error: foreign key
|
|
153
|
+
|
|
154
|
+
-- table unchanged: the per-row backfilled column was reverted
|
|
155
|
+
select * from t_child order by id;
|
|
156
|
+
→ [{"id":1,"a":1},{"id":2,"a":2}]
|
|
157
|
+
|
|
158
|
+
drop table t_child;
|
|
159
|
+
drop table t_parent;
|
|
160
|
+
-- run
|
|
161
|
+
|
|
162
|
+
-- 2e. Per-row (evaluator) default SATISFIED → ALTER succeeds, backfills per-row.
|
|
163
|
+
-- The default (new.a + 100) lands each row on an existing parent (101, 102).
|
|
164
|
+
create table t_parent (pid integer primary key);
|
|
165
|
+
insert into t_parent values (101), (102);
|
|
166
|
+
create table t_child (id integer primary key, a integer);
|
|
167
|
+
insert into t_child values (1, 1), (2, 2);
|
|
168
|
+
-- run
|
|
169
|
+
|
|
170
|
+
alter table t_child add column parent integer default (new.a + 100) references t_parent(pid);
|
|
171
|
+
-- run
|
|
172
|
+
|
|
173
|
+
select id, parent from t_child order by id;
|
|
174
|
+
→ [{"id":1,"parent":101},{"id":2,"parent":102}]
|
|
175
|
+
|
|
176
|
+
-- forward enforcement active
|
|
177
|
+
insert into t_child values (3, 3, 99);
|
|
178
|
+
-- error:
|
|
179
|
+
|
|
180
|
+
drop table t_child;
|
|
181
|
+
drop table t_parent;
|
|
182
|
+
-- run
|
|
183
|
+
|
|
184
|
+
-- 2f. Self-referential FK (parent == child) — SATISFIED.
|
|
185
|
+
-- Each row backfills parent = its own id, which exists, so all rows are satisfied.
|
|
186
|
+
create table t_self (id integer primary key, name text);
|
|
187
|
+
insert into t_self values (1, 'a'), (2, 'b');
|
|
188
|
+
-- run
|
|
189
|
+
|
|
190
|
+
alter table t_self add column parent integer default (new.id) references t_self(id);
|
|
191
|
+
-- run
|
|
192
|
+
|
|
193
|
+
select id, parent from t_self order by id;
|
|
194
|
+
→ [{"id":1,"parent":1},{"id":2,"parent":2}]
|
|
195
|
+
|
|
196
|
+
drop table t_self;
|
|
197
|
+
-- run
|
|
198
|
+
|
|
199
|
+
-- 2g. Self-referential FK (parent == child) — ORPHAN.
|
|
200
|
+
-- parent = id + 100 → 101, 102 are not ids in the table → orphans → abort.
|
|
201
|
+
create table t_self (id integer primary key, name text);
|
|
202
|
+
insert into t_self values (1, 'a'), (2, 'b');
|
|
203
|
+
-- run
|
|
204
|
+
|
|
205
|
+
alter table t_self add column parent integer default (new.id + 100) references t_self(id);
|
|
206
|
+
-- error: foreign key
|
|
207
|
+
|
|
208
|
+
-- table unchanged (self-ref post-scan read a consistent post-alter table)
|
|
209
|
+
select * from t_self order by id;
|
|
210
|
+
→ [{"id":1,"name":"a"},{"id":2,"name":"b"}]
|
|
211
|
+
|
|
212
|
+
drop table t_self;
|
|
213
|
+
-- run
|
|
214
|
+
|
|
215
|
+
-- 2h. Bare `REFERENCES parent` (no parent column) resolves to the parent PK.
|
|
216
|
+
-- Satisfied literal default succeeds; forward enforcement active.
|
|
217
|
+
create table t_parent (pid integer primary key);
|
|
218
|
+
insert into t_parent values (1), (2);
|
|
219
|
+
create table t_child (id integer primary key, name text);
|
|
220
|
+
insert into t_child values (1, 'x');
|
|
221
|
+
-- run
|
|
222
|
+
|
|
223
|
+
alter table t_child add column parent integer default 1 references t_parent;
|
|
224
|
+
-- run
|
|
225
|
+
|
|
226
|
+
select parent from t_child where id = 1;
|
|
227
|
+
→ [{"parent":1}]
|
|
228
|
+
|
|
229
|
+
insert into t_child values (2, 'y', 99);
|
|
230
|
+
-- error:
|
|
231
|
+
|
|
232
|
+
drop table t_child;
|
|
233
|
+
drop table t_parent;
|
|
234
|
+
-- run
|
|
235
|
+
|
|
236
|
+
-- 2i. Bare `REFERENCES parent` ORPHAN (PK fallback) → abort, table unchanged.
|
|
237
|
+
create table t_parent (pid integer primary key);
|
|
238
|
+
insert into t_parent values (1), (2);
|
|
239
|
+
create table t_child (id integer primary key, name text);
|
|
240
|
+
insert into t_child values (1, 'x');
|
|
241
|
+
-- run
|
|
242
|
+
|
|
243
|
+
alter table t_child add column parent integer default 99 references t_parent;
|
|
244
|
+
-- error: foreign key
|
|
245
|
+
|
|
246
|
+
select count(*) as c from table_info('t_child') where name = 'parent';
|
|
247
|
+
→ [{"c":0}]
|
|
248
|
+
|
|
249
|
+
drop table t_child;
|
|
250
|
+
drop table t_parent;
|
|
251
|
+
-- run
|
|
252
|
+
|
|
253
|
+
-- 2j. pragma foreign_keys = false → validator no-ops; orphan ADD COLUMN succeeds.
|
|
254
|
+
pragma foreign_keys = false;
|
|
255
|
+
create table t_parent (pid integer primary key);
|
|
256
|
+
insert into t_parent values (1);
|
|
257
|
+
create table t_child (id integer primary key, name text);
|
|
258
|
+
insert into t_child values (1, 'x');
|
|
259
|
+
-- run
|
|
260
|
+
|
|
261
|
+
-- pragma off: the orphan backfill (99 ∉ parent) is NOT validated → the add succeeds
|
|
262
|
+
alter table t_child add column parent integer default 99 references t_parent(pid);
|
|
263
|
+
-- run
|
|
264
|
+
|
|
265
|
+
select parent from t_child where id = 1;
|
|
266
|
+
→ [{"parent":99}]
|
|
267
|
+
|
|
268
|
+
drop table t_child;
|
|
269
|
+
drop table t_parent;
|
|
270
|
+
pragma foreign_keys = true;
|
|
271
|
+
-- run
|
|
272
|
+
|
|
273
|
+
-- 2k. Parent table ABSENT — any fully-non-NULL backfilled row is an orphan ⇒ abort;
|
|
274
|
+
-- a NULL-only backfill still succeeds (MATCH SIMPLE exempts NULL).
|
|
275
|
+
create table t_child (id integer primary key, name text);
|
|
276
|
+
insert into t_child values (1, 'x');
|
|
277
|
+
-- run
|
|
278
|
+
|
|
279
|
+
-- non-NULL default to a non-existent parent → orphan → abort, table unchanged
|
|
280
|
+
alter table t_child add column parent integer default 5 references no_such_parent(pid);
|
|
281
|
+
-- error: foreign key
|
|
282
|
+
|
|
283
|
+
select * from t_child order by id;
|
|
284
|
+
→ [{"id":1,"name":"x"}]
|
|
285
|
+
|
|
286
|
+
-- NULL backfill (no default) to a non-existent parent → succeeds
|
|
287
|
+
alter table t_child add column parent2 integer null references no_such_parent(pid);
|
|
288
|
+
-- run
|
|
289
|
+
|
|
290
|
+
select parent2 from t_child where id = 1;
|
|
291
|
+
→ [{"parent2":null}]
|
|
292
|
+
|
|
293
|
+
drop table t_child;
|
|
294
|
+
-- run
|
|
295
|
+
|
|
296
|
+
-- 2l. Empty table → no rows to validate; ALTER succeeds even with an orphan-shaped default.
|
|
297
|
+
create table t_parent (pid integer primary key);
|
|
298
|
+
insert into t_parent values (1);
|
|
299
|
+
create table t_child (id integer primary key, name text);
|
|
300
|
+
-- run
|
|
301
|
+
|
|
302
|
+
-- no existing rows ⇒ the FK post-scan finds nothing to validate ⇒ the add succeeds
|
|
303
|
+
alter table t_child add column parent integer default 99 references t_parent(pid);
|
|
304
|
+
-- run
|
|
305
|
+
|
|
306
|
+
-- forward enforcement is still installed: an orphan insert is rejected
|
|
307
|
+
insert into t_child values (1, 'x', 99);
|
|
308
|
+
-- error:
|
|
309
|
+
|
|
310
|
+
-- a satisfied insert succeeds
|
|
311
|
+
insert into t_child values (2, 'y', 1);
|
|
312
|
+
select count(*) as c from t_child;
|
|
313
|
+
→ [{"c":1}]
|
|
314
|
+
|
|
315
|
+
drop table t_child;
|
|
316
|
+
drop table t_parent;
|
|
317
|
+
-- run
|
|
318
|
+
|
|
319
|
+
-- 2m. Engine-bug guard (altered-column-not-exists-antijoin-misread).
|
|
320
|
+
-- The existing-row FK validator issues a `not exists` anti-join. FK-IND folding
|
|
321
|
+
-- (ruleAntiJoinFkEmpty + seeded INDs) folds an anti-join over a DECLARED non-null FK
|
|
322
|
+
-- to EmptyRelation under the inclusion dependency `child.fk ⊆ parent.pk`. If the new
|
|
323
|
+
-- FK were live during validation, the validator's own anti-join would fold to empty,
|
|
324
|
+
-- trusting the unvalidated invariant and silently admitting an orphan — and every
|
|
325
|
+
-- later anti-join on the table would stay mis-folded. The fix registers the new
|
|
326
|
+
-- COLUMN but NOT the new FK for the validation pass, committing the FK only after
|
|
327
|
+
-- validation passes.
|
|
328
|
+
create table p (pid integer primary key);
|
|
329
|
+
insert into p values (1), (2);
|
|
330
|
+
create table c (id integer primary key, name text);
|
|
331
|
+
insert into c values (1, 'x');
|
|
332
|
+
-- run
|
|
333
|
+
|
|
334
|
+
-- ORPHAN: 99 ∉ {1,2}. The validator's `not exists` MUST surface the orphan and abort
|
|
335
|
+
-- (pre-fix it folded to empty and admitted the violation).
|
|
336
|
+
alter table c add column parent integer default 99 references p(pid);
|
|
337
|
+
-- error: foreign key
|
|
338
|
+
|
|
339
|
+
-- Reverted to the original shape: the column was dropped and no stale FK left
|
|
340
|
+
-- declared, so a standalone scan reads the unchanged pre-ALTER table.
|
|
341
|
+
select * from c order by id;
|
|
342
|
+
→ [{"id":1,"name":"x"}]
|
|
343
|
+
|
|
344
|
+
-- VALID: every row references an existing parent (1 ∈ {1,2}) → succeeds and backfills.
|
|
345
|
+
alter table c add column parent integer default 1 references p(pid);
|
|
346
|
+
-- run
|
|
347
|
+
|
|
348
|
+
-- `select *` shows the backfilled column.
|
|
349
|
+
select * from c order by id;
|
|
350
|
+
→ [{"id":1,"name":"x","parent":1}]
|
|
351
|
+
|
|
352
|
+
-- Standalone `not exists` anti-join over the now-committed FK: the correct empty set,
|
|
353
|
+
-- because the FK genuinely holds (whether or not it folds, the answer is empty).
|
|
354
|
+
select id from c where not exists (select 1 from p where p.pid = c.parent);
|
|
355
|
+
→ []
|
|
356
|
+
|
|
357
|
+
drop table c;
|
|
358
|
+
drop table p;
|
|
359
|
+
-- run
|
|
360
|
+
|
|
361
|
+
-- 2n. CHECK + FK on the SAME ADD COLUMN (combination coverage).
|
|
362
|
+
-- The validation schema carries the new CHECK (`mergedChecks`) but NOT the new FK,
|
|
363
|
+
-- so the CHECK post-scan and the FK `not exists` scan run together in the one
|
|
364
|
+
-- try/revert region. Each arm must abort independently, and a doubly-valid add must
|
|
365
|
+
-- succeed and enforce both constraints forward.
|
|
366
|
+
create table p (pid integer primary key);
|
|
367
|
+
insert into p values (1), (2);
|
|
368
|
+
create table c (id integer primary key);
|
|
369
|
+
insert into c values (1);
|
|
370
|
+
-- run
|
|
371
|
+
|
|
372
|
+
-- CHECK arm aborts first: default 0 violates `parent > 0` (it is also an FK orphan,
|
|
373
|
+
-- but the CHECK scan runs before the FK scan).
|
|
374
|
+
alter table c add column parent integer default 0 check (parent > 0) references p(pid);
|
|
375
|
+
-- error: CHECK
|
|
376
|
+
|
|
377
|
+
-- FK arm aborts: default 99 satisfies the CHECK but references a missing parent.
|
|
378
|
+
alter table c add column parent integer default 99 check (parent > 0) references p(pid);
|
|
379
|
+
-- error: foreign key
|
|
380
|
+
|
|
381
|
+
-- Both arms satisfied → succeeds and backfills.
|
|
382
|
+
alter table c add column parent integer default 1 check (parent > 0) references p(pid);
|
|
383
|
+
-- run
|
|
384
|
+
|
|
385
|
+
select * from c order by id;
|
|
386
|
+
→ [{"id":1,"parent":1}]
|
|
387
|
+
|
|
388
|
+
-- Forward enforcement of BOTH constraints still fires post-add.
|
|
389
|
+
insert into c values (2, 0);
|
|
390
|
+
-- error: CHECK
|
|
391
|
+
|
|
392
|
+
insert into c values (3, 99);
|
|
393
|
+
-- error:
|
|
394
|
+
|
|
395
|
+
drop table c;
|
|
396
|
+
drop table p;
|
|
397
|
+
-- run
|
|
398
|
+
|
|
399
|
+
-- ===================================
|
|
400
|
+
-- 3. ADD COLUMN with COLLATE clause — Quereus rejects NOCASE on TEXT
|
|
401
|
+
-- ===================================
|
|
402
|
+
|
|
403
|
+
create table t_col (id integer primary key, name text);
|
|
404
|
+
insert into t_col values (1, 'Alice'), (2, 'BOB');
|
|
405
|
+
|
|
406
|
+
alter table t_col add column nick text null collate nocase;
|
|
407
|
+
|
|
408
|
+
drop table t_col;
|
|
409
|
+
|
|
410
|
+
-- ===================================
|
|
411
|
+
-- 4. ADD COLUMN UNIQUE rejected on populated table
|
|
412
|
+
-- ===================================
|
|
413
|
+
|
|
414
|
+
create table t_addunq (id integer primary key, a integer not null);
|
|
415
|
+
insert into t_addunq values (1, 10), (2, 20);
|
|
416
|
+
|
|
417
|
+
alter table t_addunq add column u integer unique;
|
|
418
|
+
-- error:
|
|
419
|
+
|
|
420
|
+
drop table t_addunq;
|
|
421
|
+
|
|
422
|
+
-- ===================================
|
|
423
|
+
-- 5. ADD COLUMN default value backfilled to existing rows
|
|
424
|
+
-- ===================================
|
|
425
|
+
|
|
426
|
+
-- integer default
|
|
427
|
+
create table t_int (id integer primary key);
|
|
428
|
+
insert into t_int values (1), (2);
|
|
429
|
+
|
|
430
|
+
alter table t_int add column n integer default 7;
|
|
431
|
+
|
|
432
|
+
select n from t_int order by id;
|
|
433
|
+
→ [{"n":7},{"n":7}]
|
|
434
|
+
|
|
435
|
+
drop table t_int;
|
|
436
|
+
|
|
437
|
+
create table t_real_t (id integer primary key);
|
|
438
|
+
insert into t_real_t values (1), (2);
|
|
439
|
+
|
|
440
|
+
alter table t_real_t add column r real default -123.0;
|
|
441
|
+
|
|
442
|
+
select r from t_real_t where id = 1;
|
|
443
|
+
→ [{"r":-123}]
|
|
444
|
+
|
|
445
|
+
drop table t_real_t;
|
|
446
|
+
|
|
447
|
+
-- positive real default works
|
|
448
|
+
create table t_real_p (id integer primary key);
|
|
449
|
+
insert into t_real_p values (1), (2);
|
|
450
|
+
|
|
451
|
+
alter table t_real_p add column r real default 123.0;
|
|
452
|
+
|
|
453
|
+
select r from t_real_p where id = 1;
|
|
454
|
+
→ [{"r":123}]
|
|
455
|
+
|
|
456
|
+
drop table t_real_p;
|
|
457
|
+
|
|
458
|
+
-- ===================================
|
|
459
|
+
-- 6. Default backfill participates in aggregates over pre-existing rows
|
|
460
|
+
-- ===================================
|
|
461
|
+
|
|
462
|
+
create table t_agg (id integer primary key);
|
|
463
|
+
insert into t_agg values (1), (2), (3);
|
|
464
|
+
|
|
465
|
+
alter table t_agg add column score integer default 7;
|
|
466
|
+
|
|
467
|
+
select sum(score) as s, count(score) as c from t_agg;
|
|
468
|
+
→ [{"s":21,"c":3}]
|
|
469
|
+
|
|
470
|
+
drop table t_agg;
|
|
471
|
+
-- run
|
|
472
|
+
|
|
473
|
+
-- ===================================
|
|
474
|
+
-- 7. Inline CHECK / FOREIGN KEY SURVIVE later structural ALTERs
|
|
475
|
+
--
|
|
476
|
+
-- An inline constraint on an added column routes through the module's `addConstraint` —
|
|
477
|
+
-- the same path `ALTER TABLE ADD CONSTRAINT` uses — so the MODULE owns it. That is what
|
|
478
|
+
-- makes it durable: every later structural ALTER asks the module for the new table schema
|
|
479
|
+
-- and installs that answer in the catalog verbatim, so a constraint merged only into the
|
|
480
|
+
-- engine's catalog copy is dropped on the floor by the next DROP / RENAME COLUMN (and no
|
|
481
|
+
-- error is raised — bad data is simply accepted afterwards). Under `yarn test:store` these
|
|
482
|
+
-- same cases also cover the persisted half.
|
|
483
|
+
-- ===================================
|
|
484
|
+
|
|
485
|
+
-- 7a. Inline CHECK survives an unrelated DROP COLUMN.
|
|
486
|
+
create table t_surv_chk (id integer primary key, junk text);
|
|
487
|
+
insert into t_surv_chk values (1, 'j');
|
|
488
|
+
-- run
|
|
489
|
+
|
|
490
|
+
alter table t_surv_chk add column n integer null check (n is null or n > 0);
|
|
491
|
+
-- run
|
|
492
|
+
|
|
493
|
+
-- enforces immediately
|
|
494
|
+
insert into t_surv_chk values (2, 'k', -5);
|
|
495
|
+
-- error: CHECK
|
|
496
|
+
|
|
497
|
+
alter table t_surv_chk drop column junk;
|
|
498
|
+
-- run
|
|
499
|
+
|
|
500
|
+
-- still declared after the unrelated drop (it used to vanish here)
|
|
501
|
+
select count(*) as c from check_constraint_info('t_surv_chk') where name = '_check_n';
|
|
502
|
+
→ [{"c":1}]
|
|
503
|
+
|
|
504
|
+
-- ...and still enforces
|
|
505
|
+
insert into t_surv_chk values (3, -5);
|
|
506
|
+
-- error: CHECK
|
|
507
|
+
|
|
508
|
+
-- a satisfying insert still works
|
|
509
|
+
insert into t_surv_chk values (4, 7);
|
|
510
|
+
select id, n from t_surv_chk order by id;
|
|
511
|
+
→ [{"id":1,"n":null},{"id":4,"n":7}]
|
|
512
|
+
|
|
513
|
+
-- 7b. ...and survives an unrelated RENAME COLUMN too.
|
|
514
|
+
alter table t_surv_chk rename column id to ident;
|
|
515
|
+
-- run
|
|
516
|
+
|
|
517
|
+
select count(*) as c from check_constraint_info('t_surv_chk') where name = '_check_n';
|
|
518
|
+
→ [{"c":1}]
|
|
519
|
+
|
|
520
|
+
insert into t_surv_chk values (5, -5);
|
|
521
|
+
-- error: CHECK
|
|
522
|
+
|
|
523
|
+
drop table t_surv_chk;
|
|
524
|
+
-- run
|
|
525
|
+
|
|
526
|
+
-- 7c. Inline FOREIGN KEY survives an unrelated DROP COLUMN.
|
|
527
|
+
--
|
|
528
|
+
-- The dropped column is added AFTER the FK column on purpose, so it is the FK child
|
|
529
|
+
-- column's TRAILING neighbour and no recorded position moves — this case tests survival
|
|
530
|
+
-- only. Dropping a column that PRECEDES an FK child column (which renumbers the FK's
|
|
531
|
+
-- recorded child position) is covered in `41.10-alter-drop-column-foreign-key.sqllogic`.
|
|
532
|
+
create table p_surv (pid integer primary key);
|
|
533
|
+
insert into p_surv values (1);
|
|
534
|
+
create table t_surv_fk (id integer primary key);
|
|
535
|
+
insert into t_surv_fk values (1);
|
|
536
|
+
-- run
|
|
537
|
+
|
|
538
|
+
alter table t_surv_fk add column fkcol integer null references p_surv(pid);
|
|
539
|
+
alter table t_surv_fk add column junk text null;
|
|
540
|
+
-- run
|
|
541
|
+
|
|
542
|
+
-- enforces immediately
|
|
543
|
+
insert into t_surv_fk values (2, 999, 'k');
|
|
544
|
+
-- error:
|
|
545
|
+
|
|
546
|
+
alter table t_surv_fk drop column junk;
|
|
547
|
+
-- run
|
|
548
|
+
|
|
549
|
+
-- still declared after the unrelated drop (it used to vanish here)
|
|
550
|
+
select count(*) as c from foreign_key_info('t_surv_fk') where referenced_table = 'p_surv';
|
|
551
|
+
→ [{"c":1}]
|
|
552
|
+
|
|
553
|
+
-- ...and still enforces
|
|
554
|
+
insert into t_surv_fk values (3, 999);
|
|
555
|
+
-- error:
|
|
556
|
+
|
|
557
|
+
-- a satisfying insert still works
|
|
558
|
+
insert into t_surv_fk values (4, 1);
|
|
559
|
+
select id, fkcol from t_surv_fk order by id;
|
|
560
|
+
→ [{"id":1,"fkcol":null},{"id":4,"fkcol":1}]
|
|
561
|
+
|
|
562
|
+
-- 7d. ...and survives an unrelated RENAME COLUMN too.
|
|
563
|
+
alter table t_surv_fk rename column id to ident;
|
|
564
|
+
-- run
|
|
565
|
+
|
|
566
|
+
select count(*) as c from foreign_key_info('t_surv_fk') where referenced_table = 'p_surv';
|
|
567
|
+
→ [{"c":1}]
|
|
568
|
+
|
|
569
|
+
insert into t_surv_fk values (5, 999);
|
|
570
|
+
-- error:
|
|
571
|
+
|
|
572
|
+
drop table t_surv_fk;
|
|
573
|
+
drop table p_surv;
|
|
574
|
+
-- run
|
|
575
|
+
|
|
576
|
+
-- 7e. Auto-generated constraint names agree with the `create table` spelling.
|
|
577
|
+
--
|
|
578
|
+
-- An unnamed inline FK on an added column is named `_fk_<table>_<column>` — the same name
|
|
579
|
+
-- the equivalent `create table` declaration produces. (It used to be `_fk_<column>`, an
|
|
580
|
+
-- engine-only spelling that no other path produced; routing through the module unified
|
|
581
|
+
-- the two.) An unnamed inline CHECK keeps its established `_check_<column>` name, which
|
|
582
|
+
-- `create table` also uses. Explicit names round-trip unchanged.
|
|
583
|
+
create table p_nm (pid integer primary key);
|
|
584
|
+
create table t_nm (id integer primary key);
|
|
585
|
+
-- run
|
|
586
|
+
|
|
587
|
+
alter table t_nm add column fkcol integer null references p_nm(pid);
|
|
588
|
+
alter table t_nm add column chkcol integer null check (chkcol is null or chkcol > 0);
|
|
589
|
+
alter table t_nm add column named_fk integer null constraint my_fk references p_nm(pid);
|
|
590
|
+
alter table t_nm add column named_chk integer null constraint my_chk check (named_chk is null or named_chk > 0);
|
|
591
|
+
-- run
|
|
592
|
+
|
|
593
|
+
select name from foreign_key_info('t_nm') order by name;
|
|
594
|
+
→ [{"name":"_fk_t_nm_fkcol"},{"name":"my_fk"}]
|
|
595
|
+
|
|
596
|
+
select name from check_constraint_info('t_nm') order by name;
|
|
597
|
+
→ [{"name":"_check_chkcol"},{"name":"my_chk"}]
|
|
598
|
+
|
|
599
|
+
-- The same declarations written as `create table` produce the same names.
|
|
600
|
+
create table t_nm2 (
|
|
601
|
+
id integer primary key,
|
|
602
|
+
fkcol integer null references p_nm(pid),
|
|
603
|
+
chkcol integer null check (chkcol is null or chkcol > 0)
|
|
604
|
+
);
|
|
605
|
+
-- run
|
|
606
|
+
|
|
607
|
+
select name from foreign_key_info('t_nm2') order by name;
|
|
608
|
+
→ [{"name":"_fk_t_nm2_fkcol"}]
|
|
609
|
+
|
|
610
|
+
select name from check_constraint_info('t_nm2') order by name;
|
|
611
|
+
→ [{"name":"_check_chkcol"}]
|
|
612
|
+
|
|
613
|
+
drop table t_nm2;
|
|
614
|
+
drop table t_nm;
|
|
615
|
+
drop table p_nm;
|
|
616
|
+
-- run
|
|
617
|
+
|
|
618
|
+
-- 7f. A rejected add leaves NO stranded constraint behind.
|
|
619
|
+
--
|
|
620
|
+
-- CHECK and FK are installed in that order, so an FK violation aborts AFTER the CHECK is
|
|
621
|
+
-- already in the module's schema. The revert has to hand the CHECK back before dropping
|
|
622
|
+
-- the column — neither module prunes a CHECK over a dropped column, so a stranded one
|
|
623
|
+
-- would keep naming a column the table no longer has and break the next write.
|
|
624
|
+
create table p_rev (pid integer primary key);
|
|
625
|
+
insert into p_rev values (1);
|
|
626
|
+
create table t_rev (id integer primary key, junk text);
|
|
627
|
+
insert into t_rev values (1, 'j');
|
|
628
|
+
-- run
|
|
629
|
+
|
|
630
|
+
-- default 5 satisfies `parent > 0` but references a missing parent → FK arm aborts.
|
|
631
|
+
alter table t_rev add column parent integer default 5 check (parent > 0) references p_rev(pid);
|
|
632
|
+
-- error: foreign key
|
|
633
|
+
|
|
634
|
+
-- The table is exactly as it was: column gone, and neither constraint left declared.
|
|
635
|
+
select * from t_rev order by id;
|
|
636
|
+
→ [{"id":1,"junk":"j"}]
|
|
637
|
+
|
|
638
|
+
select count(*) as c from check_constraint_info('t_rev');
|
|
639
|
+
→ [{"c":0}]
|
|
640
|
+
|
|
641
|
+
select count(*) as c from foreign_key_info('t_rev');
|
|
642
|
+
→ [{"c":0}]
|
|
643
|
+
|
|
644
|
+
-- Writes still work over the original shape.
|
|
645
|
+
insert into t_rev values (2, 'k');
|
|
646
|
+
select count(*) as c from t_rev;
|
|
647
|
+
→ [{"c":2}]
|
|
648
|
+
|
|
649
|
+
-- A satisfied retry of the same ALTER now succeeds and both constraints enforce.
|
|
650
|
+
alter table t_rev add column parent integer default 1 check (parent > 0) references p_rev(pid);
|
|
651
|
+
-- run
|
|
652
|
+
|
|
653
|
+
select count(*) as c from check_constraint_info('t_rev') where name = '_check_parent';
|
|
654
|
+
→ [{"c":1}]
|
|
655
|
+
|
|
656
|
+
select count(*) as c from foreign_key_info('t_rev') where name = '_fk_t_rev_parent';
|
|
657
|
+
→ [{"c":1}]
|
|
658
|
+
|
|
659
|
+
insert into t_rev values (3, 'z', 0);
|
|
660
|
+
-- error: CHECK
|
|
661
|
+
|
|
662
|
+
insert into t_rev values (4, 'z', 99);
|
|
663
|
+
-- error:
|
|
664
|
+
|
|
665
|
+
drop table t_rev;
|
|
666
|
+
drop table p_rev;
|
|
667
|
+
-- run
|
|
668
|
+
|
|
669
|
+
-- 7g. Per-row (expression) DEFAULT together with an inline CHECK.
|
|
670
|
+
--
|
|
671
|
+
-- The two default kinds validate the CHECK in different places: a literal DEFAULT by a
|
|
672
|
+
-- post-backfill scan, a per-row DEFAULT inside the backfill hook itself (against each
|
|
673
|
+
-- freshly-computed value, since the scan would read a stale pre-backfill snapshot). Only
|
|
674
|
+
-- the literal half was covered; this pins the per-row half in both directions, and that
|
|
675
|
+
-- the CHECK still reaches the module on this path (it is declared, and it survives a
|
|
676
|
+
-- later structural ALTER — the whole point of the reroute).
|
|
677
|
+
create table t_perrow (id integer primary key, v integer null, junk text null);
|
|
678
|
+
insert into t_perrow values (1, 10, 'j'), (2, 20, 'k');
|
|
679
|
+
-- run
|
|
680
|
+
|
|
681
|
+
alter table t_perrow add column w integer null default (new.v * 2) check (w is null or w > 0);
|
|
682
|
+
-- run
|
|
683
|
+
|
|
684
|
+
select id, w from t_perrow order by id;
|
|
685
|
+
→ [{"id":1,"w":20},{"id":2,"w":40}]
|
|
686
|
+
|
|
687
|
+
select count(*) as c from check_constraint_info('t_perrow') where name = '_check_w';
|
|
688
|
+
→ [{"c":1}]
|
|
689
|
+
|
|
690
|
+
-- the CHECK is the module's now, so an unrelated structural ALTER cannot eat it
|
|
691
|
+
alter table t_perrow drop column junk;
|
|
692
|
+
-- run
|
|
693
|
+
|
|
694
|
+
select count(*) as c from check_constraint_info('t_perrow') where name = '_check_w';
|
|
695
|
+
→ [{"c":1}]
|
|
696
|
+
|
|
697
|
+
insert into t_perrow values (3, 1, -5);
|
|
698
|
+
-- error: CHECK
|
|
699
|
+
|
|
700
|
+
drop table t_perrow;
|
|
701
|
+
-- run
|
|
702
|
+
|
|
703
|
+
-- ...and the violating direction: a per-row default that computes a CHECK-violating value
|
|
704
|
+
-- for an existing row aborts inside the backfill, leaving the table untouched.
|
|
705
|
+
create table t_perrow_bad (id integer primary key, v integer null);
|
|
706
|
+
insert into t_perrow_bad values (1, -3);
|
|
707
|
+
-- run
|
|
708
|
+
|
|
709
|
+
alter table t_perrow_bad add column w integer null default (new.v) check (w > 0);
|
|
710
|
+
-- error: CHECK
|
|
711
|
+
|
|
712
|
+
select * from t_perrow_bad;
|
|
713
|
+
→ [{"id":1,"v":-3}]
|
|
714
|
+
|
|
715
|
+
select count(*) as c from check_constraint_info('t_perrow_bad');
|
|
716
|
+
→ [{"c":0}]
|
|
717
|
+
|
|
718
|
+
-- writes still work over the original shape
|
|
719
|
+
insert into t_perrow_bad values (2, 5);
|
|
720
|
+
select count(*) as c from t_perrow_bad;
|
|
721
|
+
→ [{"c":2}]
|
|
722
|
+
|
|
723
|
+
drop table t_perrow_bad;
|
|
724
|
+
-- run
|
|
725
|
+
|
|
726
|
+
-- ===================================
|
|
727
|
+
-- 8. `DEFAULT null` is not a value source
|
|
728
|
+
--
|
|
729
|
+
-- Quereus resolves mandatoriness from the session `default_column_nullability`
|
|
730
|
+
-- (shipped as `not_null`), so a column declared without `null` is NOT NULL even when
|
|
731
|
+
-- the statement text says nothing. A DEFAULT that folds to NULL supplies no value for
|
|
732
|
+
-- the rows that already exist, so the pair is refused on a non-empty table — the same
|
|
733
|
+
-- answer both storage modules give, since the gate asks "is there a value?" and not
|
|
734
|
+
-- "which kind of DEFAULT was written?".
|
|
735
|
+
-- ===================================
|
|
736
|
+
|
|
737
|
+
-- 8a. Mandatory-by-session-option + `default null` over rows → refused.
|
|
738
|
+
create table t_dn (id integer primary key, name text null);
|
|
739
|
+
insert into t_dn values (1, 'a');
|
|
740
|
+
-- run
|
|
741
|
+
|
|
742
|
+
alter table t_dn add column extra text default null;
|
|
743
|
+
-- error: NOT NULL
|
|
744
|
+
|
|
745
|
+
-- The ALTER did not half-apply: the column is absent and writes still work.
|
|
746
|
+
select count(*) as c from table_info('t_dn') where name = 'extra';
|
|
747
|
+
→ [{"c":0}]
|
|
748
|
+
|
|
749
|
+
insert into t_dn values (2, 'b');
|
|
750
|
+
select count(*) as c from t_dn;
|
|
751
|
+
→ [{"c":2}]
|
|
752
|
+
|
|
753
|
+
drop table t_dn;
|
|
754
|
+
-- run
|
|
755
|
+
|
|
756
|
+
-- 8b. Parenthesized `default (null)` is refused identically — the gate is value-based.
|
|
757
|
+
create table t_dn2 (id integer primary key);
|
|
758
|
+
insert into t_dn2 values (1);
|
|
759
|
+
-- run
|
|
760
|
+
|
|
761
|
+
alter table t_dn2 add column extra text default (null);
|
|
762
|
+
-- error: NOT NULL
|
|
763
|
+
|
|
764
|
+
select count(*) as c from table_info('t_dn2') where name = 'extra';
|
|
765
|
+
→ [{"c":0}]
|
|
766
|
+
|
|
767
|
+
drop table t_dn2;
|
|
768
|
+
-- run
|
|
769
|
+
|
|
770
|
+
-- 8c. Spelled nullable, the same DEFAULT is legal: NULL is a value the column admits.
|
|
771
|
+
create table t_dn3 (id integer primary key, name text null);
|
|
772
|
+
insert into t_dn3 values (1, 'a');
|
|
773
|
+
-- run
|
|
774
|
+
|
|
775
|
+
alter table t_dn3 add column extra text null default null;
|
|
776
|
+
-- run
|
|
777
|
+
|
|
778
|
+
select id, extra from t_dn3 order by id;
|
|
779
|
+
→ [{"id":1,"extra":null}]
|
|
780
|
+
|
|
781
|
+
-- and later inserts over the original column list still work
|
|
782
|
+
insert into t_dn3 (id, name) values (2, 'b');
|
|
783
|
+
select id, name, extra from t_dn3 order by id;
|
|
784
|
+
→ [{"id":1,"name":"a","extra":null},{"id":2,"name":"b","extra":null}]
|
|
785
|
+
|
|
786
|
+
drop table t_dn3;
|
|
787
|
+
-- run
|
|
788
|
+
|
|
789
|
+
-- 8d. Empty table → nothing to backfill, so the mandatory column is admitted
|
|
790
|
+
-- (SQLite-compatible), and NOT NULL enforces forward from the first write.
|
|
791
|
+
create table t_dn4 (id integer primary key, name text null);
|
|
792
|
+
-- run
|
|
793
|
+
|
|
794
|
+
alter table t_dn4 add column extra text default null;
|
|
795
|
+
-- run
|
|
796
|
+
|
|
797
|
+
select count(*) as c from table_info('t_dn4') where name = 'extra' and notnull = 1;
|
|
798
|
+
→ [{"c":1}]
|
|
799
|
+
|
|
800
|
+
insert into t_dn4 (id, name) values (1, 'a');
|
|
801
|
+
-- error: NOT NULL
|
|
802
|
+
|
|
803
|
+
insert into t_dn4 values (2, 'b', 'x');
|
|
804
|
+
select id, extra from t_dn4 order by id;
|
|
805
|
+
→ [{"id":2,"extra":"x"}]
|
|
806
|
+
|
|
807
|
+
drop table t_dn4;
|
|
808
|
+
-- run
|
|
809
|
+
|
|
810
|
+
-- 8e. A bare mandatory add (no DEFAULT at all) over rows is refused the same way.
|
|
811
|
+
create table t_dn5 (id integer primary key);
|
|
812
|
+
insert into t_dn5 values (1);
|
|
813
|
+
-- run
|
|
814
|
+
|
|
815
|
+
alter table t_dn5 add column extra text;
|
|
816
|
+
-- error: NOT NULL
|
|
817
|
+
|
|
818
|
+
select count(*) as c from table_info('t_dn5') where name = 'extra';
|
|
819
|
+
→ [{"c":0}]
|
|
820
|
+
|
|
821
|
+
drop table t_dn5;
|
|
822
|
+
-- run
|
|
823
|
+
|
|
824
|
+
-- 8f. The inverse: with `default_column_nullability = 'nullable'` the same `default null`
|
|
825
|
+
-- add is LEGAL over rows, because the column is then optional — the gate resolves
|
|
826
|
+
-- mandatoriness rather than pattern-matching the DEFAULT. An explicit `not null` in the
|
|
827
|
+
-- same session is still refused, so the rule tracks the resolved column, not the pragma.
|
|
828
|
+
pragma default_column_nullability = 'nullable';
|
|
829
|
+
create table t_dn6 (id integer primary key, name text);
|
|
830
|
+
insert into t_dn6 values (1, 'a');
|
|
831
|
+
-- run
|
|
832
|
+
|
|
833
|
+
alter table t_dn6 add column extra text default null;
|
|
834
|
+
-- run
|
|
835
|
+
|
|
836
|
+
select id, extra from t_dn6 order by id;
|
|
837
|
+
→ [{"id":1,"extra":null}]
|
|
838
|
+
|
|
839
|
+
select count(*) as c from table_info('t_dn6') where name = 'extra' and notnull = 0;
|
|
840
|
+
→ [{"c":1}]
|
|
841
|
+
|
|
842
|
+
-- inserts that omit the (now optional) column keep working
|
|
843
|
+
insert into t_dn6 (id, name) values (2, 'b');
|
|
844
|
+
select count(*) as c from t_dn6;
|
|
845
|
+
→ [{"c":2}]
|
|
846
|
+
|
|
847
|
+
-- explicit `not null` under the same pragma is still refused, pre-mutation
|
|
848
|
+
alter table t_dn6 add column mandatory text not null default null;
|
|
849
|
+
-- error: NOT NULL
|
|
850
|
+
|
|
851
|
+
select count(*) as c from table_info('t_dn6') where name = 'mandatory';
|
|
852
|
+
→ [{"c":0}]
|
|
853
|
+
|
|
854
|
+
drop table t_dn6;
|
|
855
|
+
pragma default_column_nullability = 'not_null';
|