@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,408 @@
1
+ -- 13.9.1-schema-authored-schema-path-isolation.sqllogic - a table's own DDL resolves bare
2
+ -- relation names against the table's OWN schema, never the writer's search path
3
+ --
4
+ -- Sibling of 13.9-schema-authored-cte-isolation.sqllogic: same four schema-authored
5
+ -- expression kinds (a column DEFAULT, a generated-column expression, a CHECK constraint,
6
+ -- a synthesized foreign-key probe), the other leak channel. A DEFAULT used to be built on
7
+ -- a planning context still carrying the WRITING statement's schema search path (the
8
+ -- session `pragma schema_path`, or a per-statement `insert … with schema …`), while the
9
+ -- CHECK beside it narrowed to the table's own schema — so one table definition could
10
+ -- disagree with itself about what a bare `c` meant. `schemaAuthoredContext`
11
+ -- (planner/building/schema-authored-context.ts) now narrows the path in ONE place, to the
12
+ -- owning table's schema exactly, with no fallback to the session default path.
13
+ --
14
+ -- Every arm is written so the WRONG binding is observable: the DECOY relation lives in the
15
+ -- schema the writer is pointed at, the real one lives beside the table, the two disagree,
16
+ -- and the assertion pins the owning schema's answer.
17
+
18
+ pragma foreign_keys = true;
19
+ pragma schema_path = 'main';
20
+
21
+ -- The decoy `main.c` has 1 row; the real `temp.c` beside every table below has 3.
22
+ create table main.c (k integer primary key);
23
+ insert into main.c values (1);
24
+ create table temp.c (k integer primary key);
25
+ insert into temp.c values (1), (2), (3);
26
+ -- run
27
+
28
+ -- ===== Column DEFAULT (session schema path) =====
29
+
30
+ create table temp.sp_def (id integer primary key, w integer default (select count(*) from c));
31
+ -- run
32
+
33
+ insert into temp.sp_def (id) values (1);
34
+
35
+ -- 3 (temp.c, beside the table), not 1 (main.c, on the writer's path).
36
+ select id, w from temp.sp_def order by id;
37
+ → [{"id":1,"w":3}]
38
+
39
+ -- ===== Generated column, all four write sites =====
40
+ -- One stored body, four statements that compile it (the INSERT row expansion, the
41
+ -- `on conflict do update` recompute, the UPDATE recompute, and the ADD COLUMN
42
+ -- backfill), one shared builder (`planner/building/generated-column-scope.ts`) that
43
+ -- wraps every one of them in `schemaAuthoredContext`. All four must read `temp.c`
44
+ -- (3 rows, beside the table), never the decoy `main.c` on the writer's path.
45
+
46
+ create table temp.sp_gen (id integer primary key, v integer, g integer generated always as ((select count(*) from c)));
47
+ -- run
48
+
49
+ insert into temp.sp_gen (id, v) values (1, 1);
50
+
51
+ select id, v, g from temp.sp_gen order by id;
52
+ → [{"id":1,"v":1,"g":3}]
53
+
54
+ update temp.sp_gen set v = 2 where id = 1;
55
+
56
+ select id, v, g from temp.sp_gen order by id;
57
+ → [{"id":1,"v":2,"g":3}]
58
+
59
+ insert into temp.sp_gen (id, v) values (1, 5) on conflict (id) do update set v = 5;
60
+
61
+ select id, v, g from temp.sp_gen order by id;
62
+ → [{"id":1,"v":5,"g":3}]
63
+
64
+ -- the ADD COLUMN backfill, and a write through the ordinary path afterwards
65
+ create table temp.sp_gen_alter (id integer primary key, v integer);
66
+ insert into temp.sp_gen_alter values (1, 1);
67
+ -- run
68
+
69
+ alter table temp.sp_gen_alter add column g integer generated always as ((select count(*) from c));
70
+ -- run
71
+
72
+ insert into temp.sp_gen_alter (id, v) values (2, 2);
73
+
74
+ select id, v, g from temp.sp_gen_alter order by id;
75
+ → [{"id":1,"v":1,"g":3},{"id":2,"v":2,"g":3}]
76
+
77
+ -- ===== UPDATE-path schema-authored build (`building/update.ts`) =====
78
+ -- `building/update.ts` narrows on its own context (`schemaAuthoredUpdateCtx`), shared by
79
+ -- the CHECK build and the NOT NULL defaults. (The generated-column recompute no longer
80
+ -- rides on that context — it narrows inside the shared generated-expression builder,
81
+ -- pinned by the arm above.)
82
+
83
+ create table temp.sp_cku (id integer primary key, v integer, check ((select count(*) from c) = 3));
84
+ insert into temp.sp_cku values (1, 1);
85
+ -- run
86
+
87
+ update temp.sp_cku set v = 2 where id = 1;
88
+
89
+ select id, v from temp.sp_cku order by id;
90
+ → [{"id":1,"v":2}]
91
+
92
+ -- and the other direction on the UPDATE path: an update-only CHECK that only the decoy
93
+ -- satisfies must still reject
94
+ create table temp.sp_ckux (id integer primary key, v integer, check on update ((select count(*) from c) = 1));
95
+ insert into temp.sp_ckux values (1, 1);
96
+ -- run
97
+
98
+ update temp.sp_ckux set v = 2 where id = 1;
99
+ -- error: CHECK
100
+
101
+ select id, v from temp.sp_ckux order by id;
102
+ → [{"id":1,"v":1}]
103
+
104
+ -- ===== NOT NULL column DEFAULT (REPLACE substitution) =====
105
+ -- `buildNotNullDefaults` pre-builds the DEFAULT evaluator the constraint runtime
106
+ -- substitutes when REPLACE meets an explicit NULL.
107
+
108
+ create table temp.sp_nnd (id integer primary key, w integer not null default (select count(*) from c));
109
+ -- run
110
+
111
+ insert or replace into temp.sp_nnd (id, w) values (1, null);
112
+
113
+ select id, w from temp.sp_nnd order by id;
114
+ → [{"id":1,"w":3}]
115
+
116
+ -- ===== Per-statement WITH SCHEMA (distinct from the session pragma) =====
117
+ -- Session path is `temp` here, so only the statement's own `with schema main` points the
118
+ -- writer at the decoy. The default must still read temp.c.
119
+
120
+ pragma schema_path = 'temp';
121
+
122
+ create table temp.sp_ws (id integer primary key, w integer default (select count(*) from c));
123
+ -- run
124
+
125
+ insert into temp.sp_ws (id) values (1) with schema main;
126
+
127
+ select id, w from temp.sp_ws order by id;
128
+ → [{"id":1,"w":3}]
129
+
130
+ pragma schema_path = 'main';
131
+
132
+ -- ===== Controls: CHECK and child-side FK were already correct, and must stay so =====
133
+ -- The narrowing used to be duplicated inside `buildConstraintChecks` and both foreign-key
134
+ -- builders; collapsing it into the shared helper must not change either one's answer.
135
+
136
+ -- (a) a CHECK that holds against temp.c (3 rows) and fails against main.c (1 row)
137
+ create table temp.sp_ck (id integer primary key, check ((select count(*) from c) = 3));
138
+ -- run
139
+
140
+ insert into temp.sp_ck values (1);
141
+
142
+ select id from temp.sp_ck order by id;
143
+ → [{"id":1}]
144
+
145
+ -- (b) the other direction: a CHECK only the DECOY would satisfy must still reject
146
+ create table temp.sp_ckx (id integer primary key, check ((select count(*) from c) = 1));
147
+ -- run
148
+
149
+ insert into temp.sp_ckx values (1);
150
+ -- error: CHECK
151
+
152
+ select count(*) as n from temp.sp_ckx;
153
+ → [{"n":0}]
154
+
155
+ -- (c) child-side FK probe on a table in the non-default schema. The parent exists only in
156
+ -- `temp` and holds the referenced row, so a broken probe shows up as a spurious
157
+ -- `CHECK constraint failed: _fk_…`.
158
+ create table temp.sp_fkp (id integer primary key);
159
+ insert into temp.sp_fkp values (1);
160
+ create table temp.sp_fkc (id integer primary key, pid integer references sp_fkp(id));
161
+ -- run
162
+
163
+ insert into temp.sp_fkc values (1, 1);
164
+
165
+ select id, pid from temp.sp_fkc order by id;
166
+ → [{"id":1,"pid":1}]
167
+
168
+ -- ===== Write-through a view whose base table lives in the non-default schema =====
169
+ -- The base op is re-planned through `buildInsertStmt`, so it inherits the narrowing.
170
+
171
+ create table temp.sp_vt (id integer primary key, w integer default (select count(*) from c));
172
+ create view temp.sp_v as select id, w from sp_vt;
173
+ -- run
174
+
175
+ insert into temp.sp_v (id) values (1);
176
+
177
+ select id, w from temp.sp_vt order by id;
178
+ → [{"id":1,"w":3}]
179
+
180
+ -- ===== Multi-source view INSERT: the anchor key column's declared DEFAULT =====
181
+ -- The shared surrogate is minted ONCE per produced row at the envelope, from the anchor
182
+ -- key column's own `default` — the one schema-authored expression the decomposition
183
+ -- lowering builds itself rather than delegating to `buildInsertStmt` (`buildKeyDefault`
184
+ -- in planner/building/view-mutation-builder.ts). Its owner is the ANCHOR BASE TABLE's
185
+ -- schema, which is why the analyses carry `keyDefaultSchemaName` alongside the
186
+ -- expression. `main.kd_core` is a decoy with a much higher water mark.
187
+
188
+ create table main.kd_core (rid integer primary key, name text);
189
+ insert into main.kd_core values (500, 'decoy');
190
+ create table temp.kd_core (rid integer primary key default (coalesce((select max(rid) from kd_core), 0) + mutation_ordinal()), name text);
191
+ create table temp.kd_contact (rid integer primary key, email text);
192
+ create view temp.kd_v as select c.name as name, k.email as email
193
+ from kd_core c join kd_contact k on k.rid = c.rid;
194
+ insert into temp.kd_core values (100, 'seed');
195
+ -- run
196
+
197
+ insert into temp.kd_v (name, email) values ('Ada', 'ada@x.io');
198
+
199
+ -- 101 (above temp.kd_core's real high-water mark 100), not 501 (above the main decoy).
200
+ select rid, name from temp.kd_core order by rid;
201
+ → [{"rid":100,"name":"seed"},{"rid":101,"name":"Ada"}]
202
+
203
+ select rid, email from temp.kd_contact order by rid;
204
+ → [{"rid":101,"email":"ada@x.io"}]
205
+
206
+ select rid, name from main.kd_core order by rid;
207
+ → [{"rid":500,"name":"decoy"}]
208
+
209
+ -- And the owner is the ANCHOR BASE TABLE's schema, not the VIEW's — they can differ.
210
+ -- Here the view lives in `main` (with the session path) while the anchor lives in `temp`,
211
+ -- and the anchor's default reads a bare `ks_seq` that exists in both. Reading it as the
212
+ -- view's schema would take main.ks_seq's mark (500) instead of temp.ks_seq's (100).
213
+
214
+ create table temp.ks_seq (n integer primary key);
215
+ insert into temp.ks_seq values (100);
216
+ create table main.ks_seq (n integer primary key);
217
+ insert into main.ks_seq values (500);
218
+ create table temp.ks_core (rid integer primary key default (coalesce((select max(n) from ks_seq), 0) + mutation_ordinal()), name text);
219
+ create table temp.ks_contact (rid integer primary key, email text);
220
+ create view main.ks_v as select c.name as name, k.email as email
221
+ from temp.ks_core c join temp.ks_contact k on k.rid = c.rid;
222
+ -- run
223
+
224
+ insert into main.ks_v (name, email) values ('Bea', 'bea@x.io');
225
+
226
+ select rid, name from temp.ks_core order by rid;
227
+ → [{"rid":101,"name":"Bea"}]
228
+
229
+ -- ===== Control: a QUALIFIED reference inside a default is unaffected =====
230
+
231
+ create table temp.sp_q (id integer primary key, w integer default (select count(*) from main.c));
232
+ -- run
233
+
234
+ insert into temp.sp_q (id) values (1);
235
+
236
+ select id, w from temp.sp_q order by id;
237
+ → [{"id":1,"w":1}]
238
+
239
+ -- ===== The rule is strict: no fallback to the session default path =====
240
+ -- A schema-authored expression naming a relation that lives ONLY in another schema, and
241
+ -- not qualifying it, does not resolve — the same rule CHECK and FK bodies have always
242
+ -- had. (docs/schema.md § Stored bodies resolve against their home schema.)
243
+
244
+ create table main.sp_only (k integer primary key);
245
+ insert into main.sp_only values (1);
246
+ create table temp.sp_cross (id integer primary key, w integer default (select count(*) from sp_only));
247
+ -- run
248
+
249
+ insert into temp.sp_cross (id) values (1);
250
+ -- error: sp_only
251
+
252
+ select count(*) as n from temp.sp_cross;
253
+ → [{"n":0}]
254
+
255
+ -- ===== ALTER TABLE ADD COLUMN's CHECK, validated over the existing rows =====
256
+ -- The new column's CHECK is enforced against rows already in the table by a scan
257
+ -- re-prepared from the constraint's own SQL text (`validateBackfillAgainstChecks` in
258
+ -- runtime/emit/alter-table.ts). A freshly-prepared statement carries the SESSION path,
259
+ -- so that scan needs the owning schema pinned on it explicitly — the planning-context
260
+ -- helper never sees it. Both directions, since one alone cannot tell a narrowed path
261
+ -- from a scan that silently did nothing.
262
+ --
263
+ -- The per-row backfill / CHECK path below covers the same rule for a non-foldable
264
+ -- (subquery) DEFAULT and the CHECK predicates that ride alongside it — untestable until
265
+ -- bug-alter-add-column-relation-default-fails-to-emit, since before that fix a subquery
266
+ -- inside either reached the runtime unphysicalized and the whole ALTER errored outright.
267
+
268
+ create table temp.sp_ac (id integer primary key);
269
+ insert into temp.sp_ac values (1);
270
+ create table temp.sp_acx (id integer primary key);
271
+ insert into temp.sp_acx values (1);
272
+ -- run
273
+
274
+ -- true only against the main.c decoy (1 row) ⇒ must be REJECTED
275
+ alter table temp.sp_acx add column x integer default 0 check ((select count(*) from c) = 1);
276
+ -- error: CHECK
277
+
278
+ -- true against temp.c (3 rows), beside the table ⇒ must be ACCEPTED
279
+ alter table temp.sp_ac add column x integer default 0 check ((select count(*) from c) = 3);
280
+ -- run
281
+
282
+ select id, x from temp.sp_ac order by id;
283
+ → [{"id":1,"x":0}]
284
+
285
+ -- ===== ALTER TABLE ADD COLUMN's per-row backfill / CHECK, same rule =====
286
+
287
+ create table temp.sp_acbf (id integer primary key);
288
+ insert into temp.sp_acbf values (1);
289
+ -- run
290
+
291
+ -- A non-foldable (subquery) DEFAULT compiles to a per-row backfill node — 3 (temp.c,
292
+ -- beside the table), not 1 (main.c, on the writer's path).
293
+ alter table temp.sp_acbf add column n integer default (select count(*) from c);
294
+ -- run
295
+
296
+ select id, n from temp.sp_acbf order by id;
297
+ → [{"id":1,"n":3}]
298
+
299
+ -- A per-row DEFAULT (`new.id`) with an inline CHECK reading `c` — true against temp.c
300
+ -- (3 rows), beside the table ⇒ accepted.
301
+ alter table temp.sp_acbf add column m integer default (new.id) check ((select count(*) from c) = 3);
302
+ -- run
303
+
304
+ select id, m from temp.sp_acbf order by id;
305
+ → [{"id":1,"m":1}]
306
+
307
+ -- Same shape, but the CHECK is only true against the main.c decoy (1 row) ⇒ rejected —
308
+ -- distinguishes a narrowed path from a CHECK that silently did nothing.
309
+ alter table temp.sp_acbf add column mm integer default (new.id) check ((select count(*) from c) = 1);
310
+ -- error: CHECK
311
+
312
+ select * from temp.sp_acbf order by id;
313
+ → [{"id":1,"n":3,"m":1}]
314
+
315
+ -- ===== A maintained table's declared CHECK, both when it is created and when it derives =====
316
+ -- `create table … maintained as` reaches the same CHECK bodies by two routes that neither
317
+ -- INSERT nor UPDATE uses: the create-time scan over the already-derived rows
318
+ -- (`validateChecksOverExistingRows`, schema/constraint-builder.ts — again a re-prepared
319
+ -- statement, so the path is pinned on the statement) and the per-derived-row validator
320
+ -- (`core/derived-row-validator.ts`, which builds on its OWN fresh planning context — the
321
+ -- one call site that would have lost the narrowing when the constraint and foreign-key
322
+ -- builders stopped narrowing internally).
323
+
324
+ create table temp.mt_src (id integer primary key, n integer);
325
+ insert into temp.mt_src values (1, 2);
326
+ -- run
327
+
328
+ -- Created while `temp.mt_src` already holds n = 2: passes against temp.c (2 <= 3),
329
+ -- would fail against the main.c decoy (2 <= 1).
330
+ create table temp.mt (id integer primary key, n integer not null check (n <= (select count(*) from c)))
331
+ maintained as select id, n from mt_src;
332
+ -- run
333
+
334
+ select id, n from temp.mt order by id;
335
+ → [{"id":1,"n":2}]
336
+
337
+ -- and a row derived AFTER creation goes through the derived-row validator instead
338
+ insert into temp.mt_src values (2, 3);
339
+
340
+ select id, n from temp.mt order by id;
341
+ → [{"id":1,"n":2},{"id":2,"n":3}]
342
+
343
+ -- the same validator must still REJECT: 9 > 3, against temp.c
344
+ insert into temp.mt_src values (3, 9);
345
+ -- error: CHECK
346
+
347
+ -- ===== A user-declared schema behaves identically (not a `temp`-only special case) =====
348
+
349
+ declare schema spapp {
350
+ table c {
351
+ k INTEGER PRIMARY KEY
352
+ }
353
+ table t {
354
+ id INTEGER PRIMARY KEY,
355
+ w INTEGER DEFAULT (select count(*) from c)
356
+ }
357
+ }
358
+
359
+ apply schema spapp;
360
+ -- run
361
+
362
+ insert into spapp.c values (1), (2), (3), (4), (5);
363
+
364
+ insert into spapp.t (id) values (1);
365
+
366
+ -- 5 (spapp.c), not 1 (main.c, the session path).
367
+ select id, w from spapp.t order by id;
368
+ → [{"id":1,"w":5}]
369
+
370
+ -- Cleanup
371
+ drop table spapp.t;
372
+ drop table spapp.c;
373
+ drop table temp.mt;
374
+ drop table temp.mt_src;
375
+ drop table temp.sp_acx;
376
+ drop table temp.sp_ac;
377
+ drop table temp.sp_cross;
378
+ drop table main.sp_only;
379
+ drop table temp.sp_q;
380
+ drop view main.ks_v;
381
+ drop table temp.ks_contact;
382
+ drop table temp.ks_core;
383
+ drop table main.ks_seq;
384
+ drop table temp.ks_seq;
385
+ drop view temp.kd_v;
386
+ drop table temp.kd_contact;
387
+ drop table temp.kd_core;
388
+ drop table main.kd_core;
389
+ drop view temp.sp_v;
390
+ drop table temp.sp_vt;
391
+ drop table temp.sp_fkc;
392
+ drop table temp.sp_fkp;
393
+ drop table temp.sp_ckx;
394
+ drop table temp.sp_ck;
395
+ drop table temp.sp_ckux;
396
+ drop table temp.sp_cku;
397
+ drop table temp.sp_ws;
398
+ drop table temp.sp_nnd;
399
+ drop table temp.sp_gen;
400
+ drop table temp.sp_gen_alter;
401
+ drop table temp.sp_def;
402
+ -- sp_acbf's added CHECK reads `c` through a subquery (resolving, from temp, to temp.c),
403
+ -- so it has to go before it: dropping a table a stored expression still names is refused
404
+ -- (41.10.4-drop-object-expression-dependents).
405
+ drop table temp.sp_acbf;
406
+ drop table temp.c;
407
+ drop table main.c;
408
+ -- run
@@ -0,0 +1,168 @@
1
+ -- utilities.sqllogic - Edge cases for NULL handling, coercion, collation, truthiness, and aggregates
2
+
3
+ -- === NULL comparison semantics ===
4
+
5
+ select null = null;
6
+ → [{"null = null":null}]
7
+
8
+ select null < 1;
9
+ → [{"null < 1":null}]
10
+
11
+ select null > 1;
12
+ → [{"null > 1":null}]
13
+
14
+ select null != null;
15
+ → [{"null != null":null}]
16
+
17
+ select null >= 0;
18
+ → [{"null >= 0":null}]
19
+
20
+ -- === NULL sorting (total ordering: NULL first in ASC by default) ===
21
+
22
+ CREATE TABLE null_sort_t (id INTEGER PRIMARY KEY, v INTEGER NULL);
23
+ INSERT INTO null_sort_t VALUES (1, null), (2, 3), (3, 1), (4, null), (5, 2);
24
+
25
+ select v from null_sort_t order by v;
26
+ → [{"v":null},{"v":null},{"v":1},{"v":2},{"v":3}]
27
+
28
+ select v from null_sort_t order by v desc;
29
+ → [{"v":null},{"v":null},{"v":3},{"v":2},{"v":1}]
30
+
31
+ -- NULLS LAST moves nulls to end in ASC
32
+ select v from null_sort_t order by v nulls last;
33
+ → [{"v":1},{"v":2},{"v":3},{"v":null},{"v":null}]
34
+
35
+ -- NULLS FIRST in DESC keeps nulls at the start
36
+ select v from null_sort_t order by v desc nulls first;
37
+ → [{"v":null},{"v":null},{"v":3},{"v":2},{"v":1}]
38
+
39
+ -- NULLS LAST in DESC moves nulls to the end
40
+ select v from null_sort_t order by v desc nulls last;
41
+ → [{"v":3},{"v":2},{"v":1},{"v":null},{"v":null}]
42
+
43
+ DROP TABLE null_sort_t;
44
+
45
+ -- === Storage class ordering ===
46
+ -- Type ordering: NULL < NUMERIC < TEXT < BLOB
47
+
48
+ CREATE TABLE mixed_t (id INTEGER PRIMARY KEY, v ANY NULL);
49
+ INSERT INTO mixed_t VALUES (1, null), (2, 42), (3, 'hello'), (4, 3.14), (5, x'FF');
50
+
51
+ -- Verify cross-type ordering via typeof
52
+ select typeof(v) from mixed_t order by v;
53
+ → [{"typeof(v)":"null"},{"typeof(v)":"real"},{"typeof(v)":"integer"},{"typeof(v)":"text"},{"typeof(v)":"blob"}]
54
+
55
+ DROP TABLE mixed_t;
56
+
57
+ -- === Collation tests ===
58
+
59
+ -- Default (BINARY) collation: case-sensitive
60
+ select 'ABC' = 'abc';
61
+ → [{"'ABC' = 'abc'":false}]
62
+
63
+ -- NOCASE collation on column definition
64
+ CREATE TABLE nocase_t (id INTEGER PRIMARY KEY, name TEXT COLLATE NOCASE);
65
+ INSERT INTO nocase_t VALUES (1, 'Alice'), (2, 'alice'), (3, 'BOB'), (4, 'bob');
66
+
67
+ -- Case-insensitive ordering (secondary sort by id for stability)
68
+ select name from nocase_t order by name, id;
69
+ → [{"name":"Alice"},{"name":"alice"},{"name":"BOB"},{"name":"bob"}]
70
+
71
+ -- Case-insensitive equality
72
+ select id from nocase_t where name = 'alice' order by id;
73
+ → [{"id":1},{"id":2}]
74
+
75
+ DROP TABLE nocase_t;
76
+
77
+ -- RTRIM collation on column definition
78
+ CREATE TABLE rtrim_t (id INTEGER PRIMARY KEY, name TEXT COLLATE RTRIM);
79
+ INSERT INTO rtrim_t VALUES (1, 'hello'), (2, 'hello '), (3, 'world'), (4, 'world ');
80
+
81
+ -- RTRIM equality: 'hello' and 'hello ' are equal
82
+ select id from rtrim_t where name = 'hello' order by id;
83
+ → [{"id":1},{"id":2}]
84
+
85
+ select id from rtrim_t where name = 'world' order by id;
86
+ → [{"id":3},{"id":4}]
87
+
88
+ DROP TABLE rtrim_t;
89
+
90
+ -- === Coercion edge cases ===
91
+
92
+ -- Numeric string coercion in comparisons
93
+ select 42 = '42';
94
+ → [{"42 = '42'":true}]
95
+
96
+ select 42 < '43';
97
+ → [{"42 < '43'":true}]
98
+
99
+ -- Non-numeric string stays as text (cross-type comparison: number != text)
100
+ select 42 = 'hello';
101
+ → [{"42 = 'hello'":false}]
102
+
103
+ -- Scientific notation coercion
104
+ select 1000 = '1e3';
105
+ → [{"1000 = '1e3'":true}]
106
+
107
+ -- Arithmetic with mixed types
108
+ select 1 + '2';
109
+ → [{"1 + '2'":3}]
110
+
111
+ -- Non-numeric string coerces to 0 in arithmetic
112
+ select 1 + 'hello';
113
+ → [{"1 + 'hello'":1}]
114
+
115
+ select 'abc' + 0;
116
+ → [{"'abc' + 0":0}]
117
+
118
+ select '' + 0;
119
+ → [{"'' + 0":0}]
120
+
121
+ -- === Truthiness (isTruthy) edge cases ===
122
+
123
+ CREATE TABLE bool_t (id INTEGER PRIMARY KEY, v ANY NULL);
124
+ INSERT INTO bool_t VALUES (1, 0), (2, 1), (3, ''), (4, 'text'), (5, null);
125
+
126
+ -- WHERE uses numeric truthiness: strings are coerced to numbers; non-numeric strings are falsy
127
+ select id from bool_t where v;
128
+ → [{"id":2}]
129
+
130
+ DROP TABLE bool_t;
131
+
132
+ -- CASE WHEN uses isTruthy
133
+ select case when 0 then 'yes' else 'no' end as r;
134
+ → [{"r":"no"}]
135
+
136
+ select case when 1 then 'yes' else 'no' end as r;
137
+ → [{"r":"yes"}]
138
+
139
+ select case when '' then 'yes' else 'no' end as r;
140
+ → [{"r":"no"}]
141
+
142
+ select case when 'nonempty' then 'yes' else 'no' end as r;
143
+ → [{"r":"no"}]
144
+
145
+ select case when null then 'yes' else 'no' end as r;
146
+ → [{"r":"no"}]
147
+
148
+ -- === Aggregate coercion ===
149
+
150
+ -- SUM with numeric strings (coerced to numbers)
151
+ CREATE TABLE agg_t (id INTEGER PRIMARY KEY, amount TEXT);
152
+ INSERT INTO agg_t VALUES (1, '10'), (2, '20'), (3, '30');
153
+
154
+ select sum(amount) from agg_t;
155
+ → [{"sum(amount)":60}]
156
+
157
+ -- MIN/MAX with mixed coerced values
158
+ -- Numeric strings are coerced to numbers; non-numeric stay as text
159
+ -- Storage class ordering: NUMERIC < TEXT, so min = smallest number, max = largest text
160
+ INSERT INTO agg_t VALUES (4, 'z'), (5, 'a');
161
+
162
+ select min(amount) from agg_t;
163
+ → [{"min(amount)":10}]
164
+
165
+ select max(amount) from agg_t;
166
+ → [{"max(amount)":"z"}]
167
+
168
+ DROP TABLE agg_t;