@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,611 @@
1
+ -- 24-builtin-branches.sqllogic
2
+ -- Targeted tests for untested branches in builtin functions:
3
+ -- datetime heuristics, JSON edge cases, string patterns,
4
+ -- aggregate overflow, scalar coercion, conversion edge cases
5
+
6
+ -- ============================================================
7
+ -- DATETIME: heuristic numeric parsing
8
+ -- ============================================================
9
+
10
+ -- Julian day number: 2451545 = J2000.0 = 2000-01-01 12:00:00 UTC
11
+ SELECT strftime('%Y-%m-%d %H:%M:%S', 2451545);
12
+ → ["2000-01-01 12:00:00"]
13
+
14
+ -- Epoch seconds: 86400 = 1 day = 1970-01-02
15
+ SELECT datetime(86400, '+0 seconds');
16
+ → ["1970-01-02 00:00:00"]
17
+
18
+ -- Unix epoch zero
19
+ SELECT datetime(0, '+0 seconds');
20
+ → ["1970-01-01 00:00:00"]
21
+
22
+ -- Negative epoch seconds
23
+ SELECT date(-86400, '+0 days');
24
+ → ["1969-12-31"]
25
+
26
+ -- Epoch milliseconds fallback (value > max epoch seconds range)
27
+ SELECT strftime('%Y-%m-%d', 1704067200000);
28
+ → ["2024-01-01"]
29
+
30
+ -- Out-of-range numeric → null
31
+ SELECT strftime('%Y-%m-%d', 999999999999999999);
32
+ → [null]
33
+
34
+ -- ============================================================
35
+ -- DATETIME: lenient formats
36
+ -- ============================================================
37
+
38
+ -- YYYYMMDD compact format
39
+ SELECT strftime('%Y-%m-%d', '20240701');
40
+ → ["2024-07-01"]
41
+
42
+ -- Space-separated datetime
43
+ SELECT datetime('2024-01-15 10:30:00', '+0 seconds');
44
+ → ["2024-01-15 10:30:00"]
45
+
46
+ -- Fractional seconds with subsec
47
+ SELECT datetime('2024-01-01T12:00:00.500', 'subsec');
48
+ → ["2024-01-01 12:00:00.500"]
49
+
50
+ -- ============================================================
51
+ -- DATETIME: invalid inputs → null
52
+ -- ============================================================
53
+
54
+ SELECT date('not-a-date', '+0 days');
55
+ → [null]
56
+
57
+ SELECT time('', '+0 seconds');
58
+ → [null]
59
+
60
+ SELECT datetime(null, '+0 seconds');
61
+ → [null]
62
+
63
+ -- ============================================================
64
+ -- DATETIME: modifiers
65
+ -- ============================================================
66
+
67
+ SELECT date('2024-07-15', 'start of month');
68
+ → ["2024-07-01"]
69
+
70
+ SELECT date('2024-07-15', 'start of year');
71
+ → ["2024-01-01"]
72
+
73
+ SELECT date('2024-01-15', '-5 days');
74
+ → ["2024-01-10"]
75
+
76
+ SELECT date('2024-01-15', '+1 year');
77
+ → ["2025-01-15"]
78
+
79
+ SELECT date('2024-01-31', '+1 month');
80
+ → ["2024-02-29"]
81
+
82
+ SELECT date('2024-01-15', '+1 month', 'start of month');
83
+ → ["2024-02-01"]
84
+
85
+ -- ============================================================
86
+ -- STRFTIME: format specifiers (2024-07-26 is Friday, day 208)
87
+ -- ============================================================
88
+
89
+ SELECT strftime('%j', '2024-07-26 14:30:45');
90
+ → ["208"]
91
+
92
+ SELECT strftime('%D', '2024-07-26');
93
+ → ["07/26/24"]
94
+
95
+ SELECT strftime('%F', '2024-07-26');
96
+ → ["2024-07-26"]
97
+
98
+ SELECT strftime('%C', '2024-07-26');
99
+ → ["20"]
100
+
101
+ SELECT strftime('%y', '2024-07-26');
102
+ → ["24"]
103
+
104
+ SELECT strftime('%h', '2024-07-26');
105
+ → ["Jul"]
106
+
107
+ SELECT strftime('%e', '2024-07-05');
108
+ → [" 5"]
109
+
110
+ SELECT strftime('%I', '2024-07-26 14:30:45');
111
+ → ["02"]
112
+
113
+ SELECT strftime('%I', '2024-07-26 00:00:00');
114
+ → ["12"]
115
+
116
+ SELECT strftime('%k', '2024-07-26 09:00:00');
117
+ → [" 9"]
118
+
119
+ SELECT strftime('%l', '2024-07-26 14:00:00');
120
+ → [" 2"]
121
+
122
+ SELECT strftime('%p', '2024-07-26 09:00:00');
123
+ → ["AM"]
124
+
125
+ SELECT strftime('%p', '2024-07-26 14:00:00');
126
+ → ["PM"]
127
+
128
+ SELECT strftime('%P', '2024-07-26 09:00:00');
129
+ → ["am"]
130
+
131
+ SELECT strftime('%T', '2024-07-26 14:30:45');
132
+ → ["14:30:45"]
133
+
134
+ SELECT strftime('%R', '2024-07-26 14:30:45');
135
+ → ["14:30"]
136
+
137
+ SELECT strftime('%r', '2024-07-26 14:30:45');
138
+ → ["02:30:45 PM"]
139
+
140
+ SELECT strftime('%w', '2024-07-26');
141
+ → ["5"]
142
+
143
+ SELECT strftime('%u', '2024-07-26');
144
+ → ["5"]
145
+
146
+ SELECT strftime('%J', '2000-01-01 12:00:00');
147
+ → ["2451545"]
148
+
149
+ SELECT strftime('%%', '2024-07-26');
150
+ → ["%"]
151
+
152
+ SELECT strftime('%z', '2024-07-26');
153
+ → ["+0000"]
154
+
155
+ SELECT strftime('%f', '2024-07-26 14:30:45');
156
+ → [".000"]
157
+
158
+ SELECT strftime('%s', '2000-01-01 00:00:00');
159
+ → ["946684800"]
160
+
161
+ SELECT strftime('%Y/%m/%d %H:%M', '2024-07-26 14:30:45');
162
+ → ["2024/07/26 14:30"]
163
+
164
+ SELECT strftime(null, '2024-07-26');
165
+ → [null]
166
+
167
+ -- ============================================================
168
+ -- JSON: validation edge cases
169
+ -- ============================================================
170
+
171
+ SELECT json_valid(''), json_valid('null'), json_valid('true'), json_valid('false');
172
+ → [{"json_valid('')":false,"json_valid('null')":true,"json_valid('true')":true,"json_valid('false')":true}]
173
+
174
+ SELECT json_valid(42), json_valid(true), json_valid(false);
175
+ → [{"json_valid(42)":true,"json_valid(true)":true,"json_valid(false)":true}]
176
+
177
+ -- ============================================================
178
+ -- JSON: type detection
179
+ -- ============================================================
180
+
181
+ SELECT json_type('42'), json_type('3.14');
182
+ → [{"json_type('42')":"integer","json_type('3.14')":"real"}]
183
+
184
+ SELECT json_type('true'), json_type('false'), json_type('null');
185
+ → [{"json_type('true')":"true","json_type('false')":"false","json_type('null')":"null"}]
186
+
187
+ SELECT json_type('[]'), json_type('{}');
188
+ → [{"json_type('[]')":"array","json_type('{}')":"object"}]
189
+
190
+ -- ============================================================
191
+ -- JSON: extract edge cases
192
+ -- ============================================================
193
+
194
+ SELECT json_extract('{"a":1}', '$.b');
195
+ → [null]
196
+
197
+ SELECT json_extract('{"a":null}', '$.a');
198
+ → [null]
199
+
200
+ SELECT json_extract('{"a":1,"b":2}', '$.c', '$.b', '$.a');
201
+ → [2]
202
+
203
+ -- ============================================================
204
+ -- JSON: manipulation edge cases
205
+ -- ============================================================
206
+
207
+ -- Array append at length position
208
+ SELECT json_insert('[1,2,3]', '$[3]', 4);
209
+ → [[1,2,3,4]]
210
+
211
+ -- Array out-of-bounds fills with nulls
212
+ SELECT json_set('[1,2]', '$[5]', 'x');
213
+ → [[1,2,null,null,null,"x"]]
214
+
215
+ -- Root path replacement
216
+ SELECT json_replace('{"a":1}', '$', 42);
217
+ → [42]
218
+
219
+ -- Array element removal
220
+ SELECT json_remove('[10,20,30]', '$[1]');
221
+ → [[10,30]]
222
+
223
+ -- Multiple path removal
224
+ SELECT json_remove('{"a":1,"b":2,"c":3}', '$.a', '$.c');
225
+ → [{"b":2}]
226
+
227
+ -- ============================================================
228
+ -- JSON: patch edge cases
229
+ -- ============================================================
230
+
231
+ -- Empty patch → no change
232
+ SELECT json_patch('{"a":1}', '[]') as result;
233
+ → [{"result":{"a":1}}]
234
+
235
+ -- Invalid patch: missing 'op' field → null
236
+ SELECT json_patch('{"a":1}', '[{"path":"/a"}]') as result;
237
+ → [{"result":null}]
238
+
239
+ -- Non-array patch → null
240
+ SELECT json_patch('{"a":1}', '{"op":"add"}') as result;
241
+ → [{"result":null}]
242
+
243
+ -- ============================================================
244
+ -- JSON: aggregate edge cases
245
+ -- ============================================================
246
+
247
+ create table json_agg_empty (id integer primary key, v text null);
248
+ select json_group_array(v) as result from json_agg_empty;
249
+ → [{"result":null}]
250
+
251
+ insert into json_agg_empty values (1, null), (2, null);
252
+ -- run
253
+ select json_group_object(v, 1) as result from json_agg_empty;
254
+ → [{"result":null}]
255
+ drop table json_agg_empty;
256
+
257
+ -- ============================================================
258
+ -- STRING: substr edge cases
259
+ -- ============================================================
260
+
261
+ SELECT substr('hello', -2) as result;
262
+ → [{"result":"lo"}]
263
+
264
+ SELECT substr('hello', -2, 1) as result;
265
+ → [{"result":"l"}]
266
+
267
+ SELECT substr('hello', 0) as result;
268
+ → [{"result":"hello"}]
269
+
270
+ SELECT substr('hello', 0, 3) as result;
271
+ → [{"result":"hel"}]
272
+
273
+ -- Negative length → empty string
274
+ SELECT substr('hello', 2, -1) as result;
275
+ → [{"result":""}]
276
+
277
+ -- Large negative start clamps to 0
278
+ SELECT substr('hello', -100) as result;
279
+ → [{"result":"hello"}]
280
+
281
+ -- ============================================================
282
+ -- STRING: trim with regex-special characters
283
+ -- ============================================================
284
+
285
+ SELECT trim('[hello]', '[]') as result;
286
+ → [{"result":"hello"}]
287
+
288
+ SELECT trim('...test...', '.') as result;
289
+ → [{"result":"test"}]
290
+
291
+ SELECT trim('***test***', '*') as result;
292
+ → [{"result":"test"}]
293
+
294
+ SELECT trim('(test)', '()') as result;
295
+ → [{"result":"test"}]
296
+
297
+ -- Empty chars → no change
298
+ SELECT trim('hello', '') as result;
299
+ → [{"result":"hello"}]
300
+
301
+ -- ============================================================
302
+ -- STRING: LIKE edge cases
303
+ -- ============================================================
304
+
305
+ SELECT like('%', '%') as result;
306
+ → [{"result":true}]
307
+
308
+ SELECT like('_', 'a') as result;
309
+ → [{"result":true}]
310
+
311
+ SELECT like('_', '') as result;
312
+ → [{"result":false}]
313
+
314
+ SELECT like('', '') as result;
315
+ → [{"result":true}]
316
+
317
+ SELECT like('', 'a') as result;
318
+ → [{"result":false}]
319
+
320
+ SELECT like('%', '') as result;
321
+ → [{"result":true}]
322
+
323
+ -- ============================================================
324
+ -- AGGREGATE: SUM BigInt promotion on overflow
325
+ -- ============================================================
326
+
327
+ create table bigint_sum (id integer primary key, v integer);
328
+ insert into bigint_sum values (1, 5000000000000000), (2, 5000000000000000);
329
+ select sum(v) from bigint_sum;
330
+ → [{"sum(v)":10000000000000000}]
331
+ drop table bigint_sum;
332
+
333
+ -- ============================================================
334
+ -- AGGREGATE: SUM with string coercion
335
+ -- ============================================================
336
+
337
+ create table str_sum (id integer primary key, v text null);
338
+ insert into str_sum values (1, '10'), (2, '20'), (3, 'abc'), (4, null);
339
+ select sum(v) from str_sum;
340
+ → [{"sum(v)":30}]
341
+ drop table str_sum;
342
+
343
+ -- ============================================================
344
+ -- AGGREGATE: SUM with boolean values
345
+ -- ============================================================
346
+
347
+ create table bool_sum (id integer primary key, v boolean);
348
+ insert into bool_sum values (1, true), (2, false), (3, true), (4, true);
349
+ select sum(v) from bool_sum;
350
+ → [{"sum(v)":3}]
351
+ drop table bool_sum;
352
+
353
+ -- ============================================================
354
+ -- AGGREGATE: GROUP_CONCAT edge cases
355
+ -- Note: ';' as separator avoided due to parser treating ';' in strings as statement boundary
356
+ -- ============================================================
357
+
358
+ create table gc_t (id integer primary key, grp text, val text null);
359
+ insert into gc_t values (1, 'a', 'x'), (2, 'a', null), (3, 'a', 'y'), (4, 'b', null), (5, 'b', null);
360
+ -- run
361
+
362
+ -- Custom separator
363
+ select group_concat(val, '|') from gc_t where grp = 'a';
364
+ → [{"group_concat(val, '|')":"x|y"}]
365
+
366
+ -- All null values → null
367
+ select group_concat(val) from gc_t where grp = 'b';
368
+ → [{"group_concat(val)":null}]
369
+
370
+ -- Empty separator
371
+ select group_concat(val, '') from gc_t where grp = 'a';
372
+ → [{"group_concat(val, '')":"xy"}]
373
+
374
+ drop table gc_t;
375
+
376
+ -- ============================================================
377
+ -- AGGREGATE: statistical functions with known dataset
378
+ -- ============================================================
379
+
380
+ -- Dataset: [2, 4, 4, 4, 5, 5, 7, 9], n=8, sum=40, sumSq=232, mean=5
381
+ create table stat_t (id integer primary key, v real);
382
+ insert into stat_t values (1, 2.0), (2, 4.0), (3, 4.0), (4, 4.0), (5, 5.0), (6, 5.0), (7, 7.0), (8, 9.0);
383
+ -- run
384
+
385
+ -- var_pop = 232/8 - 25 = 4
386
+ select var_pop(v) from stat_t;
387
+ → [{"var_pop(v)":4}]
388
+
389
+ -- stddev_pop = sqrt(4) = 2
390
+ select stddev_pop(v) from stat_t;
391
+ → [{"stddev_pop(v)":2}]
392
+
393
+ -- var_samp = (232 - 1600/8) / 7 = 32/7
394
+ select var_samp(v) from stat_t;
395
+ → [{"var_samp(v)":4.571428571428571}]
396
+
397
+ -- stddev_samp = sqrt(32/7)
398
+ select stddev_samp(v) from stat_t;
399
+ → [{"stddev_samp(v)":2.138089935299395}]
400
+
401
+ drop table stat_t;
402
+
403
+ -- Single-value boundaries
404
+ create table stat_one (id integer primary key, v real);
405
+ insert into stat_one values (1, 42.0);
406
+ -- run
407
+
408
+ select var_pop(v) from stat_one;
409
+ → [{"var_pop(v)":0}]
410
+
411
+ select var_samp(v) from stat_one;
412
+ → [{"var_samp(v)":null}]
413
+
414
+ select stddev_pop(v) from stat_one;
415
+ → [{"stddev_pop(v)":0}]
416
+
417
+ select stddev_samp(v) from stat_one;
418
+ → [{"stddev_samp(v)":null}]
419
+
420
+ drop table stat_one;
421
+
422
+ -- ============================================================
423
+ -- AGGREGATE: MIN/MAX with nulls
424
+ -- ============================================================
425
+
426
+ create table minmax_t (id integer primary key, v integer null);
427
+ insert into minmax_t values (1, 3), (2, null), (3, 1), (4, null), (5, 7);
428
+ select min(v), max(v) from minmax_t;
429
+ → [{"min(v)":1,"max(v)":7}]
430
+ drop table minmax_t;
431
+
432
+ -- All nulls → null for all aggregates
433
+ create table allnull (id integer primary key, v integer null);
434
+ insert into allnull values (1, null), (2, null);
435
+ select min(v), max(v), sum(v), avg(v) from allnull;
436
+ → [{"min(v)":null,"max(v)":null,"sum(v)":null,"avg(v)":null}]
437
+ drop table allnull;
438
+
439
+ -- ============================================================
440
+ -- AGGREGATE: TOTAL with non-numeric
441
+ -- ============================================================
442
+
443
+ create table total_t (id integer primary key, v text null);
444
+ insert into total_t values (1, 'abc'), (2, null), (3, 'def');
445
+ select total(v) from total_t;
446
+ → [{"total(v)":0}]
447
+ drop table total_t;
448
+
449
+ -- ============================================================
450
+ -- SCALAR: coalesce
451
+ -- ============================================================
452
+
453
+ SELECT coalesce(null, null, 3) as result;
454
+ → [{"result":3}]
455
+
456
+ SELECT coalesce(null, null, null) as result;
457
+ → [{"result":null}]
458
+
459
+ SELECT coalesce(1, 2, 3) as result;
460
+ → [{"result":1}]
461
+
462
+ SELECT coalesce(null, 1, 'text') as result;
463
+ → [{"result":1}]
464
+
465
+ -- ============================================================
466
+ -- SCALAR: nullif
467
+ -- ============================================================
468
+
469
+ SELECT nullif(1, 1) as result;
470
+ → [{"result":null}]
471
+
472
+ SELECT nullif(1, 2) as result;
473
+ → [{"result":1}]
474
+
475
+ SELECT nullif('a', 'a') as result;
476
+ → [{"result":null}]
477
+
478
+ SELECT nullif('a', 'b') as result;
479
+ → [{"result":"a"}]
480
+
481
+ SELECT nullif(null, null) as result;
482
+ → [{"result":null}]
483
+
484
+ -- ============================================================
485
+ -- SCALAR: iif with string conditions
486
+ -- ============================================================
487
+
488
+ SELECT iif('1', 'yes', 'no') as result;
489
+ → [{"result":"yes"}]
490
+
491
+ SELECT iif('0', 'yes', 'no') as result;
492
+ → [{"result":"no"}]
493
+
494
+ SELECT iif('abc', 'yes', 'no') as result;
495
+ → [{"result":"no"}]
496
+
497
+ SELECT iif(true, 'yes', 'no') as result;
498
+ → [{"result":"yes"}]
499
+
500
+ SELECT iif(false, 'yes', 'no') as result;
501
+ → [{"result":"no"}]
502
+
503
+ -- ============================================================
504
+ -- SCALAR: choose boundaries
505
+ -- ============================================================
506
+
507
+ SELECT choose(1, 'a', 'b', 'c') as result;
508
+ → [{"result":"a"}]
509
+
510
+ SELECT choose(3, 'a', 'b', 'c') as result;
511
+ → [{"result":"c"}]
512
+
513
+ SELECT choose(4, 'a', 'b', 'c') as result;
514
+ → [{"result":null}]
515
+
516
+ SELECT choose(-1, 'a', 'b') as result;
517
+ → [{"result":null}]
518
+
519
+ -- ============================================================
520
+ -- SCALAR: greatest/least with nulls
521
+ -- ============================================================
522
+
523
+ SELECT greatest(null, 3, null, 1) as result;
524
+ → [{"result":3}]
525
+
526
+ SELECT greatest(null, null) as result;
527
+ → [{"result":null}]
528
+
529
+ SELECT greatest(null, 42) as result;
530
+ → [{"result":42}]
531
+
532
+ -- least skips NULLs, matching greatest, so the answer never depends on where
533
+ -- a NULL sits in the argument list.
534
+ SELECT least(1, null) as result;
535
+ → [{"result":1}]
536
+
537
+ SELECT least(null, 1) as result;
538
+ → [{"result":1}]
539
+
540
+ SELECT least(null, null) as result;
541
+ → [{"result":null}]
542
+
543
+ SELECT least(3, null, 1) as result;
544
+ → [{"result":1}]
545
+
546
+ SELECT least(1, null, 3) as result;
547
+ → [{"result":1}]
548
+
549
+ -- Skipping is by argument, not by position: the same multiset of non-NULL
550
+ -- arguments gives the same answer whatever order the NULLs arrive in.
551
+ SELECT least(null, 3, null, 1, null) as result;
552
+ → [{"result":1}]
553
+
554
+ SELECT greatest(3, null, 1) as result;
555
+ → [{"result":3}]
556
+
557
+ -- A single non-NULL argument survives on its own, with no comparison to make.
558
+ SELECT least(null, 7, null) as result, greatest(null, 7, null) as result2;
559
+ → [{"result":7,"result2":7}]
560
+
561
+ -- Non-numeric comparison groups take the same path — TEXT ranks by collation,
562
+ -- and the returned value is the raw argument (`returnsArg`), not a coerced key.
563
+ SELECT least('b', null, 'a') as result, greatest('b', null, 'a') as result2;
564
+ → [{"result":"a","result2":"b"}]
565
+
566
+ -- Mixed group: the fold ranks coerced keys ('abc' reads as 0) but still hands
567
+ -- back the raw argument, and the NULL is skipped as in a single-type group.
568
+ SELECT least('abc', null, 1) as result, greatest('abc', null, 1) as result2;
569
+ → [{"result":"abc","result2":1}]
570
+
571
+ -- All-NULL and single-NULL calls answer NULL for both directions.
572
+ SELECT least(null, null, null) as result, greatest(null, null, null) as result2;
573
+ → [{"result":null,"result2":null}]
574
+
575
+ SELECT least(null) as result, greatest(null) as result2;
576
+ → [{"result":null,"result2":null}]
577
+
578
+ -- ============================================================
579
+ -- SCALAR: typeof edge cases
580
+ -- ============================================================
581
+
582
+ SELECT typeof(true), typeof(false);
583
+ → [{"typeof(true)":"integer","typeof(false)":"integer"}]
584
+
585
+ SELECT typeof(json_object('a', 1));
586
+ → [{"typeof(json_object('a', 1))":"json"}]
587
+
588
+ -- ============================================================
589
+ -- CONVERSION: error paths
590
+ -- ============================================================
591
+
592
+ SELECT integer('not_a_number');
593
+ -- error: Cannot convert to INTEGER
594
+
595
+ SELECT integer('') as result;
596
+ → [{"result":null}]
597
+
598
+ SELECT real('not_a_number');
599
+ -- error: Cannot convert to REAL
600
+
601
+ SELECT real('') as result;
602
+ → [{"result":null}]
603
+
604
+ SELECT boolean('');
605
+ -- error: Cannot convert to BOOLEAN
606
+
607
+ SELECT boolean('yes'), boolean('no');
608
+ → [{"boolean('yes')":true,"boolean('no')":false}]
609
+
610
+ SELECT boolean('on'), boolean('off');
611
+ → [{"boolean('on')":true,"boolean('off')":false}]
@@ -0,0 +1,75 @@
1
+ -- substr-extras.sqllogic - substr / substring scenarios beyond 24-builtin-branches:
2
+ -- NULL propagation, substring() alias, Y past end, 2-arg negative-Y forms,
3
+ -- Z-negative semantics (chars preceding Y, per SQLite docs).
4
+ -- adapted from SQLite test/substr.test and test/func2.test
5
+
6
+ -- NULL in the string or start argument propagates to NULL
7
+ select substr(null, 1, 1) as result;
8
+ → [{"result":null}]
9
+
10
+ -- Quereus deviation: NULL Y propagates to NULL, but NULL Z is treated as 0 (empty string),
11
+ -- not NULL. SQLite propagates NULL for any NULL argument.
12
+ create table substr_nulls (id integer primary key, s text null, y integer null, z integer null);
13
+ insert into substr_nulls values (1, 'hello', null, 1), (2, 'hello', 1, null);
14
+ select substr(s, y, z) from substr_nulls order by id;
15
+ → [{"substr(s, y, z)":null},{"substr(s, y, z)":""}]
16
+ drop table substr_nulls;
17
+
18
+ -- substring() is an alias of substr()
19
+ select substring('hello', 2, 3) = substr('hello', 2, 3) as result;
20
+ → [{"result":true}]
21
+
22
+ select substring('hello', 2) = substr('hello', 2) as result;
23
+ → [{"result":true}]
24
+
25
+ -- Y > strlen returns empty string (3-arg)
26
+ select substr('hello', 100, 5) as result;
27
+ → [{"result":""}]
28
+
29
+ -- Y > strlen returns empty string (2-arg)
30
+ select substr('hi', 5) as result;
31
+ → [{"result":""}]
32
+
33
+ -- 2-arg form with negative Y counts from end
34
+ select substr('abcdef', -3) as result;
35
+ → [{"result":"def"}]
36
+
37
+ -- Y past beginning with abs(Y) > strlen clamps to start
38
+ select substr('abc', -10) as result;
39
+ → [{"result":"abc"}]
40
+
41
+ -- Y + Z extending past end: returns the available tail, no padding
42
+ select substr('hello', 3, 100) as result;
43
+ → [{"result":"llo"}]
44
+
45
+ -- 3-arg with Y=0 and length=1: SQLite treats Y=0 as Y=1 in this form
46
+ select substr('abcdef', 0, 1) as result;
47
+ → [{"result":"a"}]
48
+
49
+ -- 3-arg with Y=0 and length=2
50
+ select substr('abcdef', 0, 2) as result;
51
+ → [{"result":"ab"}]
52
+
53
+ -- Y=0 with length 0: empty
54
+ select substr('abc', 0, 0) as result;
55
+ → [{"result":""}]
56
+
57
+ -- Negative Z: Quereus returns empty string. (SQLite returns abs(Z) chars preceding Y;
58
+ -- Quereus deviates and clamps to empty per the existing 24-builtin-branches assertion.)
59
+ select substr('abcdef', 4, -1) as result;
60
+ → [{"result":""}]
61
+
62
+ select substr('abcdef', 4, -3) as result;
63
+ → [{"result":""}]
64
+
65
+ -- Negative Y with negative Z (Quereus: empty)
66
+ select substr('abcdef', -2, -2) as result;
67
+ → [{"result":""}]
68
+
69
+ -- substr indexes by Unicode code point. Non-BMP `😀` is one code point (was two UTF-16 code units).
70
+ select substr('a😀b', 2, 1) as result;
71
+ → [{"result":"😀"}]
72
+
73
+ -- BMP multi-byte character ('é' is one UTF-16 code unit) works correctly.
74
+ select substr('café', 1, 4) as result;
75
+ → [{"result":"café"}]