@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,754 @@
1
+ -- 105-vtab-memory-mutation-kills.sqllogic
2
+ -- Mutation-killing tests targeting packages/quereus/src/vtab/memory/ (module.ts, table.ts, connection.ts)
3
+
4
+ -- ===================================================================
5
+ -- SECTION 1: IS NULL on NOT NULL column → empty result (module.ts:145-158)
6
+ -- ===================================================================
7
+
8
+ create table nn_test (id integer primary key, a integer not null, b text null);
9
+ insert into nn_test values (1, 10, 'x'), (2, 20, null), (3, 30, 'z');
10
+
11
+ -- IS NULL on NOT NULL column should return empty (planner marks all filters handled, returns 0 rows)
12
+ select * from nn_test where a is null;
13
+ → []
14
+
15
+ -- IS NULL on nullable column should return matching rows
16
+ select id from nn_test where b is null;
17
+ → [{"id": 2}]
18
+
19
+ -- IS NULL on the key column should return empty — not because it is a key (membership implies
20
+ -- nothing about nullability) but because it is NOT NULL under the shipped default
21
+ select * from nn_test where id is null;
22
+ → []
23
+
24
+ -- Combine IS NULL NOT NULL with other filters — the IS NULL short-circuits
25
+ select id from nn_test where a is null and b = 'x';
26
+ → []
27
+
28
+ drop table nn_test;
29
+
30
+ -- ===================================================================
31
+ -- SECTION 2: IS NOT NULL on NOT NULL column → tautology (module.ts:212-227)
32
+ -- ===================================================================
33
+
34
+ create table isnn_test (id integer primary key, a integer not null, b text null);
35
+ insert into isnn_test values (1, 10, 'x'), (2, 20, null), (3, 30, 'z');
36
+
37
+ -- IS NOT NULL on NOT NULL column is a tautology — all rows returned
38
+ select id from isnn_test where a is not null order by id;
39
+ → [{"id": 1}, {"id": 2}, {"id": 3}]
40
+
41
+ -- IS NOT NULL on PK is a tautology — all rows returned
42
+ select id from isnn_test where id is not null order by id;
43
+ → [{"id": 1}, {"id": 2}, {"id": 3}]
44
+
45
+ -- IS NOT NULL on nullable column filters correctly
46
+ select id from isnn_test where b is not null order by id;
47
+ → [{"id": 1}, {"id": 3}]
48
+
49
+ -- Combine IS NOT NULL tautology with a real filter
50
+ select id from isnn_test where a is not null and b = 'z';
51
+ → [{"id": 3}]
52
+
53
+ drop table isnn_test;
54
+
55
+ -- ===================================================================
56
+ -- SECTION 3: PK ordering advertisement (module.ts:188-204)
57
+ -- B-tree scans produce PK order naturally.
58
+ -- ===================================================================
59
+
60
+ create table pk_order (id integer primary key, val text);
61
+ insert into pk_order values (3, 'c'), (1, 'a'), (5, 'e'), (2, 'b'), (4, 'd');
62
+
63
+ -- Full scan should produce rows in PK order without explicit ORDER BY
64
+ select id, val from pk_order;
65
+ → [{"id": 1, "val": "a"}, {"id": 2, "val": "b"}, {"id": 3, "val": "c"}, {"id": 4, "val": "d"}, {"id": 5, "val": "e"}]
66
+
67
+ -- ORDER BY pk should be satisfied by the natural BTree order
68
+ select id from pk_order order by id;
69
+ → [{"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}]
70
+
71
+ -- DESC PK table
72
+ drop table pk_order;
73
+ create table pk_desc (id integer primary key desc, val text);
74
+ insert into pk_desc values (3, 'c'), (1, 'a'), (5, 'e'), (2, 'b'), (4, 'd');
75
+
76
+ -- Natural order should be descending
77
+ select id, val from pk_desc;
78
+ → [{"id": 5, "val": "e"}, {"id": 4, "val": "d"}, {"id": 3, "val": "c"}, {"id": 2, "val": "b"}, {"id": 1, "val": "a"}]
79
+
80
+ drop table pk_desc;
81
+
82
+ -- ===================================================================
83
+ -- SECTION 4: Full scan fallback (module.ts:172-177)
84
+ -- ===================================================================
85
+
86
+ create table no_idx (id integer primary key, name text, age integer);
87
+ insert into no_idx values (1, 'Alice', 30), (2, 'Bob', 25), (3, 'Charlie', 35);
88
+
89
+ -- Filter on non-indexed column forces full scan
90
+ select name from no_idx where name = 'Bob';
91
+ → [{"name": "Bob"}]
92
+
93
+ -- Filter on non-indexed column with range
94
+ select name from no_idx where age > 28 order by id;
95
+ → [{"name": "Alice"}, {"name": "Charlie"}]
96
+
97
+ drop table no_idx;
98
+
99
+ -- ===================================================================
100
+ -- SECTION 5: Index equality matching / prefix matching (module.ts:325-363)
101
+ -- ===================================================================
102
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
103
+
104
+ -- ===================================================================
105
+ -- SECTION 6: Index range matching (module.ts:368-389)
106
+ -- ===================================================================
107
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
108
+
109
+ -- ===================================================================
110
+ -- SECTION 7: Prefix-equality + trailing-range on composite index (module.ts:264-281)
111
+ -- ===================================================================
112
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
113
+
114
+ -- ===================================================================
115
+ -- SECTION 8: Ordering from index (module.ts:414-461)
116
+ -- ===================================================================
117
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
118
+
119
+ -- ===================================================================
120
+ -- SECTION 9: Composite primary keys (table.ts:389-395 comparePrimaryKey)
121
+ -- ===================================================================
122
+
123
+ create table comp_pk (a integer, b text, c integer, primary key (a, b));
124
+ insert into comp_pk values (1, 'x', 100), (1, 'y', 200), (2, 'x', 300), (2, 'y', 400);
125
+
126
+ -- Point lookup on composite PK
127
+ select c from comp_pk where a = 1 and b = 'y';
128
+ → [{"c": 200}]
129
+
130
+ -- Range on first PK column
131
+ select a, b from comp_pk where a = 2 order by a, b;
132
+ → [{"a": 2, "b": "x"}, {"a": 2, "b": "y"}]
133
+
134
+ -- All rows in PK order
135
+ select a, b, c from comp_pk;
136
+ → [{"a": 1, "b": "x", "c": 100}, {"a": 1, "b": "y", "c": 200}, {"a": 2, "b": "x", "c": 300}, {"a": 2, "b": "y", "c": 400}]
137
+
138
+ -- Update by composite PK
139
+ update comp_pk set c = 999 where a = 1 and b = 'x';
140
+ select c from comp_pk where a = 1 and b = 'x';
141
+ → [{"c": 999}]
142
+
143
+ -- Delete by composite PK
144
+ delete from comp_pk where a = 2 and b = 'y';
145
+ select count(*) as cnt from comp_pk;
146
+ → [{"cnt": 3}]
147
+
148
+ -- Duplicate PK should fail
149
+ insert into comp_pk values (1, 'y', 500);
150
+ -- error: UNIQUE constraint
151
+
152
+ drop table comp_pk;
153
+
154
+ -- ===================================================================
155
+ -- SECTION 10: Multi-column secondary indexes
156
+ -- ===================================================================
157
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
158
+
159
+ -- ===================================================================
160
+ -- SECTION 11: DESC secondary indexes (table.ts:411-428 getIndexComparator)
161
+ -- ===================================================================
162
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
163
+
164
+ -- ===================================================================
165
+ -- SECTION 12: SAVEPOINT / RELEASE / ROLLBACK TO sequences (table.ts:290-303)
166
+ -- ===================================================================
167
+
168
+ create table sp_data (id integer primary key, val text);
169
+ insert into sp_data values (1, 'original');
170
+
171
+ -- Basic savepoint + release
172
+ begin;
173
+ savepoint s1;
174
+ insert into sp_data values (2, 'in-s1');
175
+ release savepoint s1;
176
+ commit;
177
+ select val from sp_data where id = 2;
178
+ → [{"val": "in-s1"}]
179
+
180
+ -- Savepoint + rollback to
181
+ begin;
182
+ savepoint s2;
183
+ update sp_data set val = 'modified' where id = 1;
184
+ insert into sp_data values (3, 'in-s2');
185
+ select val from sp_data where id = 1;
186
+ → [{"val": "modified"}]
187
+ rollback to savepoint s2;
188
+ -- Changes after s2 should be undone
189
+ select val from sp_data where id = 1;
190
+ → [{"val": "original"}]
191
+ select count(*) as cnt from sp_data where id = 3;
192
+ → [{"cnt": 0}]
193
+ commit;
194
+
195
+ -- Nested savepoints: rollback to outer discards inner
196
+ begin;
197
+ insert into sp_data values (10, 'base');
198
+ savepoint outer_sp;
199
+ insert into sp_data values (11, 'outer');
200
+ savepoint inner_sp;
201
+ insert into sp_data values (12, 'inner');
202
+ rollback to savepoint outer_sp;
203
+ -- Both inner_sp and outer_sp changes should be gone
204
+ select count(*) as cnt from sp_data where id in (11, 12);
205
+ → [{"cnt": 0}]
206
+ -- base insert should remain
207
+ select count(*) as cnt from sp_data where id = 10;
208
+ → [{"cnt": 1}]
209
+ commit;
210
+
211
+ -- Cleanup
212
+ delete from sp_data where id >= 10;
213
+ -- run
214
+
215
+ -- Savepoint after rollback-to — can continue working
216
+ begin;
217
+ savepoint reuse;
218
+ insert into sp_data values (20, 'will-undo');
219
+ rollback to savepoint reuse;
220
+ -- Insert after rollback-to
221
+ insert into sp_data values (21, 'after-rollback');
222
+ release savepoint reuse;
223
+ commit;
224
+ select count(*) as cnt from sp_data where id = 20;
225
+ → [{"cnt": 0}]
226
+ select val from sp_data where id = 21;
227
+ → [{"val": "after-rollback"}]
228
+
229
+ drop table sp_data;
230
+
231
+ -- ===================================================================
232
+ -- SECTION 13: Transaction isolation (BEGIN, INSERT, ROLLBACK)
233
+ -- ===================================================================
234
+
235
+ create table iso_test (id integer primary key, val text);
236
+ insert into iso_test values (1, 'committed');
237
+
238
+ -- Rollback should discard all uncommitted changes
239
+ begin;
240
+ insert into iso_test values (2, 'uncommitted');
241
+ update iso_test set val = 'changed' where id = 1;
242
+ select val from iso_test where id = 1;
243
+ → [{"val": "changed"}]
244
+ select count(*) as cnt from iso_test;
245
+ → [{"cnt": 2}]
246
+ rollback;
247
+
248
+ -- After rollback, original state should be restored
249
+ select val from iso_test where id = 1;
250
+ → [{"val": "committed"}]
251
+ select count(*) as cnt from iso_test;
252
+ → [{"cnt": 1}]
253
+
254
+ -- Delete inside transaction then rollback
255
+ begin;
256
+ delete from iso_test where id = 1;
257
+ select count(*) as cnt from iso_test;
258
+ → [{"cnt": 0}]
259
+ rollback;
260
+ select count(*) as cnt from iso_test;
261
+ → [{"cnt": 1}]
262
+
263
+ drop table iso_test;
264
+
265
+ -- ===================================================================
266
+ -- SECTION 14: committed.* snapshot reads (table.ts:231, 244)
267
+ -- ===================================================================
268
+
269
+ create table snap_test (id integer primary key, val integer);
270
+ insert into snap_test values (1, 100), (2, 200);
271
+ -- run
272
+
273
+ begin;
274
+ update snap_test set val = 999 where id = 1;
275
+ insert into snap_test values (3, 300);
276
+
277
+ -- committed.snap_test should see pre-transaction state
278
+ select val from committed.snap_test where id = 1;
279
+ → [{"val": 100}]
280
+ select count(*) as cnt from committed.snap_test;
281
+ → [{"cnt": 2}]
282
+
283
+ -- Current table sees uncommitted changes
284
+ select val from snap_test where id = 1;
285
+ → [{"val": 999}]
286
+ select count(*) as cnt from snap_test;
287
+ → [{"cnt": 3}]
288
+ commit;
289
+
290
+ -- After commit, committed.* shows the new state
291
+ select val from committed.snap_test where id = 1;
292
+ → [{"val": 999}]
293
+ select count(*) as cnt from committed.snap_test;
294
+ → [{"cnt": 3}]
295
+
296
+ -- committed.* is read-only
297
+ insert into committed.snap_test values (4, 400);
298
+ -- error: Cannot modify committed-state
299
+
300
+ update committed.snap_test set val = 0 where id = 1;
301
+ -- error: Cannot modify committed-state
302
+
303
+ delete from committed.snap_test where id = 1;
304
+ -- error: Cannot modify committed-state
305
+
306
+ drop table snap_test;
307
+ -- run
308
+
309
+ -- ===================================================================
310
+ -- SECTION 15: ALTER TABLE on memory tables
311
+ -- ===================================================================
312
+
313
+ -- ADD COLUMN
314
+ create table alt_test (id integer primary key, name text);
315
+ insert into alt_test values (1, 'Alice'), (2, 'Bob');
316
+
317
+ alter table alt_test add column age integer null;
318
+ select * from alt_test order by id;
319
+ → [{"id": 1, "name": "Alice", "age": null}, {"id": 2, "name": "Bob", "age": null}]
320
+
321
+ -- Insert with new column
322
+ insert into alt_test values (3, 'Charlie', 30);
323
+ select * from alt_test where id = 3;
324
+ → [{"id": 3, "name": "Charlie", "age": 30}]
325
+
326
+ -- ADD COLUMN with default
327
+ alter table alt_test add column status text default 'active';
328
+ select status from alt_test where id = 1;
329
+ → [{"status": "active"}]
330
+
331
+ -- DROP COLUMN
332
+ alter table alt_test drop column status;
333
+ select * from alt_test where id = 1;
334
+ → [{"id": 1, "name": "Alice", "age": null}]
335
+
336
+ -- RENAME COLUMN
337
+ alter table alt_test rename column name to full_name;
338
+ select full_name from alt_test where id = 2;
339
+ → [{"full_name": "Bob"}]
340
+
341
+ -- Verify data integrity after all alterations
342
+ select * from alt_test order by id;
343
+ → [{"id": 1, "full_name": "Alice", "age": null}, {"id": 2, "full_name": "Bob", "age": null}, {"id": 3, "full_name": "Charlie", "age": 30}]
344
+
345
+ drop table alt_test;
346
+
347
+ -- ===================================================================
348
+ -- SECTION 16: Index CREATE/DROP on populated tables
349
+ -- ===================================================================
350
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
351
+
352
+ -- ===================================================================
353
+ -- SECTION 17: Edge cases for IS NULL / IS NOT NULL interactions
354
+ -- ===================================================================
355
+
356
+ create table null_edge (id integer primary key, a integer not null, b text null, c integer null);
357
+ insert into null_edge values (1, 10, null, null), (2, 20, 'x', 100), (3, 30, null, 200);
358
+
359
+ -- IS NULL on NOT NULL with other non-null conditions: still empty
360
+ select id from null_edge where a is null and c > 0;
361
+ → []
362
+
363
+ -- IS NOT NULL on NOT NULL + IS NULL on nullable
364
+ select id from null_edge where a is not null and b is null order by id;
365
+ → [{"id": 1}, {"id": 3}]
366
+
367
+ -- IS NOT NULL on both NOT NULL and nullable
368
+ select id from null_edge where a is not null and c is not null order by id;
369
+ → [{"id": 2}, {"id": 3}]
370
+
371
+ -- IS NOT NULL on NOT NULL col in a join
372
+ create table null_edge2 (id integer primary key, ref integer not null);
373
+ insert into null_edge2 values (1, 1), (2, 2);
374
+ select ne.id, ne2.id as ref_id from null_edge ne join null_edge2 ne2 on ne.id = ne2.ref where ne.a is not null and ne2.ref is not null order by ne.id;
375
+ → [{"id": 1, "ref_id": 1}, {"id": 2, "ref_id": 2}]
376
+ drop table null_edge2;
377
+
378
+ drop table null_edge;
379
+
380
+ -- ===================================================================
381
+ -- SECTION 18: PK point lookup and PK range with LIMIT
382
+ -- ===================================================================
383
+
384
+ create table pk_lookup (id integer primary key, data text);
385
+ insert into pk_lookup values (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e');
386
+
387
+ -- PK point lookup
388
+ select data from pk_lookup where id = 3;
389
+ → [{"data": "c"}]
390
+
391
+ -- PK point lookup — not found
392
+ select data from pk_lookup where id = 99;
393
+ → []
394
+
395
+ -- PK range with LIMIT
396
+ select id from pk_lookup where id > 1 order by id limit 2;
397
+ → [{"id": 2}, {"id": 3}]
398
+
399
+ -- PK range with both bounds and LIMIT
400
+ select id from pk_lookup where id >= 2 and id <= 4 order by id limit 2;
401
+ → [{"id": 2}, {"id": 3}]
402
+
403
+ drop table pk_lookup;
404
+
405
+ -- ===================================================================
406
+ -- SECTION 19: Empty table edge cases
407
+ -- ===================================================================
408
+
409
+ create table empty_t (id integer primary key, val text not null default 'x');
410
+
411
+ -- IS NULL on NOT NULL column of empty table
412
+ select * from empty_t where val is null;
413
+ → []
414
+
415
+ -- IS NOT NULL on NOT NULL column of empty table
416
+ select * from empty_t where val is not null;
417
+ → []
418
+
419
+ -- Count of empty table
420
+ select count(*) as cnt from empty_t;
421
+ → [{"cnt": 0}]
422
+
423
+ -- Range scan on empty table
424
+ select * from empty_t where id > 0;
425
+ → []
426
+
427
+ -- Insert and verify
428
+ insert into empty_t values (1, 'hello');
429
+ select * from empty_t;
430
+ → [{"id": 1, "val": "hello"}]
431
+
432
+ drop table empty_t;
433
+
434
+ -- ===================================================================
435
+ -- SECTION 20: Multiple filters handled — cost nudge (module.ts:206-210)
436
+ -- When no index handles any filter, cost gets a small nudge (+0.01)
437
+ -- ===================================================================
438
+
439
+ create table cost_nudge (id integer primary key, a text, b text);
440
+ insert into cost_nudge values (1, 'foo', 'bar'), (2, 'baz', 'qux');
441
+
442
+ -- Filter on non-indexed column (forces full scan, no filters handled)
443
+ select id from cost_nudge where a = 'foo' and b = 'bar';
444
+ → [{"id": 1}]
445
+
446
+ -- Verify both filters work
447
+ select id from cost_nudge where a = 'baz' and b = 'qux';
448
+ → [{"id": 2}]
449
+
450
+ -- No matches
451
+ select id from cost_nudge where a = 'nope' and b = 'nada';
452
+ → []
453
+
454
+ drop table cost_nudge;
455
+
456
+ -- ===================================================================
457
+ -- SECTION 21: Transaction with index modifications
458
+ -- ===================================================================
459
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
460
+
461
+ -- ===================================================================
462
+ -- SECTION 22: Composite PK with different types
463
+ -- ===================================================================
464
+
465
+ create table comp_pk_types (
466
+ region text,
467
+ id integer,
468
+ detail text,
469
+ primary key (region, id)
470
+ );
471
+ insert into comp_pk_types values ('us', 1, 'a'), ('us', 2, 'b'), ('eu', 1, 'c'), ('eu', 2, 'd');
472
+
473
+ -- Lookup by full composite key
474
+ select detail from comp_pk_types where region = 'eu' and id = 2;
475
+ → [{"detail": "d"}]
476
+
477
+ -- Lookup by first part of composite key
478
+ select detail from comp_pk_types where region = 'us' order by id;
479
+ → [{"detail": "a"}, {"detail": "b"}]
480
+
481
+ -- Update by composite PK
482
+ update comp_pk_types set detail = 'updated' where region = 'eu' and id = 1;
483
+ select detail from comp_pk_types where region = 'eu' and id = 1;
484
+ → [{"detail": "updated"}]
485
+
486
+ -- Delete by composite PK
487
+ delete from comp_pk_types where region = 'us' and id = 1;
488
+ select count(*) as cnt from comp_pk_types where region = 'us';
489
+ → [{"cnt": 1}]
490
+
491
+ drop table comp_pk_types;
492
+
493
+ -- ===================================================================
494
+ -- SECTION 23: Three-column composite PK ordering
495
+ -- ===================================================================
496
+
497
+ create table triple_pk (a integer, b integer, c integer, val text, primary key (a, b, c));
498
+ insert into triple_pk values (1, 1, 1, 'aaa'), (1, 1, 2, 'aab'), (1, 2, 1, 'aba'), (2, 1, 1, 'baa');
499
+
500
+ -- Natural PK order
501
+ select a, b, c from triple_pk;
502
+ → [{"a": 1, "b": 1, "c": 1}, {"a": 1, "b": 1, "c": 2}, {"a": 1, "b": 2, "c": 1}, {"a": 2, "b": 1, "c": 1}]
503
+
504
+ -- Equality on first two, range on third
505
+ select val from triple_pk where a = 1 and b = 1 order by c;
506
+ → [{"val": "aaa"}, {"val": "aab"}]
507
+
508
+ -- Equality on first only
509
+ select val from triple_pk where a = 1 order by b, c;
510
+ → [{"val": "aaa"}, {"val": "aab"}, {"val": "aba"}]
511
+
512
+ drop table triple_pk;
513
+
514
+ -- ===================================================================
515
+ -- SECTION 24: Unique index constraint enforcement
516
+ -- ===================================================================
517
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
518
+
519
+ -- ===================================================================
520
+ -- SECTION 25: SAVEPOINT with mutations on indexed table
521
+ -- ===================================================================
522
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
523
+
524
+ -- ===================================================================
525
+ -- SECTION 26: Large-ish dataset for index effectiveness
526
+ -- ===================================================================
527
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
528
+
529
+ -- ===================================================================
530
+ -- SECTION 27: RENAME TABLE on memory table
531
+ -- ===================================================================
532
+
533
+ create table rename_me (id integer primary key, val text);
534
+ insert into rename_me values (1, 'hello');
535
+ alter table rename_me rename to renamed_t;
536
+ -- run
537
+
538
+ -- Old name should fail
539
+ select * from rename_me;
540
+ -- error: not found
541
+
542
+ -- New name should work
543
+ select val from renamed_t where id = 1;
544
+ → [{"val": "hello"}]
545
+
546
+ -- Can mutate renamed table
547
+ insert into renamed_t values (2, 'world');
548
+ select count(*) as cnt from renamed_t;
549
+ → [{"cnt": 2}]
550
+
551
+ drop table renamed_t;
552
+
553
+ -- ===================================================================
554
+ -- SECTION 28: Connection disconnect cleanup (connection.ts:59-67)
555
+ -- ===================================================================
556
+
557
+ -- Verify that after a table is dropped and recreated, everything works cleanly
558
+ create table conn_test (id integer primary key, val text);
559
+ insert into conn_test values (1, 'first');
560
+ drop table conn_test;
561
+
562
+ create table conn_test (id integer primary key, val integer);
563
+ insert into conn_test values (1, 42);
564
+ select val from conn_test where id = 1;
565
+ → [{"val": 42}]
566
+ drop table conn_test;
567
+
568
+ -- ===================================================================
569
+ -- SECTION 29: connection.ts — begin/commit/rollback via table operations
570
+ -- ===================================================================
571
+
572
+ create table conn_tx (id integer primary key, val text);
573
+ insert into conn_tx values (1, 'a');
574
+
575
+ -- Begin/commit cycle through connection
576
+ begin;
577
+ insert into conn_tx values (2, 'b');
578
+ commit;
579
+ select count(*) as cnt from conn_tx;
580
+ → [{"cnt": 2}]
581
+
582
+ -- Begin/rollback cycle through connection
583
+ begin;
584
+ insert into conn_tx values (3, 'c');
585
+ rollback;
586
+ select count(*) as cnt from conn_tx;
587
+ → [{"cnt": 2}]
588
+
589
+ -- Multiple begin/commit cycles
590
+ begin;
591
+ insert into conn_tx values (4, 'd');
592
+ commit;
593
+ begin;
594
+ insert into conn_tx values (5, 'e');
595
+ commit;
596
+ select count(*) as cnt from conn_tx;
597
+ → [{"cnt": 4}]
598
+
599
+ drop table conn_tx;
600
+
601
+ -- ===================================================================
602
+ -- SECTION 30: connection.ts — savepoint through connection wrapper
603
+ -- ===================================================================
604
+
605
+ create table conn_sp (id integer primary key, val text);
606
+ insert into conn_sp values (1, 'orig');
607
+
608
+ begin;
609
+ savepoint cs1;
610
+ insert into conn_sp values (2, 'in-cs1');
611
+ savepoint cs2;
612
+ insert into conn_sp values (3, 'in-cs2');
613
+
614
+ -- Both rows visible
615
+ select count(*) as cnt from conn_sp;
616
+ → [{"cnt": 3}]
617
+
618
+ -- Rollback to cs2
619
+ rollback to savepoint cs2;
620
+ select count(*) as cnt from conn_sp;
621
+ → [{"cnt": 2}]
622
+
623
+ -- Release cs2 (merged into cs1)
624
+ release savepoint cs2;
625
+
626
+ -- Release cs1 (merged into transaction)
627
+ release savepoint cs1;
628
+ commit;
629
+
630
+ -- Only id=2 survived (cs2 was rolled back)
631
+ select id, val from conn_sp order by id;
632
+ → [{"id": 1, "val": "orig"}, {"id": 2, "val": "in-cs1"}]
633
+
634
+ drop table conn_sp;
635
+
636
+ -- ===================================================================
637
+ -- SECTION 31: Index on non-integer types
638
+ -- ===================================================================
639
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
640
+
641
+ -- ===================================================================
642
+ -- SECTION 32: Index on text column (basic)
643
+ -- ===================================================================
644
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
645
+
646
+ -- ===================================================================
647
+ -- SECTION 33: ALTER TABLE + index interaction
648
+ -- ===================================================================
649
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
650
+
651
+ -- ===================================================================
652
+ -- SECTION 34: PK range scan edge cases
653
+ -- ===================================================================
654
+
655
+ create table pk_range_edge (id integer primary key, val text);
656
+ insert into pk_range_edge values (10, 'a'), (20, 'b'), (30, 'c'), (40, 'd');
657
+
658
+ -- Range that includes all rows
659
+ select id from pk_range_edge where id >= 10 and id <= 40 order by id;
660
+ → [{"id": 10}, {"id": 20}, {"id": 30}, {"id": 40}]
661
+
662
+ -- Range that includes no rows (gap)
663
+ select id from pk_range_edge where id > 10 and id < 20;
664
+ → []
665
+
666
+ -- Exact boundary (>= and <=)
667
+ select id from pk_range_edge where id >= 20 and id <= 20;
668
+ → [{"id": 20}]
669
+
670
+ -- Range beyond data
671
+ select id from pk_range_edge where id > 40;
672
+ → []
673
+ select id from pk_range_edge where id < 10;
674
+ → []
675
+
676
+ drop table pk_range_edge;
677
+
678
+ -- ===================================================================
679
+ -- SECTION 35: Multiple secondary indexes on same table
680
+ -- ===================================================================
681
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
682
+
683
+ -- ===================================================================
684
+ -- SECTION 36: Verify gatherAvailableIndexes includes PK pseudo-index (module.ts:463-477)
685
+ -- ===================================================================
686
+
687
+ -- Table with no secondary indexes — PK pseudo-index is the only access path
688
+ create table pk_only (id integer primary key, data text);
689
+ insert into pk_only values (1, 'a'), (2, 'b'), (3, 'c');
690
+
691
+ -- PK equality
692
+ select data from pk_only where id = 2;
693
+ → [{"data": "b"}]
694
+
695
+ -- PK range
696
+ select data from pk_only where id > 1 and id < 3;
697
+ → [{"data": "b"}]
698
+
699
+ -- Full scan (filter on non-PK)
700
+ select data from pk_only where data = 'c';
701
+ → [{"data": "c"}]
702
+
703
+ drop table pk_only;
704
+
705
+ -- ===================================================================
706
+ -- SECTION 37: UPSERT with ON CONFLICT on memory table
707
+ -- ===================================================================
708
+
709
+ create table upsert_t (id integer primary key, val text);
710
+ insert into upsert_t values (1, 'original');
711
+
712
+ -- Upsert: update on conflict
713
+ insert into upsert_t values (1, 'updated') on conflict (id) do update set val = excluded.val;
714
+ select val from upsert_t where id = 1;
715
+ → [{"val": "updated"}]
716
+
717
+ -- Upsert: no conflict, insert
718
+ insert into upsert_t values (2, 'new') on conflict (id) do update set val = excluded.val;
719
+ select count(*) as cnt from upsert_t;
720
+ → [{"cnt": 2}]
721
+
722
+ -- Upsert: do nothing on conflict
723
+ insert into upsert_t values (1, 'ignored') on conflict (id) do nothing;
724
+ select val from upsert_t where id = 1;
725
+ → [{"val": "updated"}]
726
+
727
+ drop table upsert_t;
728
+
729
+ -- ===================================================================
730
+ -- SECTION 38: DELETE with index and verify index consistency
731
+ -- ===================================================================
732
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
733
+
734
+ -- ===================================================================
735
+ -- SECTION 39: UPDATE affecting indexed columns
736
+ -- ===================================================================
737
+ -- Lives in 105.1-vtab-memory-index-mutation-kills (it needs standalone index DDL).
738
+
739
+ -- ===================================================================
740
+ -- SECTION 40: Composite PK with DESC direction
741
+ -- ===================================================================
742
+
743
+ create table comp_pk_desc (a integer, b integer, primary key (a, b desc));
744
+ insert into comp_pk_desc values (1, 3), (1, 1), (1, 2), (2, 2), (2, 1);
745
+
746
+ -- Natural order should be: a ASC, b DESC
747
+ select a, b from comp_pk_desc;
748
+ → [{"a": 1, "b": 3}, {"a": 1, "b": 2}, {"a": 1, "b": 1}, {"a": 2, "b": 2}, {"a": 2, "b": 1}]
749
+
750
+ -- Lookup by first PK column
751
+ select b from comp_pk_desc where a = 1 order by b desc;
752
+ → [{"b": 3}, {"b": 2}, {"b": 1}]
753
+
754
+ drop table comp_pk_desc;