@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,171 @@
1
+ -- Column-level ON CONFLICT directives in DDL (e.g.
2
+ -- `... PRIMARY KEY ON CONFLICT REPLACE`). Quereus now honors these as the
3
+ -- per-constraint default conflict resolution. Statement-level OR clauses
4
+ -- still take precedence over the column-level default.
5
+
6
+ -- ===================================
7
+ -- 1. PRIMARY KEY ON CONFLICT REPLACE — duplicate insert silently replaces
8
+ -- ===================================
9
+
10
+ create table pk_replace (a integer primary key on conflict replace, b text);
11
+ insert into pk_replace values (1, 'first');
12
+
13
+ insert into pk_replace values (1, 'second');
14
+
15
+ select a, b from pk_replace;
16
+ → [{"a":1,"b":"second"}]
17
+
18
+ drop table pk_replace;
19
+
20
+ -- ===================================
21
+ -- 2. PRIMARY KEY ON CONFLICT IGNORE — duplicate insert silently dropped
22
+ -- ===================================
23
+
24
+ create table pk_ignore (a integer primary key on conflict ignore, b text);
25
+ insert into pk_ignore values (10, 'data');
26
+
27
+ insert into pk_ignore values (10, 'conflict');
28
+
29
+ select a, b from pk_ignore;
30
+ → [{"a":10,"b":"data"}]
31
+
32
+ drop table pk_ignore;
33
+
34
+ -- ===================================
35
+ -- 3. UNIQUE ON CONFLICT REPLACE — second insert replaces existing row
36
+ -- ===================================
37
+
38
+ create table uniq_replace (id integer primary key, email text unique on conflict replace);
39
+ insert into uniq_replace values (1, 'a@x');
40
+
41
+ insert into uniq_replace values (2, 'a@x');
42
+
43
+ -- The new row (id=2) wins; the old one is replaced.
44
+ select id, email from uniq_replace order by id;
45
+ → [{"id":2,"email":"a@x"}]
46
+
47
+ drop table uniq_replace;
48
+
49
+ -- ===================================
50
+ -- 4. NOT NULL ON CONFLICT IGNORE — violating row silently skipped
51
+ -- ===================================
52
+
53
+ create table nn_ignore (id integer primary key, name text not null on conflict ignore);
54
+ insert into nn_ignore values (1, 'valid');
55
+
56
+ insert into nn_ignore (id) values (2);
57
+
58
+ select id, name from nn_ignore order by id;
59
+ → [{"id":1,"name":"valid"}]
60
+
61
+ drop table nn_ignore;
62
+
63
+ -- ===================================
64
+ -- 5. CHECK ON CONFLICT IGNORE — parser accepts; violations silently skipped
65
+ -- ===================================
66
+
67
+ create table ck_ignore (id integer primary key, n integer check (n > 0) on conflict ignore);
68
+ insert into ck_ignore values (1, 10);
69
+
70
+ -- CHECK violation under column-level IGNORE: row dropped.
71
+ insert into ck_ignore values (2, -5);
72
+
73
+ select id, n from ck_ignore order by id;
74
+ → [{"id":1,"n":10}]
75
+
76
+ drop table ck_ignore;
77
+
78
+ -- ===================================
79
+ -- 6. Statement-level OR clause overrides column-level ON CONFLICT directive
80
+ -- ===================================
81
+
82
+ create table override_t (a integer primary key on conflict ignore, b text);
83
+ insert into override_t values (1, 'first');
84
+
85
+ -- statement-level OR ABORT must beat the column-level IGNORE directive.
86
+ insert or abort into override_t values (1, 'second');
87
+ -- error: UNIQUE constraint failed
88
+
89
+ -- only original row remains
90
+ select a, b from override_t;
91
+ → [{"a":1,"b":"first"}]
92
+
93
+ drop table override_t;
94
+
95
+ -- ===================================
96
+ -- 7. UPDATE path honors PRIMARY KEY ON CONFLICT REPLACE
97
+ -- ===================================
98
+
99
+ create table pk_upd_replace (id integer primary key on conflict replace, v text);
100
+ insert into pk_upd_replace values (1, 'a'), (2, 'b');
101
+
102
+ -- No OR clause on UPDATE — column-level REPLACE should apply.
103
+ update pk_upd_replace set id = 2 where id = 1;
104
+
105
+ select id, v from pk_upd_replace order by id;
106
+ → [{"id":2,"v":"a"}]
107
+
108
+ drop table pk_upd_replace;
109
+
110
+ -- ===================================
111
+ -- 8. UPDATE path honors PRIMARY KEY ON CONFLICT IGNORE
112
+ -- ===================================
113
+
114
+ create table pk_upd_ignore (id integer primary key on conflict ignore, v text);
115
+ insert into pk_upd_ignore values (1, 'a'), (2, 'b');
116
+
117
+ update pk_upd_ignore set id = 2 where id = 1;
118
+
119
+ select id, v from pk_upd_ignore order by id;
120
+ → [{"id":1,"v":"a"},{"id":2,"v":"b"}]
121
+
122
+ drop table pk_upd_ignore;
123
+
124
+ -- ===================================
125
+ -- 9. UPDATE-with-PK-change under REPLACE cascades FK ON DELETE for evicted row
126
+ -- ===================================
127
+ -- Quereus's default `on update` is `restrict`, so any child of the moved row
128
+ -- would block the update before the eviction can happen. To isolate the
129
+ -- evicted row's cascade, only the row that gets evicted has a child here.
130
+
131
+ create table parent_evict (id integer primary key on conflict replace, v text);
132
+ create table child_evict (
133
+ id integer primary key,
134
+ parent_id integer references parent_evict(id) on delete cascade
135
+ );
136
+ insert into parent_evict values (1, 'one'), (2, 'two');
137
+ insert into child_evict values (20, 2);
138
+
139
+ -- Move parent id=1 onto id=2; column-level REPLACE evicts the row at id=2.
140
+ update parent_evict set id = 2 where id = 1;
141
+
142
+ -- The row formerly at id=2 was evicted, so its child (id=20) must be cascaded.
143
+ select id, parent_id from child_evict;
144
+ → []
145
+
146
+ select id, v from parent_evict order by id;
147
+ → [{"id":2,"v":"one"}]
148
+
149
+ drop table child_evict;
150
+ drop table parent_evict;
151
+
152
+ -- ===================================
153
+ -- 10. UPDATE-with-PK-change under REPLACE applies ON DELETE SET NULL for evicted row
154
+ -- ===================================
155
+
156
+ create table p_set_null (id integer primary key on conflict replace, v text);
157
+ create table c_set_null (
158
+ id integer primary key,
159
+ parent_id integer null references p_set_null(id) on delete set null
160
+ );
161
+ insert into p_set_null values (1, 'a'), (2, 'b');
162
+ insert into c_set_null values (200, 2);
163
+
164
+ update p_set_null set id = 2 where id = 1;
165
+
166
+ -- Evicted parent (2, 'b') triggers SET NULL on its child (200).
167
+ select id, parent_id from c_set_null;
168
+ → [{"id":200,"parent_id":null}]
169
+
170
+ drop table c_set_null;
171
+ drop table p_set_null;
@@ -0,0 +1,113 @@
1
+ -- Table-level `PRIMARY KEY (...) ON CONFLICT <action>` directive. Mirrors 29.1
2
+ -- (column-level) but exercises the constraint on a composite PK declared as a
3
+ -- table-level constraint, which previously parsed correctly but had its
4
+ -- `ON CONFLICT` action silently dropped (resolving to ABORT).
5
+
6
+ -- ===================================
7
+ -- 1. PRIMARY KEY (...) ON CONFLICT IGNORE — duplicate insert silently dropped
8
+ -- ===================================
9
+
10
+ create table tpk_ignore (a integer, b integer, v text, primary key (a, b) on conflict ignore);
11
+ insert into tpk_ignore values (1, 1, 'first');
12
+
13
+ insert into tpk_ignore values (1, 1, 'second');
14
+
15
+ select a, b, v from tpk_ignore;
16
+ → [{"a":1,"b":1,"v":"first"}]
17
+
18
+ drop table tpk_ignore;
19
+
20
+ -- ===================================
21
+ -- 2. PRIMARY KEY (...) ON CONFLICT REPLACE — duplicate insert silently replaces
22
+ -- ===================================
23
+
24
+ create table tpk_replace (a integer, b integer, v text, primary key (a, b) on conflict replace);
25
+ insert into tpk_replace values (1, 1, 'first');
26
+
27
+ insert into tpk_replace values (1, 1, 'second');
28
+
29
+ select a, b, v from tpk_replace;
30
+ → [{"a":1,"b":1,"v":"second"}]
31
+
32
+ drop table tpk_replace;
33
+
34
+ -- ===================================
35
+ -- 3. PRIMARY KEY (...) ON CONFLICT FAIL — duplicate insert errors
36
+ -- ===================================
37
+
38
+ create table tpk_fail (a integer, b integer, v text, primary key (a, b) on conflict fail);
39
+ insert into tpk_fail values (1, 1, 'first');
40
+
41
+ insert into tpk_fail values (1, 1, 'second');
42
+ -- error: UNIQUE constraint failed
43
+
44
+ -- The original row is still there; the conflicting insert errored out.
45
+ select a, b, v from tpk_fail;
46
+ → [{"a":1,"b":1,"v":"first"}]
47
+
48
+ drop table tpk_fail;
49
+
50
+ -- ===================================
51
+ -- 4. PRIMARY KEY (...) ON CONFLICT ROLLBACK — duplicate insert errors
52
+ -- ===================================
53
+ -- The per-constraint ROLLBACK action surfaces as a constraint failure at the
54
+ -- helper layer (statement aborts). Translation into a tx-wide rollback of the
55
+ -- enclosing transaction would require additional runtime wiring beyond the
56
+ -- schema-build + helper scope of this change; see implementer notes.
57
+
58
+ create table tpk_rb (a integer, b integer, v text, primary key (a, b) on conflict rollback);
59
+ insert into tpk_rb values (1, 1, 'first');
60
+
61
+ insert into tpk_rb values (1, 1, 'second');
62
+ -- error: UNIQUE constraint failed
63
+
64
+ select a, b, v from tpk_rb;
65
+ → [{"a":1,"b":1,"v":"first"}]
66
+
67
+ drop table tpk_rb;
68
+
69
+ -- ===================================
70
+ -- 5. Statement-level OR clause overrides table-level ON CONFLICT directive
71
+ -- ===================================
72
+
73
+ create table tpk_override (a integer, b integer, v text, primary key (a, b) on conflict ignore);
74
+ insert into tpk_override values (1, 1, 'first');
75
+
76
+ -- statement-level OR ABORT must beat the table-level IGNORE directive.
77
+ insert or abort into tpk_override values (1, 1, 'second');
78
+ -- error: UNIQUE constraint failed
79
+
80
+ -- only the original row remains
81
+ select a, b, v from tpk_override;
82
+ → [{"a":1,"b":1,"v":"first"}]
83
+
84
+ drop table tpk_override;
85
+
86
+ -- ===================================
87
+ -- 6. UPDATE path honors table-level PRIMARY KEY ON CONFLICT REPLACE
88
+ -- ===================================
89
+
90
+ create table tpk_upd_replace (a integer, b integer, v text, primary key (a, b) on conflict replace);
91
+ insert into tpk_upd_replace values (1, 1, 'a'), (2, 2, 'b');
92
+
93
+ -- No OR clause on UPDATE — table-level REPLACE should apply.
94
+ update tpk_upd_replace set a = 2, b = 2 where a = 1 and b = 1;
95
+
96
+ select a, b, v from tpk_upd_replace order by a, b;
97
+ → [{"a":2,"b":2,"v":"a"}]
98
+
99
+ drop table tpk_upd_replace;
100
+
101
+ -- ===================================
102
+ -- 7. UPDATE path honors table-level PRIMARY KEY ON CONFLICT IGNORE
103
+ -- ===================================
104
+
105
+ create table tpk_upd_ignore (a integer, b integer, v text, primary key (a, b) on conflict ignore);
106
+ insert into tpk_upd_ignore values (1, 1, 'a'), (2, 2, 'b');
107
+
108
+ update tpk_upd_ignore set a = 2, b = 2 where a = 1 and b = 1;
109
+
110
+ select a, b, v from tpk_upd_ignore order by a, b;
111
+ → [{"a":1,"b":1,"v":"a"},{"a":2,"b":2,"v":"b"}]
112
+
113
+ drop table tpk_upd_ignore;
@@ -0,0 +1,418 @@
1
+ -- constraints.sqllogic - Testing integrity constraints
2
+
3
+ -- Basic table creation (without constraint enforcement)
4
+ CREATE TABLE t_basic (
5
+ id INTEGER PRIMARY KEY,
6
+ name TEXT,
7
+ value INTEGER
8
+ );
9
+
10
+ INSERT INTO t_basic VALUES (1, 'test', 100);
11
+ SELECT * FROM t_basic;
12
+ → [{"id":1,"name":"test","value":100}]
13
+
14
+ DROP TABLE t_basic;
15
+
16
+ -- === NOT NULL Constraints ===
17
+
18
+ CREATE TABLE t_notnull (
19
+ id INTEGER PRIMARY KEY,
20
+ req TEXT NOT NULL,
21
+ opt TEXT NULL
22
+ );
23
+
24
+ -- Insert valid row
25
+ INSERT INTO t_notnull (id, req, opt) VALUES (1, 'required', 'optional');
26
+ SELECT req, opt FROM t_notnull WHERE id = 1;
27
+ → [{"req":"required","opt":"optional"}]
28
+
29
+ -- Insert omitting NOT NULL column (no default)
30
+ INSERT INTO t_notnull (id, opt) VALUES (2, 'no_req');
31
+ -- error: NOT NULL constraint failed: t_notnull.req
32
+
33
+ -- Insert explicit NULL into NOT NULL column
34
+ INSERT INTO t_notnull (id, req) VALUES (3, NULL);
35
+ -- error: NOT NULL constraint failed: t_notnull.req
36
+
37
+ -- Update optional to NULL (allowed)
38
+ UPDATE t_notnull SET opt = NULL WHERE id = 1;
39
+ SELECT opt FROM t_notnull WHERE id = 1;
40
+ → [{"opt":null}]
41
+
42
+ -- Update required to NULL (fail)
43
+ UPDATE t_notnull SET req = NULL WHERE id = 1;
44
+ -- error: NOT NULL constraint failed: t_notnull.req
45
+
46
+ -- Verify state after failed update
47
+ SELECT req FROM t_notnull WHERE id = 1;
48
+ → [{"req":"required"}]
49
+
50
+ DROP TABLE t_notnull;
51
+
52
+ -- === Simple CHECK Constraints (Default ON INSERT, UPDATE) ===
53
+
54
+ CREATE TABLE t_check (
55
+ id INTEGER PRIMARY KEY,
56
+ pos INT CHECK(pos > 0),
57
+ bal REAL CHECK(bal >= 0)
58
+ );
59
+
60
+ -- Insert valid
61
+ INSERT INTO t_check VALUES (1, 10, 100.5);
62
+ SELECT pos, bal FROM t_check WHERE id = 1;
63
+ → [{"pos":10,"bal":100.5}]
64
+
65
+ -- Insert invalid pos
66
+ INSERT INTO t_check VALUES (2, -5, 50);
67
+ -- error: CHECK constraint failed: _check_pos
68
+
69
+ -- Insert invalid bal
70
+ INSERT INTO t_check VALUES (3, 5, -0.01);
71
+ -- error: CHECK constraint failed: _check_bal
72
+
73
+ -- Update valid to valid
74
+ UPDATE t_check SET pos = 20, bal = 99.9 WHERE id = 1;
75
+ SELECT pos, bal FROM t_check WHERE id = 1;
76
+ → [{"pos":20,"bal":99.9}]
77
+
78
+ -- Update valid to invalid pos
79
+ UPDATE t_check SET pos = 0 WHERE id = 1;
80
+ -- error: CHECK constraint failed: _check_pos
81
+
82
+ -- Update valid to invalid bal
83
+ UPDATE t_check SET bal = -10 WHERE id = 1;
84
+ -- error: CHECK constraint failed: _check_bal
85
+
86
+ -- Verify state after failed updates
87
+ SELECT pos, bal FROM t_check WHERE id = 1;
88
+ → [{"pos":20,"bal":99.9}]
89
+
90
+ DROP TABLE t_check;
91
+
92
+ -- === Row-Level CHECK ON ... Constraints ===
93
+
94
+ CREATE TABLE t_check_on (
95
+ id INTEGER PRIMARY KEY,
96
+ status TEXT CHECK ON INSERT (status IN ('active', 'inactive')),
97
+ val INTEGER,
98
+ CONSTRAINT positive_val CHECK ON UPDATE (NEW.val >= 0),
99
+ CONSTRAINT no_delete CHECK ON DELETE (FALSE)
100
+ );
101
+
102
+ -- Insert valid (status check applies)
103
+ INSERT INTO t_check_on (id, status, val) VALUES (1, 'active', 100);
104
+ SELECT status, val FROM t_check_on WHERE id = 1;
105
+ → [{"status":"active","val":100}]
106
+
107
+ -- Insert invalid status
108
+ INSERT INTO t_check_on (id, status, val) VALUES (2, 'pending', 200);
109
+ -- error: CHECK constraint failed: _check_status
110
+
111
+ -- Update status (check does NOT apply on UPDATE)
112
+ UPDATE t_check_on SET status = 'archived' WHERE id = 1;
113
+ SELECT status FROM t_check_on WHERE id = 1;
114
+ → [{"status":"archived"}]
115
+
116
+ -- Update val valid (positive_val check applies)
117
+ UPDATE t_check_on SET val = 50 WHERE id = 1;
118
+ SELECT val FROM t_check_on WHERE id = 1;
119
+ → [{"val":50}]
120
+
121
+ -- Update val invalid (positive_val check applies)
122
+ UPDATE t_check_on SET val = -1 WHERE id = 1;
123
+ -- error: CHECK constraint failed: positive_val
124
+
125
+ -- Verify state after failed update
126
+ SELECT val FROM t_check_on WHERE id = 1;
127
+ → [{"val":50}]
128
+
129
+ -- Attempt DELETE (no_delete check applies)
130
+ DELETE FROM t_check_on WHERE id = 1;
131
+ -- error: CHECK constraint failed: no_delete
132
+
133
+ -- Verify state after failed delete
134
+ SELECT count(*) FROM t_check_on WHERE id = 1;
135
+ → [{"count(*)":1}]
136
+
137
+ DROP TABLE t_check_on;
138
+
139
+ -- === CHECK ON with NEW/OLD aliases ===
140
+
141
+ CREATE TABLE t_check_alias (
142
+ id INTEGER PRIMARY KEY,
143
+ version INTEGER DEFAULT 1,
144
+ payload TEXT,
145
+ CONSTRAINT version_increase CHECK ON UPDATE (NEW.version > OLD.version)
146
+ );
147
+
148
+ INSERT INTO t_check_alias (id, payload) VALUES (10, 'initial data');
149
+ SELECT version FROM t_check_alias WHERE id = 10;
150
+ → [{"version":1}]
151
+
152
+ -- Valid update (increasing version)
153
+ UPDATE t_check_alias SET version = 2, payload = 'updated data' WHERE id = 10;
154
+ SELECT version, payload FROM t_check_alias WHERE id = 10;
155
+ → [{"version":2,"payload":"updated data"}]
156
+
157
+ -- Invalid update (same version)
158
+ UPDATE t_check_alias SET version = 2, payload = 'no change' WHERE id = 10;
159
+ -- error: CHECK constraint failed: version_increase
160
+
161
+ -- Invalid update (decreasing version)
162
+ UPDATE t_check_alias SET version = 1, payload = 'revert?' WHERE id = 10;
163
+ -- error: CHECK constraint failed: version_increase
164
+
165
+ -- Verify state after failed updates
166
+ SELECT version, payload FROM t_check_alias WHERE id = 10;
167
+ → [{"version":2,"payload":"updated data"}]
168
+
169
+ DROP TABLE t_check_alias;
170
+
171
+ -- === CHECK ON with Subquery ===
172
+
173
+ CREATE TABLE products (sku TEXT PRIMARY KEY, price REAL);
174
+ CREATE TABLE inventory (loc TEXT, sku TEXT, qty INTEGER CHECK(qty >= 0) /* Simple check */,
175
+ FOREIGN KEY (sku) REFERENCES products(sku));
176
+ ALTER TABLE inventory ADD CONSTRAINT enough_stock CHECK ON UPDATE (
177
+ new.qty <= (SELECT sum(s.qty) FROM inventory s WHERE s.sku = NEW.sku)
178
+ );
179
+ ALTER TABLE inventory ADD CONSTRAINT no_delete_if_positive CHECK ON DELETE (
180
+ old.qty <= 0
181
+ );
182
+
183
+ INSERT INTO products VALUES ('A1', 10.0), ('B2', 20.0);
184
+ INSERT INTO inventory VALUES ('W1', 'A1', 50), ('W2', 'A1', 30), ('W1', 'B2', 100);
185
+
186
+ SELECT sku, sum(qty) FROM inventory GROUP BY sku ORDER BY sku;
187
+ → [{"sku":"A1","sum(qty)":80},{"sku":"B2","sum(qty)":100}]
188
+
189
+ -- Valid update (decreasing stock is allowed by enough_stock on update)
190
+ UPDATE inventory SET qty = 25 WHERE loc = 'W1' AND sku = 'A1';
191
+ SELECT qty FROM inventory WHERE loc = 'W1' AND sku = 'A1';
192
+ → [{"qty":25}]
193
+
194
+ -- Invalid update (cannot set negative simple check)
195
+ UPDATE inventory SET qty = -5 WHERE loc = 'W1' AND sku = 'A1';
196
+ -- error: CHECK constraint failed: _check_qty
197
+
198
+ -- Attempt to delete row with positive quantity
199
+ DELETE FROM inventory WHERE loc = 'W1' AND sku = 'A1';
200
+ -- error: CHECK constraint failed: no_delete_if_positive
201
+
202
+ -- Set quantity to 0
203
+ UPDATE inventory SET qty = 0 WHERE loc = 'W1' AND sku = 'A1';
204
+ SELECT qty FROM inventory WHERE loc = 'W1' AND sku = 'A1';
205
+ → [{"qty":0}]
206
+
207
+ -- Now delete should work
208
+ DELETE FROM inventory WHERE loc = 'W1' AND sku = 'A1';
209
+ SELECT count(*) FROM inventory WHERE loc = 'W1' AND sku = 'A1';
210
+ → [{"count(*)":0}]
211
+
212
+ DROP TABLE inventory;
213
+ DROP TABLE products;
214
+
215
+ -- === CHECK with EXISTS subquery referencing another table (INSERT/UPDATE) ===
216
+
217
+ CREATE TABLE ref_table (
218
+ id TEXT PRIMARY KEY,
219
+ name TEXT
220
+ );
221
+
222
+ CREATE TABLE dependent (
223
+ id INTEGER PRIMARY KEY,
224
+ ref_id TEXT,
225
+ CONSTRAINT ref_must_exist CHECK ON INSERT, UPDATE (
226
+ EXISTS (SELECT 1 FROM ref_table WHERE ref_table.id = NEW.ref_id)
227
+ )
228
+ );
229
+
230
+ -- Insert into empty dependent table should fail (ref_table is empty)
231
+ INSERT INTO dependent (id, ref_id) VALUES (1, 'abc');
232
+ -- error: CHECK constraint failed: ref_must_exist
233
+
234
+ -- Populate ref_table
235
+ INSERT INTO ref_table VALUES ('abc', 'Valid Reference');
236
+ SELECT * FROM ref_table;
237
+ → [{"id":"abc","name":"Valid Reference"}]
238
+
239
+ -- Now insert should succeed
240
+ INSERT INTO dependent (id, ref_id) VALUES (1, 'abc');
241
+ SELECT * FROM dependent;
242
+ → [{"id":1,"ref_id":"abc"}]
243
+
244
+ -- Try to update to non-existent reference
245
+ UPDATE dependent SET ref_id = 'xyz' WHERE id = 1;
246
+ -- error: CHECK constraint failed: ref_must_exist
247
+
248
+ -- Verify state unchanged
249
+ SELECT ref_id FROM dependent WHERE id = 1;
250
+ → [{"ref_id":"abc"}]
251
+
252
+ -- Add another valid reference
253
+ INSERT INTO ref_table VALUES ('xyz', 'Another Valid');
254
+
255
+ -- Now update should succeed
256
+ UPDATE dependent SET ref_id = 'xyz' WHERE id = 1;
257
+ SELECT ref_id FROM dependent WHERE id = 1;
258
+ → [{"ref_id":"xyz"}]
259
+
260
+ DROP TABLE dependent;
261
+ DROP TABLE ref_table;
262
+
263
+ -- === Deferred row-level CHECK (EXISTS) commit-time enforcement ===
264
+
265
+ -- Recreate tables
266
+ CREATE TABLE ref_table (
267
+ id TEXT PRIMARY KEY,
268
+ name TEXT
269
+ );
270
+
271
+ CREATE TABLE dependent (
272
+ id INTEGER PRIMARY KEY,
273
+ ref_id TEXT,
274
+ CONSTRAINT ref_must_exist CHECK ON INSERT, UPDATE (
275
+ EXISTS (SELECT 1 FROM ref_table WHERE ref_table.id = NEW.ref_id)
276
+ )
277
+ );
278
+
279
+ -- Case A: Violation allowed within transaction, rejected at COMMIT
280
+ BEGIN;
281
+ INSERT INTO dependent (id, ref_id) VALUES (100, 'missing');
282
+ COMMIT;
283
+ -- error: CHECK constraint failed: ref_must_exist
284
+
285
+ -- Ensure nothing was committed
286
+ SELECT count(*) FROM dependent WHERE id = 100;
287
+ → [{"count(*)":0}]
288
+
289
+ -- Case B: Fix violation before COMMIT → succeeds
290
+ BEGIN;
291
+ INSERT INTO dependent (id, ref_id) VALUES (101, 'later');
292
+ INSERT INTO ref_table VALUES ('later', 'OK');
293
+ COMMIT;
294
+ SELECT ref_id FROM dependent WHERE id = 101;
295
+ → [{"ref_id":"later"}]
296
+
297
+ -- Case C: Savepoint rollback of violating change → COMMIT succeeds
298
+ BEGIN;
299
+ SAVEPOINT sp;
300
+ INSERT INTO dependent (id, ref_id) VALUES (102, 'nope');
301
+ ROLLBACK TO SAVEPOINT sp;
302
+ COMMIT;
303
+ SELECT count(*) FROM dependent WHERE id = 102;
304
+ → [{"count(*)":0}]
305
+
306
+ DROP TABLE dependent;
307
+ DROP TABLE ref_table;
308
+
309
+ -- === ALTER TABLE ADD CONSTRAINT ===
310
+
311
+ CREATE TABLE t_alter(x INT, y TEXT);
312
+
313
+ -- Add a simple CHECK constraint
314
+ ALTER TABLE t_alter ADD CONSTRAINT positive_x CHECK (x > 0);
315
+
316
+ -- Test that the constraint is enforced on INSERT
317
+ INSERT INTO t_alter VALUES (5, 'valid');
318
+ SELECT * FROM t_alter;
319
+ → [{"x":5,"y":"valid"}]
320
+
321
+ -- Test constraint failure
322
+ INSERT INTO t_alter VALUES (-1, 'invalid');
323
+ -- error: CHECK constraint failed: positive_x
324
+
325
+ -- Verify state after failed insert
326
+ SELECT * FROM t_alter;
327
+ → [{"x":5,"y":"valid"}]
328
+
329
+ -- Add constraint with operation specifier
330
+ ALTER TABLE t_alter ADD CONSTRAINT y_on_update CHECK ON UPDATE (length(y) > 2);
331
+
332
+ -- Test UPDATE constraint
333
+ UPDATE t_alter SET y = 'good' WHERE x = 5;
334
+ SELECT * FROM t_alter;
335
+ → [{"x":5,"y":"good"}]
336
+
337
+ -- Test UPDATE constraint failure
338
+ UPDATE t_alter SET y = 'no' WHERE x = 5;
339
+ -- error: CHECK constraint failed: y_on_update
340
+
341
+ -- Verify state after failed update
342
+ SELECT * FROM t_alter;
343
+ → [{"x":5,"y":"good"}]
344
+
345
+ -- Test that INSERT is not affected by UPDATE-only constraint
346
+ INSERT INTO t_alter VALUES (10, 'hi');
347
+ SELECT * FROM t_alter ORDER BY x;
348
+ → [{"x":5,"y":"good"},{"x":10,"y":"hi"}]
349
+
350
+ DROP TABLE t_alter;
351
+
352
+ -- === NOT EXISTS constraint (lowercase operators) ===
353
+
354
+ CREATE TABLE other_table (
355
+ id INTEGER PRIMARY KEY,
356
+ value TEXT
357
+ );
358
+
359
+ CREATE TABLE main_table (
360
+ id INTEGER PRIMARY KEY,
361
+ name TEXT
362
+ );
363
+
364
+ -- Add constraint with lowercase 'not exists'
365
+ ALTER TABLE main_table ADD CONSTRAINT is_valid CHECK (not exists (select 1 from other_table));
366
+
367
+ -- Insert should succeed when other_table is empty
368
+ INSERT INTO main_table VALUES (1, 'first');
369
+ SELECT * FROM main_table;
370
+ → [{"id":1,"name":"first"}]
371
+
372
+ -- Insert into other_table
373
+ INSERT INTO other_table VALUES (1, 'data');
374
+
375
+ -- Now insert into main_table should fail (other_table is not empty)
376
+ INSERT INTO main_table VALUES (2, 'second');
377
+ -- error: CHECK constraint failed: is_valid
378
+
379
+ -- Clear other_table
380
+ DELETE FROM other_table WHERE id = 1;
381
+
382
+ -- Now insert should succeed again
383
+ INSERT INTO main_table VALUES (2, 'second');
384
+ SELECT count(*) FROM main_table;
385
+ → [{"count(*)":2}]
386
+
387
+ DROP TABLE main_table;
388
+ DROP TABLE other_table;
389
+
390
+ -- === Lowercase logical operators in constraints ===
391
+
392
+ CREATE TABLE t_lowercase (
393
+ id INTEGER PRIMARY KEY,
394
+ value INTEGER,
395
+ name TEXT,
396
+ CONSTRAINT check_and CHECK (value > 0 and value < 100),
397
+ CONSTRAINT check_like CHECK (name like 'test%')
398
+ );
399
+
400
+ -- Test AND constraint
401
+ INSERT INTO t_lowercase VALUES (1, 50, 'test1');
402
+
403
+ -- Test AND constraint failure (value too high)
404
+ INSERT INTO t_lowercase VALUES (2, 150, 'test2');
405
+ -- error: CHECK constraint failed: check_and (value > 0 and value < 100)
406
+
407
+ -- Test AND constraint failure (value too low)
408
+ INSERT INTO t_lowercase VALUES (3, -5, 'test3');
409
+ -- error: CHECK constraint failed: check_and (value > 0 and value < 100)
410
+
411
+ -- Test LIKE constraint
412
+ INSERT INTO t_lowercase VALUES (5, 75, 'testing');
413
+
414
+ -- Test LIKE constraint failure
415
+ INSERT INTO t_lowercase VALUES (6, 30, 'invalid');
416
+ -- error: CHECK constraint failed: check_like (name like 'test%')
417
+
418
+ DROP TABLE t_lowercase;