@quereus/quereus 4.20.1 → 4.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/README.md +2 -0
  2. package/package.json +7 -4
  3. package/test/README.md +173 -0
  4. package/test/logic/01-basic.sqllogic +39 -0
  5. package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
  6. package/test/logic/01.2-strings.sqllogic +43 -0
  7. package/test/logic/01.5-insert-select.sqllogic +237 -0
  8. package/test/logic/01.6-update-extras.sqllogic +118 -0
  9. package/test/logic/01.7-update-from.sqllogic +67 -0
  10. package/test/logic/01.8-delete-extras.sqllogic +122 -0
  11. package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
  12. package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
  13. package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
  14. package/test/logic/01.9-query-expr-values.sqllogic +111 -0
  15. package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
  16. package/test/logic/02-filters.sqllogic +54 -0
  17. package/test/logic/02-smoke.sqllogic +62 -0
  18. package/test/logic/02.1-bind-parameters.sqllogic +223 -0
  19. package/test/logic/03-expressions.sqllogic +190 -0
  20. package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
  21. package/test/logic/03.4-defaults.sqllogic +554 -0
  22. package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
  23. package/test/logic/03.5-tvf.sqllogic +61 -0
  24. package/test/logic/03.6-type-system.sqllogic +544 -0
  25. package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
  26. package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
  27. package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
  28. package/test/logic/03.8-not-precedence.sqllogic +255 -0
  29. package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
  30. package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
  31. package/test/logic/04-order-by.sqllogic +38 -0
  32. package/test/logic/04-transactions.sqllogic +239 -0
  33. package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
  34. package/test/logic/05-vtab_memory.sqllogic +50 -0
  35. package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
  36. package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
  37. package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
  38. package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
  39. package/test/logic/06-builtin_functions.sqllogic +149 -0
  40. package/test/logic/06.1-string-functions.sqllogic +92 -0
  41. package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
  42. package/test/logic/06.2-math-functions.sqllogic +82 -0
  43. package/test/logic/06.3-schema.sqllogic +48 -0
  44. package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
  45. package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
  46. package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
  47. package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
  48. package/test/logic/06.3.4-view-info.sqllogic +378 -0
  49. package/test/logic/06.3.5-column-info.sqllogic +347 -0
  50. package/test/logic/06.3.6-schema-views.sqllogic +29 -0
  51. package/test/logic/06.4-schema-search-path.sqllogic +354 -0
  52. package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
  53. package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
  54. package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
  55. package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
  56. package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
  57. package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
  58. package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
  59. package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
  60. package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
  61. package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
  62. package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
  63. package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
  64. package/test/logic/06.7-json-extended.sqllogic +53 -0
  65. package/test/logic/06.8-json-path-operators.sqllogic +99 -0
  66. package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
  67. package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
  68. package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
  69. package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
  70. package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
  71. package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
  72. package/test/logic/07-aggregates.sqllogic +193 -0
  73. package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
  74. package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
  75. package/test/logic/07.3-group-by-extras.sqllogic +602 -0
  76. package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
  77. package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
  78. package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
  79. package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
  80. package/test/logic/07.5-window.sqllogic +1941 -0
  81. package/test/logic/07.5.1-window-named.sqllogic +13 -0
  82. package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
  83. package/test/logic/07.6-subqueries.sqllogic +78 -0
  84. package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
  85. package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
  86. package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
  87. package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
  88. package/test/logic/07.7.1-in-extras.sqllogic +158 -0
  89. package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
  90. package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
  91. package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
  92. package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
  93. package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
  94. package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
  95. package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
  96. package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
  97. package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
  98. package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
  99. package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
  100. package/test/logic/07.9-in-value-list.sqllogic +154 -0
  101. package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
  102. package/test/logic/08-views.sqllogic +64 -0
  103. package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
  104. package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
  105. package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
  106. package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
  107. package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
  108. package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
  109. package/test/logic/09-set_operations.sqllogic +244 -0
  110. package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
  111. package/test/logic/10-distinct_datatypes.sqllogic +127 -0
  112. package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
  113. package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
  114. package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
  115. package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
  116. package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
  117. package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
  118. package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
  119. package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
  120. package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
  121. package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
  122. package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
  123. package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
  124. package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
  125. package/test/logic/10.2-column-features.sqllogic +365 -0
  126. package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
  127. package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
  128. package/test/logic/10.3-function-features.sqllogic +247 -0
  129. package/test/logic/10.4-schema-scale.sqllogic +168 -0
  130. package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
  131. package/test/logic/10.5-indexes.sqllogic +164 -0
  132. package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
  133. package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
  134. package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
  135. package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
  136. package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
  137. package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
  138. package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
  139. package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
  140. package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
  141. package/test/logic/100.1-where-extras.sqllogic +163 -0
  142. package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
  143. package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
  144. package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
  145. package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
  146. package/test/logic/102-unique-constraints.sqllogic +145 -0
  147. package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
  148. package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
  149. package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
  150. package/test/logic/102.2-unique-collation.sqllogic +181 -0
  151. package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
  152. package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
  153. package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
  154. package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
  155. package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
  156. package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
  157. package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
  158. package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
  159. package/test/logic/108-cardinality-estimation.sqllogic +146 -0
  160. package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
  161. package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
  162. package/test/logic/11-joins.sqllogic +86 -0
  163. package/test/logic/11.1-join-using.sqllogic +267 -0
  164. package/test/logic/11.2-comma-join.sqllogic +35 -0
  165. package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
  166. package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
  167. package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
  168. package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
  169. package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
  170. package/test/logic/12-empty-primary-key.sqllogic +124 -0
  171. package/test/logic/12-join_padding_order.sqllogic +58 -0
  172. package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
  173. package/test/logic/13-cte.sqllogic +137 -0
  174. package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
  175. package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
  176. package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
  177. package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
  178. package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
  179. package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
  180. package/test/logic/13.4-cte-extras.sqllogic +98 -0
  181. package/test/logic/13.5-cte-join-order.sqllogic +166 -0
  182. package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
  183. package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
  184. package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
  185. package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
  186. package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
  187. package/test/logic/14-utilities.sqllogic +168 -0
  188. package/test/logic/15-timespan.sqllogic +279 -0
  189. package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
  190. package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
  191. package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
  192. package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
  193. package/test/logic/16-epoch.sqllogic +187 -0
  194. package/test/logic/17-weekday-modifier.sqllogic +78 -0
  195. package/test/logic/18-json-string-escapes.sqllogic +86 -0
  196. package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
  197. package/test/logic/20-empty-single-row.sqllogic +261 -0
  198. package/test/logic/21-null-edge-cases.sqllogic +227 -0
  199. package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
  200. package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
  201. package/test/logic/21.2-between-edges.sqllogic +157 -0
  202. package/test/logic/22-boundary-values.sqllogic +175 -0
  203. package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
  204. package/test/logic/24-builtin-branches.sqllogic +611 -0
  205. package/test/logic/24.1-substr-extras.sqllogic +75 -0
  206. package/test/logic/24.2-random-extras.sqllogic +39 -0
  207. package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
  208. package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
  209. package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
  210. package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
  211. package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
  212. package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
  213. package/test/logic/26-join-edge-cases.sqllogic +333 -0
  214. package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
  215. package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
  216. package/test/logic/26.3-join-on-constants.sqllogic +61 -0
  217. package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
  218. package/test/logic/27-window-edge-cases.sqllogic +206 -0
  219. package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
  220. package/test/logic/27.2-window-exclude.sqllogic +13 -0
  221. package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
  222. package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
  223. package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
  224. package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
  225. package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
  226. package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
  227. package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
  228. package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
  229. package/test/logic/40-constraints.sqllogic +418 -0
  230. package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
  231. package/test/logic/40.2-check-extras.sqllogic +683 -0
  232. package/test/logic/41-alter-table.sqllogic +191 -0
  233. package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
  234. package/test/logic/41-fk-cross-schema.sqllogic +155 -0
  235. package/test/logic/41-fk-extended-targets.sqllogic +173 -0
  236. package/test/logic/41-foreign-keys.sqllogic +1001 -0
  237. package/test/logic/41-generated-column-errors.sqllogic +225 -0
  238. package/test/logic/41-generated-column-extras.sqllogic +598 -0
  239. package/test/logic/41-generated-column-scope.sqllogic +329 -0
  240. package/test/logic/41-generated-columns.sqllogic +361 -0
  241. package/test/logic/41.1-alter-pk.sqllogic +230 -0
  242. package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
  243. package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
  244. package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
  245. package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
  246. package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
  247. package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
  248. package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
  249. package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
  250. package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
  251. package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
  252. package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
  253. package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
  254. package/test/logic/41.2-alter-column.sqllogic +382 -0
  255. package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
  256. package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
  257. package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
  258. package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
  259. package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
  260. package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
  261. package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
  262. package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
  263. package/test/logic/41.5-alter-misc.sqllogic +48 -0
  264. package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
  265. package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
  266. package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
  267. package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
  268. package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
  269. package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
  270. package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
  271. package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
  272. package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
  273. package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
  274. package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
  275. package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
  276. package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
  277. package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
  278. package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
  279. package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
  280. package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
  281. package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
  282. package/test/logic/42-committed-snapshot.sqllogic +254 -0
  283. package/test/logic/42-returning.sqllogic +159 -0
  284. package/test/logic/42.1-returning-extras.sqllogic +232 -0
  285. package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
  286. package/test/logic/43-default-nullability.sqllogic +131 -0
  287. package/test/logic/43-transition-constraints.sqllogic +341 -0
  288. package/test/logic/43.1-default-collation.sqllogic +140 -0
  289. package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
  290. package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
  291. package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
  292. package/test/logic/44-determinism-validation.sqllogic +164 -0
  293. package/test/logic/44-orthogonality.sqllogic +146 -0
  294. package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
  295. package/test/logic/45-udf-determinism.sqllogic +39 -0
  296. package/test/logic/46-mutation-context.sqllogic +595 -0
  297. package/test/logic/47-upsert.sqllogic +255 -0
  298. package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
  299. package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
  300. package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
  301. package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
  302. package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
  303. package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
  304. package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
  305. package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
  306. package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
  307. package/test/logic/49-reference-graph.sqllogic +84 -0
  308. package/test/logic/50-declarative-schema.sqllogic +2550 -0
  309. package/test/logic/50-metadata-tags.sqllogic +1033 -0
  310. package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
  311. package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
  312. package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
  313. package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
  314. package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
  315. package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
  316. package/test/logic/51-lens-foundation.sqllogic +147 -0
  317. package/test/logic/51-materialized-views.sqllogic +376 -0
  318. package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
  319. package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
  320. package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
  321. package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
  322. package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
  323. package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
  324. package/test/logic/52-lens-overrides.sqllogic +566 -0
  325. package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
  326. package/test/logic/53-reserved-tags.sqllogic +252 -0
  327. package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
  328. package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
  329. package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
  330. package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
  331. package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
  332. package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
  333. package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
  334. package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
  335. package/test/logic/55-lens-prover.sqllogic +202 -0
  336. package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
  337. package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
  338. package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
  339. package/test/logic/81-quickpick.sqllogic +24 -0
  340. package/test/logic/82-bloom-join.sqllogic +185 -0
  341. package/test/logic/83-merge-join.sqllogic +280 -0
  342. package/test/logic/84-asof-scan.sqllogic +238 -0
  343. package/test/logic/84-key-cardinality.sqllogic +50 -0
  344. package/test/logic/85-relational-const-folding.sqllogic +51 -0
  345. package/test/logic/86-scalar-cse.sqllogic +42 -0
  346. package/test/logic/90-error_paths.sqllogic +114 -0
  347. package/test/logic/90.1-parse-errors.sqllogic +77 -0
  348. package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
  349. package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
  350. package/test/logic/90.3-expression-errors.sqllogic +43 -0
  351. package/test/logic/90.4-dml-errors.sqllogic +47 -0
  352. package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
  353. package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
  354. package/test/logic/90.6-select-error-paths.sqllogic +57 -0
  355. package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
  356. package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
  357. package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
  358. package/test/logic/93.1-view-error-paths.sqllogic +74 -0
  359. package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
  360. package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
  361. package/test/logic/93.4-view-mutation.sqllogic +4881 -0
  362. package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
  363. package/test/logic/93.5-authored-inverse.sqllogic +415 -0
  364. package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
  365. package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
  366. package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
  367. package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
  368. package/test/logic/95-assertions.sqllogic +1417 -0
  369. package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
  370. package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
  371. package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
  372. package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
  373. package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
  374. package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
  375. package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
  376. package/test/logic/drop-unique-index.sqllogic +88 -0
  377. 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