@quereus/quereus 4.20.0 → 4.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. package/README.md +2 -0
  2. package/dist/src/common/types.d.ts +4 -4
  3. package/dist/src/index.d.ts +1 -1
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js +3 -2
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/src/schema/catalog-rendering.js +13 -1
  8. package/dist/src/schema/catalog-rendering.js.map +1 -1
  9. package/dist/src/schema/catalog.d.ts +35 -2
  10. package/dist/src/schema/catalog.d.ts.map +1 -1
  11. package/dist/src/schema/catalog.js +42 -33
  12. package/dist/src/schema/catalog.js.map +1 -1
  13. package/dist/src/schema/schema-differ.d.ts +1 -1
  14. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  15. package/dist/src/schema/schema-differ.js +195 -33
  16. package/dist/src/schema/schema-differ.js.map +1 -1
  17. package/dist/src/schema/unique-enforcement.d.ts +23 -1
  18. package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
  19. package/dist/src/schema/unique-enforcement.js +43 -1
  20. package/dist/src/schema/unique-enforcement.js.map +1 -1
  21. package/dist/src/vtab/memory/layer/manager.d.ts +15 -12
  22. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  23. package/dist/src/vtab/memory/layer/manager.js +87 -100
  24. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  25. package/package.json +7 -4
  26. package/test/README.md +173 -0
  27. package/test/logic/01-basic.sqllogic +39 -0
  28. package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
  29. package/test/logic/01.2-strings.sqllogic +43 -0
  30. package/test/logic/01.5-insert-select.sqllogic +237 -0
  31. package/test/logic/01.6-update-extras.sqllogic +118 -0
  32. package/test/logic/01.7-update-from.sqllogic +67 -0
  33. package/test/logic/01.8-delete-extras.sqllogic +122 -0
  34. package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
  35. package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
  36. package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
  37. package/test/logic/01.9-query-expr-values.sqllogic +111 -0
  38. package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
  39. package/test/logic/02-filters.sqllogic +54 -0
  40. package/test/logic/02-smoke.sqllogic +62 -0
  41. package/test/logic/02.1-bind-parameters.sqllogic +223 -0
  42. package/test/logic/03-expressions.sqllogic +190 -0
  43. package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
  44. package/test/logic/03.4-defaults.sqllogic +554 -0
  45. package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
  46. package/test/logic/03.5-tvf.sqllogic +61 -0
  47. package/test/logic/03.6-type-system.sqllogic +544 -0
  48. package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
  49. package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
  50. package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
  51. package/test/logic/03.8-not-precedence.sqllogic +255 -0
  52. package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
  53. package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
  54. package/test/logic/04-order-by.sqllogic +38 -0
  55. package/test/logic/04-transactions.sqllogic +239 -0
  56. package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
  57. package/test/logic/05-vtab_memory.sqllogic +50 -0
  58. package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
  59. package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
  60. package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
  61. package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
  62. package/test/logic/06-builtin_functions.sqllogic +149 -0
  63. package/test/logic/06.1-string-functions.sqllogic +92 -0
  64. package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
  65. package/test/logic/06.2-math-functions.sqllogic +82 -0
  66. package/test/logic/06.3-schema.sqllogic +48 -0
  67. package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
  68. package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
  69. package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
  70. package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
  71. package/test/logic/06.3.4-view-info.sqllogic +378 -0
  72. package/test/logic/06.3.5-column-info.sqllogic +347 -0
  73. package/test/logic/06.3.6-schema-views.sqllogic +29 -0
  74. package/test/logic/06.4-schema-search-path.sqllogic +354 -0
  75. package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
  76. package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
  77. package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
  78. package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
  79. package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
  80. package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
  81. package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
  82. package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
  83. package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
  84. package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
  85. package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
  86. package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
  87. package/test/logic/06.7-json-extended.sqllogic +53 -0
  88. package/test/logic/06.8-json-path-operators.sqllogic +99 -0
  89. package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
  90. package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
  91. package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
  92. package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
  93. package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
  94. package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
  95. package/test/logic/07-aggregates.sqllogic +193 -0
  96. package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
  97. package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
  98. package/test/logic/07.3-group-by-extras.sqllogic +602 -0
  99. package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
  100. package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
  101. package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
  102. package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
  103. package/test/logic/07.5-window.sqllogic +1941 -0
  104. package/test/logic/07.5.1-window-named.sqllogic +13 -0
  105. package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
  106. package/test/logic/07.6-subqueries.sqllogic +78 -0
  107. package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
  108. package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
  109. package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
  110. package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
  111. package/test/logic/07.7.1-in-extras.sqllogic +158 -0
  112. package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
  113. package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
  114. package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
  115. package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
  116. package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
  117. package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
  118. package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
  119. package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
  120. package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
  121. package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
  122. package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
  123. package/test/logic/07.9-in-value-list.sqllogic +154 -0
  124. package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
  125. package/test/logic/08-views.sqllogic +64 -0
  126. package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
  127. package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
  128. package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
  129. package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
  130. package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
  131. package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
  132. package/test/logic/09-set_operations.sqllogic +244 -0
  133. package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
  134. package/test/logic/10-distinct_datatypes.sqllogic +127 -0
  135. package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
  136. package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
  137. package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
  138. package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
  139. package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
  140. package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
  141. package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
  142. package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
  143. package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
  144. package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
  145. package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
  146. package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
  147. package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
  148. package/test/logic/10.2-column-features.sqllogic +365 -0
  149. package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
  150. package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
  151. package/test/logic/10.3-function-features.sqllogic +247 -0
  152. package/test/logic/10.4-schema-scale.sqllogic +168 -0
  153. package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
  154. package/test/logic/10.5-indexes.sqllogic +164 -0
  155. package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
  156. package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
  157. package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
  158. package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
  159. package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
  160. package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
  161. package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
  162. package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
  163. package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
  164. package/test/logic/100.1-where-extras.sqllogic +163 -0
  165. package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
  166. package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
  167. package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
  168. package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
  169. package/test/logic/102-unique-constraints.sqllogic +145 -0
  170. package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
  171. package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
  172. package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
  173. package/test/logic/102.2-unique-collation.sqllogic +181 -0
  174. package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
  175. package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
  176. package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
  177. package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
  178. package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
  179. package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
  180. package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
  181. package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
  182. package/test/logic/108-cardinality-estimation.sqllogic +146 -0
  183. package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
  184. package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
  185. package/test/logic/11-joins.sqllogic +86 -0
  186. package/test/logic/11.1-join-using.sqllogic +267 -0
  187. package/test/logic/11.2-comma-join.sqllogic +35 -0
  188. package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
  189. package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
  190. package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
  191. package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
  192. package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
  193. package/test/logic/12-empty-primary-key.sqllogic +124 -0
  194. package/test/logic/12-join_padding_order.sqllogic +58 -0
  195. package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
  196. package/test/logic/13-cte.sqllogic +137 -0
  197. package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
  198. package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
  199. package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
  200. package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
  201. package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
  202. package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
  203. package/test/logic/13.4-cte-extras.sqllogic +98 -0
  204. package/test/logic/13.5-cte-join-order.sqllogic +166 -0
  205. package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
  206. package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
  207. package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
  208. package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
  209. package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
  210. package/test/logic/14-utilities.sqllogic +168 -0
  211. package/test/logic/15-timespan.sqllogic +279 -0
  212. package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
  213. package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
  214. package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
  215. package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
  216. package/test/logic/16-epoch.sqllogic +187 -0
  217. package/test/logic/17-weekday-modifier.sqllogic +78 -0
  218. package/test/logic/18-json-string-escapes.sqllogic +86 -0
  219. package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
  220. package/test/logic/20-empty-single-row.sqllogic +261 -0
  221. package/test/logic/21-null-edge-cases.sqllogic +227 -0
  222. package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
  223. package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
  224. package/test/logic/21.2-between-edges.sqllogic +157 -0
  225. package/test/logic/22-boundary-values.sqllogic +175 -0
  226. package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
  227. package/test/logic/24-builtin-branches.sqllogic +611 -0
  228. package/test/logic/24.1-substr-extras.sqllogic +75 -0
  229. package/test/logic/24.2-random-extras.sqllogic +39 -0
  230. package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
  231. package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
  232. package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
  233. package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
  234. package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
  235. package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
  236. package/test/logic/26-join-edge-cases.sqllogic +333 -0
  237. package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
  238. package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
  239. package/test/logic/26.3-join-on-constants.sqllogic +61 -0
  240. package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
  241. package/test/logic/27-window-edge-cases.sqllogic +206 -0
  242. package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
  243. package/test/logic/27.2-window-exclude.sqllogic +13 -0
  244. package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
  245. package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
  246. package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
  247. package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
  248. package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
  249. package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
  250. package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
  251. package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
  252. package/test/logic/40-constraints.sqllogic +418 -0
  253. package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
  254. package/test/logic/40.2-check-extras.sqllogic +683 -0
  255. package/test/logic/41-alter-table.sqllogic +191 -0
  256. package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
  257. package/test/logic/41-fk-cross-schema.sqllogic +155 -0
  258. package/test/logic/41-fk-extended-targets.sqllogic +173 -0
  259. package/test/logic/41-foreign-keys.sqllogic +1001 -0
  260. package/test/logic/41-generated-column-errors.sqllogic +225 -0
  261. package/test/logic/41-generated-column-extras.sqllogic +598 -0
  262. package/test/logic/41-generated-column-scope.sqllogic +329 -0
  263. package/test/logic/41-generated-columns.sqllogic +361 -0
  264. package/test/logic/41.1-alter-pk.sqllogic +230 -0
  265. package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
  266. package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
  267. package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
  268. package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
  269. package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
  270. package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
  271. package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
  272. package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
  273. package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
  274. package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
  275. package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
  276. package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
  277. package/test/logic/41.2-alter-column.sqllogic +382 -0
  278. package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
  279. package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
  280. package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
  281. package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
  282. package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
  283. package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
  284. package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
  285. package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
  286. package/test/logic/41.5-alter-misc.sqllogic +48 -0
  287. package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
  288. package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
  289. package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
  290. package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
  291. package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
  292. package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
  293. package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
  294. package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
  295. package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
  296. package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
  297. package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
  298. package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
  299. package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
  300. package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
  301. package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
  302. package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
  303. package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
  304. package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
  305. package/test/logic/42-committed-snapshot.sqllogic +254 -0
  306. package/test/logic/42-returning.sqllogic +159 -0
  307. package/test/logic/42.1-returning-extras.sqllogic +232 -0
  308. package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
  309. package/test/logic/43-default-nullability.sqllogic +131 -0
  310. package/test/logic/43-transition-constraints.sqllogic +341 -0
  311. package/test/logic/43.1-default-collation.sqllogic +140 -0
  312. package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
  313. package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
  314. package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
  315. package/test/logic/44-determinism-validation.sqllogic +164 -0
  316. package/test/logic/44-orthogonality.sqllogic +146 -0
  317. package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
  318. package/test/logic/45-udf-determinism.sqllogic +39 -0
  319. package/test/logic/46-mutation-context.sqllogic +595 -0
  320. package/test/logic/47-upsert.sqllogic +255 -0
  321. package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
  322. package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
  323. package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
  324. package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
  325. package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
  326. package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
  327. package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
  328. package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
  329. package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
  330. package/test/logic/49-reference-graph.sqllogic +84 -0
  331. package/test/logic/50-declarative-schema.sqllogic +2550 -0
  332. package/test/logic/50-metadata-tags.sqllogic +1033 -0
  333. package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
  334. package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
  335. package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
  336. package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
  337. package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
  338. package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
  339. package/test/logic/51-lens-foundation.sqllogic +147 -0
  340. package/test/logic/51-materialized-views.sqllogic +376 -0
  341. package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
  342. package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
  343. package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
  344. package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
  345. package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
  346. package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
  347. package/test/logic/52-lens-overrides.sqllogic +566 -0
  348. package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
  349. package/test/logic/53-reserved-tags.sqllogic +252 -0
  350. package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
  351. package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
  352. package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
  353. package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
  354. package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
  355. package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
  356. package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
  357. package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
  358. package/test/logic/55-lens-prover.sqllogic +202 -0
  359. package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
  360. package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
  361. package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
  362. package/test/logic/81-quickpick.sqllogic +24 -0
  363. package/test/logic/82-bloom-join.sqllogic +185 -0
  364. package/test/logic/83-merge-join.sqllogic +280 -0
  365. package/test/logic/84-asof-scan.sqllogic +238 -0
  366. package/test/logic/84-key-cardinality.sqllogic +50 -0
  367. package/test/logic/85-relational-const-folding.sqllogic +51 -0
  368. package/test/logic/86-scalar-cse.sqllogic +42 -0
  369. package/test/logic/90-error_paths.sqllogic +114 -0
  370. package/test/logic/90.1-parse-errors.sqllogic +77 -0
  371. package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
  372. package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
  373. package/test/logic/90.3-expression-errors.sqllogic +43 -0
  374. package/test/logic/90.4-dml-errors.sqllogic +47 -0
  375. package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
  376. package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
  377. package/test/logic/90.6-select-error-paths.sqllogic +57 -0
  378. package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
  379. package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
  380. package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
  381. package/test/logic/93.1-view-error-paths.sqllogic +74 -0
  382. package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
  383. package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
  384. package/test/logic/93.4-view-mutation.sqllogic +4881 -0
  385. package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
  386. package/test/logic/93.5-authored-inverse.sqllogic +415 -0
  387. package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
  388. package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
  389. package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
  390. package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
  391. package/test/logic/95-assertions.sqllogic +1417 -0
  392. package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
  393. package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
  394. package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
  395. package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
  396. package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
  397. package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
  398. package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
  399. package/test/logic/drop-unique-index.sqllogic +88 -0
  400. package/test/logic/pushdown-test.sqllogic +36 -0
@@ -0,0 +1,217 @@
1
+ -- 28.2-set-op-branch-types.sqllogic
2
+ -- Cross-branch type merge for set operations (ticket
3
+ -- union-branch-value-not-converted-on-write): a set operation advertises a type
4
+ -- it actually produces, merged symmetrically across both operands, so a branch
5
+ -- stores exactly what it would have stored on its own — in either arm order.
6
+ -- No `using memory`, so store mode exercises the same rules on the store path.
7
+
8
+ -- ============================================================
9
+ -- DATE branch vs TEXT branch. No common concrete type exists (temporal parse is
10
+ -- normalizing), so the merge advertises ANY and every cell converts at the DML —
11
+ -- the raw literal normalizes and the already-stored value survives
12
+ -- re-conversion (temporal conversion is idempotent).
13
+ -- ============================================================
14
+
15
+ create table sobt_d (id integer primary key, d date);
16
+ create table sobt_d2 (id integer primary key, d date);
17
+ insert into sobt_d values (1, '2024-06-05');
18
+ -- run
19
+
20
+ -- Single-arm baseline: the literal normalizes to a plain date.
21
+ insert into sobt_d2 select 2, '2024-01-02T00:00:00Z';
22
+ -- run
23
+
24
+ select id, d from sobt_d2;
25
+ → [{"id":2,"d":"2024-01-02"}]
26
+
27
+ -- DATE arm on the LEFT: the TEXT literal in the right arm must STILL normalize
28
+ -- (it used to ride the advertised DATE type unconverted — raw timestamp text
29
+ -- silently stored in a DATE column).
30
+ delete from sobt_d2;
31
+ insert into sobt_d2 select id, d from sobt_d union all select 2, '2024-01-02T00:00:00Z';
32
+ -- run
33
+
34
+ select id, d from sobt_d2 order by id;
35
+ → [{"id":1,"d":"2024-06-05"},{"id":2,"d":"2024-01-02"}]
36
+
37
+ -- DATE arm on the RIGHT: same result — the merge is order-independent.
38
+ delete from sobt_d2;
39
+ insert into sobt_d2 select 2, '2024-01-02T00:00:00Z' union all select id, d from sobt_d;
40
+ -- run
41
+
42
+ select id, d from sobt_d2 order by id;
43
+ → [{"id":1,"d":"2024-06-05"},{"id":2,"d":"2024-01-02"}]
44
+
45
+ -- ============================================================
46
+ -- Must-keep-working cases: pairs whose conversion is total and idempotent keep
47
+ -- their current behavior, and the numeric merge must promote (NOT collapse to
48
+ -- TEXT the way CASE branch typing does).
49
+ -- ============================================================
50
+
51
+ -- Mixed INTEGER/TEXT values pass through a bag union unchanged.
52
+ select 1 as v union all select 'a';
53
+ → [{"v":1},{"v":"a"}]
54
+
55
+ -- INTEGER ∪ REAL promotes numerically: both values stay numbers.
56
+ select 1 as v union all select 2.5;
57
+ → [{"v":1},{"v":2.5}]
58
+
59
+ create table sobt_i (id integer primary key, n integer);
60
+
61
+ -- TEXT numeral in either arm still converts on insert.
62
+ insert into sobt_i select 1, 5 union all select 2, '7';
63
+ -- run
64
+
65
+ select id, n from sobt_i order by id;
66
+ → [{"id":1,"n":5},{"id":2,"n":7}]
67
+
68
+ delete from sobt_i;
69
+ insert into sobt_i select 1, '7' union all select 2, 5;
70
+ -- run
71
+
72
+ select id, n from sobt_i order by id;
73
+ → [{"id":1,"n":7},{"id":2,"n":5}]
74
+
75
+ -- ============================================================
76
+ -- A `select null` branch must not poison a well-typed union: NULL is a member
77
+ -- of every type, so the other branch's type stands and its values are
78
+ -- untouched.
79
+ -- ============================================================
80
+
81
+ create table sobt_n (id integer primary key, d date null);
82
+ insert into sobt_n select 3, null union all select 4, d from sobt_d;
83
+ -- run
84
+
85
+ select id, d from sobt_n order by id;
86
+ → [{"id":3,"d":null},{"id":4,"d":"2024-06-05"}]
87
+
88
+ -- ...and in the other arm order: the NULL branch on the right must not poison
89
+ -- the DATE claim either.
90
+ delete from sobt_n;
91
+ insert into sobt_n select 4, d from sobt_d union all select 3, null;
92
+ -- run
93
+
94
+ select id, d from sobt_n order by id;
95
+ → [{"id":3,"d":null},{"id":4,"d":"2024-06-05"}]
96
+
97
+ -- ============================================================
98
+ -- DIFF (symmetric difference) expands to (A except B) union (B except A); the
99
+ -- operands are aligned ONCE before the expansion, so both inner EXCEPTs — and
100
+ -- the outer UNION — see the same merged column type.
101
+ -- ============================================================
102
+
103
+ create table sobt_j (id integer primary key, j json);
104
+ insert into sobt_j values (1, '"abc"');
105
+ -- run
106
+
107
+ -- The TEXT branch is cast to JSON, so the shared value cancels and only the
108
+ -- symmetric difference remains — in either arm order.
109
+ select j from sobt_j diff select '"xyz"';
110
+ → [{"j":"abc"},{"j":"xyz"}]
111
+
112
+ select '"xyz"' as j diff select j from sobt_j;
113
+ → [{"j":"xyz"},{"j":"abc"}]
114
+
115
+ select j from sobt_j diff select '"abc"';
116
+ → []
117
+
118
+ -- ============================================================
119
+ -- ORDER BY over a set operation, a view over one, and a nested set operation
120
+ -- all still resolve after branch alignment (the aligned branch republishes its
121
+ -- columns; the compound scope resolves against the set operation's output).
122
+ -- ============================================================
123
+
124
+ select j as x from sobt_j union all select '"9"' order by x;
125
+ → [{"x":"9"},{"x":"abc"}]
126
+
127
+ create view sobt_v as select j as x from sobt_j union all select '"9"';
128
+ -- run
129
+
130
+ select json_quote(x) as q from sobt_v order by 1;
131
+ → [{"q":"\"9\""},{"q":"\"abc\""}]
132
+
133
+ select j from sobt_j union select '"9"' union select '"abc"';
134
+ → [{"j":"abc"},{"j":"9"}]
135
+
136
+ -- ============================================================
137
+ -- Mixed whole-number/decimal branches (ticket
138
+ -- set-op-numeric-promotion-skips-conversion). Neither branch is converted, so
139
+ -- the merge advertises NUMERIC — a type the mixed stream genuinely inhabits —
140
+ -- rather than REAL, which the DML write pass would have believed and skipped
141
+ -- conversion for. Small integers cannot discriminate (both internal forms
142
+ -- coincide) and the harness normalizes BigInt to Number before comparing rows,
143
+ -- so the stored-form assertions all go through `cast(v as text)`.
144
+ -- ============================================================
145
+
146
+ create table sobt_r (id integer primary key, v real);
147
+
148
+ -- Baseline: a direct insert converts to the REAL (floating point) form, which
149
+ -- rounds 2^53+1 down to 2^53.
150
+ insert into sobt_r values (1, 9007199254740993);
151
+ -- run
152
+
153
+ select cast(v as text) as t from sobt_r;
154
+ → [{"t":"9007199254740992"}]
155
+
156
+ -- Whole-number arm on the LEFT: the REAL column must store exactly what the
157
+ -- direct insert stored.
158
+ delete from sobt_r;
159
+ insert into sobt_r (id, v) select 1, 9007199254740993 union all select 2, 2.5;
160
+ -- run
161
+
162
+ select cast(v as text) as t from sobt_r order by id;
163
+ → [{"t":"9007199254740992"},{"t":"2.5"}]
164
+
165
+ -- Whole-number arm on the RIGHT: same result — the merge is order-independent.
166
+ delete from sobt_r;
167
+ insert into sobt_r (id, v) select 2, 2.5 union all select 1, 9007199254740993;
168
+ -- run
169
+
170
+ select cast(v as text) as t from sobt_r order by id;
171
+ → [{"t":"9007199254740992"},{"t":"2.5"}]
172
+
173
+ -- A REAL-declared KEY fed by the same mix: an unconverted bigint used to reach
174
+ -- REAL_TYPE.compare and throw ("Cannot convert a BigInt value to a number").
175
+ create table sobt_rk (v real primary key);
176
+ insert into sobt_rk (v) select 9007199254740993 union all select 2.5;
177
+ -- run
178
+
179
+ select cast(v as text) as t from sobt_rk order by v;
180
+ → [{"t":"2.5"},{"t":"9007199254740992"}]
181
+
182
+ -- A NUMERIC-declared KEY: conversion IS legitimately skipped here (NUMERIC holds
183
+ -- both forms), so the bigint reaches NUMERIC_TYPE.compare and must be ordered,
184
+ -- not rejected (ticket numeric-comparator-rejects-bigint), and stored intact.
185
+ create table sobt_nk (v numeric primary key);
186
+ insert into sobt_nk (v) select 9007199254740993 union all select 2.5;
187
+ -- run
188
+
189
+ select cast(v as text) as t from sobt_nk order by v;
190
+ → [{"t":"2.5"},{"t":"9007199254740993"}]
191
+
192
+ -- READ side is untouched by this fix: each row keeps its own storage class
193
+ -- through a compound select (as SQLite does), so a big whole number does NOT
194
+ -- get rounded on the way out.
195
+ select cast(v as text) as t from (select 9007199254740993 as v union all select 2.5) as s;
196
+ → [{"t":"9007199254740993"},{"t":"2.5"}]
197
+
198
+ -- Three or more `union all` arms collapse into AsyncGatherNode, which folds the
199
+ -- same merge across every branch — the mixed pair must still reach NUMERIC there.
200
+ create table sobt_g (v real primary key);
201
+ insert into sobt_g (v) select 2.5 union all select 9007199254740993 union all select 7;
202
+ -- run
203
+
204
+ select cast(v as text) as t from sobt_g order by v;
205
+ → [{"t":"2.5"},{"t":"7"},{"t":"9007199254740992"}]
206
+
207
+ -- Deduplicating set operations compare across branches under the merged type, so
208
+ -- the whole-number and decimal spellings of one value must collapse (and not
209
+ -- throw out of the comparator on the bigint operand).
210
+ select v from (select 1 as v union select 1.0) as s;
211
+ → [{"v":1}]
212
+
213
+ select v from (select 3 as v intersect select 3.0) as s;
214
+ → [{"v":3}]
215
+
216
+ select v from (select 3 as v except select 3.0) as s;
217
+ → []
@@ -0,0 +1,442 @@
1
+ -- constraint-edge-cases.sqllogic - Edge-case interactions between constraints, FK cascades, and assertions
2
+
3
+ PRAGMA foreign_keys = true;
4
+
5
+ -- ===================================================================
6
+ -- Multi-row DELETE with cascading FKs
7
+ -- Delete multiple parent rows in a single statement where each parent
8
+ -- has children — verify all children are cascaded correctly.
9
+ -- ===================================================================
10
+
11
+ CREATE TABLE mr_parent (
12
+ id INTEGER PRIMARY KEY,
13
+ name TEXT
14
+ );
15
+
16
+ CREATE TABLE mr_child (
17
+ id INTEGER PRIMARY KEY,
18
+ parent_id INTEGER,
19
+ info TEXT,
20
+ FOREIGN KEY (parent_id) REFERENCES mr_parent(id) ON DELETE CASCADE
21
+ );
22
+
23
+ INSERT INTO mr_parent VALUES (1, 'P1'), (2, 'P2'), (3, 'P3');
24
+ INSERT INTO mr_child VALUES (10, 1, 'C1a'), (11, 1, 'C1b'), (20, 2, 'C2a'), (21, 2, 'C2b'), (30, 3, 'C3a');
25
+
26
+ SELECT count(*) FROM mr_child;
27
+ → [{"count(*)":5}]
28
+
29
+ -- Delete two parents at once — children of both should be cascaded
30
+ DELETE FROM mr_parent WHERE id IN (1, 2);
31
+
32
+ SELECT count(*) FROM mr_parent;
33
+ → [{"count(*)":1}]
34
+
35
+ SELECT count(*) FROM mr_child;
36
+ → [{"count(*)":1}]
37
+
38
+ -- Only P3's child remains
39
+ SELECT id, parent_id FROM mr_child;
40
+ → [{"id":30,"parent_id":3}]
41
+
42
+ DROP TABLE mr_child;
43
+ DROP TABLE mr_parent;
44
+
45
+ -- ===================================================================
46
+ -- CASCADE across three levels
47
+ -- grandparent → parent → child FK chain with CASCADE DELETE
48
+ -- ===================================================================
49
+
50
+ CREATE TABLE gp (
51
+ id INTEGER PRIMARY KEY,
52
+ name TEXT
53
+ );
54
+
55
+ CREATE TABLE par (
56
+ id INTEGER PRIMARY KEY,
57
+ gp_id INTEGER,
58
+ FOREIGN KEY (gp_id) REFERENCES gp(id) ON DELETE CASCADE
59
+ );
60
+
61
+ CREATE TABLE ch (
62
+ id INTEGER PRIMARY KEY,
63
+ par_id INTEGER,
64
+ FOREIGN KEY (par_id) REFERENCES par(id) ON DELETE CASCADE
65
+ );
66
+
67
+ INSERT INTO gp VALUES (1, 'G1'), (2, 'G2');
68
+ INSERT INTO par VALUES (10, 1), (11, 1), (20, 2);
69
+ INSERT INTO ch VALUES (100, 10), (101, 10), (110, 11), (200, 20);
70
+
71
+ SELECT count(*) FROM ch;
72
+ → [{"count(*)":4}]
73
+
74
+ -- Delete grandparent — should cascade through parent to child
75
+ DELETE FROM gp WHERE id = 1;
76
+
77
+ SELECT count(*) FROM gp;
78
+ → [{"count(*)":1}]
79
+
80
+ SELECT count(*) FROM par;
81
+ → [{"count(*)":1}]
82
+
83
+ -- Only children of G2's parent (par id=20) remain
84
+ SELECT count(*) FROM ch;
85
+ → [{"count(*)":1}]
86
+
87
+ SELECT id, par_id FROM ch;
88
+ → [{"id":200,"par_id":20}]
89
+
90
+ DROP TABLE ch;
91
+ DROP TABLE par;
92
+ DROP TABLE gp;
93
+
94
+ -- ===================================================================
95
+ -- SET NULL cascade on multi-row delete
96
+ -- Delete multiple parents with SET NULL children — verify all affected
97
+ -- children have NULLed FK columns.
98
+ -- ===================================================================
99
+
100
+ CREATE TABLE snm_parent (
101
+ id INTEGER PRIMARY KEY,
102
+ name TEXT
103
+ );
104
+
105
+ CREATE TABLE snm_child (
106
+ id INTEGER PRIMARY KEY,
107
+ parent_id INTEGER NULL,
108
+ FOREIGN KEY (parent_id) REFERENCES snm_parent(id) ON DELETE SET NULL
109
+ );
110
+
111
+ INSERT INTO snm_parent VALUES (1, 'X'), (2, 'Y'), (3, 'Z');
112
+ INSERT INTO snm_child VALUES (10, 1), (11, 1), (20, 2), (30, 3);
113
+
114
+ -- Delete two parents at once
115
+ DELETE FROM snm_parent WHERE id IN (1, 2);
116
+
117
+ SELECT id, parent_id FROM snm_child ORDER BY id;
118
+ → [{"id":10,"parent_id":null},{"id":11,"parent_id":null},{"id":20,"parent_id":null},{"id":30,"parent_id":3}]
119
+
120
+ DROP TABLE snm_child;
121
+ DROP TABLE snm_parent;
122
+
123
+ -- ===================================================================
124
+ -- Multiple assertions in same transaction
125
+ -- Two independent assertions, one passes and one fails — verify the
126
+ -- failing one prevents COMMIT and the error identifies which assertion.
127
+ -- ===================================================================
128
+
129
+ CREATE TABLE ma_data (id INTEGER PRIMARY KEY, a INTEGER, b INTEGER);
130
+ INSERT INTO ma_data VALUES (1, 10, 20);
131
+ -- run
132
+
133
+ CREATE ASSERTION ma_a_positive CHECK (NOT EXISTS (SELECT 1 FROM ma_data WHERE a < 0));
134
+ CREATE ASSERTION ma_b_small CHECK (NOT EXISTS (SELECT 1 FROM ma_data WHERE b > 100));
135
+ -- run
136
+
137
+ -- Both pass: valid insert
138
+ BEGIN;
139
+ INSERT INTO ma_data VALUES (2, 5, 50);
140
+ COMMIT;
141
+ -- run
142
+
143
+ SELECT count(*) FROM ma_data;
144
+ → [{"count(*)":2}]
145
+
146
+ -- a passes, b fails → should identify ma_b_small
147
+ BEGIN;
148
+ INSERT INTO ma_data VALUES (3, 1, 200);
149
+ COMMIT;
150
+ -- error: Integrity assertion failed: ma_b_small
151
+
152
+ -- a fails → should identify ma_a_positive
153
+ BEGIN;
154
+ INSERT INTO ma_data VALUES (4, -5, 10);
155
+ COMMIT;
156
+ -- error: Integrity assertion failed: ma_a_positive
157
+
158
+ -- Verify only original 2 rows
159
+ SELECT count(*) FROM ma_data;
160
+ → [{"count(*)":2}]
161
+
162
+ DROP ASSERTION ma_a_positive;
163
+ DROP ASSERTION ma_b_small;
164
+ DROP TABLE ma_data;
165
+ -- run
166
+
167
+ -- ===================================================================
168
+ -- Deferred CHECK + assertion in same transaction
169
+ -- A deferred row-level CHECK and a global assertion both evaluated at
170
+ -- COMMIT — verify both are checked and the first failure is reported.
171
+ -- ===================================================================
172
+
173
+ CREATE TABLE ref_lookup (id TEXT PRIMARY KEY, label TEXT);
174
+ INSERT INTO ref_lookup VALUES ('valid', 'Valid Ref');
175
+ -- run
176
+
177
+ CREATE TABLE da_data (
178
+ id INTEGER PRIMARY KEY,
179
+ ref_id TEXT,
180
+ val INTEGER,
181
+ CONSTRAINT ref_exists CHECK ON INSERT, UPDATE (
182
+ EXISTS (SELECT 1 FROM ref_lookup WHERE ref_lookup.id = NEW.ref_id)
183
+ )
184
+ );
185
+ -- run
186
+
187
+ CREATE ASSERTION da_val_positive CHECK (NOT EXISTS (SELECT 1 FROM da_data WHERE val < 0));
188
+ -- run
189
+
190
+ -- Both pass
191
+ BEGIN;
192
+ INSERT INTO da_data VALUES (1, 'valid', 10);
193
+ COMMIT;
194
+ -- run
195
+
196
+ SELECT count(*) FROM da_data;
197
+ → [{"count(*)":1}]
198
+
199
+ -- Deferred CHECK fails (bad ref_id)
200
+ BEGIN;
201
+ INSERT INTO da_data VALUES (2, 'missing', 5);
202
+ COMMIT;
203
+ -- error: CHECK constraint failed: ref_exists
204
+
205
+ -- Assertion fails (negative val, valid ref)
206
+ BEGIN;
207
+ INSERT INTO da_data VALUES (3, 'valid', -10);
208
+ COMMIT;
209
+ -- error: Integrity assertion failed: da_val_positive
210
+
211
+ -- Verify only original row exists
212
+ SELECT count(*) FROM da_data;
213
+ → [{"count(*)":1}]
214
+
215
+ DROP ASSERTION da_val_positive;
216
+ DROP TABLE da_data;
217
+ DROP TABLE ref_lookup;
218
+ -- run
219
+
220
+ -- ===================================================================
221
+ -- Multiple child tables with different cascade actions on same parent
222
+ -- One child uses CASCADE, another uses SET NULL — both should fire
223
+ -- correctly on parent delete.
224
+ -- ===================================================================
225
+
226
+ CREATE TABLE mc_parent (
227
+ id INTEGER PRIMARY KEY,
228
+ name TEXT
229
+ );
230
+
231
+ CREATE TABLE mc_cascade_child (
232
+ id INTEGER PRIMARY KEY,
233
+ parent_id INTEGER,
234
+ FOREIGN KEY (parent_id) REFERENCES mc_parent(id) ON DELETE CASCADE
235
+ );
236
+
237
+ CREATE TABLE mc_setnull_child (
238
+ id INTEGER PRIMARY KEY,
239
+ parent_id INTEGER NULL,
240
+ FOREIGN KEY (parent_id) REFERENCES mc_parent(id) ON DELETE SET NULL
241
+ );
242
+
243
+ INSERT INTO mc_parent VALUES (1, 'P1'), (2, 'P2');
244
+ INSERT INTO mc_cascade_child VALUES (10, 1), (11, 1), (20, 2);
245
+ INSERT INTO mc_setnull_child VALUES (100, 1), (101, 1), (200, 2);
246
+
247
+ -- Delete parent 1 — cascade child rows deleted, setnull child rows nulled
248
+ DELETE FROM mc_parent WHERE id = 1;
249
+
250
+ -- CASCADE child: rows for parent 1 gone
251
+ SELECT count(*) FROM mc_cascade_child WHERE parent_id = 1;
252
+ → [{"count(*)":0}]
253
+
254
+ -- CASCADE child: parent 2 rows untouched
255
+ SELECT count(*) FROM mc_cascade_child WHERE parent_id = 2;
256
+ → [{"count(*)":1}]
257
+
258
+ -- SET NULL child: rows for parent 1 have null FK
259
+ SELECT id, parent_id FROM mc_setnull_child ORDER BY id;
260
+ → [{"id":100,"parent_id":null},{"id":101,"parent_id":null},{"id":200,"parent_id":2}]
261
+
262
+ DROP TABLE mc_cascade_child;
263
+ DROP TABLE mc_setnull_child;
264
+ DROP TABLE mc_parent;
265
+
266
+ -- ===================================================================
267
+ -- Savepoint interaction with deferred constraints
268
+ -- Insert violating row, create savepoint, fix the violation, rollback
269
+ -- savepoint (restoring violation), then attempt COMMIT — should fail.
270
+ -- ===================================================================
271
+
272
+ CREATE TABLE sp_ref (id TEXT PRIMARY KEY, name TEXT);
273
+ INSERT INTO sp_ref VALUES ('ok', 'OK');
274
+ -- run
275
+
276
+ CREATE TABLE sp_data (
277
+ id INTEGER PRIMARY KEY,
278
+ ref_id TEXT,
279
+ CONSTRAINT sp_ref_exists CHECK ON INSERT, UPDATE (
280
+ EXISTS (SELECT 1 FROM sp_ref WHERE sp_ref.id = NEW.ref_id)
281
+ )
282
+ );
283
+ -- run
284
+
285
+ BEGIN;
286
+ -- Insert violating row (bad ref_id) — deferred until COMMIT
287
+ INSERT INTO sp_data VALUES (1, 'bad');
288
+ -- Create savepoint
289
+ SAVEPOINT sp1;
290
+ -- Fix the violation by adding the missing ref
291
+ INSERT INTO sp_ref VALUES ('bad', 'Now Valid');
292
+ -- Rollback savepoint — restoring the violation (ref 'bad' no longer exists)
293
+ ROLLBACK TO SAVEPOINT sp1;
294
+ -- Attempt COMMIT — should fail because 'bad' ref doesn't exist
295
+ COMMIT;
296
+ -- error: CHECK constraint failed: sp_ref_exists
297
+
298
+ -- Verify nothing was committed
299
+ SELECT count(*) FROM sp_data;
300
+ → [{"count(*)":0}]
301
+
302
+ DROP TABLE sp_data;
303
+ DROP TABLE sp_ref;
304
+ -- run
305
+
306
+ -- ===================================================================
307
+ -- Constraint violation in multi-statement transaction
308
+ -- First statement valid, second violates a deferred constraint, third
309
+ -- fixes it — COMMIT should succeed since end-state is valid.
310
+ -- ===================================================================
311
+
312
+ CREATE TABLE fix_ref (id TEXT PRIMARY KEY, name TEXT);
313
+ INSERT INTO fix_ref VALUES ('a', 'Alpha'), ('b', 'Beta');
314
+ -- run
315
+
316
+ CREATE TABLE fix_data (
317
+ id INTEGER PRIMARY KEY,
318
+ ref_id TEXT,
319
+ CONSTRAINT fix_ref_exists CHECK ON INSERT, UPDATE (
320
+ EXISTS (SELECT 1 FROM fix_ref WHERE fix_ref.id = NEW.ref_id)
321
+ )
322
+ );
323
+ -- run
324
+
325
+ BEGIN;
326
+ -- Valid insert
327
+ INSERT INTO fix_data VALUES (1, 'a');
328
+ -- Violating insert (ref 'missing' doesn't exist yet)
329
+ INSERT INTO fix_data VALUES (2, 'missing');
330
+ -- Fix violation by adding the missing reference
331
+ INSERT INTO fix_ref VALUES ('missing', 'Now Exists');
332
+ -- COMMIT should succeed because end-state is valid
333
+ COMMIT;
334
+ -- run
335
+
336
+ SELECT count(*) FROM fix_data;
337
+ → [{"count(*)":2}]
338
+
339
+ SELECT ref_id FROM fix_data ORDER BY id;
340
+ → [{"ref_id":"a"},{"ref_id":"missing"}]
341
+
342
+ DROP TABLE fix_data;
343
+ DROP TABLE fix_ref;
344
+ -- run
345
+
346
+ -- ===================================================================
347
+ -- FK cascade triggering a CHECK violation
348
+ -- Parent delete cascades SET NULL to child, but the child table has a
349
+ -- NOT NULL constraint on the FK column — the cascade cannot satisfy the
350
+ -- constraint, so the operation should fail.
351
+ -- ===================================================================
352
+
353
+ CREATE TABLE fkc_parent (
354
+ id INTEGER PRIMARY KEY,
355
+ name TEXT
356
+ );
357
+
358
+ CREATE TABLE fkc_child (
359
+ id INTEGER PRIMARY KEY,
360
+ parent_id INTEGER NOT NULL,
361
+ FOREIGN KEY (parent_id) REFERENCES fkc_parent(id) ON DELETE SET NULL
362
+ );
363
+
364
+ INSERT INTO fkc_parent VALUES (1, 'P1'), (2, 'P2');
365
+ INSERT INTO fkc_child VALUES (10, 1), (20, 2);
366
+
367
+ -- Commit setup
368
+ SELECT count(*) FROM fkc_child;
369
+ → [{"count(*)":2}]
370
+
371
+ -- Delete parent — cascade tries SET NULL but column is NOT NULL → should fail
372
+ DELETE FROM fkc_parent WHERE id = 1;
373
+ -- error: NOT NULL constraint failed: fkc_child.parent_id
374
+
375
+ -- Verify nothing was deleted
376
+ SELECT count(*) FROM fkc_parent;
377
+ → [{"count(*)":2}]
378
+
379
+ SELECT count(*) FROM fkc_child;
380
+ → [{"count(*)":2}]
381
+
382
+ DROP TABLE fkc_child;
383
+ DROP TABLE fkc_parent;
384
+
385
+ -- ===================================================================
386
+ -- Assertion referencing multiple tables
387
+ -- CREATE ASSERTION checking that count(*) from table a equals
388
+ -- count(*) from table b — verify evaluation across tables at commit.
389
+ -- ===================================================================
390
+
391
+ CREATE TABLE tbl_a (id INTEGER PRIMARY KEY, val TEXT);
392
+ CREATE TABLE tbl_b (id INTEGER PRIMARY KEY, val TEXT);
393
+ -- run
394
+
395
+ CREATE ASSERTION counts_equal CHECK (
396
+ (SELECT count(*) FROM tbl_a) = (SELECT count(*) FROM tbl_b)
397
+ );
398
+ -- run
399
+
400
+ -- Both empty: OK
401
+ BEGIN;
402
+ COMMIT;
403
+ -- run
404
+
405
+ -- Insert into both equally: OK
406
+ BEGIN;
407
+ INSERT INTO tbl_a VALUES (1, 'a1');
408
+ INSERT INTO tbl_b VALUES (1, 'b1');
409
+ COMMIT;
410
+ -- run
411
+
412
+ SELECT count(*) FROM tbl_a;
413
+ → [{"count(*)":1}]
414
+
415
+ -- Insert into a only → counts diverge → fails
416
+ BEGIN;
417
+ INSERT INTO tbl_a VALUES (2, 'a2');
418
+ COMMIT;
419
+ -- error: Integrity assertion failed: counts_equal
420
+
421
+ -- Insert into b only → counts diverge → fails
422
+ BEGIN;
423
+ INSERT INTO tbl_b VALUES (2, 'b2');
424
+ COMMIT;
425
+ -- error: Integrity assertion failed: counts_equal
426
+
427
+ -- Insert into both → counts match again → OK
428
+ BEGIN;
429
+ INSERT INTO tbl_a VALUES (2, 'a2');
430
+ INSERT INTO tbl_b VALUES (2, 'b2');
431
+ COMMIT;
432
+ -- run
433
+
434
+ SELECT count(*) FROM tbl_a;
435
+ → [{"count(*)":2}]
436
+ SELECT count(*) FROM tbl_b;
437
+ → [{"count(*)":2}]
438
+
439
+ DROP ASSERTION counts_equal;
440
+ DROP TABLE tbl_b;
441
+ DROP TABLE tbl_a;
442
+ -- run