@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,974 @@
1
+ -- 101-builtin-mutation-kills.sqllogic
2
+ -- Mutation-killing tests for builtin functions in scalar.ts, string.ts,
3
+ -- aggregate.ts, and conversion.ts. Each test targets a specific code path
4
+ -- that a common mutant (flipped comparison, removed null guard, off-by-one,
5
+ -- swapped operator) would break.
6
+
7
+ -- ============================================================
8
+ -- SETUP
9
+ -- ============================================================
10
+
11
+ create table mk (id integer primary key, v_int integer null, v_real real null, v_text text null);
12
+ insert into mk values (1, null, null, null);
13
+ insert into mk values (2, 0, 0.0, '');
14
+ insert into mk values (3, -5, -3.14, 'hello');
15
+ insert into mk values (4, 42, 2.718, 'world');
16
+
17
+ -- ============================================================
18
+ -- scalar.ts: abs
19
+ -- ============================================================
20
+
21
+ -- Kill: remove "if (arg === null) return null" guard
22
+ select abs(v_int) as r from mk where id = 1;
23
+ → [{"r":null}]
24
+
25
+ -- Kill: abs(0) must return 0, not null (guards n<0 vs n<=0 mutations)
26
+ select abs(v_int) as r from mk where id = 2;
27
+ → [{"r":0}]
28
+
29
+ -- Kill: abs of negative integer
30
+ select abs(v_int) as r from mk where id = 3;
31
+ → [{"r":5}]
32
+
33
+ -- Kill: abs of positive integer unchanged
34
+ select abs(v_int) as r from mk where id = 4;
35
+ → [{"r":42}]
36
+
37
+ -- Kill: abs of negative real
38
+ select abs(v_real) as r from mk where id = 3;
39
+ → [{"r":3.14}]
40
+
41
+ -- Kill: abs(0.0) must return 0
42
+ select abs(v_real) as r from mk where id = 2;
43
+ → [{"r":0}]
44
+
45
+ -- ============================================================
46
+ -- scalar.ts: round
47
+ -- ============================================================
48
+
49
+ -- Kill: remove null guard for first argument
50
+ select round(v_real) as r from mk where id = 1;
51
+ → [{"r":null}]
52
+
53
+ -- Kill: round(0.0) must be 0, not null
54
+ select round(v_real) as r from mk where id = 2;
55
+ → [{"r":0}]
56
+
57
+ -- Kill: round with explicit 0 decimal places
58
+ select round(v_real, 0) as r from mk where id = 3;
59
+ → [{"r":-3}]
60
+
61
+ -- Kill: round with negative precision
62
+ select round(12345, -3) as r;
63
+ → [{"r":12000}]
64
+
65
+ -- Kill: round(x, null) treats null places as 0
66
+ select round(3.7, null) as r;
67
+ → [{"r":4}]
68
+
69
+ -- ============================================================
70
+ -- scalar.ts: sqrt
71
+ -- ============================================================
72
+
73
+ -- Kill: remove null guard
74
+ select sqrt(v_real) as r from mk where id = 1;
75
+ → [{"r":null}]
76
+
77
+ -- Kill: sqrt(0) must return 0, not null (guards num < 0 vs num <= 0)
78
+ select sqrt(0) as r;
79
+ → [{"r":0}]
80
+
81
+ -- Kill: sqrt of negative returns null
82
+ select sqrt(-4) as r;
83
+ → [{"r":null}]
84
+
85
+ -- Kill: sqrt of perfect square
86
+ select sqrt(25) as r;
87
+ → [{"r":5}]
88
+
89
+ -- ============================================================
90
+ -- scalar.ts: pow / power
91
+ -- ============================================================
92
+
93
+ -- Kill: null propagation in base
94
+ select pow(v_real, 2) as r from mk where id = 1;
95
+ → [{"r":null}]
96
+
97
+ -- Kill: null propagation in exponent
98
+ select pow(2, v_real) as r from mk where id = 1;
99
+ → [{"r":null}]
100
+
101
+ -- Kill: pow(0, 0) = 1 (JavaScript Math.pow behavior)
102
+ select pow(0, 0) as r;
103
+ → [{"r":1}]
104
+
105
+ -- Kill: pow(x, 1) = x
106
+ select pow(7, 1) as r;
107
+ → [{"r":7}]
108
+
109
+ -- Kill: pow with negative base, even exponent
110
+ select pow(-3, 2) as r;
111
+ → [{"r":9}]
112
+
113
+ -- Kill: pow with negative base, odd exponent
114
+ select pow(-2, 3) as r;
115
+ → [{"r":-8}]
116
+
117
+ -- ============================================================
118
+ -- scalar.ts: floor / ceil
119
+ -- ============================================================
120
+
121
+ -- Kill: floor null guard
122
+ select floor(v_real) as r from mk where id = 1;
123
+ → [{"r":null}]
124
+
125
+ -- Kill: ceil null guard
126
+ select ceil(v_real) as r from mk where id = 1;
127
+ → [{"r":null}]
128
+
129
+ -- Kill: floor(0.0) = 0 (not null)
130
+ select floor(0.0) as r;
131
+ → [{"r":0}]
132
+
133
+ -- Kill: ceil(0.0) = 0 (not null)
134
+ select ceil(0.0) as r;
135
+ → [{"r":0}]
136
+
137
+ -- Kill: floor of negative fraction rounds toward negative infinity
138
+ select floor(-0.1) as r;
139
+ → [{"r":-1}]
140
+
141
+ -- Kill: ceil of negative fraction rounds toward zero (JS: -0 == 0)
142
+ select ceil(-0.1) = 0 as r;
143
+ → [{"r":true}]
144
+
145
+ -- Kill: floor of positive fraction rounds toward zero
146
+ select floor(0.9) as r;
147
+ → [{"r":0}]
148
+
149
+ -- Kill: ceil of positive fraction rounds toward positive infinity
150
+ select ceil(0.1) as r;
151
+ → [{"r":1}]
152
+
153
+ -- Kill: ceiling is alias for ceil
154
+ select ceiling(2.3) as r;
155
+ → [{"r":3}]
156
+
157
+ -- ============================================================
158
+ -- scalar.ts: clamp
159
+ -- ============================================================
160
+
161
+ -- Kill: value exactly at min boundary
162
+ select clamp(0, 0, 10) as r;
163
+ → [{"r":0}]
164
+
165
+ -- Kill: value exactly at max boundary
166
+ select clamp(10, 0, 10) as r;
167
+ → [{"r":10}]
168
+
169
+ -- Kill: value one below min
170
+ select clamp(-1, 0, 10) as r;
171
+ → [{"r":0}]
172
+
173
+ -- Kill: value one above max
174
+ select clamp(11, 0, 10) as r;
175
+ → [{"r":10}]
176
+
177
+ -- Kill: min == max, value equal
178
+ select clamp(5, 5, 5) as r;
179
+ → [{"r":5}]
180
+
181
+ -- Kill: min == max, value below
182
+ select clamp(3, 5, 5) as r;
183
+ → [{"r":5}]
184
+
185
+ -- Kill: min == max, value above
186
+ select clamp(7, 5, 5) as r;
187
+ → [{"r":5}]
188
+
189
+ -- ============================================================
190
+ -- scalar.ts: coalesce
191
+ -- ============================================================
192
+
193
+ -- Kill: single non-null arg returns it (not null)
194
+ select coalesce(42) as r;
195
+ → [{"r":42}]
196
+
197
+ -- Kill: all null returns null
198
+ select coalesce(null, null) as r;
199
+ → [{"r":null}]
200
+
201
+ -- Kill: first non-null wins (not second, not last)
202
+ select coalesce(null, 'first', 'second') as r;
203
+ → [{"r":"first"}]
204
+
205
+ -- Kill: zero is non-null (not treated as falsy)
206
+ select coalesce(null, 0) as r;
207
+ → [{"r":0}]
208
+
209
+ -- Kill: empty string is non-null
210
+ select coalesce(null, '') as r;
211
+ → [{"r":""}]
212
+
213
+ -- Kill: false is non-null
214
+ select coalesce(null, false) as r;
215
+ → [{"r":false}]
216
+
217
+ -- ============================================================
218
+ -- scalar.ts: nullif
219
+ -- ============================================================
220
+
221
+ -- Kill: nullif returns null when args equal
222
+ select nullif(5, 5) as r;
223
+ → [{"r":null}]
224
+
225
+ -- Kill: nullif returns first arg when different
226
+ select nullif(5, 10) as r;
227
+ → [{"r":5}]
228
+
229
+ -- Kill: nullif with zero — 0 equals 0
230
+ select nullif(0, 0) as r;
231
+ → [{"r":null}]
232
+
233
+ -- Kill: nullif with zero and non-zero
234
+ select nullif(0, 1) as r;
235
+ → [{"r":0}]
236
+
237
+ -- Kill: nullif(null, 1) — null first arg
238
+ select nullif(null, 1) as r;
239
+ → [{"r":null}]
240
+
241
+ -- ============================================================
242
+ -- scalar.ts: iif
243
+ -- ============================================================
244
+
245
+ -- Kill: iif with bigint-like large integer condition (truthy)
246
+ select iif(999999, 'yes', 'no') as r;
247
+ → [{"r":"yes"}]
248
+
249
+ -- Kill: iif with negative number (truthy, not zero)
250
+ select iif(-1, 'yes', 'no') as r;
251
+ → [{"r":"yes"}]
252
+
253
+ -- Kill: iif with string '0' is falsy
254
+ select iif('0', 'yes', 'no') as r;
255
+ → [{"r":"no"}]
256
+
257
+ -- Kill: iif with string '1' is truthy
258
+ select iif('1', 'yes', 'no') as r;
259
+ → [{"r":"yes"}]
260
+
261
+ -- Kill: iif with non-numeric string is falsy (NaN → false)
262
+ select iif('abc', 'yes', 'no') as r;
263
+ → [{"r":"no"}]
264
+
265
+ -- Kill: iif returns the actual value of the branch (not boolean)
266
+ select iif(1, 42, 99) as r;
267
+ → [{"r":42}]
268
+
269
+ select iif(0, 42, 99) as r;
270
+ → [{"r":99}]
271
+
272
+ -- ============================================================
273
+ -- scalar.ts: choose
274
+ -- ============================================================
275
+
276
+ -- Kill: index 1 returns first value arg
277
+ select choose(1, 'a', 'b', 'c') as r;
278
+ → [{"r":"a"}]
279
+
280
+ -- Kill: index 3 returns last value arg
281
+ select choose(3, 'a', 'b', 'c') as r;
282
+ → [{"r":"c"}]
283
+
284
+ -- Kill: index 0 out of range (1-based)
285
+ select choose(0, 'a', 'b') as r;
286
+ → [{"r":null}]
287
+
288
+ -- Kill: index beyond length returns null
289
+ select choose(4, 'a', 'b', 'c') as r;
290
+ → [{"r":null}]
291
+
292
+ -- Kill: negative index returns null
293
+ select choose(-1, 'a') as r;
294
+ → [{"r":null}]
295
+
296
+ -- ============================================================
297
+ -- scalar.ts: greatest / least
298
+ -- ============================================================
299
+
300
+ -- Kill: greatest with all nulls returns null (not first arg)
301
+ select greatest(null, null, null) as r;
302
+ → [{"r":null}]
303
+
304
+ -- Kill: greatest skips nulls and finds max
305
+ select greatest(null, 5, null, 3) as r;
306
+ → [{"r":5}]
307
+
308
+ -- Kill: least with all nulls returns null
309
+ select least(null, null) as r;
310
+ → [{"r":null}]
311
+
312
+ -- Kill: least skips nulls and finds min
313
+ select least(null, 5, null, 3) as r;
314
+ → [{"r":3}]
315
+
316
+ -- Kill: least with negative values
317
+ select least(-10, -5, 0) as r;
318
+ → [{"r":-10}]
319
+
320
+ -- Kill: greatest with negative values
321
+ select greatest(-10, -5, 0) as r;
322
+ → [{"r":0}]
323
+
324
+ -- Kill: single-element greatest/least
325
+ select greatest(7) as g, least(7) as l;
326
+ → [{"g":7,"l":7}]
327
+
328
+ -- ============================================================
329
+ -- string.ts: length
330
+ -- ============================================================
331
+
332
+ -- Kill: length(null) returns null
333
+ select length(v_text) as r from mk where id = 1;
334
+ → [{"r":null}]
335
+
336
+ -- Kill: length('') returns 0, not null
337
+ select length(v_text) as r from mk where id = 2;
338
+ → [{"r":0}]
339
+
340
+ -- Kill: length of non-empty string
341
+ select length(v_text) as r from mk where id = 3;
342
+ → [{"r":5}]
343
+
344
+ -- ============================================================
345
+ -- string.ts: substr
346
+ -- ============================================================
347
+
348
+ -- Kill: substr(null, ...) returns null
349
+ select substr(v_text, 1) as r from mk where id = 1;
350
+ → [{"r":null}]
351
+
352
+ -- Kill: substr with null start returns null
353
+ select substr('hello', null) as r;
354
+ → [{"r":null}]
355
+
356
+ -- Kill: substr start=1 returns full string (1-based indexing)
357
+ select substr('hello', 1) as r;
358
+ → [{"r":"hello"}]
359
+
360
+ -- Kill: substr start=1 len=0 returns empty string
361
+ select substr('hello', 1, 0) as r;
362
+ → [{"r":""}]
363
+
364
+ -- Kill: substr on empty string
365
+ select substr('', 1) as r;
366
+ → [{"r":""}]
367
+
368
+ -- Kill: substr start past end of string
369
+ select substr('hi', 5) as r;
370
+ → [{"r":""}]
371
+
372
+ -- Kill: substr start=1 len=1 gets first character
373
+ select substr('hello', 1, 1) as r;
374
+ → [{"r":"h"}]
375
+
376
+ -- Kill: substr len longer than remaining string
377
+ select substr('hello', 3, 100) as r;
378
+ → [{"r":"llo"}]
379
+
380
+ -- ============================================================
381
+ -- string.ts: replace
382
+ -- ============================================================
383
+
384
+ -- Kill: all args null returns null
385
+ select replace(null, null, null) as r;
386
+ → [{"r":null}]
387
+
388
+ -- Kill: null string returns null
389
+ select replace(null, 'a', 'b') as r;
390
+ → [{"r":null}]
391
+
392
+ -- Kill: null pattern returns null
393
+ select replace('hello', null, 'b') as r;
394
+ → [{"r":null}]
395
+
396
+ -- Kill: null replacement returns null
397
+ select replace('hello', 'l', null) as r;
398
+ → [{"r":null}]
399
+
400
+ -- Kill: empty pattern returns original string unchanged
401
+ select replace('hello', '', 'x') as r;
402
+ → [{"r":"hello"}]
403
+
404
+ -- Kill: replace when pattern not found returns original
405
+ select replace('hello', 'xyz', 'abc') as r;
406
+ → [{"r":"hello"}]
407
+
408
+ -- Kill: replace all occurrences (not just first)
409
+ select replace('banana', 'a', 'o') as r;
410
+ → [{"r":"bonono"}]
411
+
412
+ -- Kill: replace with empty replacement (deletion)
413
+ select replace('hello world', ' world', '') as r;
414
+ → [{"r":"hello"}]
415
+
416
+ -- ============================================================
417
+ -- string.ts: instr
418
+ -- ============================================================
419
+
420
+ -- Kill: null propagation
421
+ select instr(null, 'a') as r;
422
+ → [{"r":null}]
423
+
424
+ select instr('hello', null) as r;
425
+ → [{"r":null}]
426
+
427
+ -- Kill: found at position 1 (not 0)
428
+ select instr('hello', 'h') as r;
429
+ → [{"r":1}]
430
+
431
+ -- Kill: found at last position
432
+ select instr('hello', 'o') as r;
433
+ → [{"r":5}]
434
+
435
+ -- Kill: not found returns 0 (not -1, not null)
436
+ select instr('hello', 'z') as r;
437
+ → [{"r":0}]
438
+
439
+ -- Kill: empty substring returns 0
440
+ select instr('hello', '') as r;
441
+ → [{"r":0}]
442
+
443
+ -- Kill: empty string searched returns 0
444
+ select instr('', 'a') as r;
445
+ → [{"r":0}]
446
+
447
+ -- Kill: both empty returns 0
448
+ select instr('', '') as r;
449
+ → [{"r":0}]
450
+
451
+ -- ============================================================
452
+ -- string.ts: trim / ltrim / rtrim
453
+ -- ============================================================
454
+
455
+ -- Kill: trim(null) returns null
456
+ select trim(null) as r;
457
+ → [{"r":null}]
458
+
459
+ -- Kill: ltrim(null) returns null
460
+ select ltrim(null) as r;
461
+ → [{"r":null}]
462
+
463
+ -- Kill: rtrim(null) returns null
464
+ select rtrim(null) as r;
465
+ → [{"r":null}]
466
+
467
+ -- Kill: trim whitespace from both sides
468
+ select trim(' hello ') as r;
469
+ → [{"r":"hello"}]
470
+
471
+ -- Kill: ltrim removes left only
472
+ select ltrim(' hello ') as r;
473
+ → [{"r":"hello "}]
474
+
475
+ -- Kill: rtrim removes right only
476
+ select rtrim(' hello ') as r;
477
+ → [{"r":" hello"}]
478
+
479
+ -- Kill: trim with no whitespace returns same string
480
+ select trim('hello') as r;
481
+ → [{"r":"hello"}]
482
+
483
+ -- Kill: trim empty string returns empty
484
+ select trim('') as r;
485
+ → [{"r":""}]
486
+
487
+ -- Kill: trim with custom chars null → default whitespace trim
488
+ select trim(' hello ', null) as r;
489
+ → [{"r":"hello"}]
490
+
491
+ -- Kill: ltrim with custom chars
492
+ select ltrim('xxxhello', 'x') as r;
493
+ → [{"r":"hello"}]
494
+
495
+ -- Kill: rtrim with custom chars
496
+ select rtrim('helloyyy', 'y') as r;
497
+ → [{"r":"hello"}]
498
+
499
+ -- ============================================================
500
+ -- string.ts: lower / upper
501
+ -- ============================================================
502
+
503
+ -- Kill: lower(null) returns null
504
+ select lower(null) as r;
505
+ → [{"r":null}]
506
+
507
+ -- Kill: upper(null) returns null
508
+ select upper(null) as r;
509
+ → [{"r":null}]
510
+
511
+ -- Kill: lower of empty string
512
+ select lower('') as r;
513
+ → [{"r":""}]
514
+
515
+ -- Kill: upper of empty string
516
+ select upper('') as r;
517
+ → [{"r":""}]
518
+
519
+ -- Kill: lower of already-lowercase
520
+ select lower('hello') as r;
521
+ → [{"r":"hello"}]
522
+
523
+ -- Kill: upper of already-uppercase
524
+ select upper('HELLO') as r;
525
+ → [{"r":"HELLO"}]
526
+
527
+ -- Kill: lower on non-string returns null (not coerced)
528
+ select lower(v_int) as r from mk where id = 4;
529
+ → [{"r":null}]
530
+
531
+ -- Kill: upper on non-string returns null
532
+ select upper(v_int) as r from mk where id = 4;
533
+ → [{"r":null}]
534
+
535
+ -- ============================================================
536
+ -- string.ts: reverse
537
+ -- ============================================================
538
+
539
+ -- Kill: reverse of null returns null (non-string → null)
540
+ select reverse(null) as r;
541
+ → [{"r":null}]
542
+
543
+ -- Kill: reverse of empty string
544
+ select reverse('') as r;
545
+ → [{"r":""}]
546
+
547
+ -- Kill: reverse of single character
548
+ select reverse('x') as r;
549
+ → [{"r":"x"}]
550
+
551
+ -- Kill: reverse of palindrome unchanged
552
+ select reverse('aba') as r;
553
+ → [{"r":"aba"}]
554
+
555
+ -- ============================================================
556
+ -- string.ts: like / glob null propagation
557
+ -- ============================================================
558
+
559
+ -- Kill: like with null text returns null
560
+ select like('a%', null) as r;
561
+ → [{"r":null}]
562
+
563
+ -- Kill: like with null pattern returns null
564
+ select like(null, 'abc') as r;
565
+ → [{"r":null}]
566
+
567
+ -- Kill: glob with null text returns null
568
+ select glob('a*', null) as r;
569
+ → [{"r":null}]
570
+
571
+ -- Kill: glob with null pattern returns null
572
+ select glob(null, 'abc') as r;
573
+ → [{"r":null}]
574
+
575
+ -- ============================================================
576
+ -- string.ts: lpad / rpad
577
+ -- ============================================================
578
+
579
+ -- Kill: lpad with null string returns null
580
+ select lpad(null, 5, '*') as r;
581
+ → [{"r":null}]
582
+
583
+ -- Kill: rpad with null string returns null
584
+ select rpad(null, 5, '*') as r;
585
+ → [{"r":null}]
586
+
587
+ -- Kill: lpad when string already at target length (no padding needed)
588
+ select lpad('hello', 5, '*') as r;
589
+ → [{"r":"hello"}]
590
+
591
+ -- Kill: rpad when string already at target length
592
+ select rpad('hello', 5, '*') as r;
593
+ → [{"r":"hello"}]
594
+
595
+ -- Kill: lpad shorter than target
596
+ select lpad('hi', 4, '-') as r;
597
+ → [{"r":"--hi"}]
598
+
599
+ -- Kill: rpad shorter than target
600
+ select rpad('hi', 4, '-') as r;
601
+ → [{"r":"hi--"}]
602
+
603
+ -- ============================================================
604
+ -- aggregate.ts: count(*) vs count(X) on empty table
605
+ -- ============================================================
606
+
607
+ create table mk_agg_empty (id integer primary key, val integer null);
608
+
609
+ -- Kill: count(*) on empty table must be 0
610
+ select count(*) as r from mk_agg_empty;
611
+ → [{"r":0}]
612
+
613
+ -- Kill: count(x) on empty table must be 0
614
+ select count(val) as r from mk_agg_empty;
615
+ → [{"r":0}]
616
+
617
+ -- Kill: sum on empty table must be null (not 0)
618
+ select sum(val) as r from mk_agg_empty;
619
+ → [{"r":null}]
620
+
621
+ -- Kill: avg on empty table must be null
622
+ select avg(val) as r from mk_agg_empty;
623
+ → [{"r":null}]
624
+
625
+ -- Kill: min on empty table must be null
626
+ select min(val) as r from mk_agg_empty;
627
+ → [{"r":null}]
628
+
629
+ -- Kill: max on empty table must be null
630
+ select max(val) as r from mk_agg_empty;
631
+ → [{"r":null}]
632
+
633
+ -- Kill: total on empty table must be 0.0 (not null — SQLite compat)
634
+ select total(val) as r from mk_agg_empty;
635
+ → [{"r":0}]
636
+
637
+ drop table mk_agg_empty;
638
+
639
+ -- ============================================================
640
+ -- aggregate.ts: count(X) skips nulls
641
+ -- ============================================================
642
+
643
+ create table mk_agg_nulls (id integer primary key, val integer null);
644
+ insert into mk_agg_nulls values (1, null), (2, 10), (3, null), (4, 20);
645
+
646
+ -- Kill: count(*) counts all rows including null
647
+ select count(*) as r from mk_agg_nulls;
648
+ → [{"r":4}]
649
+
650
+ -- Kill: count(val) skips nulls
651
+ select count(val) as r from mk_agg_nulls;
652
+ → [{"r":2}]
653
+
654
+ -- Kill: sum skips nulls
655
+ select sum(val) as r from mk_agg_nulls;
656
+ → [{"r":30}]
657
+
658
+ -- Kill: avg skips nulls (30/2 = 15)
659
+ select avg(val) as r from mk_agg_nulls;
660
+ → [{"r":15}]
661
+
662
+ -- Kill: min skips nulls
663
+ select min(val) as r from mk_agg_nulls;
664
+ → [{"r":10}]
665
+
666
+ -- Kill: max skips nulls
667
+ select max(val) as r from mk_agg_nulls;
668
+ → [{"r":20}]
669
+
670
+ drop table mk_agg_nulls;
671
+
672
+ -- ============================================================
673
+ -- aggregate.ts: all-null values
674
+ -- ============================================================
675
+
676
+ create table mk_agg_allnull (id integer primary key, val integer null);
677
+ insert into mk_agg_allnull values (1, null), (2, null);
678
+
679
+ -- Kill: sum of all-null is null (not 0)
680
+ select sum(val) as r from mk_agg_allnull;
681
+ → [{"r":null}]
682
+
683
+ -- Kill: avg of all-null is null
684
+ select avg(val) as r from mk_agg_allnull;
685
+ → [{"r":null}]
686
+
687
+ -- Kill: min of all-null is null
688
+ select min(val) as r from mk_agg_allnull;
689
+ → [{"r":null}]
690
+
691
+ -- Kill: max of all-null is null
692
+ select max(val) as r from mk_agg_allnull;
693
+ → [{"r":null}]
694
+
695
+ -- Kill: total of all-null is 0 (not null — total never returns null)
696
+ select total(val) as r from mk_agg_allnull;
697
+ → [{"r":0}]
698
+
699
+ -- Kill: count(val) of all-null is 0
700
+ select count(val) as r from mk_agg_allnull;
701
+ → [{"r":0}]
702
+
703
+ -- Kill: count(*) counts rows regardless of null values
704
+ select count(*) as r from mk_agg_allnull;
705
+ → [{"r":2}]
706
+
707
+ drop table mk_agg_allnull;
708
+
709
+ -- ============================================================
710
+ -- aggregate.ts: single-value aggregates
711
+ -- ============================================================
712
+
713
+ create table mk_agg_one (id integer primary key, val real);
714
+ insert into mk_agg_one values (1, 7.5);
715
+
716
+ -- Kill: sum of single value
717
+ select sum(val) as r from mk_agg_one;
718
+ → [{"r":7.5}]
719
+
720
+ -- Kill: avg of single value equals the value itself
721
+ select avg(val) as r from mk_agg_one;
722
+ → [{"r":7.5}]
723
+
724
+ -- Kill: min == max for single value
725
+ select min(val) as r, max(val) as r2 from mk_agg_one;
726
+ → [{"r":7.5,"r2":7.5}]
727
+
728
+ -- Kill: var_pop of single value is 0
729
+ select var_pop(val) as r from mk_agg_one;
730
+ → [{"r":0}]
731
+
732
+ -- Kill: var_samp of single value is null (needs n > 1)
733
+ select var_samp(val) as r from mk_agg_one;
734
+ → [{"r":null}]
735
+
736
+ -- Kill: stddev_pop of single value is 0
737
+ select stddev_pop(val) as r from mk_agg_one;
738
+ → [{"r":0}]
739
+
740
+ -- Kill: stddev_samp of single value is null
741
+ select stddev_samp(val) as r from mk_agg_one;
742
+ → [{"r":null}]
743
+
744
+ drop table mk_agg_one;
745
+
746
+ -- ============================================================
747
+ -- aggregate.ts: statistical functions on empty set
748
+ -- ============================================================
749
+
750
+ create table mk_agg_stat_empty (id integer primary key, val real null);
751
+
752
+ select var_pop(val) as r from mk_agg_stat_empty;
753
+ → [{"r":null}]
754
+
755
+ select var_samp(val) as r from mk_agg_stat_empty;
756
+ → [{"r":null}]
757
+
758
+ select stddev_pop(val) as r from mk_agg_stat_empty;
759
+ → [{"r":null}]
760
+
761
+ select stddev_samp(val) as r from mk_agg_stat_empty;
762
+ → [{"r":null}]
763
+
764
+ drop table mk_agg_stat_empty;
765
+
766
+ -- ============================================================
767
+ -- aggregate.ts: two-value var_samp (not null, unlike single-value)
768
+ -- ============================================================
769
+
770
+ create table mk_agg_two (id integer primary key, val real);
771
+ insert into mk_agg_two values (1, 10.0), (2, 20.0);
772
+
773
+ -- var_samp([10, 20]) = (sumSq - sum*sum/n) / (n-1)
774
+ -- = (100+400 - 900/2) / 1 = (500 - 450) / 1 = 50
775
+ select var_samp(val) as r from mk_agg_two;
776
+ → [{"r":50}]
777
+
778
+ -- stddev_samp([10, 20]) = sqrt(50)
779
+ select stddev_samp(val) as r from mk_agg_two;
780
+ → [{"r":7.0710678118654755}]
781
+
782
+ drop table mk_agg_two;
783
+
784
+ -- ============================================================
785
+ -- aggregate.ts: total always returns 0 for non-numeric
786
+ -- ============================================================
787
+
788
+ create table mk_total_text (id integer primary key, val text);
789
+ insert into mk_total_text values (1, 'hello'), (2, 'world');
790
+
791
+ -- Kill: total of non-numeric text → 0 (NaN treated as 0)
792
+ select total(val) as r from mk_total_text;
793
+ → [{"r":0}]
794
+
795
+ drop table mk_total_text;
796
+
797
+ -- ============================================================
798
+ -- aggregate.ts: total with mixed numeric strings
799
+ -- ============================================================
800
+
801
+ create table mk_total_mixed (id integer primary key, val text null);
802
+ insert into mk_total_mixed values (1, '10'), (2, 'abc'), (3, '20'), (4, null);
803
+
804
+ -- Kill: total coerces numeric strings, treats non-numeric as 0, skips null
805
+ select total(val) as r from mk_total_mixed;
806
+ → [{"r":30}]
807
+
808
+ drop table mk_total_mixed;
809
+
810
+ -- ============================================================
811
+ -- aggregate.ts: group_concat
812
+ -- ============================================================
813
+
814
+ create table mk_gc (id integer primary key, val text null);
815
+ insert into mk_gc values (1, 'a'), (2, null), (3, 'b'), (4, 'c');
816
+
817
+ -- Kill: group_concat with default separator (comma)
818
+ select group_concat(val) as r from mk_gc;
819
+ → [{"r":"a,b,c"}]
820
+
821
+ -- Kill: group_concat skips nulls
822
+ select group_concat(val, '-') as r from mk_gc;
823
+ → [{"r":"a-b-c"}]
824
+
825
+ -- Kill: group_concat empty separator joins directly
826
+ select group_concat(val, '') as r from mk_gc;
827
+ → [{"r":"abc"}]
828
+
829
+ drop table mk_gc;
830
+
831
+ -- ============================================================
832
+ -- aggregate.ts: group_concat all nulls returns null
833
+ -- ============================================================
834
+
835
+ create table mk_gc_null (id integer primary key, val text null);
836
+ insert into mk_gc_null values (1, null), (2, null);
837
+
838
+ select group_concat(val) as r from mk_gc_null;
839
+ → [{"r":null}]
840
+
841
+ drop table mk_gc_null;
842
+
843
+ -- ============================================================
844
+ -- conversion.ts: null handling for all conversion functions
845
+ -- ============================================================
846
+
847
+ select integer(null) as r;
848
+ → [{"r":null}]
849
+
850
+ select real(null) as r;
851
+ → [{"r":null}]
852
+
853
+ select text(null) as r;
854
+ → [{"r":null}]
855
+
856
+ select boolean(null) as r;
857
+ → [{"r":null}]
858
+
859
+ -- ============================================================
860
+ -- conversion.ts: identity conversions (already correct type)
861
+ -- ============================================================
862
+
863
+ select integer(42) as r;
864
+ → [{"r":42}]
865
+
866
+ select real(3.14) as r;
867
+ → [{"r":3.14}]
868
+
869
+ select text('hello') as r;
870
+ → [{"r":"hello"}]
871
+
872
+ select boolean(true) as r;
873
+ → [{"r":true}]
874
+
875
+ select boolean(false) as r;
876
+ → [{"r":false}]
877
+
878
+ -- ============================================================
879
+ -- conversion.ts: cross-type conversions
880
+ -- ============================================================
881
+
882
+ -- Kill: integer from real truncates
883
+ select integer(3.9) as r;
884
+ → [{"r":3}]
885
+
886
+ -- Kill: integer from negative real truncates toward zero
887
+ select integer(-3.9) as r;
888
+ → [{"r":-3}]
889
+
890
+ -- Kill: integer from string
891
+ select integer('42') as r;
892
+ → [{"r":42}]
893
+
894
+ -- Kill: integer from true/false
895
+ select integer(true) as r;
896
+ → [{"r":1}]
897
+
898
+ select integer(false) as r;
899
+ → [{"r":0}]
900
+
901
+ -- Kill: integer(0) is not null
902
+ select integer(0) as r;
903
+ → [{"r":0}]
904
+
905
+ -- Kill: real from integer
906
+ select real(42) as r;
907
+ → [{"r":42}]
908
+
909
+ -- Kill: real from string
910
+ select real('3.14') as r;
911
+ → [{"r":3.14}]
912
+
913
+ -- Kill: text from integer
914
+ select text(42) as r;
915
+ → [{"r":"42"}]
916
+
917
+ -- Kill: text from real
918
+ select text(3.14) as r;
919
+ → [{"r":"3.14"}]
920
+
921
+ -- Kill: text from boolean
922
+ select text(true) as r;
923
+ → [{"r":"true"}]
924
+
925
+ select text(false) as r;
926
+ → [{"r":"false"}]
927
+
928
+ -- Kill: text of zero
929
+ select text(0) as r;
930
+ → [{"r":"0"}]
931
+
932
+ -- Kill: text of empty string is empty string
933
+ select text('') as r;
934
+ → [{"r":""}]
935
+
936
+ -- Kill: boolean from 1 and 0
937
+ select boolean(1) as r;
938
+ → [{"r":true}]
939
+
940
+ select boolean(0) as r;
941
+ → [{"r":false}]
942
+
943
+ -- Kill: boolean from 'yes'/'no'
944
+ select boolean('yes') as r;
945
+ → [{"r":true}]
946
+
947
+ select boolean('no') as r;
948
+ → [{"r":false}]
949
+
950
+ -- Kill: boolean from 'on'/'off'
951
+ select boolean('on') as r;
952
+ → [{"r":true}]
953
+
954
+ select boolean('off') as r;
955
+ → [{"r":false}]
956
+
957
+ -- ============================================================
958
+ -- conversion.ts: error paths
959
+ -- ============================================================
960
+
961
+ select integer('not_a_number');
962
+ -- error: Cannot convert to INTEGER
963
+
964
+ select real('not_a_number');
965
+ -- error: Cannot convert to REAL
966
+
967
+ select boolean('maybe');
968
+ -- error: Cannot convert to BOOLEAN
969
+
970
+ -- ============================================================
971
+ -- CLEANUP
972
+ -- ============================================================
973
+
974
+ drop table mk;