@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,1616 @@
|
|
|
1
|
+
-- 41.10.2-alter-drop-column-check-and-assertion.sqllogic
|
|
2
|
+
--
|
|
3
|
+
-- Subject: `ALTER TABLE … DROP COLUMN` vs. the three EXPRESSION dependents that used to
|
|
4
|
+
-- survive the drop verbatim — a CHECK constraint on the same table, an assertion whose
|
|
5
|
+
-- CHECK body names the column, and a sibling column's DEFAULT (§15-18).
|
|
6
|
+
--
|
|
7
|
+
-- DROP COLUMN's dependents split in two. A STRUCTURAL dependent (a UNIQUE over the
|
|
8
|
+
-- column, the table's own FK using it as a child column — §41.10 and §41.10.1) is
|
|
9
|
+
-- defined by a column set, so losing a column makes it a DIFFERENT constraint and the
|
|
10
|
+
-- engine removes it with the column. An EXPRESSION dependent is arbitrary user logic
|
|
11
|
+
-- with no narrowed form at all, so the engine REFUSES the drop: that is what the
|
|
12
|
+
-- generated-column and partial-index guards already did, and these two now join them.
|
|
13
|
+
--
|
|
14
|
+
-- Left unguarded, both dependents fail much later — while a WRITE statement is being
|
|
15
|
+
-- planned, before any row is touched. The CHECK arm makes its own table unwritable;
|
|
16
|
+
-- the assertion arm makes the WHOLE DATABASE unwritable, because the assertion
|
|
17
|
+
-- evaluator recompiles every live assertion on any commit that touched any table, so
|
|
18
|
+
-- one unresolvable body blocks writes to tables that have nothing to do with the
|
|
19
|
+
-- altered one. §6 asserts exactly that: an unrelated table stays writable.
|
|
20
|
+
--
|
|
21
|
+
-- Detection is scope-aware, not a bare name match: a CHECK expression and an assertion
|
|
22
|
+
-- body may both contain subqueries, so a depth-blind walk would false-refuse a legal
|
|
23
|
+
-- drop whose only same-named column lives on ANOTHER table. §4 and §7 pin that.
|
|
24
|
+
--
|
|
25
|
+
-- Detection also follows VIEW and MATERIALIZED VIEW bodies, to any depth — the assertion
|
|
26
|
+
-- arm in §23, the CHECK / DEFAULT / generated arm in §26-§29 — because a rule that reads
|
|
27
|
+
-- the column through a view breaks just as thoroughly as one that names it. §30 re-pins
|
|
28
|
+
-- the scope controls one hop deeper, since that is where a name-collecting walk would
|
|
29
|
+
-- quietly turn a missed refusal into a false one.
|
|
30
|
+
--
|
|
31
|
+
-- Detection follows column REPUBLICATION too (§31-§36): a view whose `select *` /
|
|
32
|
+
-- `select t.*` re-exposes the column spells its name nowhere, so each body is probed
|
|
33
|
+
-- against every republication target of the dropped column, not the base table alone
|
|
34
|
+
-- (schema/column-republication.ts — the same lineage RENAME COLUMN's cascade re-targets
|
|
35
|
+
-- on). §35 is the one place drop and rename diverge: an explicit column list stops the
|
|
36
|
+
-- rename cascade (published names are pinned) but breaks OUTRIGHT under the drop (the
|
|
37
|
+
-- star's arity changes), so it refuses on being named at all. §36 guards the false-refusal
|
|
38
|
+
-- direction, including the view-aware column-source resolver's fix of §29's old wrong answer.
|
|
39
|
+
--
|
|
40
|
+
-- No `-- requires-capability:` directive: the file uses no standalone index DDL, so it
|
|
41
|
+
-- runs under both the memory module (`yarn test`) and the store module
|
|
42
|
+
-- (`yarn test:store`). The store leg matters — it persists table DDL, so a CHECK broken
|
|
43
|
+
-- by an unguarded drop would survive a reopen.
|
|
44
|
+
|
|
45
|
+
-- ===================================================================
|
|
46
|
+
-- 1. A NAMED CHECK naming the dropped column refuses the drop, and the
|
|
47
|
+
-- table is left completely untouched (the guard runs before the module).
|
|
48
|
+
-- ===================================================================
|
|
49
|
+
|
|
50
|
+
create table DcChk (id integer primary key, a integer, b integer, constraint chk_ab check (b > a));
|
|
51
|
+
insert into DcChk values (1, 1, 2);
|
|
52
|
+
-- run
|
|
53
|
+
|
|
54
|
+
alter table DcChk drop column a;
|
|
55
|
+
-- error: chk_ab
|
|
56
|
+
|
|
57
|
+
-- Untouched: the column is still there and still holds its value...
|
|
58
|
+
select a, b from DcChk;
|
|
59
|
+
→ [{"a":1,"b":2}]
|
|
60
|
+
|
|
61
|
+
-- ...and the CHECK still enforces, so nothing was half-applied.
|
|
62
|
+
insert into DcChk values (2, 5, 4);
|
|
63
|
+
-- error: chk_ab
|
|
64
|
+
|
|
65
|
+
insert into DcChk values (3, 5, 9);
|
|
66
|
+
select count(*) as c from DcChk;
|
|
67
|
+
→ [{"c":2}]
|
|
68
|
+
|
|
69
|
+
drop table DcChk;
|
|
70
|
+
-- run
|
|
71
|
+
|
|
72
|
+
-- ===================================================================
|
|
73
|
+
-- 2. An UNNAMED table-level CHECK has no name to quote, so the message
|
|
74
|
+
-- quotes its expression instead — the only handle the user has on it.
|
|
75
|
+
-- ===================================================================
|
|
76
|
+
--
|
|
77
|
+
-- Accepted cost: `DROP CONSTRAINT` resolves by name only, so this column is undroppable
|
|
78
|
+
-- short of rebuilding the table. Same position SQLite takes.
|
|
79
|
+
|
|
80
|
+
create table DcAnon (id integer primary key, a integer, b integer, check (b > a));
|
|
81
|
+
-- run
|
|
82
|
+
|
|
83
|
+
alter table DcAnon drop column a;
|
|
84
|
+
-- error: it is referenced by the CHECK constraint (b > a)
|
|
85
|
+
|
|
86
|
+
drop table DcAnon;
|
|
87
|
+
-- run
|
|
88
|
+
|
|
89
|
+
-- ===================================================================
|
|
90
|
+
-- 2b. A COLUMN-LEVEL unnamed CHECK is auto-named `_check_<column>` at
|
|
91
|
+
-- declaration time, so unlike §2 it DOES have a name to address.
|
|
92
|
+
-- ===================================================================
|
|
93
|
+
--
|
|
94
|
+
-- The asymmetry with §2 is deliberate and worth pinning: `constraint-builder.ts` names a
|
|
95
|
+
-- column-level CHECK `_check_<column>` when it lifts it to the table's constraint list,
|
|
96
|
+
-- and that name is stored, so the refusal quotes it and `DROP CONSTRAINT` can resolve it.
|
|
97
|
+
-- A column's OWN inline CHECK is refused like any other — the guard does not special-case
|
|
98
|
+
-- "this CHECK only exists because of the column being dropped".
|
|
99
|
+
|
|
100
|
+
create table DcCol (id integer primary key, a integer check (a > 0), b integer);
|
|
101
|
+
insert into DcCol values (1, 5, 6);
|
|
102
|
+
-- run
|
|
103
|
+
|
|
104
|
+
alter table DcCol drop column a;
|
|
105
|
+
-- error: CHECK constraint '_check_a'
|
|
106
|
+
|
|
107
|
+
-- Still enforcing, so nothing was half-applied.
|
|
108
|
+
insert into DcCol values (2, -1, 6);
|
|
109
|
+
-- error: _check_a
|
|
110
|
+
|
|
111
|
+
alter table DcCol drop constraint _check_a;
|
|
112
|
+
alter table DcCol drop column a;
|
|
113
|
+
select b from DcCol;
|
|
114
|
+
→ [{"b":6}]
|
|
115
|
+
|
|
116
|
+
drop table DcCol;
|
|
117
|
+
-- run
|
|
118
|
+
|
|
119
|
+
-- ===================================================================
|
|
120
|
+
-- 3. A CHECK that does NOT name the dropped column is no obstacle, and
|
|
121
|
+
-- still enforces over its own column afterwards.
|
|
122
|
+
-- ===================================================================
|
|
123
|
+
|
|
124
|
+
create table DcOther (id integer primary key, a integer, b integer, constraint chk_b check (b > 0));
|
|
125
|
+
insert into DcOther values (1, 7, 3);
|
|
126
|
+
alter table DcOther drop column a;
|
|
127
|
+
select b from DcOther;
|
|
128
|
+
→ [{"b":3}]
|
|
129
|
+
|
|
130
|
+
insert into DcOther values (2, -1);
|
|
131
|
+
-- error: chk_b
|
|
132
|
+
|
|
133
|
+
insert into DcOther values (3, 4);
|
|
134
|
+
select count(*) as c from DcOther;
|
|
135
|
+
→ [{"c":2}]
|
|
136
|
+
|
|
137
|
+
drop table DcOther;
|
|
138
|
+
-- run
|
|
139
|
+
|
|
140
|
+
-- ===================================================================
|
|
141
|
+
-- 4. A CHECK whose only match for the dropped name sits inside a SUBQUERY
|
|
142
|
+
-- over ANOTHER table must NOT block the drop.
|
|
143
|
+
-- ===================================================================
|
|
144
|
+
--
|
|
145
|
+
-- The `v` inside the subquery binds to `DcSrc.v`, not to the dropped `DcSub.v`. A
|
|
146
|
+
-- depth-blind walk sees the bare name and false-refuses.
|
|
147
|
+
|
|
148
|
+
create table DcSrc (uid integer primary key, v integer);
|
|
149
|
+
insert into DcSrc values (1, 5);
|
|
150
|
+
create table DcSub (id integer primary key, v integer, w integer, check ((select min(v) from DcSrc) >= 0));
|
|
151
|
+
insert into DcSub values (1, 2, 3);
|
|
152
|
+
-- run
|
|
153
|
+
|
|
154
|
+
alter table DcSub drop column v;
|
|
155
|
+
select w from DcSub;
|
|
156
|
+
→ [{"w":3}]
|
|
157
|
+
|
|
158
|
+
-- Still writable, and the surviving CHECK still evaluates against DcSrc.
|
|
159
|
+
insert into DcSub values (2, 9);
|
|
160
|
+
select count(*) as c from DcSub;
|
|
161
|
+
→ [{"c":2}]
|
|
162
|
+
|
|
163
|
+
drop table DcSub;
|
|
164
|
+
drop table DcSrc;
|
|
165
|
+
-- run
|
|
166
|
+
|
|
167
|
+
-- ===================================================================
|
|
168
|
+
-- 5. Escape hatch for a NAMED CHECK: drop the constraint, then the column.
|
|
169
|
+
-- ===================================================================
|
|
170
|
+
|
|
171
|
+
create table DcEsc (id integer primary key, a integer, b integer, constraint chk_esc check (b > a));
|
|
172
|
+
insert into DcEsc values (1, 1, 2);
|
|
173
|
+
-- run
|
|
174
|
+
|
|
175
|
+
alter table DcEsc drop column a;
|
|
176
|
+
-- error: chk_esc
|
|
177
|
+
|
|
178
|
+
alter table DcEsc drop constraint chk_esc;
|
|
179
|
+
alter table DcEsc drop column a;
|
|
180
|
+
select b from DcEsc;
|
|
181
|
+
→ [{"b":2}]
|
|
182
|
+
|
|
183
|
+
-- Nothing constrains the surviving column any more.
|
|
184
|
+
insert into DcEsc values (2, -5);
|
|
185
|
+
select count(*) as c from DcEsc;
|
|
186
|
+
→ [{"c":2}]
|
|
187
|
+
|
|
188
|
+
drop table DcEsc;
|
|
189
|
+
-- run
|
|
190
|
+
|
|
191
|
+
-- ===================================================================
|
|
192
|
+
-- 6. An ASSERTION whose body names the column refuses the drop — and an
|
|
193
|
+
-- UNRELATED table stays writable, which is the damage this prevents.
|
|
194
|
+
-- ===================================================================
|
|
195
|
+
|
|
196
|
+
create table DcAsrt (id integer primary key, x integer, y integer);
|
|
197
|
+
create table DcBystander (id integer primary key);
|
|
198
|
+
insert into DcAsrt values (1, 4, 5);
|
|
199
|
+
commit;
|
|
200
|
+
-- run
|
|
201
|
+
|
|
202
|
+
create assertion dc_nonneg check (not exists (select 1 from DcAsrt where x < 0));
|
|
203
|
+
-- run
|
|
204
|
+
|
|
205
|
+
alter table DcAsrt drop column x;
|
|
206
|
+
-- error: dc_nonneg
|
|
207
|
+
|
|
208
|
+
-- The column survived, so the assertion still compiles and every write still commits —
|
|
209
|
+
-- including a write to a table that never appears in the assertion body. Unguarded, the
|
|
210
|
+
-- drop would have made THIS insert fail with `Column not found: x`.
|
|
211
|
+
insert into DcBystander values (1);
|
|
212
|
+
commit;
|
|
213
|
+
select count(*) as c from DcBystander;
|
|
214
|
+
→ [{"c":1}]
|
|
215
|
+
|
|
216
|
+
-- The assertion still does its job on the altered table.
|
|
217
|
+
insert into DcAsrt values (2, -1, 0);
|
|
218
|
+
commit;
|
|
219
|
+
-- error: dc_nonneg
|
|
220
|
+
|
|
221
|
+
-- ===================================================================
|
|
222
|
+
-- 7. An assertion body that names the TABLE but not the dropped column is
|
|
223
|
+
-- no obstacle — including a `select *` body, which names no column at all.
|
|
224
|
+
-- ===================================================================
|
|
225
|
+
|
|
226
|
+
alter table DcAsrt drop column y;
|
|
227
|
+
select x from DcAsrt where id = 1;
|
|
228
|
+
→ [{"x":4}]
|
|
229
|
+
|
|
230
|
+
create table DcStar (id integer primary key, p integer, q integer);
|
|
231
|
+
create assertion dc_star check (not exists (select * from DcStar where id < 0));
|
|
232
|
+
-- run
|
|
233
|
+
|
|
234
|
+
alter table DcStar drop column p;
|
|
235
|
+
insert into DcStar values (1, 8);
|
|
236
|
+
commit;
|
|
237
|
+
select q from DcStar;
|
|
238
|
+
→ [{"q":8}]
|
|
239
|
+
|
|
240
|
+
-- ...and a body whose only match for the name sits on a DIFFERENT table, the assertion
|
|
241
|
+
-- mirror of §4. `z` in the body is DcZb.z, so DcZa.z drops freely.
|
|
242
|
+
create table DcZa (id integer primary key, z integer);
|
|
243
|
+
create table DcZb (id integer primary key, z integer);
|
|
244
|
+
create assertion dc_z check (not exists (select 1 from DcZb where z < 0));
|
|
245
|
+
-- run
|
|
246
|
+
|
|
247
|
+
alter table DcZa drop column z;
|
|
248
|
+
commit;
|
|
249
|
+
select count(*) as c from DcZa;
|
|
250
|
+
→ [{"c":0}]
|
|
251
|
+
|
|
252
|
+
drop assertion dc_z;
|
|
253
|
+
drop table DcZa;
|
|
254
|
+
drop table DcZb;
|
|
255
|
+
drop assertion dc_star;
|
|
256
|
+
drop table DcStar;
|
|
257
|
+
-- run
|
|
258
|
+
|
|
259
|
+
-- ===================================================================
|
|
260
|
+
-- 8. Escape hatch for an assertion: drop the assertion, then the column.
|
|
261
|
+
-- ===================================================================
|
|
262
|
+
|
|
263
|
+
drop assertion dc_nonneg;
|
|
264
|
+
alter table DcAsrt drop column x;
|
|
265
|
+
-- run
|
|
266
|
+
|
|
267
|
+
select id from DcAsrt;
|
|
268
|
+
→ [{"id":1}]
|
|
269
|
+
|
|
270
|
+
drop table DcAsrt;
|
|
271
|
+
drop table DcBystander;
|
|
272
|
+
-- run
|
|
273
|
+
|
|
274
|
+
-- ===================================================================
|
|
275
|
+
-- 9. Spelling does not matter: a case-only variant and a table-qualified
|
|
276
|
+
-- reference both block the drop.
|
|
277
|
+
-- ===================================================================
|
|
278
|
+
|
|
279
|
+
create table DcCase (id integer primary key, a integer, b integer, check (B > A));
|
|
280
|
+
-- run
|
|
281
|
+
|
|
282
|
+
alter table DcCase drop column a;
|
|
283
|
+
-- error: it is referenced by the CHECK constraint (B > A)
|
|
284
|
+
|
|
285
|
+
drop table DcCase;
|
|
286
|
+
-- run
|
|
287
|
+
|
|
288
|
+
create table DcQual (id integer primary key, a integer, b integer, check (DcQual.b > DcQual.a));
|
|
289
|
+
-- run
|
|
290
|
+
|
|
291
|
+
alter table DcQual drop column a;
|
|
292
|
+
-- error: it is referenced by the CHECK constraint
|
|
293
|
+
|
|
294
|
+
drop table DcQual;
|
|
295
|
+
-- run
|
|
296
|
+
|
|
297
|
+
create table DcQAsrt (id integer primary key, x integer, y integer);
|
|
298
|
+
create assertion dc_qual check (not exists (select 1 from DcQAsrt where DcQAsrt.x < 0));
|
|
299
|
+
-- run
|
|
300
|
+
|
|
301
|
+
alter table DcQAsrt drop column x;
|
|
302
|
+
-- error: dc_qual
|
|
303
|
+
|
|
304
|
+
drop assertion dc_qual;
|
|
305
|
+
drop table DcQAsrt;
|
|
306
|
+
-- run
|
|
307
|
+
|
|
308
|
+
-- ===================================================================
|
|
309
|
+
-- 10. Both dependents at once: the CHECK message wins, because the CHECK
|
|
310
|
+
-- guard runs first — widening blast radius, most local violation first.
|
|
311
|
+
-- ===================================================================
|
|
312
|
+
|
|
313
|
+
create table DcBoth (id integer primary key, a integer, b integer, constraint chk_both check (b > a));
|
|
314
|
+
-- run
|
|
315
|
+
|
|
316
|
+
create assertion dc_both check (not exists (select 1 from DcBoth where a < 0));
|
|
317
|
+
-- run
|
|
318
|
+
|
|
319
|
+
alter table DcBoth drop column a;
|
|
320
|
+
-- error: chk_both
|
|
321
|
+
|
|
322
|
+
drop assertion dc_both;
|
|
323
|
+
drop table DcBoth;
|
|
324
|
+
-- run
|
|
325
|
+
|
|
326
|
+
-- ===================================================================
|
|
327
|
+
-- 11. The two PRE-EXISTING expression guards are unchanged by the new ones,
|
|
328
|
+
-- and a table with no CHECKs at all still drops cleanly.
|
|
329
|
+
-- ===================================================================
|
|
330
|
+
--
|
|
331
|
+
-- The generated-column guard is checked ahead of the CHECK guard, so its message is the
|
|
332
|
+
-- one reported even though the CHECK also names the column. The partial-index guard is
|
|
333
|
+
-- NOT exercised here: declaring a partial index needs `create index … where`, which
|
|
334
|
+
-- would force a `requires-capability: standalone-index-ddl` directive and take this file
|
|
335
|
+
-- out of the store leg — the leg that matters most for a persisted CHECK. It has no
|
|
336
|
+
-- sqllogic coverage anywhere else either.
|
|
337
|
+
|
|
338
|
+
create table DcGen (id integer primary key, a integer, g integer generated always as (a + 1), constraint chk_gen check (a > 0));
|
|
339
|
+
-- run
|
|
340
|
+
|
|
341
|
+
alter table DcGen drop column a;
|
|
342
|
+
-- error: generated column 'g'
|
|
343
|
+
|
|
344
|
+
drop table DcGen;
|
|
345
|
+
-- run
|
|
346
|
+
|
|
347
|
+
create table DcBare (id integer primary key, a integer, b integer);
|
|
348
|
+
insert into DcBare values (1, 1, 2);
|
|
349
|
+
alter table DcBare drop column a;
|
|
350
|
+
select b from DcBare;
|
|
351
|
+
→ [{"b":2}]
|
|
352
|
+
|
|
353
|
+
drop table DcBare;
|
|
354
|
+
-- run
|
|
355
|
+
|
|
356
|
+
-- ===================================================================
|
|
357
|
+
-- 12. A CHECK naming the column through a ROW-IMAGE qualifier —
|
|
358
|
+
-- `new.<col>` / `old.<col>` — refuses the drop like any other.
|
|
359
|
+
-- ===================================================================
|
|
360
|
+
--
|
|
361
|
+
-- `new.<col>` / `old.<col>` name the row being written explicitly; an unqualified
|
|
362
|
+
-- column in a CHECK means the same thing implicitly (docs/sql-ddl.md § CHECK
|
|
363
|
+
-- Constraints). The two spellings must refuse identically, or the qualified one
|
|
364
|
+
-- silently buys an unwritable table: the drop is accepted and every subsequent write
|
|
365
|
+
-- then fails while being planned, with `new.a isn't a column`.
|
|
366
|
+
--
|
|
367
|
+
-- The walk decides this the same way RENAME COLUMN decides what to rewrite, so §26–§27
|
|
368
|
+
-- of 41.3-alter-rename-propagation are the other half of the same guarantee.
|
|
369
|
+
|
|
370
|
+
create table DcNew (id integer primary key, a integer, b integer, constraint chk_new check (new.a > 0));
|
|
371
|
+
insert into DcNew values (1, 5, 6);
|
|
372
|
+
-- run
|
|
373
|
+
|
|
374
|
+
alter table DcNew drop column a;
|
|
375
|
+
-- error: CHECK constraint 'chk_new'
|
|
376
|
+
|
|
377
|
+
-- Untouched, exactly as §1 asserts for the unqualified spelling.
|
|
378
|
+
select a, b from DcNew;
|
|
379
|
+
→ [{"a":5,"b":6}]
|
|
380
|
+
|
|
381
|
+
insert into DcNew values (2, -1, 6);
|
|
382
|
+
-- error: chk_new
|
|
383
|
+
|
|
384
|
+
drop table DcNew;
|
|
385
|
+
-- run
|
|
386
|
+
|
|
387
|
+
-- A DELETE-only CHECK names the OLD row image; same refusal.
|
|
388
|
+
create table DcOld (id integer primary key, a integer, b integer, constraint chk_old check on delete (old.a > 0));
|
|
389
|
+
insert into DcOld values (1, 5, 6);
|
|
390
|
+
insert into DcOld values (2, -1, 7);
|
|
391
|
+
-- run
|
|
392
|
+
|
|
393
|
+
alter table DcOld drop column a;
|
|
394
|
+
-- error: CHECK constraint 'chk_old'
|
|
395
|
+
|
|
396
|
+
-- Still enforcing over the OLD row, so nothing was half-applied.
|
|
397
|
+
delete from DcOld where id = 2;
|
|
398
|
+
-- error: chk_old
|
|
399
|
+
|
|
400
|
+
delete from DcOld where id = 1;
|
|
401
|
+
select count(*) as c from DcOld;
|
|
402
|
+
→ [{"c":1}]
|
|
403
|
+
|
|
404
|
+
drop table DcOld;
|
|
405
|
+
-- run
|
|
406
|
+
|
|
407
|
+
-- Case folds like every other identifier in the engine.
|
|
408
|
+
create table DcNewCase (id integer primary key, a integer, b integer, constraint chk_case check (NEW.A > 0));
|
|
409
|
+
-- run
|
|
410
|
+
|
|
411
|
+
alter table DcNewCase drop column a;
|
|
412
|
+
-- error: CHECK constraint 'chk_case'
|
|
413
|
+
|
|
414
|
+
drop table DcNewCase;
|
|
415
|
+
-- run
|
|
416
|
+
|
|
417
|
+
-- ===================================================================
|
|
418
|
+
-- 13. `new` and `old` are NOT reserved words here, so the row-image match is
|
|
419
|
+
-- scope-aware: a subquery over a real table named "new" is not a row image.
|
|
420
|
+
-- ===================================================================
|
|
421
|
+
--
|
|
422
|
+
-- `create table "new" (…)` is legal, so `"new".a` inside a CHECK subquery binds to that
|
|
423
|
+
-- table's column, not to the written row. A depth-blind `qualifier === 'new'` match would
|
|
424
|
+
-- false-refuse this drop — the row-image mirror of §4.
|
|
425
|
+
|
|
426
|
+
create table "new" (a integer primary key);
|
|
427
|
+
insert into "new" values (3);
|
|
428
|
+
create table DcShadow (id integer primary key, a integer, b integer, check ((select max("new".a) from "new") >= 0));
|
|
429
|
+
insert into DcShadow values (1, 2, 3);
|
|
430
|
+
-- run
|
|
431
|
+
|
|
432
|
+
alter table DcShadow drop column a;
|
|
433
|
+
select b from DcShadow;
|
|
434
|
+
→ [{"b":3}]
|
|
435
|
+
|
|
436
|
+
-- Still writable, and the surviving CHECK still evaluates against the "new" table.
|
|
437
|
+
insert into DcShadow values (2, 9);
|
|
438
|
+
select count(*) as c from DcShadow;
|
|
439
|
+
→ [{"c":2}]
|
|
440
|
+
|
|
441
|
+
drop table DcShadow;
|
|
442
|
+
drop table "new";
|
|
443
|
+
-- run
|
|
444
|
+
|
|
445
|
+
-- ===================================================================
|
|
446
|
+
-- 14. The same scope-awareness for a `new` rebound by an ALIAS or by a CTE name
|
|
447
|
+
-- ===================================================================
|
|
448
|
+
--
|
|
449
|
+
-- §13 covers the rebind-by-unaliased-source shape only; a FROM source can bind the name
|
|
450
|
+
-- by alias or by `with` clause too, and neither is a row image. Both drops must be
|
|
451
|
+
-- ALLOWED. Refusal half of §28 in 41.3-alter-rename-propagation.
|
|
452
|
+
|
|
453
|
+
create table UcAlias (k integer primary key, a integer);
|
|
454
|
+
create table DcAlias (id integer primary key, a integer, b integer,
|
|
455
|
+
check ((select max("new".a) from UcAlias as "new") >= 0));
|
|
456
|
+
insert into DcAlias values (1, 2, 3);
|
|
457
|
+
-- run
|
|
458
|
+
|
|
459
|
+
alter table DcAlias drop column a;
|
|
460
|
+
select b from DcAlias;
|
|
461
|
+
→ [{"b":3}]
|
|
462
|
+
|
|
463
|
+
drop table DcAlias;
|
|
464
|
+
drop table UcAlias;
|
|
465
|
+
-- run
|
|
466
|
+
|
|
467
|
+
create table DcCte (id integer primary key, a integer, b integer,
|
|
468
|
+
check ((with "new" as (select 1 as a) select max("new".a) from "new") >= 0));
|
|
469
|
+
insert into DcCte values (1, 2, 3);
|
|
470
|
+
-- run
|
|
471
|
+
|
|
472
|
+
alter table DcCte drop column a;
|
|
473
|
+
select b from DcCte;
|
|
474
|
+
→ [{"b":3}]
|
|
475
|
+
|
|
476
|
+
drop table DcCte;
|
|
477
|
+
-- run
|
|
478
|
+
|
|
479
|
+
-- ===================================================================
|
|
480
|
+
-- 15. A sibling column's DEFAULT naming the dropped column refuses the drop
|
|
481
|
+
-- ===================================================================
|
|
482
|
+
--
|
|
483
|
+
-- A DEFAULT is a third EXPRESSION dependent and gets the same policy as the two above.
|
|
484
|
+
-- Left unguarded the drop succeeded and the table could then accept NO new row at all:
|
|
485
|
+
-- every insert failed at plan time with "new.a isn't a column". The guard runs FIRST of
|
|
486
|
+
-- the four — ordered by widening blast radius, and a DEFAULT names a column of the very
|
|
487
|
+
-- table being altered, the narrowest end.
|
|
488
|
+
--
|
|
489
|
+
-- The message names the column whose DEFAULT is in the way, the handle the user needs.
|
|
490
|
+
-- Forward half of §29 in 41.3-alter-rename-propagation.
|
|
491
|
+
|
|
492
|
+
create table DcDef (id integer primary key, a integer, b integer default (new.a + 1));
|
|
493
|
+
insert into DcDef (id, a) values (1, 5);
|
|
494
|
+
-- run
|
|
495
|
+
|
|
496
|
+
alter table DcDef drop column a;
|
|
497
|
+
-- error: it is referenced by the DEFAULT of column 'b'
|
|
498
|
+
|
|
499
|
+
-- Untouched: the column is still there, still holds its value...
|
|
500
|
+
select id, a, b from DcDef;
|
|
501
|
+
→ [{"id":1,"a":5,"b":6}]
|
|
502
|
+
|
|
503
|
+
-- ...and the DEFAULT still computes, so nothing was half-applied.
|
|
504
|
+
insert into DcDef (id, a) values (2, 9);
|
|
505
|
+
select id, b from DcDef where id = 2;
|
|
506
|
+
→ [{"id":2,"b":10}]
|
|
507
|
+
|
|
508
|
+
drop table DcDef;
|
|
509
|
+
-- run
|
|
510
|
+
|
|
511
|
+
-- ===================================================================
|
|
512
|
+
-- 16. Dropping the column that OWNS a self-naming DEFAULT is still allowed
|
|
513
|
+
-- ===================================================================
|
|
514
|
+
--
|
|
515
|
+
-- A column's own DEFAULT goes away with the column, so there is nothing for the drop to
|
|
516
|
+
-- orphan. Refusing here would turn away a legal drop; the guard skips the dropped
|
|
517
|
+
-- column's own default for exactly that reason.
|
|
518
|
+
|
|
519
|
+
create table DcDefSelf (id integer primary key, a integer default (new.id + 1), b integer);
|
|
520
|
+
insert into DcDefSelf (id, b) values (1, 7);
|
|
521
|
+
-- run
|
|
522
|
+
|
|
523
|
+
alter table DcDefSelf drop column a;
|
|
524
|
+
select id, b from DcDefSelf;
|
|
525
|
+
→ [{"id":1,"b":7}]
|
|
526
|
+
|
|
527
|
+
-- Still writable afterwards.
|
|
528
|
+
insert into DcDefSelf (id, b) values (2, 8);
|
|
529
|
+
select count(*) as c from DcDefSelf;
|
|
530
|
+
→ [{"c":2}]
|
|
531
|
+
|
|
532
|
+
drop table DcDefSelf;
|
|
533
|
+
-- run
|
|
534
|
+
|
|
535
|
+
-- ===================================================================
|
|
536
|
+
-- 17. A DEFAULT whose only match sits inside a SUBQUERY over ANOTHER table
|
|
537
|
+
-- is no obstacle — the same scope-awareness §4 pins for a CHECK
|
|
538
|
+
-- ===================================================================
|
|
539
|
+
--
|
|
540
|
+
-- The inner `v` binds to `UcDef.v`, not to this table's own `v`, so a depth-blind name
|
|
541
|
+
-- match would false-refuse a legal drop. Sharing the probe with the rename walk is what
|
|
542
|
+
-- keeps the two definitions of "names the column" identical.
|
|
543
|
+
|
|
544
|
+
create table UcDef (k integer primary key, v integer);
|
|
545
|
+
insert into UcDef values (1, 11);
|
|
546
|
+
-- run
|
|
547
|
+
|
|
548
|
+
create table DcDefSub (id integer primary key, v integer,
|
|
549
|
+
w integer default ((select min(v) from UcDef)));
|
|
550
|
+
insert into DcDefSub (id, v) values (1, 2);
|
|
551
|
+
-- run
|
|
552
|
+
|
|
553
|
+
alter table DcDefSub drop column v;
|
|
554
|
+
select id, w from DcDefSub;
|
|
555
|
+
→ [{"id":1,"w":11}]
|
|
556
|
+
|
|
557
|
+
-- Still writable, and the surviving DEFAULT still reads UcDef.
|
|
558
|
+
insert into DcDefSub (id) values (2);
|
|
559
|
+
select id, w from DcDefSub where id = 2;
|
|
560
|
+
→ [{"id":2,"w":11}]
|
|
561
|
+
|
|
562
|
+
drop table DcDefSub;
|
|
563
|
+
drop table UcDef;
|
|
564
|
+
-- run
|
|
565
|
+
|
|
566
|
+
-- ===================================================================
|
|
567
|
+
-- 18. A `new` rebound by an inner FROM inside a DEFAULT does not block the drop
|
|
568
|
+
-- ===================================================================
|
|
569
|
+
--
|
|
570
|
+
-- Mirror of §13 for the DEFAULT arm: `"new".a` there names the real table `"new"`, not
|
|
571
|
+
-- this table's row image, so dropping this table's own like-named column is legal.
|
|
572
|
+
|
|
573
|
+
create table "new" (a integer primary key);
|
|
574
|
+
insert into "new" values (3);
|
|
575
|
+
-- run
|
|
576
|
+
|
|
577
|
+
create table DcDefShadow (id integer primary key, a integer,
|
|
578
|
+
b integer default ((select max("new".a) from "new")));
|
|
579
|
+
insert into DcDefShadow (id, a) values (1, 7);
|
|
580
|
+
-- run
|
|
581
|
+
|
|
582
|
+
alter table DcDefShadow drop column a;
|
|
583
|
+
select id, b from DcDefShadow;
|
|
584
|
+
→ [{"id":1,"b":3}]
|
|
585
|
+
|
|
586
|
+
drop table DcDefShadow;
|
|
587
|
+
drop table "new";
|
|
588
|
+
-- run
|
|
589
|
+
|
|
590
|
+
-- ===================================================================
|
|
591
|
+
-- 19. A CHECK on ANOTHER table, reading this column through a subquery,
|
|
592
|
+
-- refuses the drop — and the message names that other table
|
|
593
|
+
-- ===================================================================
|
|
594
|
+
--
|
|
595
|
+
-- §1–§18 all keep the dependent on the altered table. But a CHECK may contain a
|
|
596
|
+
-- subquery, so another table's constraint can legitimately read this one; RENAME COLUMN
|
|
597
|
+
-- has always rewritten exactly those, across every table in every schema, while the DROP
|
|
598
|
+
-- guard used to scan the altered table alone. The drop was accepted and the OTHER table
|
|
599
|
+
-- became unwritable, with `Column not found: v` naming neither this table, nor the
|
|
600
|
+
-- dropped column, nor the constraint that broke.
|
|
601
|
+
--
|
|
602
|
+
-- The message has to name the referencing table: it is the one handle the user has on a
|
|
603
|
+
-- statement that mentions only the altered one.
|
|
604
|
+
|
|
605
|
+
create table DcXsrc (id integer primary key, v integer);
|
|
606
|
+
insert into DcXsrc values (1, 10);
|
|
607
|
+
create table DcXref (id integer primary key, n integer,
|
|
608
|
+
constraint ck_xref check (n < (select max(v) from DcXsrc)));
|
|
609
|
+
-- run
|
|
610
|
+
|
|
611
|
+
alter table DcXsrc drop column v;
|
|
612
|
+
-- error: CHECK constraint 'ck_xref' on table 'DcXref'
|
|
613
|
+
|
|
614
|
+
-- Untouched, so the referencing table is still writable — the damage this prevents.
|
|
615
|
+
insert into DcXref values (1, 1);
|
|
616
|
+
select n from DcXref;
|
|
617
|
+
→ [{"n":1}]
|
|
618
|
+
|
|
619
|
+
-- ...and the CHECK still enforces against DcXsrc.
|
|
620
|
+
insert into DcXref values (2, 99);
|
|
621
|
+
-- error: ck_xref
|
|
622
|
+
|
|
623
|
+
-- Escape hatch, same shape as §5: drop the constraint, then the column.
|
|
624
|
+
alter table DcXref drop constraint ck_xref;
|
|
625
|
+
alter table DcXsrc drop column v;
|
|
626
|
+
select id from DcXsrc;
|
|
627
|
+
→ [{"id":1}]
|
|
628
|
+
|
|
629
|
+
drop table DcXref;
|
|
630
|
+
drop table DcXsrc;
|
|
631
|
+
-- run
|
|
632
|
+
|
|
633
|
+
-- ===================================================================
|
|
634
|
+
-- 20. Same for a DEFAULT and a GENERATED body on another table
|
|
635
|
+
-- ===================================================================
|
|
636
|
+
--
|
|
637
|
+
-- Both are column-level expressions and reach this column the only way they can — through
|
|
638
|
+
-- a subquery — so both get the DEFAULT guard's message plus the owning table's name.
|
|
639
|
+
|
|
640
|
+
create table DcDsrc (id integer primary key, v integer);
|
|
641
|
+
insert into DcDsrc values (1, 11);
|
|
642
|
+
create table DcDref (id integer primary key, w integer default ((select min(v) from DcDsrc)));
|
|
643
|
+
-- run
|
|
644
|
+
|
|
645
|
+
alter table DcDsrc drop column v;
|
|
646
|
+
-- error: the DEFAULT of column 'w' on table 'DcDref'
|
|
647
|
+
|
|
648
|
+
-- Still writable, and the DEFAULT still reads DcDsrc.
|
|
649
|
+
insert into DcDref (id) values (1);
|
|
650
|
+
select id, w from DcDref;
|
|
651
|
+
→ [{"id":1,"w":11}]
|
|
652
|
+
|
|
653
|
+
drop table DcDref;
|
|
654
|
+
drop table DcDsrc;
|
|
655
|
+
-- run
|
|
656
|
+
|
|
657
|
+
-- A generated body must qualify its subquery's column (`DcGsrc.v`) — an unqualified name
|
|
658
|
+
-- there is resolved against the OWNING table at declaration time and rejected outright.
|
|
659
|
+
create table DcGsrc (id integer primary key, v integer);
|
|
660
|
+
insert into DcGsrc values (1, 12);
|
|
661
|
+
create table DcGref (id integer primary key,
|
|
662
|
+
g integer generated always as ((select max(DcGsrc.v) from DcGsrc)));
|
|
663
|
+
insert into DcGref (id) values (1);
|
|
664
|
+
-- run
|
|
665
|
+
|
|
666
|
+
alter table DcGsrc drop column v;
|
|
667
|
+
-- error: the GENERATED expression of column 'g' on table 'DcGref'
|
|
668
|
+
|
|
669
|
+
select id, g from DcGref;
|
|
670
|
+
→ [{"id":1,"g":12}]
|
|
671
|
+
|
|
672
|
+
drop table DcGref;
|
|
673
|
+
drop table DcGsrc;
|
|
674
|
+
-- run
|
|
675
|
+
|
|
676
|
+
-- ===================================================================
|
|
677
|
+
-- 21. A like-named column on a THIRD table does not block the drop
|
|
678
|
+
-- ===================================================================
|
|
679
|
+
--
|
|
680
|
+
-- The other-table mirror of §4: the scan is scope-aware in both directions, so widening
|
|
681
|
+
-- it to every table must not start refusing drops whose only name match belongs to a
|
|
682
|
+
-- table nobody mentioned. `v` in DcNref's CHECK binds DcNoise.v.
|
|
683
|
+
|
|
684
|
+
create table DcNsrc (id integer primary key, v integer);
|
|
685
|
+
create table DcNoise (k integer primary key, v integer);
|
|
686
|
+
create table DcNref (id integer primary key, n integer, check ((select min(v) from DcNoise) >= 0));
|
|
687
|
+
insert into DcNsrc values (1, 5);
|
|
688
|
+
-- run
|
|
689
|
+
|
|
690
|
+
alter table DcNsrc drop column v;
|
|
691
|
+
select id from DcNsrc;
|
|
692
|
+
→ [{"id":1}]
|
|
693
|
+
|
|
694
|
+
drop table DcNref;
|
|
695
|
+
drop table DcNoise;
|
|
696
|
+
drop table DcNsrc;
|
|
697
|
+
-- run
|
|
698
|
+
|
|
699
|
+
-- The commonest false-refusal shape: another table simply HAS a column of the same name
|
|
700
|
+
-- and constrains its own, bare or self-qualified. Neither is a reference to this one.
|
|
701
|
+
create table DcOwn (id integer primary key, v integer);
|
|
702
|
+
create table DcOwnBare (id integer primary key, v integer, check (v > 0));
|
|
703
|
+
create table DcOwnQual (id integer primary key, v integer, check (DcOwnQual.v > 0));
|
|
704
|
+
insert into DcOwn values (1, 4);
|
|
705
|
+
-- run
|
|
706
|
+
|
|
707
|
+
alter table DcOwn drop column v;
|
|
708
|
+
select id from DcOwn;
|
|
709
|
+
→ [{"id":1}]
|
|
710
|
+
|
|
711
|
+
-- The other tables' own constraints are untouched and still enforcing.
|
|
712
|
+
insert into DcOwnBare values (1, -1);
|
|
713
|
+
-- error: CHECK constraint failed
|
|
714
|
+
|
|
715
|
+
insert into DcOwnQual values (1, -1);
|
|
716
|
+
-- error: CHECK constraint failed
|
|
717
|
+
|
|
718
|
+
drop table DcOwnQual;
|
|
719
|
+
drop table DcOwnBare;
|
|
720
|
+
drop table DcOwn;
|
|
721
|
+
-- run
|
|
722
|
+
|
|
723
|
+
-- ===================================================================
|
|
724
|
+
-- 22. Cross-schema: what decides a match is whether the reference RESOLVES
|
|
725
|
+
-- to the altered table, not whether the bare names collide
|
|
726
|
+
-- ===================================================================
|
|
727
|
+
--
|
|
728
|
+
-- Same rule §48–§49 of 41.3-alter-rename-propagation pin for the rename: a CHECK in
|
|
729
|
+
-- `temp` naming `main.DcCs` explicitly IS a reference, while a bare name in `temp` that
|
|
730
|
+
-- `temp` itself holds is not.
|
|
731
|
+
|
|
732
|
+
create table main.DcCs (id integer primary key, v integer);
|
|
733
|
+
create table temp.DcCsRef (id integer primary key, n integer,
|
|
734
|
+
constraint ck_cs check (n < (select max(v) from main.DcCs)));
|
|
735
|
+
-- run
|
|
736
|
+
|
|
737
|
+
alter table main.DcCs drop column v;
|
|
738
|
+
-- error: CHECK constraint 'ck_cs' on table 'temp.DcCsRef'
|
|
739
|
+
|
|
740
|
+
drop table temp.DcCsRef;
|
|
741
|
+
drop table main.DcCs;
|
|
742
|
+
-- run
|
|
743
|
+
|
|
744
|
+
create table main.DcDup (id integer primary key, v integer);
|
|
745
|
+
create table temp.DcDup (id integer primary key, v integer);
|
|
746
|
+
-- The CHECK's home is temp, so its bare `DcDup` binds temp.DcDup.
|
|
747
|
+
create table temp.DcDupRef (id integer primary key, n integer,
|
|
748
|
+
check (n < (select max(v) from DcDup)));
|
|
749
|
+
insert into main.DcDup values (1, 7);
|
|
750
|
+
-- run
|
|
751
|
+
|
|
752
|
+
alter table main.DcDup drop column v;
|
|
753
|
+
select id from main.DcDup;
|
|
754
|
+
→ [{"id":1}]
|
|
755
|
+
|
|
756
|
+
drop table temp.DcDupRef;
|
|
757
|
+
drop table temp.DcDup;
|
|
758
|
+
drop table main.DcDup;
|
|
759
|
+
-- run
|
|
760
|
+
|
|
761
|
+
-- ===================================================================
|
|
762
|
+
-- 23. An assertion reaches the column THROUGH a view
|
|
763
|
+
-- ===================================================================
|
|
764
|
+
--
|
|
765
|
+
-- The assertion body names a view; the VIEW's body names the column. Dropping the
|
|
766
|
+
-- column used to be accepted and then made every write to the whole database fail —
|
|
767
|
+
-- the assertion evaluator recompiles every live assertion on any commit.
|
|
768
|
+
--
|
|
769
|
+
-- No column lineage through the view's projection is built, and none is needed: the
|
|
770
|
+
-- match is on the view's own body. If no body in the chain named the column, the
|
|
771
|
+
-- assertion could not have been reading it.
|
|
772
|
+
|
|
773
|
+
create table DcVw (id integer primary key, x integer);
|
|
774
|
+
create view DcVwV as select id, x from DcVw;
|
|
775
|
+
create table DcVwBystander (id integer primary key);
|
|
776
|
+
create assertion dc_vw check (not exists (select 1 from DcVwV where x < 0));
|
|
777
|
+
-- run
|
|
778
|
+
|
|
779
|
+
-- The message names the chain — an assertion whose body does not mention `x` is
|
|
780
|
+
-- unactionable advice without it.
|
|
781
|
+
alter table DcVw drop column x;
|
|
782
|
+
-- error: it is referenced by assertion 'dc_vw' through view 'DcVwV'
|
|
783
|
+
|
|
784
|
+
-- Clean no-op: the unrelated table is still writable, which is exactly what the
|
|
785
|
+
-- missed refusal used to break.
|
|
786
|
+
insert into DcVwBystander values (1);
|
|
787
|
+
commit;
|
|
788
|
+
select count(*) as c from DcVwBystander;
|
|
789
|
+
→ [{"c":1}]
|
|
790
|
+
|
|
791
|
+
drop assertion dc_vw;
|
|
792
|
+
alter table DcVw drop column x;
|
|
793
|
+
drop view DcVwV;
|
|
794
|
+
drop table DcVw;
|
|
795
|
+
drop table DcVwBystander;
|
|
796
|
+
-- run
|
|
797
|
+
|
|
798
|
+
-- Three levels deep — one-hop expansion is the natural under-fix.
|
|
799
|
+
create table DcCh (id integer primary key, x integer);
|
|
800
|
+
create view DcCh1 as select id, x from DcCh;
|
|
801
|
+
create view DcCh2 as select id, x from DcCh1;
|
|
802
|
+
create assertion dc_ch check (not exists (select 1 from DcCh2 where x < 0));
|
|
803
|
+
-- run
|
|
804
|
+
|
|
805
|
+
alter table DcCh drop column x;
|
|
806
|
+
-- error: it is referenced by assertion 'dc_ch' through view 'DcCh2' -> view 'DcCh1'
|
|
807
|
+
|
|
808
|
+
drop assertion dc_ch;
|
|
809
|
+
drop view DcCh2;
|
|
810
|
+
drop view DcCh1;
|
|
811
|
+
drop table DcCh;
|
|
812
|
+
-- run
|
|
813
|
+
|
|
814
|
+
-- A view in the chain that names the TABLE but not the column is no obstacle,
|
|
815
|
+
-- exactly as a direct `select *` body is not (§7).
|
|
816
|
+
create table DcVwStar (id integer primary key, p integer, q integer);
|
|
817
|
+
create view DcVwStarV as select id, q from DcVwStar;
|
|
818
|
+
create assertion dc_vw_star check (not exists (select 1 from DcVwStarV where q < 0));
|
|
819
|
+
-- run
|
|
820
|
+
|
|
821
|
+
alter table DcVwStar drop column p;
|
|
822
|
+
insert into DcVwStar values (1, 8);
|
|
823
|
+
commit;
|
|
824
|
+
select q from DcVwStar;
|
|
825
|
+
→ [{"q":8}]
|
|
826
|
+
|
|
827
|
+
drop assertion dc_vw_star;
|
|
828
|
+
drop view DcVwStarV;
|
|
829
|
+
drop table DcVwStar;
|
|
830
|
+
-- run
|
|
831
|
+
|
|
832
|
+
-- ===================================================================
|
|
833
|
+
-- 24. The assertion guard consults assertions in EVERY schema
|
|
834
|
+
-- ===================================================================
|
|
835
|
+
--
|
|
836
|
+
-- Same rule §22 pins for CHECK constraints: what decides a match is whether the
|
|
837
|
+
-- reference RESOLVES to the altered table, not which schema the rule lives in. The
|
|
838
|
+
-- refusal qualifies the assertion so the user can find the thing to drop.
|
|
839
|
+
|
|
840
|
+
create table main.DcXs (id integer primary key, v integer);
|
|
841
|
+
create assertion temp.dc_xs check (not exists (select 1 from main.DcXs where v < 0));
|
|
842
|
+
-- run
|
|
843
|
+
|
|
844
|
+
alter table main.DcXs drop column v;
|
|
845
|
+
-- error: it is referenced by assertion 'temp.dc_xs'
|
|
846
|
+
|
|
847
|
+
drop assertion temp.dc_xs;
|
|
848
|
+
alter table main.DcXs drop column v;
|
|
849
|
+
drop table main.DcXs;
|
|
850
|
+
-- run
|
|
851
|
+
|
|
852
|
+
-- ...and a bare name in `temp` that `temp` itself holds is not a reference to main's.
|
|
853
|
+
create table main.DcXsDup (id integer primary key, v integer);
|
|
854
|
+
create table temp.DcXsDup (id integer primary key, v integer);
|
|
855
|
+
create assertion temp.dc_xs_dup check (not exists (select 1 from DcXsDup where v < 0));
|
|
856
|
+
insert into main.DcXsDup values (1, 7);
|
|
857
|
+
-- run
|
|
858
|
+
|
|
859
|
+
alter table main.DcXsDup drop column v;
|
|
860
|
+
select id from main.DcXsDup;
|
|
861
|
+
→ [{"id":1}]
|
|
862
|
+
|
|
863
|
+
drop assertion temp.dc_xs_dup;
|
|
864
|
+
drop table temp.DcXsDup;
|
|
865
|
+
drop table main.DcXsDup;
|
|
866
|
+
-- run
|
|
867
|
+
|
|
868
|
+
-- The two widenings composed: a `temp` assertion reaching a `main` column through a
|
|
869
|
+
-- `main` view. Only the composition proves the column probe runs each reached body
|
|
870
|
+
-- under that body's OWN home schema rather than the root assertion's — the view's
|
|
871
|
+
-- bare `DcXv` must bind main's even though the assertion lives in temp.
|
|
872
|
+
create table main.DcXv (id integer primary key, v integer);
|
|
873
|
+
create view main.DcXvV as select id, v from DcXv;
|
|
874
|
+
create assertion temp.dc_xv check (not exists (select 1 from main.DcXvV where v < 0));
|
|
875
|
+
-- run
|
|
876
|
+
|
|
877
|
+
alter table main.DcXv drop column v;
|
|
878
|
+
-- error: it is referenced by assertion 'temp.dc_xv' through view 'DcXvV'
|
|
879
|
+
|
|
880
|
+
drop assertion temp.dc_xv;
|
|
881
|
+
drop view main.DcXvV;
|
|
882
|
+
drop table main.DcXv;
|
|
883
|
+
-- run
|
|
884
|
+
|
|
885
|
+
-- ===================================================================
|
|
886
|
+
-- 25. A merely SHADOWED name in the reach is still not a reference
|
|
887
|
+
-- ===================================================================
|
|
888
|
+
--
|
|
889
|
+
-- The closure walks every body it reaches with the same scope-aware probe, so a
|
|
890
|
+
-- `with DcSh as (…)` that shadows the name binds the CTE, not the real table. This is
|
|
891
|
+
-- the property a collect-everything walk would silently lose, turning a missed
|
|
892
|
+
-- refusal into a false one.
|
|
893
|
+
|
|
894
|
+
create table DcSh (id integer primary key, x integer);
|
|
895
|
+
create table DcShSrc (id integer primary key, x integer);
|
|
896
|
+
create assertion dc_sh check (not exists (
|
|
897
|
+
with DcSh as (select id, x from DcShSrc) select 1 from DcSh where x < 0));
|
|
898
|
+
-- run
|
|
899
|
+
|
|
900
|
+
alter table DcSh drop column x;
|
|
901
|
+
select id from DcSh;
|
|
902
|
+
→ []
|
|
903
|
+
|
|
904
|
+
-- ...and the table the CTE actually reads IS still protected.
|
|
905
|
+
alter table DcShSrc drop column x;
|
|
906
|
+
-- error: it is referenced by assertion 'dc_sh'
|
|
907
|
+
|
|
908
|
+
drop assertion dc_sh;
|
|
909
|
+
drop table DcShSrc;
|
|
910
|
+
drop table DcSh;
|
|
911
|
+
-- run
|
|
912
|
+
|
|
913
|
+
-- ===================================================================
|
|
914
|
+
-- 26. A CHECK on another table reaches the column THROUGH a view
|
|
915
|
+
-- ===================================================================
|
|
916
|
+
--
|
|
917
|
+
-- §19's shape with a view in the middle. The referencing CHECK never spells `DcRv` at
|
|
918
|
+
-- all — it reads a view whose body does — and dropping the column used to be accepted,
|
|
919
|
+
-- leaving DcRvRef unwritable with an error naming neither the column nor the constraint.
|
|
920
|
+
--
|
|
921
|
+
-- No column lineage through the view's projection is needed here, exactly as in §23: the
|
|
922
|
+
-- match is on the VIEW's body. If no body in the chain named the column, the CHECK could
|
|
923
|
+
-- not have been reading it.
|
|
924
|
+
|
|
925
|
+
create table DcRv (id integer primary key, v integer);
|
|
926
|
+
insert into DcRv values (1, 10);
|
|
927
|
+
create view DcRvV as select id, v from DcRv;
|
|
928
|
+
create table DcRvRef (id integer primary key, n integer,
|
|
929
|
+
constraint ck_dcrv check (n < (select max(DcRvV.v) from DcRvV)));
|
|
930
|
+
-- run
|
|
931
|
+
|
|
932
|
+
-- The message names the chain — a constraint whose body does not mention `v` is
|
|
933
|
+
-- unactionable advice without it. Same spelling the assertion arm uses in §23.
|
|
934
|
+
alter table DcRv drop column v;
|
|
935
|
+
-- error: Cannot drop column 'v' from 'DcRv': CHECK constraint 'ck_dcrv' on table 'DcRvRef' reaches it through view 'DcRvV'
|
|
936
|
+
|
|
937
|
+
-- Nothing was applied: the column is still there, and the CHECK still enforces.
|
|
938
|
+
select v from DcRv;
|
|
939
|
+
→ [{"v":10}]
|
|
940
|
+
|
|
941
|
+
insert into DcRvRef values (1, 99);
|
|
942
|
+
-- error: ck_dcrv
|
|
943
|
+
|
|
944
|
+
-- Escape hatch, same as §19: drop the constraint, then the column.
|
|
945
|
+
alter table DcRvRef drop constraint ck_dcrv;
|
|
946
|
+
alter table DcRv drop column v;
|
|
947
|
+
select id from DcRv;
|
|
948
|
+
→ [{"id":1}]
|
|
949
|
+
|
|
950
|
+
drop table DcRvRef;
|
|
951
|
+
drop view DcRvV;
|
|
952
|
+
drop table DcRv;
|
|
953
|
+
-- run
|
|
954
|
+
|
|
955
|
+
-- Three levels deep, and the whole path is rendered.
|
|
956
|
+
create table DcCv (id integer primary key, v integer);
|
|
957
|
+
create view DcCv1 as select id, v from DcCv;
|
|
958
|
+
create view DcCv2 as select id, v from DcCv1;
|
|
959
|
+
create table DcCvRef (id integer primary key, n integer,
|
|
960
|
+
constraint ck_dccv check (n < (select max(DcCv2.v) from DcCv2)));
|
|
961
|
+
-- run
|
|
962
|
+
|
|
963
|
+
alter table DcCv drop column v;
|
|
964
|
+
-- error: CHECK constraint 'ck_dccv' on table 'DcCvRef' reaches it through view 'DcCv2' -> view 'DcCv1'
|
|
965
|
+
|
|
966
|
+
alter table DcCvRef drop constraint ck_dccv;
|
|
967
|
+
drop view DcCv2;
|
|
968
|
+
drop view DcCv1;
|
|
969
|
+
drop table DcCv;
|
|
970
|
+
drop table DcCvRef;
|
|
971
|
+
-- run
|
|
972
|
+
|
|
973
|
+
-- A view in the chain that names the TABLE but not the COLUMN is no obstacle, exactly as
|
|
974
|
+
-- a direct `select id, q` body is not (§7, §23). The TABLE verb has no such hole — it
|
|
975
|
+
-- matches the object, not a column — which is 41.10.4 §10's business, not this file's.
|
|
976
|
+
create table DcVs (id integer primary key, p integer, q integer);
|
|
977
|
+
create view DcVsV as select id, q from DcVs;
|
|
978
|
+
create table DcVsRef (id integer primary key, n integer,
|
|
979
|
+
check (n < (select max(DcVsV.q) from DcVsV)));
|
|
980
|
+
insert into DcVs values (1, 3, 8);
|
|
981
|
+
-- run
|
|
982
|
+
|
|
983
|
+
alter table DcVs drop column p;
|
|
984
|
+
select q from DcVs;
|
|
985
|
+
→ [{"q":8}]
|
|
986
|
+
|
|
987
|
+
drop table DcVsRef;
|
|
988
|
+
drop view DcVsV;
|
|
989
|
+
drop table DcVs;
|
|
990
|
+
-- run
|
|
991
|
+
|
|
992
|
+
-- ===================================================================
|
|
993
|
+
-- 27. A materialized view in the chain reads as one
|
|
994
|
+
-- ===================================================================
|
|
995
|
+
|
|
996
|
+
create table DcMv (id integer primary key, v integer);
|
|
997
|
+
insert into DcMv values (1, 6);
|
|
998
|
+
create materialized view DcMvM as select id, v from DcMv;
|
|
999
|
+
create table DcMvRef (id integer primary key, n integer,
|
|
1000
|
+
constraint ck_dcmv check (n < (select max(DcMvM.v) from DcMvM)));
|
|
1001
|
+
-- run
|
|
1002
|
+
|
|
1003
|
+
alter table DcMv drop column v;
|
|
1004
|
+
-- error: CHECK constraint 'ck_dcmv' on table 'DcMvRef' reaches it through materialized view 'DcMvM'
|
|
1005
|
+
|
|
1006
|
+
alter table DcMvRef drop constraint ck_dcmv;
|
|
1007
|
+
drop materialized view DcMvM;
|
|
1008
|
+
drop table DcMv;
|
|
1009
|
+
drop table DcMvRef;
|
|
1010
|
+
-- run
|
|
1011
|
+
|
|
1012
|
+
-- ===================================================================
|
|
1013
|
+
-- 28. DEFAULT and GENERATED bodies follow chains too
|
|
1014
|
+
-- ===================================================================
|
|
1015
|
+
--
|
|
1016
|
+
-- §20's shapes one view deeper. All three arms run the same probe, so widening one
|
|
1017
|
+
-- without the others would let two guards over the same DDL disagree.
|
|
1018
|
+
|
|
1019
|
+
create table DcDv (id integer primary key, v integer);
|
|
1020
|
+
insert into DcDv values (1, 11);
|
|
1021
|
+
create view DcDvV as select id, v from DcDv;
|
|
1022
|
+
create table DcDvRef (id integer primary key, w integer default ((select min(DcDvV.v) from DcDvV)));
|
|
1023
|
+
-- run
|
|
1024
|
+
|
|
1025
|
+
alter table DcDv drop column v;
|
|
1026
|
+
-- error: the DEFAULT of column 'w' on table 'DcDvRef' reaches it through view 'DcDvV'
|
|
1027
|
+
|
|
1028
|
+
insert into DcDvRef (id) values (1);
|
|
1029
|
+
select id, w from DcDvRef;
|
|
1030
|
+
→ [{"id":1,"w":11}]
|
|
1031
|
+
|
|
1032
|
+
drop table DcDvRef;
|
|
1033
|
+
drop view DcDvV;
|
|
1034
|
+
drop table DcDv;
|
|
1035
|
+
-- run
|
|
1036
|
+
|
|
1037
|
+
create table DcGv (id integer primary key, v integer);
|
|
1038
|
+
insert into DcGv values (1, 12);
|
|
1039
|
+
create view DcGvV as select id, v from DcGv;
|
|
1040
|
+
create table DcGvRef (id integer primary key,
|
|
1041
|
+
g integer generated always as ((select max(DcGvV.v) from DcGvV)));
|
|
1042
|
+
insert into DcGvRef (id) values (1);
|
|
1043
|
+
-- run
|
|
1044
|
+
|
|
1045
|
+
alter table DcGv drop column v;
|
|
1046
|
+
-- error: the GENERATED expression of column 'g' on table 'DcGvRef' reaches it through view 'DcGvV'
|
|
1047
|
+
|
|
1048
|
+
select id, g from DcGvRef;
|
|
1049
|
+
→ [{"id":1,"g":12}]
|
|
1050
|
+
|
|
1051
|
+
drop table DcGvRef;
|
|
1052
|
+
drop view DcGvV;
|
|
1053
|
+
drop table DcGv;
|
|
1054
|
+
-- run
|
|
1055
|
+
|
|
1056
|
+
-- ===================================================================
|
|
1057
|
+
-- 29. An OWN-table CHECK reaching its own column through a view
|
|
1058
|
+
-- ===================================================================
|
|
1059
|
+
--
|
|
1060
|
+
-- The seeded probe still applies to the CHECK's OWN body and to nothing below it: a view
|
|
1061
|
+
-- body is a relation with no written-row seed, so a reached body's unqualified names bind
|
|
1062
|
+
-- through its own FROM clauses.
|
|
1063
|
+
--
|
|
1064
|
+
-- Both spellings refuse. The QUALIFIED one (`DcOvV.v`) matches on the view's body, which
|
|
1065
|
+
-- names `DcOv.v`. The UNQUALIFIED one binds the view's own exposed `v` —
|
|
1066
|
+
-- `buildColumnSourceResolver` answers "does source X expose column `v`?" for a VIEW by
|
|
1067
|
+
-- reading its published columns — and refuses through the same view: the view is a
|
|
1068
|
+
-- REPUBLICATION target of the dropped column (schema/column-republication.ts), so a
|
|
1069
|
+
-- reference spelled against the view counts. What this scope-awareness buys is the
|
|
1070
|
+
-- other direction, pinned in §36: an unqualified `v` binding a view over ANOTHER table
|
|
1071
|
+
-- no longer false-refuses this table's drop.
|
|
1072
|
+
|
|
1073
|
+
create table DcOv (id integer primary key, v integer);
|
|
1074
|
+
create view DcOvV as select id, v from DcOv;
|
|
1075
|
+
-- run
|
|
1076
|
+
|
|
1077
|
+
alter table DcOv add constraint ck_dcov check (id < (select max(DcOvV.v) from DcOvV));
|
|
1078
|
+
-- run
|
|
1079
|
+
|
|
1080
|
+
alter table DcOv drop column v;
|
|
1081
|
+
-- error: Cannot drop column 'v' from 'DcOv': CHECK constraint 'ck_dcov' reaches it through view 'DcOvV'
|
|
1082
|
+
|
|
1083
|
+
alter table DcOv drop constraint ck_dcov;
|
|
1084
|
+
alter table DcOv add constraint ck_dcov2 check (id < (select max(v) from DcOvV));
|
|
1085
|
+
-- run
|
|
1086
|
+
|
|
1087
|
+
alter table DcOv drop column v;
|
|
1088
|
+
-- error: Cannot drop column 'v' from 'DcOv': CHECK constraint 'ck_dcov2' reaches it through view 'DcOvV'
|
|
1089
|
+
|
|
1090
|
+
alter table DcOv drop constraint ck_dcov2;
|
|
1091
|
+
alter table DcOv drop column v;
|
|
1092
|
+
select count(*) as c from DcOv;
|
|
1093
|
+
→ [{"c":0}]
|
|
1094
|
+
|
|
1095
|
+
drop view DcOvV;
|
|
1096
|
+
drop table DcOv;
|
|
1097
|
+
-- run
|
|
1098
|
+
|
|
1099
|
+
-- ===================================================================
|
|
1100
|
+
-- 30. The widening must not start false-refusing
|
|
1101
|
+
-- ===================================================================
|
|
1102
|
+
--
|
|
1103
|
+
-- §21 and §25 re-pinned one view deeper: the closure is scope-aware by construction, so
|
|
1104
|
+
-- adding hops must not turn a missed refusal into a false one.
|
|
1105
|
+
|
|
1106
|
+
-- §21's shape with a view in the way: `uv` re-exposes a LIKE-NAMED column of a THIRD
|
|
1107
|
+
-- table, so dropping this table's own `v` is still legal.
|
|
1108
|
+
create table DcPv (id integer primary key, v integer);
|
|
1109
|
+
create table DcPvNoise (k integer primary key, v integer);
|
|
1110
|
+
create view DcPvV as select k, v from DcPvNoise;
|
|
1111
|
+
create table DcPvRef (id integer primary key, n integer,
|
|
1112
|
+
check ((select min(DcPvV.v) from DcPvV) >= 0));
|
|
1113
|
+
insert into DcPv values (1, 5);
|
|
1114
|
+
-- run
|
|
1115
|
+
|
|
1116
|
+
alter table DcPv drop column v;
|
|
1117
|
+
select id from DcPv;
|
|
1118
|
+
→ [{"id":1}]
|
|
1119
|
+
|
|
1120
|
+
drop table DcPvRef;
|
|
1121
|
+
drop view DcPvV;
|
|
1122
|
+
drop table DcPvNoise;
|
|
1123
|
+
drop table DcPv;
|
|
1124
|
+
-- run
|
|
1125
|
+
|
|
1126
|
+
-- §25's shape one hop out of the assertion arm and into this one: a CTE inside the VIEW's
|
|
1127
|
+
-- body that merely SHADOWS the name binds the CTE, and the table it really reads IS
|
|
1128
|
+
-- protected.
|
|
1129
|
+
create table DcSv (id integer primary key, x integer);
|
|
1130
|
+
create table DcSvSrc (id integer primary key, x integer);
|
|
1131
|
+
create view DcSvV as with DcSv as (select id, x from DcSvSrc) select id, x from DcSv;
|
|
1132
|
+
create table DcSvRef (id integer primary key, n integer,
|
|
1133
|
+
check ((select min(DcSvV.x) from DcSvV) >= 0));
|
|
1134
|
+
-- run
|
|
1135
|
+
|
|
1136
|
+
alter table DcSv drop column x;
|
|
1137
|
+
select count(*) as c from DcSv;
|
|
1138
|
+
→ [{"c":0}]
|
|
1139
|
+
|
|
1140
|
+
alter table DcSvSrc drop column x;
|
|
1141
|
+
-- error: reaches it through view 'DcSvV'
|
|
1142
|
+
|
|
1143
|
+
drop table DcSvRef;
|
|
1144
|
+
drop view DcSvV;
|
|
1145
|
+
drop table DcSvSrc;
|
|
1146
|
+
drop table DcSv;
|
|
1147
|
+
-- run
|
|
1148
|
+
|
|
1149
|
+
-- §22's cross-schema rule composed with the chain: the view's bare `DcXvw` binds MAIN's
|
|
1150
|
+
-- because the VIEW lives in main, even though the CHECK that reaches it lives in temp.
|
|
1151
|
+
create table main.DcXvw (id integer primary key, v integer);
|
|
1152
|
+
create view main.DcXvwV as select id, v from DcXvw;
|
|
1153
|
+
create table temp.DcXvwRef (id integer primary key, n integer,
|
|
1154
|
+
constraint ck_dcxvw check (n < (select max(DcXvwV.v) from main.DcXvwV)));
|
|
1155
|
+
-- run
|
|
1156
|
+
|
|
1157
|
+
alter table main.DcXvw drop column v;
|
|
1158
|
+
-- error: CHECK constraint 'ck_dcxvw' on table 'temp.DcXvwRef' reaches it through view 'DcXvwV'
|
|
1159
|
+
|
|
1160
|
+
drop table temp.DcXvwRef;
|
|
1161
|
+
drop view main.DcXvwV;
|
|
1162
|
+
drop table main.DcXvw;
|
|
1163
|
+
-- run
|
|
1164
|
+
|
|
1165
|
+
-- ...and the other direction: a bare name inside a `temp` view body that `temp` itself
|
|
1166
|
+
-- holds says nothing about main's like-named table.
|
|
1167
|
+
create table main.DcXvd (id integer primary key, v integer);
|
|
1168
|
+
create table temp.DcXvd (id integer primary key, v integer);
|
|
1169
|
+
create view temp.DcXvdV as select id, v from DcXvd;
|
|
1170
|
+
create table temp.DcXvdRef (id integer primary key, n integer,
|
|
1171
|
+
check (n < (select max(DcXvdV.v) from DcXvdV)));
|
|
1172
|
+
insert into main.DcXvd values (1, 7);
|
|
1173
|
+
-- run
|
|
1174
|
+
|
|
1175
|
+
alter table main.DcXvd drop column v;
|
|
1176
|
+
select id from main.DcXvd;
|
|
1177
|
+
→ [{"id":1}]
|
|
1178
|
+
|
|
1179
|
+
drop table temp.DcXvdRef;
|
|
1180
|
+
drop view temp.DcXvdV;
|
|
1181
|
+
drop table temp.DcXvd;
|
|
1182
|
+
drop table main.DcXvd;
|
|
1183
|
+
-- run
|
|
1184
|
+
|
|
1185
|
+
-- ===================================================================
|
|
1186
|
+
-- 31. A view that re-exposes the column by a STAR blocks the drop
|
|
1187
|
+
-- ===================================================================
|
|
1188
|
+
--
|
|
1189
|
+
-- `create view v as select * from t` spells the column nowhere, so the name probe over
|
|
1190
|
+
-- the chain's bodies sees nothing — the hole that used to let this drop through, after
|
|
1191
|
+
-- which the assertion failed every write to the whole database with `Column not found`.
|
|
1192
|
+
-- The guard now probes every body against every REPUBLICATION target of the dropped
|
|
1193
|
+
-- column (schema/column-republication.ts — the same lineage the RENAME COLUMN cascade
|
|
1194
|
+
-- re-targets on), and the assertion's `where x < 0` references the column against the
|
|
1195
|
+
-- view, which IS such a target.
|
|
1196
|
+
|
|
1197
|
+
create table DcSt (id integer primary key, x integer);
|
|
1198
|
+
create table DcStBy (id integer primary key);
|
|
1199
|
+
create view DcStV as select * from DcSt;
|
|
1200
|
+
create assertion dc_st check (not exists (select 1 from DcStV where x < 0));
|
|
1201
|
+
-- run
|
|
1202
|
+
|
|
1203
|
+
alter table DcSt drop column x;
|
|
1204
|
+
-- error: it is referenced by assertion 'dc_st'
|
|
1205
|
+
|
|
1206
|
+
-- Clean no-op: the unrelated table is still writable — the whole-database blast radius
|
|
1207
|
+
-- this refusal exists to prevent.
|
|
1208
|
+
insert into DcStBy values (1);
|
|
1209
|
+
commit;
|
|
1210
|
+
select count(*) as c from DcStBy;
|
|
1211
|
+
→ [{"c":1}]
|
|
1212
|
+
|
|
1213
|
+
-- The assertion still does its job through the star.
|
|
1214
|
+
insert into DcSt values (1, -1);
|
|
1215
|
+
commit;
|
|
1216
|
+
-- error: dc_st
|
|
1217
|
+
|
|
1218
|
+
drop assertion dc_st;
|
|
1219
|
+
alter table DcSt drop column x;
|
|
1220
|
+
drop view DcStV;
|
|
1221
|
+
drop table DcSt;
|
|
1222
|
+
drop table DcStBy;
|
|
1223
|
+
-- run
|
|
1224
|
+
|
|
1225
|
+
-- The `select t.*` spelling re-exposes identically.
|
|
1226
|
+
create table DcSq (id integer primary key, x integer);
|
|
1227
|
+
create view DcSqV as select DcSq.* from DcSq;
|
|
1228
|
+
create assertion dc_sq check (not exists (select 1 from DcSqV where x < 0));
|
|
1229
|
+
-- run
|
|
1230
|
+
|
|
1231
|
+
alter table DcSq drop column x;
|
|
1232
|
+
-- error: it is referenced by assertion 'dc_sq'
|
|
1233
|
+
|
|
1234
|
+
drop assertion dc_sq;
|
|
1235
|
+
drop view DcSqV;
|
|
1236
|
+
drop table DcSq;
|
|
1237
|
+
-- run
|
|
1238
|
+
|
|
1239
|
+
-- ===================================================================
|
|
1240
|
+
-- 32. The same star hole on the CHECK / DEFAULT arm
|
|
1241
|
+
-- ===================================================================
|
|
1242
|
+
--
|
|
1243
|
+
-- Blast radius one table instead of the database, same lineage answer — both guard
|
|
1244
|
+
-- families consult the one republication fixpoint, so they cannot disagree.
|
|
1245
|
+
|
|
1246
|
+
create table DcSc (id integer primary key, x integer);
|
|
1247
|
+
create view DcScV as select * from DcSc;
|
|
1248
|
+
create table DcScRef (id integer primary key, n integer,
|
|
1249
|
+
constraint ck_dcsc check (n < (select max(DcScV.x) from DcScV)));
|
|
1250
|
+
-- run
|
|
1251
|
+
|
|
1252
|
+
alter table DcSc drop column x;
|
|
1253
|
+
-- error: CHECK constraint 'ck_dcsc' on table 'DcScRef'
|
|
1254
|
+
|
|
1255
|
+
-- The unqualified spelling binds the view's exposed column and refuses the same way.
|
|
1256
|
+
alter table DcScRef drop constraint ck_dcsc;
|
|
1257
|
+
alter table DcScRef add constraint ck_dcsc2 check (n < (select max(x) from DcScV));
|
|
1258
|
+
-- run
|
|
1259
|
+
|
|
1260
|
+
alter table DcSc drop column x;
|
|
1261
|
+
-- error: CHECK constraint 'ck_dcsc2' on table 'DcScRef'
|
|
1262
|
+
|
|
1263
|
+
alter table DcScRef drop constraint ck_dcsc2;
|
|
1264
|
+
alter table DcSc drop column x;
|
|
1265
|
+
select count(*) as c from DcSc;
|
|
1266
|
+
→ [{"c":0}]
|
|
1267
|
+
|
|
1268
|
+
drop table DcScRef;
|
|
1269
|
+
drop view DcScV;
|
|
1270
|
+
drop table DcSc;
|
|
1271
|
+
-- run
|
|
1272
|
+
|
|
1273
|
+
-- A DEFAULT reading through the star, same answer.
|
|
1274
|
+
create table DcSd (id integer primary key, x integer);
|
|
1275
|
+
create view DcSdV as select * from DcSd;
|
|
1276
|
+
create table DcSdRef (id integer primary key, w integer default ((select min(DcSdV.x) from DcSdV)));
|
|
1277
|
+
-- run
|
|
1278
|
+
|
|
1279
|
+
alter table DcSd drop column x;
|
|
1280
|
+
-- error: the DEFAULT of column 'w' on table 'DcSdRef'
|
|
1281
|
+
|
|
1282
|
+
drop table DcSdRef;
|
|
1283
|
+
drop view DcSdV;
|
|
1284
|
+
drop table DcSd;
|
|
1285
|
+
-- run
|
|
1286
|
+
|
|
1287
|
+
-- ===================================================================
|
|
1288
|
+
-- 33. A chain with the star at either position
|
|
1289
|
+
-- ===================================================================
|
|
1290
|
+
--
|
|
1291
|
+
-- Star at the BOTTOM: v2's body names the column against v1, and v1 is a republication
|
|
1292
|
+
-- target, so the match lands on v2's body and the message names it.
|
|
1293
|
+
|
|
1294
|
+
create table DcCb (id integer primary key, x integer);
|
|
1295
|
+
create view DcCb1 as select * from DcCb;
|
|
1296
|
+
create view DcCb2 as select id, x from DcCb1;
|
|
1297
|
+
create assertion dc_cb check (not exists (select 1 from DcCb2 where x < 0));
|
|
1298
|
+
-- run
|
|
1299
|
+
|
|
1300
|
+
alter table DcCb drop column x;
|
|
1301
|
+
-- error: it is referenced by assertion 'dc_cb' through view 'DcCb2'
|
|
1302
|
+
|
|
1303
|
+
drop assertion dc_cb;
|
|
1304
|
+
drop view DcCb2;
|
|
1305
|
+
drop view DcCb1;
|
|
1306
|
+
drop table DcCb;
|
|
1307
|
+
-- run
|
|
1308
|
+
|
|
1309
|
+
-- Star at the TOP (v1 names the column, v2 stars over v1): already refused before the
|
|
1310
|
+
-- widening, re-pinned so the whole path still renders.
|
|
1311
|
+
create table DcCt (id integer primary key, x integer);
|
|
1312
|
+
create view DcCt1 as select id, x from DcCt;
|
|
1313
|
+
create view DcCt2 as select * from DcCt1;
|
|
1314
|
+
create assertion dc_ct check (not exists (select 1 from DcCt2 where x < 0));
|
|
1315
|
+
-- run
|
|
1316
|
+
|
|
1317
|
+
alter table DcCt drop column x;
|
|
1318
|
+
-- error: it is referenced by assertion 'dc_ct' through view 'DcCt2' -> view 'DcCt1'
|
|
1319
|
+
|
|
1320
|
+
drop assertion dc_ct;
|
|
1321
|
+
drop view DcCt2;
|
|
1322
|
+
drop view DcCt1;
|
|
1323
|
+
drop table DcCt;
|
|
1324
|
+
-- run
|
|
1325
|
+
|
|
1326
|
+
-- ===================================================================
|
|
1327
|
+
-- 34. A MATERIALIZED VIEW star refuses too — deliberately conservative
|
|
1328
|
+
-- ===================================================================
|
|
1329
|
+
--
|
|
1330
|
+
-- An MV's backing table keeps its own columns, so the assertion would in fact have kept
|
|
1331
|
+
-- compiling and running against frozen contents (the MV goes stale and its next
|
|
1332
|
+
-- `refresh materialized view` would fail). Refusing anyway keeps ONE rule for both
|
|
1333
|
+
-- object kinds, matches the named-projection MV refusal §27 pins, and errs the same
|
|
1334
|
+
-- direction `DROP TABLE` does for the same object.
|
|
1335
|
+
|
|
1336
|
+
create table DcSm (id integer primary key, x integer);
|
|
1337
|
+
create materialized view DcSmM as select * from DcSm;
|
|
1338
|
+
create assertion dc_sm check (not exists (select 1 from DcSmM where x < 0));
|
|
1339
|
+
-- run
|
|
1340
|
+
|
|
1341
|
+
alter table DcSm drop column x;
|
|
1342
|
+
-- error: it is referenced by assertion 'dc_sm'
|
|
1343
|
+
|
|
1344
|
+
drop assertion dc_sm;
|
|
1345
|
+
alter table DcSm drop column x;
|
|
1346
|
+
drop materialized view DcSmM;
|
|
1347
|
+
drop table DcSm;
|
|
1348
|
+
-- run
|
|
1349
|
+
|
|
1350
|
+
-- ===================================================================
|
|
1351
|
+
-- 35. An EXPLICIT COLUMN LIST over a star breaks the whole view
|
|
1352
|
+
-- ===================================================================
|
|
1353
|
+
--
|
|
1354
|
+
-- `create view v(a, b) as select * from t` pins the published names, so no published
|
|
1355
|
+
-- name shifts — the rename cascade rightly ignores such a view. The drop must not: the
|
|
1356
|
+
-- lineage here is POSITIONAL, and dropping any starred-over column changes the body's
|
|
1357
|
+
-- arity, breaking the view outright — every reader of it, not one column. A rule whose
|
|
1358
|
+
-- reach names such a view at all refuses, and the message says the view breaks
|
|
1359
|
+
-- entirely rather than pointing at a column name no body spells.
|
|
1360
|
+
|
|
1361
|
+
create table DcSl (id integer primary key, x integer);
|
|
1362
|
+
create table DcSlBy (id integer primary key);
|
|
1363
|
+
create view DcSlV(a, b) as select * from DcSl;
|
|
1364
|
+
create assertion dc_sl check (not exists (select 1 from DcSlV where b < 0));
|
|
1365
|
+
-- run
|
|
1366
|
+
|
|
1367
|
+
alter table DcSl drop column x;
|
|
1368
|
+
-- error: dropping the column breaks it outright
|
|
1369
|
+
|
|
1370
|
+
insert into DcSlBy values (1);
|
|
1371
|
+
commit;
|
|
1372
|
+
select count(*) as c from DcSlBy;
|
|
1373
|
+
→ [{"c":1}]
|
|
1374
|
+
|
|
1375
|
+
drop assertion dc_sl;
|
|
1376
|
+
drop view DcSlV;
|
|
1377
|
+
drop table DcSl;
|
|
1378
|
+
drop table DcSlBy;
|
|
1379
|
+
-- run
|
|
1380
|
+
|
|
1381
|
+
-- The CHECK arm gets the same refusal from the same lineage.
|
|
1382
|
+
create table DcSl2 (id integer primary key, x integer);
|
|
1383
|
+
create view DcSl2V(a, b) as select * from DcSl2;
|
|
1384
|
+
create table DcSl2Ref (id integer primary key, n integer,
|
|
1385
|
+
constraint ck_dcsl2 check (n < (select max(b) from DcSl2V)));
|
|
1386
|
+
-- run
|
|
1387
|
+
|
|
1388
|
+
alter table DcSl2 drop column x;
|
|
1389
|
+
-- error: dropping the column breaks it outright
|
|
1390
|
+
|
|
1391
|
+
drop table DcSl2Ref;
|
|
1392
|
+
drop view DcSl2V;
|
|
1393
|
+
drop table DcSl2;
|
|
1394
|
+
-- run
|
|
1395
|
+
|
|
1396
|
+
-- Guard rail: an explicit column list over a body that does NOT star over the table
|
|
1397
|
+
-- pins nothing positional — dropping an unprojected column is still legal even while a
|
|
1398
|
+
-- rule reads the view.
|
|
1399
|
+
create table DcSl3 (id integer primary key, x integer);
|
|
1400
|
+
create view DcSl3V(a) as select id from DcSl3;
|
|
1401
|
+
create assertion dc_sl3 check (not exists (select 1 from DcSl3V where a < 0));
|
|
1402
|
+
-- run
|
|
1403
|
+
|
|
1404
|
+
alter table DcSl3 drop column x;
|
|
1405
|
+
select count(*) as c from DcSl3;
|
|
1406
|
+
→ [{"c":0}]
|
|
1407
|
+
|
|
1408
|
+
drop assertion dc_sl3;
|
|
1409
|
+
drop view DcSl3V;
|
|
1410
|
+
drop table DcSl3;
|
|
1411
|
+
-- run
|
|
1412
|
+
|
|
1413
|
+
-- ===================================================================
|
|
1414
|
+
-- 36. The widening must not start false-refusing
|
|
1415
|
+
-- ===================================================================
|
|
1416
|
+
--
|
|
1417
|
+
-- A star view republishes EVERY column of its source, but target-ness is per dropped
|
|
1418
|
+
-- column and the probe still matches names — a rule reading only a surviving column
|
|
1419
|
+
-- through the star is no obstacle.
|
|
1420
|
+
|
|
1421
|
+
create table DcSg (id integer primary key, x integer, y integer);
|
|
1422
|
+
create view DcSgV as select * from DcSg;
|
|
1423
|
+
create assertion dc_sg check (not exists (select 1 from DcSgV where y < 0));
|
|
1424
|
+
-- run
|
|
1425
|
+
|
|
1426
|
+
alter table DcSg drop column x;
|
|
1427
|
+
select count(*) as c from DcSg;
|
|
1428
|
+
→ [{"c":0}]
|
|
1429
|
+
|
|
1430
|
+
-- ...and the column the rule DOES read through the star still refuses.
|
|
1431
|
+
alter table DcSg drop column y;
|
|
1432
|
+
-- error: it is referenced by assertion 'dc_sg'
|
|
1433
|
+
|
|
1434
|
+
drop assertion dc_sg;
|
|
1435
|
+
drop view DcSgV;
|
|
1436
|
+
drop table DcSg;
|
|
1437
|
+
-- run
|
|
1438
|
+
|
|
1439
|
+
-- The view-aware column-source resolver also fixes the OPPOSITE direction — §29's old
|
|
1440
|
+
-- false refusal: an own-table CHECK whose unqualified `v` binds a view over ANOTHER
|
|
1441
|
+
-- table said nothing about this table's `v`, yet used to block its drop (the resolver
|
|
1442
|
+
-- looked the view up as a table, found no columns, and fell back to the owning-table
|
|
1443
|
+
-- seed). The reference resolves inside the subquery, so the drop is legal.
|
|
1444
|
+
|
|
1445
|
+
create table DcSg2 (id integer primary key, v integer);
|
|
1446
|
+
create table DcSg2u (id integer primary key, v integer);
|
|
1447
|
+
create view DcSg2uv as select v from DcSg2u;
|
|
1448
|
+
-- run
|
|
1449
|
+
|
|
1450
|
+
alter table DcSg2 add constraint ck_dcsg2 check (id < (select max(v) from DcSg2uv));
|
|
1451
|
+
-- run
|
|
1452
|
+
|
|
1453
|
+
alter table DcSg2 drop column v;
|
|
1454
|
+
select count(*) as c from DcSg2;
|
|
1455
|
+
→ [{"c":0}]
|
|
1456
|
+
|
|
1457
|
+
-- The constraint still enforces against the view over the other table.
|
|
1458
|
+
insert into DcSg2u values (1, 0);
|
|
1459
|
+
insert into DcSg2 values (5);
|
|
1460
|
+
-- error: ck_dcsg2
|
|
1461
|
+
|
|
1462
|
+
insert into DcSg2u values (2, 50);
|
|
1463
|
+
insert into DcSg2 values (5);
|
|
1464
|
+
select count(*) as c from DcSg2;
|
|
1465
|
+
→ [{"c":1}]
|
|
1466
|
+
|
|
1467
|
+
drop table DcSg2;
|
|
1468
|
+
drop view DcSg2uv;
|
|
1469
|
+
drop table DcSg2u;
|
|
1470
|
+
-- run
|
|
1471
|
+
|
|
1472
|
+
-- ===================================================================
|
|
1473
|
+
-- 37. ANOTHER table's row-image qualifier does not block dropping a column
|
|
1474
|
+
-- of a table called "new"
|
|
1475
|
+
-- ===================================================================
|
|
1476
|
+
--
|
|
1477
|
+
-- §12 pins the refusal when the row image is the ALTERED table's own (`check
|
|
1478
|
+
-- (new.a > 0)` on the table being altered); §13/§14 pin the FROM-rebound edges. The
|
|
1479
|
+
-- remaining cell of the matrix: the qualifier sits on a DIFFERENT table, where it names
|
|
1480
|
+
-- THAT table's row image — not a column of the real table "new" — so `alter table "new"
|
|
1481
|
+
-- drop column v` is legal. Pre-fix the guard treated the foreign `new.v` as a reference
|
|
1482
|
+
-- to the table "new" and false-refused.
|
|
1483
|
+
|
|
1484
|
+
create table "new" (id integer primary key, v integer);
|
|
1485
|
+
create table DcNwCk (id integer primary key, v integer, constraint ck_dcnw check (new.v > 0));
|
|
1486
|
+
create table DcNwDf (id integer primary key, v integer, d integer default (new.v + 1));
|
|
1487
|
+
-- run
|
|
1488
|
+
|
|
1489
|
+
alter table "new" drop column v;
|
|
1490
|
+
select count(*) as c from "new";
|
|
1491
|
+
→ [{"c":0}]
|
|
1492
|
+
|
|
1493
|
+
-- Both foreign tables keep working against their own row images.
|
|
1494
|
+
insert into DcNwCk values (1, 5);
|
|
1495
|
+
insert into DcNwDf (id, v) values (1, 4);
|
|
1496
|
+
select d from DcNwDf;
|
|
1497
|
+
→ [{"d":5}]
|
|
1498
|
+
|
|
1499
|
+
drop table DcNwDf;
|
|
1500
|
+
drop table DcNwCk;
|
|
1501
|
+
drop table "new";
|
|
1502
|
+
-- run
|
|
1503
|
+
|
|
1504
|
+
-- ...and a GENUINE reference to the table "new" (through a subquery FROM) still
|
|
1505
|
+
-- refuses, so the allowance is the row image and not the name.
|
|
1506
|
+
create table "new" (id integer primary key, v integer);
|
|
1507
|
+
create table DcNwRef (id integer primary key, n integer,
|
|
1508
|
+
constraint ck_dcnwref check (n < (select max("new".v) from "new")));
|
|
1509
|
+
-- run
|
|
1510
|
+
|
|
1511
|
+
alter table "new" drop column v;
|
|
1512
|
+
-- error: CHECK constraint 'ck_dcnwref' on table 'DcNwRef'
|
|
1513
|
+
|
|
1514
|
+
drop table DcNwRef;
|
|
1515
|
+
drop table "new";
|
|
1516
|
+
-- run
|
|
1517
|
+
|
|
1518
|
+
-- ===================================================================
|
|
1519
|
+
-- 38. An ALIASED FROM source keeps its columns in scope
|
|
1520
|
+
-- ===================================================================
|
|
1521
|
+
--
|
|
1522
|
+
-- A FROM alias adds a qualifier; it does not take the source's columns out of
|
|
1523
|
+
-- scope, so a bare `x` written against `from t a` binds `t.x` exactly as it
|
|
1524
|
+
-- would against `from t`. The scope walk used to treat an aliased source as
|
|
1525
|
+
-- contributing nothing to unqualified resolution, so this drop was ACCEPTED and
|
|
1526
|
+
-- the orphaned assertion then failed every write to the whole database with
|
|
1527
|
+
-- `Column not found: x`.
|
|
1528
|
+
|
|
1529
|
+
create table DcAl (id integer primary key, x integer);
|
|
1530
|
+
create table DcAlBy (id integer primary key);
|
|
1531
|
+
create assertion dc_al check (not exists (select 1 from DcAl a where x < 0));
|
|
1532
|
+
-- run
|
|
1533
|
+
|
|
1534
|
+
alter table DcAl drop column x;
|
|
1535
|
+
-- error: it is referenced by assertion 'dc_al'
|
|
1536
|
+
|
|
1537
|
+
-- The database is still writable, which is the whole point of refusing.
|
|
1538
|
+
insert into DcAlBy values (1);
|
|
1539
|
+
commit;
|
|
1540
|
+
select count(*) as c from DcAlBy;
|
|
1541
|
+
→ [{"c":1}]
|
|
1542
|
+
|
|
1543
|
+
drop assertion dc_al;
|
|
1544
|
+
drop table DcAl;
|
|
1545
|
+
drop table DcAlBy;
|
|
1546
|
+
-- run
|
|
1547
|
+
|
|
1548
|
+
-- The republication arm: a view that re-exposes the column through a bare star
|
|
1549
|
+
-- over an aliased source is a republisher like any other, so a rule reading it
|
|
1550
|
+
-- blocks the drop even though no body spells the column's name.
|
|
1551
|
+
create table DcAlS (id integer primary key, x integer);
|
|
1552
|
+
create view DcAlSV as select * from DcAlS a;
|
|
1553
|
+
create assertion dc_als check (not exists (select 1 from DcAlSV where x < 0));
|
|
1554
|
+
-- run
|
|
1555
|
+
|
|
1556
|
+
-- No chain in the message: the fixpoint makes DcAlSV a republication TARGET, so the
|
|
1557
|
+
-- assertion's own body names the column directly against it — the same shape §31
|
|
1558
|
+
-- pins for `select *` / `select t.*` over an unaliased source.
|
|
1559
|
+
alter table DcAlS drop column x;
|
|
1560
|
+
-- error: it is referenced by assertion 'dc_als'
|
|
1561
|
+
|
|
1562
|
+
drop assertion dc_als;
|
|
1563
|
+
drop view DcAlSV;
|
|
1564
|
+
drop table DcAlS;
|
|
1565
|
+
-- run
|
|
1566
|
+
|
|
1567
|
+
-- ...and the CHECK arm of the same shape, under a join whose renamed side carries
|
|
1568
|
+
-- the alias.
|
|
1569
|
+
create table DcAlJ (id integer primary key, x integer);
|
|
1570
|
+
create table DcAlJU (id integer primary key, n integer);
|
|
1571
|
+
create table DcAlJRef (id integer primary key, n integer,
|
|
1572
|
+
constraint ck_dcalj check (n < (select max(x)
|
|
1573
|
+
from DcAlJ a join DcAlJU u on a.id = u.id)));
|
|
1574
|
+
-- run
|
|
1575
|
+
|
|
1576
|
+
alter table DcAlJ drop column x;
|
|
1577
|
+
-- error: CHECK constraint 'ck_dcalj' on table 'DcAlJRef'
|
|
1578
|
+
|
|
1579
|
+
drop table DcAlJRef;
|
|
1580
|
+
drop table DcAlJU;
|
|
1581
|
+
drop table DcAlJ;
|
|
1582
|
+
-- run
|
|
1583
|
+
|
|
1584
|
+
-- ...and the column-DEFAULT arm. Same walk, different site: the assertion and CHECK
|
|
1585
|
+
-- arms above both reach the walk through a body the drop guard probes as a rule,
|
|
1586
|
+
-- while a DEFAULT is an expression carried by a column. Both bare-under-alias
|
|
1587
|
+
-- spellings are here — one where the alias is the only thing between the ref and
|
|
1588
|
+
-- the source, one where the source is joined.
|
|
1589
|
+
create table DcAlD (id integer primary key, x integer);
|
|
1590
|
+
create table DcAlDRef (id integer primary key,
|
|
1591
|
+
n integer default ((select max(x) from DcAlD a where x > 0)));
|
|
1592
|
+
-- run
|
|
1593
|
+
|
|
1594
|
+
alter table DcAlD drop column x;
|
|
1595
|
+
-- error: it is referenced by the DEFAULT of column 'n' on table 'DcAlDRef'
|
|
1596
|
+
|
|
1597
|
+
drop table DcAlDRef;
|
|
1598
|
+
drop table DcAlD;
|
|
1599
|
+
-- run
|
|
1600
|
+
|
|
1601
|
+
-- Guard rail: widening the binding must not start capturing a bare name that
|
|
1602
|
+
-- legitimately binds somewhere ELSE. Here the rule's `x` binds the aliased `DcAlO`,
|
|
1603
|
+
-- not the altered table, so dropping DcAlN.x is still legal.
|
|
1604
|
+
create table DcAlN (id integer primary key, x integer);
|
|
1605
|
+
create table DcAlO (id integer primary key, x integer);
|
|
1606
|
+
create assertion dc_aln check (not exists (select 1 from DcAlO b where x < 0));
|
|
1607
|
+
-- run
|
|
1608
|
+
|
|
1609
|
+
alter table DcAlN drop column x;
|
|
1610
|
+
select count(*) as c from DcAlN;
|
|
1611
|
+
→ [{"c":0}]
|
|
1612
|
+
|
|
1613
|
+
drop assertion dc_aln;
|
|
1614
|
+
drop table DcAlO;
|
|
1615
|
+
drop table DcAlN;
|
|
1616
|
+
-- run
|