@quereus/quereus 4.20.1 → 4.20.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/README.md +2 -0
  2. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  3. package/dist/src/schema/schema-differ.js +17 -69
  4. package/dist/src/schema/schema-differ.js.map +1 -1
  5. package/package.json +7 -4
  6. package/test/README.md +173 -0
  7. package/test/logic/01-basic.sqllogic +39 -0
  8. package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
  9. package/test/logic/01.2-strings.sqllogic +43 -0
  10. package/test/logic/01.5-insert-select.sqllogic +237 -0
  11. package/test/logic/01.6-update-extras.sqllogic +118 -0
  12. package/test/logic/01.7-update-from.sqllogic +67 -0
  13. package/test/logic/01.8-delete-extras.sqllogic +122 -0
  14. package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
  15. package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
  16. package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
  17. package/test/logic/01.9-query-expr-values.sqllogic +111 -0
  18. package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
  19. package/test/logic/02-filters.sqllogic +54 -0
  20. package/test/logic/02-smoke.sqllogic +62 -0
  21. package/test/logic/02.1-bind-parameters.sqllogic +223 -0
  22. package/test/logic/03-expressions.sqllogic +190 -0
  23. package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
  24. package/test/logic/03.4-defaults.sqllogic +554 -0
  25. package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
  26. package/test/logic/03.5-tvf.sqllogic +61 -0
  27. package/test/logic/03.6-type-system.sqllogic +544 -0
  28. package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
  29. package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
  30. package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
  31. package/test/logic/03.8-not-precedence.sqllogic +255 -0
  32. package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
  33. package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
  34. package/test/logic/04-order-by.sqllogic +38 -0
  35. package/test/logic/04-transactions.sqllogic +239 -0
  36. package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
  37. package/test/logic/05-vtab_memory.sqllogic +50 -0
  38. package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
  39. package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
  40. package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
  41. package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
  42. package/test/logic/06-builtin_functions.sqllogic +149 -0
  43. package/test/logic/06.1-string-functions.sqllogic +92 -0
  44. package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
  45. package/test/logic/06.2-math-functions.sqllogic +82 -0
  46. package/test/logic/06.3-schema.sqllogic +48 -0
  47. package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
  48. package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
  49. package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
  50. package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
  51. package/test/logic/06.3.4-view-info.sqllogic +378 -0
  52. package/test/logic/06.3.5-column-info.sqllogic +347 -0
  53. package/test/logic/06.3.6-schema-views.sqllogic +29 -0
  54. package/test/logic/06.4-schema-search-path.sqllogic +354 -0
  55. package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
  56. package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
  57. package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
  58. package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
  59. package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
  60. package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
  61. package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
  62. package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
  63. package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
  64. package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
  65. package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
  66. package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
  67. package/test/logic/06.7-json-extended.sqllogic +53 -0
  68. package/test/logic/06.8-json-path-operators.sqllogic +99 -0
  69. package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
  70. package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
  71. package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
  72. package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
  73. package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
  74. package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
  75. package/test/logic/07-aggregates.sqllogic +193 -0
  76. package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
  77. package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
  78. package/test/logic/07.3-group-by-extras.sqllogic +602 -0
  79. package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
  80. package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
  81. package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
  82. package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
  83. package/test/logic/07.5-window.sqllogic +1941 -0
  84. package/test/logic/07.5.1-window-named.sqllogic +13 -0
  85. package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
  86. package/test/logic/07.6-subqueries.sqllogic +78 -0
  87. package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
  88. package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
  89. package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
  90. package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
  91. package/test/logic/07.7.1-in-extras.sqllogic +158 -0
  92. package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
  93. package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
  94. package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
  95. package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
  96. package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
  97. package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
  98. package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
  99. package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
  100. package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
  101. package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
  102. package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
  103. package/test/logic/07.9-in-value-list.sqllogic +154 -0
  104. package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
  105. package/test/logic/08-views.sqllogic +64 -0
  106. package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
  107. package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
  108. package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
  109. package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
  110. package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
  111. package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
  112. package/test/logic/09-set_operations.sqllogic +244 -0
  113. package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
  114. package/test/logic/10-distinct_datatypes.sqllogic +127 -0
  115. package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
  116. package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
  117. package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
  118. package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
  119. package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
  120. package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
  121. package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
  122. package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
  123. package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
  124. package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
  125. package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
  126. package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
  127. package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
  128. package/test/logic/10.2-column-features.sqllogic +365 -0
  129. package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
  130. package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
  131. package/test/logic/10.3-function-features.sqllogic +247 -0
  132. package/test/logic/10.4-schema-scale.sqllogic +168 -0
  133. package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
  134. package/test/logic/10.5-indexes.sqllogic +164 -0
  135. package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
  136. package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
  137. package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
  138. package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
  139. package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
  140. package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
  141. package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
  142. package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
  143. package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
  144. package/test/logic/100.1-where-extras.sqllogic +163 -0
  145. package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
  146. package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
  147. package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
  148. package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
  149. package/test/logic/102-unique-constraints.sqllogic +145 -0
  150. package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
  151. package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
  152. package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
  153. package/test/logic/102.2-unique-collation.sqllogic +181 -0
  154. package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
  155. package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
  156. package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
  157. package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
  158. package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
  159. package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
  160. package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
  161. package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
  162. package/test/logic/108-cardinality-estimation.sqllogic +146 -0
  163. package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
  164. package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
  165. package/test/logic/11-joins.sqllogic +86 -0
  166. package/test/logic/11.1-join-using.sqllogic +267 -0
  167. package/test/logic/11.2-comma-join.sqllogic +35 -0
  168. package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
  169. package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
  170. package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
  171. package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
  172. package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
  173. package/test/logic/12-empty-primary-key.sqllogic +124 -0
  174. package/test/logic/12-join_padding_order.sqllogic +58 -0
  175. package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
  176. package/test/logic/13-cte.sqllogic +137 -0
  177. package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
  178. package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
  179. package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
  180. package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
  181. package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
  182. package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
  183. package/test/logic/13.4-cte-extras.sqllogic +98 -0
  184. package/test/logic/13.5-cte-join-order.sqllogic +166 -0
  185. package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
  186. package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
  187. package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
  188. package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
  189. package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
  190. package/test/logic/14-utilities.sqllogic +168 -0
  191. package/test/logic/15-timespan.sqllogic +279 -0
  192. package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
  193. package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
  194. package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
  195. package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
  196. package/test/logic/16-epoch.sqllogic +187 -0
  197. package/test/logic/17-weekday-modifier.sqllogic +78 -0
  198. package/test/logic/18-json-string-escapes.sqllogic +86 -0
  199. package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
  200. package/test/logic/20-empty-single-row.sqllogic +261 -0
  201. package/test/logic/21-null-edge-cases.sqllogic +227 -0
  202. package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
  203. package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
  204. package/test/logic/21.2-between-edges.sqllogic +157 -0
  205. package/test/logic/22-boundary-values.sqllogic +175 -0
  206. package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
  207. package/test/logic/24-builtin-branches.sqllogic +611 -0
  208. package/test/logic/24.1-substr-extras.sqllogic +75 -0
  209. package/test/logic/24.2-random-extras.sqllogic +39 -0
  210. package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
  211. package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
  212. package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
  213. package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
  214. package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
  215. package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
  216. package/test/logic/26-join-edge-cases.sqllogic +333 -0
  217. package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
  218. package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
  219. package/test/logic/26.3-join-on-constants.sqllogic +61 -0
  220. package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
  221. package/test/logic/27-window-edge-cases.sqllogic +206 -0
  222. package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
  223. package/test/logic/27.2-window-exclude.sqllogic +13 -0
  224. package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
  225. package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
  226. package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
  227. package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
  228. package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
  229. package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
  230. package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
  231. package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
  232. package/test/logic/40-constraints.sqllogic +418 -0
  233. package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
  234. package/test/logic/40.2-check-extras.sqllogic +683 -0
  235. package/test/logic/41-alter-table.sqllogic +191 -0
  236. package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
  237. package/test/logic/41-fk-cross-schema.sqllogic +155 -0
  238. package/test/logic/41-fk-extended-targets.sqllogic +173 -0
  239. package/test/logic/41-foreign-keys.sqllogic +1001 -0
  240. package/test/logic/41-generated-column-errors.sqllogic +225 -0
  241. package/test/logic/41-generated-column-extras.sqllogic +598 -0
  242. package/test/logic/41-generated-column-scope.sqllogic +329 -0
  243. package/test/logic/41-generated-columns.sqllogic +361 -0
  244. package/test/logic/41.1-alter-pk.sqllogic +230 -0
  245. package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
  246. package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
  247. package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
  248. package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
  249. package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
  250. package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
  251. package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
  252. package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
  253. package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
  254. package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
  255. package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
  256. package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
  257. package/test/logic/41.2-alter-column.sqllogic +382 -0
  258. package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
  259. package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
  260. package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
  261. package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
  262. package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
  263. package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
  264. package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
  265. package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
  266. package/test/logic/41.5-alter-misc.sqllogic +48 -0
  267. package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
  268. package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
  269. package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
  270. package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
  271. package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
  272. package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
  273. package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
  274. package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
  275. package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
  276. package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
  277. package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
  278. package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
  279. package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
  280. package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
  281. package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
  282. package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
  283. package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
  284. package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
  285. package/test/logic/42-committed-snapshot.sqllogic +254 -0
  286. package/test/logic/42-returning.sqllogic +159 -0
  287. package/test/logic/42.1-returning-extras.sqllogic +232 -0
  288. package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
  289. package/test/logic/43-default-nullability.sqllogic +131 -0
  290. package/test/logic/43-transition-constraints.sqllogic +341 -0
  291. package/test/logic/43.1-default-collation.sqllogic +140 -0
  292. package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
  293. package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
  294. package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
  295. package/test/logic/44-determinism-validation.sqllogic +164 -0
  296. package/test/logic/44-orthogonality.sqllogic +146 -0
  297. package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
  298. package/test/logic/45-udf-determinism.sqllogic +39 -0
  299. package/test/logic/46-mutation-context.sqllogic +595 -0
  300. package/test/logic/47-upsert.sqllogic +255 -0
  301. package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
  302. package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
  303. package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
  304. package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
  305. package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
  306. package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
  307. package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
  308. package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
  309. package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
  310. package/test/logic/49-reference-graph.sqllogic +84 -0
  311. package/test/logic/50-declarative-schema.sqllogic +2550 -0
  312. package/test/logic/50-metadata-tags.sqllogic +1033 -0
  313. package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
  314. package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
  315. package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
  316. package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +210 -0
  317. package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
  318. package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
  319. package/test/logic/51-lens-foundation.sqllogic +147 -0
  320. package/test/logic/51-materialized-views.sqllogic +376 -0
  321. package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
  322. package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
  323. package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
  324. package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
  325. package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
  326. package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
  327. package/test/logic/52-lens-overrides.sqllogic +566 -0
  328. package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
  329. package/test/logic/53-reserved-tags.sqllogic +252 -0
  330. package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
  331. package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
  332. package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
  333. package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
  334. package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
  335. package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
  336. package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
  337. package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
  338. package/test/logic/55-lens-prover.sqllogic +202 -0
  339. package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
  340. package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
  341. package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
  342. package/test/logic/81-quickpick.sqllogic +24 -0
  343. package/test/logic/82-bloom-join.sqllogic +185 -0
  344. package/test/logic/83-merge-join.sqllogic +280 -0
  345. package/test/logic/84-asof-scan.sqllogic +238 -0
  346. package/test/logic/84-key-cardinality.sqllogic +50 -0
  347. package/test/logic/85-relational-const-folding.sqllogic +51 -0
  348. package/test/logic/86-scalar-cse.sqllogic +42 -0
  349. package/test/logic/90-error_paths.sqllogic +114 -0
  350. package/test/logic/90.1-parse-errors.sqllogic +77 -0
  351. package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
  352. package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
  353. package/test/logic/90.3-expression-errors.sqllogic +43 -0
  354. package/test/logic/90.4-dml-errors.sqllogic +47 -0
  355. package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
  356. package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
  357. package/test/logic/90.6-select-error-paths.sqllogic +57 -0
  358. package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
  359. package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
  360. package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
  361. package/test/logic/93.1-view-error-paths.sqllogic +74 -0
  362. package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
  363. package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
  364. package/test/logic/93.4-view-mutation.sqllogic +4881 -0
  365. package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
  366. package/test/logic/93.5-authored-inverse.sqllogic +415 -0
  367. package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
  368. package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
  369. package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
  370. package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
  371. package/test/logic/95-assertions.sqllogic +1417 -0
  372. package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
  373. package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
  374. package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
  375. package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
  376. package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
  377. package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
  378. package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
  379. package/test/logic/drop-unique-index.sqllogic +88 -0
  380. package/test/logic/pushdown-test.sqllogic +36 -0
@@ -0,0 +1,178 @@
1
+ -- ALTER COLUMN SET DEFAULT / SET DATA TYPE are checked against the column's
2
+ -- (current, or newly-set) declared type — the same `foldDefaultToType` guard
3
+ -- CREATE TABLE runs (see 10.1.7-create-table-default-type-check.sqllogic), so an
4
+ -- ALTER cannot mint a column CREATE TABLE would refuse.
5
+
6
+ -- ============================================================
7
+ -- 1. SET DEFAULT: the new literal default must convert to the column's CURRENT type
8
+ -- ============================================================
9
+
10
+ create table t_sd (id integer primary key, n integer null);
11
+ insert into t_sd (id, n) values (1, 5);
12
+ -- run
13
+
14
+ alter table t_sd alter column n set default 'abc';
15
+ -- error: Type conversion failed
16
+
17
+ -- The column keeps its previous default (none here) — a later insert relying on
18
+ -- it still sees no default applied, and the column's type is unchanged.
19
+ insert into t_sd (id) values (2);
20
+ select id, n from t_sd order by id;
21
+ → [{"id":1,"n":5},{"id":2,"n":null}]
22
+
23
+ drop table t_sd;
24
+ -- run
25
+
26
+ -- A refused SET DEFAULT also leaves an EXISTING default in place — the column is
27
+ -- not left defaultless by the failed statement.
28
+ create table t_sd_keep (id integer primary key, n integer default 3);
29
+ alter table t_sd_keep alter column n set default 'abc';
30
+ -- error: Type conversion failed
31
+
32
+ insert into t_sd_keep (id) values (1);
33
+ select n from t_sd_keep where id = 1;
34
+ → [{"n":3}]
35
+
36
+ drop table t_sd_keep;
37
+ -- run
38
+
39
+ -- A convertible literal SET DEFAULT still succeeds, and a later insert stores it
40
+ -- already converted.
41
+ create table t_sd_ok (id integer primary key, n integer);
42
+ alter table t_sd_ok alter column n set default '7';
43
+ -- run
44
+
45
+ insert into t_sd_ok (id) values (1);
46
+ select n, typeof(n) as t from t_sd_ok where id = 1;
47
+ → [{"n":7,"t":"integer"}]
48
+
49
+ drop table t_sd_ok;
50
+ -- run
51
+
52
+ -- ============================================================
53
+ -- 2. SET DATA TYPE: the column's EXISTING stored default must convert to the NEW type
54
+ --
55
+ -- Each row below supplies `n` explicitly (a value that DOES convert to the new
56
+ -- type) so the retype's own value-conversion never fails — the only thing under
57
+ -- test is whether the column's DECLARED (not necessarily used) default converts.
58
+ -- ============================================================
59
+
60
+ create table t_retype (id integer primary key, n text null default 'abc');
61
+ insert into t_retype (id, n) values (1, '99');
62
+ -- run
63
+
64
+ alter table t_retype alter column n set data type integer;
65
+ -- error: Type conversion failed
66
+
67
+ -- Neither the type nor the stored rows moved.
68
+ select id, n, typeof(n) as t from t_retype order by id;
69
+ → [{"id":1,"n":"99","t":"text"}]
70
+
71
+ drop table t_retype;
72
+ -- run
73
+
74
+ -- The remedy the error should leave available: DROP DEFAULT, then the same retype
75
+ -- succeeds.
76
+ create table t_retype_fix (id integer primary key, n text null default 'abc');
77
+ insert into t_retype_fix (id, n) values (1, '99');
78
+ -- run
79
+
80
+ alter table t_retype_fix alter column n set data type integer;
81
+ -- error: Type conversion failed
82
+
83
+ alter table t_retype_fix alter column n drop default;
84
+ -- run
85
+
86
+ alter table t_retype_fix alter column n set data type integer;
87
+ -- run
88
+
89
+ insert into t_retype_fix (id) values (2);
90
+ select id, n from t_retype_fix order by id;
91
+ → [{"id":1,"n":99},{"id":2,"n":null}]
92
+
93
+ drop table t_retype_fix;
94
+ -- run
95
+
96
+ -- A retype whose EXISTING default IS convertible to the new type still succeeds,
97
+ -- and a later insert (using the post-retype default) stores it already converted.
98
+ create table t_retype_ok (id integer primary key, n text default '7');
99
+ insert into t_retype_ok (id, n) values (1, '42');
100
+ -- run
101
+
102
+ alter table t_retype_ok alter column n set data type integer;
103
+ -- run
104
+
105
+ insert into t_retype_ok (id) values (2);
106
+ select id, n, typeof(n) as t from t_retype_ok order by id;
107
+ → [{"id":1,"n":42,"t":"integer"},{"id":2,"n":7,"t":"integer"}]
108
+
109
+ drop table t_retype_ok;
110
+ -- run
111
+
112
+ -- ============================================================
113
+ -- 3. A PRIMARY KEY column already refuses SET DATA TYPE — that refusal must win
114
+ -- over the new default/type fold (checked first).
115
+ -- ============================================================
116
+
117
+ create table t_pk (id integer primary key default '5');
118
+ -- run
119
+
120
+ alter table t_pk alter column id set data type integer;
121
+ -- error: PRIMARY KEY
122
+
123
+ drop table t_pk;
124
+ -- run
125
+
126
+ -- ============================================================
127
+ -- 4. A declarative migration that retypes a column AND replaces (or drops) its
128
+ -- DEFAULT must still apply: the outgoing default is dropped BEFORE the retype, so
129
+ -- a default only the OLD type could hold does not veto the migration. Only a
130
+ -- migration that keeps an unconvertible default hits the §2 refusal.
131
+ -- ============================================================
132
+
133
+ create table t_mig (id integer primary key, n text default 'abc');
134
+ insert into t_mig (id, n) values (1, '99');
135
+ -- run
136
+
137
+ declare schema main {
138
+ table t_mig {
139
+ id INTEGER PRIMARY KEY,
140
+ n INTEGER DEFAULT 0
141
+ }
142
+ }
143
+
144
+ -- run
145
+
146
+ apply schema main;
147
+ -- run
148
+
149
+ insert into t_mig (id) values (2);
150
+ select id, n, typeof(n) as t from t_mig order by id;
151
+ → [{"id":1,"n":99,"t":"integer"},{"id":2,"n":0,"t":"integer"}]
152
+
153
+ drop table t_mig;
154
+ -- run
155
+
156
+ -- The same shape with the DEFAULT dropped rather than replaced.
157
+ create table t_mig_drop (id integer primary key, n text default 'abc');
158
+ insert into t_mig_drop (id, n) values (1, '99');
159
+ -- run
160
+
161
+ declare schema main {
162
+ table t_mig_drop {
163
+ id INTEGER PRIMARY KEY,
164
+ n INTEGER NULL
165
+ }
166
+ }
167
+
168
+ -- run
169
+
170
+ apply schema main;
171
+ -- run
172
+
173
+ insert into t_mig_drop (id) values (2);
174
+ select id, n from t_mig_drop order by id;
175
+ → [{"id":1,"n":99},{"id":2,"n":null}]
176
+
177
+ drop table t_mig_drop;
178
+ -- run
@@ -0,0 +1,364 @@
1
+ -- 41.16-fk-unenforceable.sqllogic - a FOREIGN KEY that cannot be enforced must SAY SO
2
+ --
3
+ -- Two ways a declared foreign key ends up unenforceable, and what the engine owes the
4
+ -- user in each case:
5
+ --
6
+ -- A. the parent table does not exist. MATCH SIMPLE still admits a row whose FK columns
7
+ -- are NULL, and every other row is rejected — the behaviour is right and unchanged.
8
+ -- What changes is the MESSAGE: it used to quote the engine-synthesized null-guard
9
+ -- expression (`_fk_x_c (NEW.c is null or 0)`), which named nothing the user wrote.
10
+ -- It now names the missing table, qualified by the schema it was looked up in —
11
+ -- which is what makes the cross-schema mistake below diagnosable at all.
12
+ --
13
+ -- B. the child's FK column count does not line up with the parent key it references.
14
+ -- Both FK check builders used to `continue` past such a key, leaving it declared but
15
+ -- NOT ENFORCED: orphans accepted on the child, RESTRICT silently bypassed on the
16
+ -- parent. The statement now fails instead.
17
+
18
+ pragma foreign_keys = true;
19
+
20
+ -- ===================================
21
+ -- A1. missing parent — the error names the table, not the synthesized expression
22
+ -- ===================================
23
+
24
+ create table ghost_c (id integer primary key, c integer null references ghost_parent(refd));
25
+
26
+ insert into ghost_c values (1, 5);
27
+ -- error: CHECK constraint failed: _fk_ghost_c_c — referenced table 'main.ghost_parent' does not exist
28
+
29
+ select count(*) as n from ghost_c;
30
+ → [{"n":0}]
31
+
32
+ -- MATCH SIMPLE is untouched: a NULL FK column still satisfies the constraint
33
+ insert into ghost_c values (2, null);
34
+
35
+ select id, c from ghost_c order by id;
36
+ → [{"id":2,"c":null}]
37
+
38
+ -- the UPDATE path reports the same thing
39
+ update ghost_c set c = 7 where id = 2;
40
+ -- error: referenced table 'main.ghost_parent' does not exist
41
+
42
+ -- ===================================
43
+ -- A2. composite FK, MATCH SIMPLE — one NULL column is enough to admit the row
44
+ -- ===================================
45
+
46
+ create table ghost_c2 (id integer primary key, x integer null, y integer null,
47
+ foreign key (x, y) references ghost_parent2(a, b));
48
+
49
+ insert into ghost_c2 values (1, 1, null);
50
+ insert into ghost_c2 values (2, null, null);
51
+
52
+ select id, x, y from ghost_c2 order by id;
53
+ → [{"id":1,"x":1,"y":null},{"id":2,"x":null,"y":null}]
54
+
55
+ -- both non-NULL: rejected, naming the missing parent
56
+ insert into ghost_c2 values (3, 1, 2);
57
+ -- error: referenced table 'main.ghost_parent2' does not exist
58
+
59
+ -- ===================================
60
+ -- A3. the immediate and the deferred report paths must agree
61
+ --
62
+ -- A child-side FK check is EXISTS-shaped, so it auto-defers to COMMIT under the default
63
+ -- ABORT resolution; `or fail` forces evaluation at row time instead. Both must produce
64
+ -- the same text (they share `constraintViolationMessage`).
65
+ -- ===================================
66
+
67
+ -- deferred: the failure surfaces at COMMIT of an explicit transaction
68
+ begin;
69
+ insert into ghost_c values (10, 5);
70
+ commit;
71
+ -- error: CHECK constraint failed: _fk_ghost_c_c — referenced table 'main.ghost_parent' does not exist
72
+
73
+ select count(*) as n from ghost_c;
74
+ → [{"n":1}]
75
+
76
+ -- immediate: `or fail` evaluates at row time
77
+ insert or fail into ghost_c values (11, 5);
78
+ -- error: CHECK constraint failed: _fk_ghost_c_c — referenced table 'main.ghost_parent' does not exist
79
+
80
+ select count(*) as n from ghost_c;
81
+ → [{"n":1}]
82
+
83
+ -- ===================================
84
+ -- A4. `pragma foreign_keys = off` builds no checks at all — a missing parent must not
85
+ -- start raising just because the message got better
86
+ -- ===================================
87
+
88
+ pragma foreign_keys = false;
89
+
90
+ insert into ghost_c values (20, 5);
91
+
92
+ select id, c from ghost_c order by id;
93
+ → [{"id":2,"c":null},{"id":20,"c":5}]
94
+
95
+ delete from ghost_c where id = 20;
96
+
97
+ pragma foreign_keys = true;
98
+
99
+ drop table ghost_c2;
100
+ drop table ghost_c;
101
+
102
+ -- ===================================
103
+ -- A5. resolution is PER PLAN, not cached at CREATE — forward references stay legal
104
+ --
105
+ -- `create table child` naming a not-yet-declared parent is documented as legal
106
+ -- (docs/sql-ddl.md § Order Independence): restore-from-dump and mutually-referencing
107
+ -- tables depend on it. So the child below must start enforcing the moment the parent
108
+ -- appears, with no DDL on the child itself.
109
+ -- ===================================
110
+
111
+ create table fwd_c (id integer primary key, p integer null references fwd_p(pid));
112
+
113
+ -- before the parent exists: rejected, naming it
114
+ insert into fwd_c values (1, 1);
115
+ -- error: referenced table 'main.fwd_p' does not exist
116
+
117
+ create table fwd_p (pid integer primary key);
118
+ insert into fwd_p values (1);
119
+
120
+ -- now the very same insert succeeds — the check resolved on the LATER plan
121
+ insert into fwd_c values (1, 1);
122
+
123
+ select id, p from fwd_c order by id;
124
+ → [{"id":1,"p":1}]
125
+
126
+ -- and a genuine orphan still fails with the ordinary FK message (parent exists)
127
+ insert into fwd_c values (2, 99);
128
+ -- error: CHECK constraint failed: _fk_fwd_c_p
129
+
130
+ -- ===================================
131
+ -- A6. …and the other direction: DROP the parent and the child goes back to reporting
132
+ -- the missing table. Proves nothing was cached from creation.
133
+ -- ===================================
134
+
135
+ delete from fwd_c;
136
+ drop table fwd_p;
137
+
138
+ insert into fwd_c values (3, 1);
139
+ -- error: referenced table 'main.fwd_p' does not exist
140
+
141
+ drop table fwd_c;
142
+
143
+ -- ===================================
144
+ -- A7. cross-schema: an UNQUALIFIED parent name binds to the CHILD's OWN schema
145
+ --
146
+ -- That rule is deliberate and matches SQLite, where a foreign key cannot cross
147
+ -- databases (docs/sql-constraints.md §7.6). The failure mode it produces is nasty:
148
+ -- the parent plainly exists — in `main` — and the child in another schema silently
149
+ -- refuses every row. Naming the schema in the message is what makes it diagnosable,
150
+ -- and it points straight at the remedy: qualify the parent.
151
+ -- ===================================
152
+
153
+ declare schema xs {}
154
+ apply schema xs;
155
+ -- run
156
+
157
+ create table main.xs_parent (pid integer primary key);
158
+ insert into main.xs_parent values (1);
159
+
160
+ -- unqualified `xs_parent` inside a table declared in `xs` means `xs.xs_parent`
161
+ create table xs.xs_child (id integer primary key, p integer null references xs_parent(pid));
162
+
163
+ insert into xs.xs_child values (1, 1);
164
+ -- error: referenced table 'xs.xs_parent' does not exist
165
+
166
+ -- qualifying the parent is the fix, and it works
167
+ create table xs.xs_child2 (id integer primary key, p integer null references main.xs_parent(pid));
168
+
169
+ insert into xs.xs_child2 values (1, 1);
170
+
171
+ select id, p from xs.xs_child2 order by id;
172
+ → [{"id":1,"p":1}]
173
+
174
+ -- and it is a real check, not a resolution that quietly stopped enforcing
175
+ insert into xs.xs_child2 values (2, 99);
176
+ -- error: CHECK constraint failed: _fk_xs_child2_p
177
+
178
+ drop table xs.xs_child2;
179
+ drop table xs.xs_child;
180
+ drop table main.xs_parent;
181
+
182
+ -- ===================================
183
+ -- B1. column-count mismatch, child side — `references <parent>` with no column list
184
+ -- defaults to the parent's PRIMARY KEY, which may have a different arity
185
+ --
186
+ -- The written-parent-column form (`references mp(a, b)`) is already refused at CREATE
187
+ -- (41-fk-extended-targets.sqllogic case 5). The defaulted form cannot be: the parent may
188
+ -- not exist yet, and its primary key can change afterwards. So it is caught at the
189
+ -- enforcement seam instead — the statement fails rather than the key going unenforced.
190
+ -- ===================================
191
+
192
+ create table mm_p (a integer not null, b integer not null, primary key (a, b));
193
+ create table mm_c (id integer primary key, x integer null references mm_p);
194
+
195
+ insert into mm_p values (1, 2);
196
+
197
+ insert into mm_c values (1, 1);
198
+ -- error: Foreign key '_fk_mm_c_x' on table 'main.mm_c': 1 column(s) reference the primary key of 'main.mm_p', which has 2 column(s).
199
+
200
+ select count(*) as n from mm_c;
201
+ → [{"n":0}]
202
+
203
+ -- ===================================
204
+ -- B2. …and the parent side. This is the part that used to be silent: a RESTRICT delete
205
+ -- against the parent simply went through, because the parent-side builder skipped
206
+ -- the malformed key exactly as the child-side one did.
207
+ -- ===================================
208
+
209
+ delete from mm_p where a = 1;
210
+ -- error: Foreign key '_fk_mm_c_x' on table 'main.mm_c': 1 column(s) reference the primary key of 'main.mm_p', which has 2 column(s).
211
+
212
+ select count(*) as n from mm_p;
213
+ → [{"n":1}]
214
+
215
+ -- the parent-side UPDATE path too
216
+ update mm_p set b = 3 where a = 1;
217
+ -- error: Foreign key '_fk_mm_c_x' on table 'main.mm_c'
218
+
219
+ select a, b from mm_p order by a;
220
+ → [{"a":1,"b":2}]
221
+
222
+ -- reads are unaffected — a malformed key must not break introspection or queries
223
+ select count(*) as n from mm_p join mm_c on mm_c.x = mm_p.a;
224
+ → [{"n":0}]
225
+
226
+ drop table mm_c;
227
+ drop table mm_p;
228
+
229
+ -- ===================================
230
+ -- B4. `pragma foreign_keys = off` silences arm B too — enforcement off means off on
231
+ -- BOTH sides. The parent side is the one at risk: the runtime DML executor calls
232
+ -- the batchability gate unconditionally (the pragma is re-checked at flush), so
233
+ -- the gate must not raise while enforcement is off.
234
+ -- ===================================
235
+
236
+ pragma foreign_keys = false;
237
+
238
+ create table offmm_p (a integer not null, b integer not null, primary key (a, b));
239
+ create table offmm_c (id integer primary key, x integer null references offmm_p);
240
+
241
+ insert into offmm_p values (1, 2);
242
+ insert into offmm_c values (1, 1);
243
+
244
+ -- child side: no checks are built at all
245
+ select id, x from offmm_c order by id;
246
+ → [{"id":1,"x":1}]
247
+
248
+ -- parent side, both ops: neither the plan gate nor the runtime gate may raise
249
+ delete from offmm_p where a = 1;
250
+
251
+ select count(*) as n from offmm_p;
252
+ → [{"n":0}]
253
+
254
+ insert into offmm_p values (3, 4);
255
+ update offmm_p set b = 5 where a = 3;
256
+
257
+ select a, b from offmm_p order by a;
258
+ → [{"a":3,"b":5}]
259
+
260
+ pragma foreign_keys = true;
261
+
262
+ drop table offmm_c;
263
+ drop table offmm_p;
264
+
265
+ -- ===================================
266
+ -- B5. arm B on the propagating actions — the CASCADE / SET NULL dispatch sites resolve
267
+ -- the referenced columns separately from the RESTRICT pre-check, so a mismatched
268
+ -- key must raise there too rather than cascading nowhere.
269
+ -- ===================================
270
+
271
+ create table cas_p (a integer not null, b integer not null, primary key (a, b));
272
+ create table cas_c (id integer primary key, x integer null references cas_p on delete cascade);
273
+
274
+ insert into cas_p values (1, 2);
275
+
276
+ delete from cas_p where a = 1;
277
+ -- error: Foreign key '_fk_cas_c_x' on table 'main.cas_c': 1 column(s) reference the primary key of 'main.cas_p', which has 2 column(s).
278
+
279
+ select count(*) as n from cas_p;
280
+ → [{"n":1}]
281
+
282
+ drop table cas_c;
283
+ drop table cas_p;
284
+
285
+ create table sn_p (a integer not null, b integer not null, primary key (a, b));
286
+ create table sn_c (id integer primary key, x integer null references sn_p on update set null);
287
+
288
+ insert into sn_p values (1, 2);
289
+
290
+ update sn_p set b = 3 where a = 1;
291
+ -- error: Foreign key '_fk_sn_c_x' on table 'main.sn_c': 1 column(s) reference the primary key of 'main.sn_p', which has 2 column(s).
292
+
293
+ select a, b from sn_p order by a;
294
+ → [{"a":1,"b":2}]
295
+
296
+ drop table sn_c;
297
+ drop table sn_p;
298
+
299
+ -- ===================================
300
+ -- B6. `alter table … add constraint` reaches the same wording. The existing-row scan
301
+ -- resolves the parent key itself, so it is a separate seam from the DML builders
302
+ -- and used to phrase the mismatch its own way.
303
+ -- ===================================
304
+
305
+ create table alt_p (a integer not null, b integer not null, primary key (a, b));
306
+ create table alt_c (id integer primary key, x integer null, y integer null);
307
+
308
+ insert into alt_p values (1, 2);
309
+ insert into alt_c values (1, 1, 2);
310
+
311
+ alter table alt_c add constraint fk_alt foreign key (x) references alt_p;
312
+ -- error: Foreign key 'fk_alt' on table 'main.alt_c': 1 column(s) reference the primary key of 'main.alt_p', which has 2 column(s).
313
+
314
+ -- the refusal left nothing behind — the correctly-shaped ADD over the same rows works
315
+ alter table alt_c add constraint fk_alt2 foreign key (x, y) references alt_p;
316
+
317
+ insert into alt_c values (2, 9, 9);
318
+ -- error: CHECK constraint failed: fk_alt2
319
+
320
+ drop table alt_c;
321
+ drop table alt_p;
322
+
323
+ -- ===================================
324
+ -- B3. the correctly-shaped composite case still works end to end, so B1/B2 are not
325
+ -- rejecting every defaulted `references <parent>`
326
+ -- ===================================
327
+
328
+ create table ok_p (a integer not null, b integer not null, primary key (a, b));
329
+ create table ok_c (id integer primary key, x integer null, y integer null, foreign key (x, y) references ok_p);
330
+
331
+ insert into ok_p values (1, 2);
332
+ insert into ok_c values (1, 1, 2);
333
+
334
+ select id, x, y from ok_c order by id;
335
+ → [{"id":1,"x":1,"y":2}]
336
+
337
+ insert into ok_c values (2, 9, 9);
338
+ -- error: CHECK constraint failed: _fk_ok_c_x_y
339
+
340
+ -- RESTRICT is genuinely enforced on the parent
341
+ delete from ok_p where a = 1;
342
+ -- error: FOREIGN KEY constraint failed
343
+
344
+ select a, b from ok_p order by a;
345
+ → [{"a":1,"b":2}]
346
+
347
+ drop table ok_c;
348
+ drop table ok_p;
349
+
350
+ -- single-column defaulted `references <parent>` — the ordinary shape
351
+ create table ok1_p (pid integer primary key);
352
+ create table ok1_c (id integer primary key, p integer null references ok1_p);
353
+
354
+ insert into ok1_p values (1);
355
+ insert into ok1_c values (1, 1);
356
+
357
+ select id, p from ok1_c order by id;
358
+ → [{"id":1,"p":1}]
359
+
360
+ insert into ok1_c values (2, 99);
361
+ -- error: CHECK constraint failed: _fk_ok1_c_p
362
+
363
+ drop table ok1_c;
364
+ drop table ok1_p;