@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,227 @@
1
+ -- null-edge-cases.sqllogic - Systematic NULL behavior tests across SQL positions
2
+
3
+ -- =============================================================================
4
+ -- Setup
5
+ -- =============================================================================
6
+
7
+ create table n1 (id integer primary key, val integer null, txt text null);
8
+ insert into n1 values (1, 10, 'a'), (2, null, 'b'), (3, 30, null), (4, null, null);
9
+
10
+ -- =============================================================================
11
+ -- NULL in join keys
12
+ -- =============================================================================
13
+
14
+ create table n2 (id integer primary key, ref integer null);
15
+ insert into n2 values (1, 10), (2, null), (3, 30);
16
+
17
+ -- INNER JOIN: NULL keys should NOT match
18
+ select n1.id, n1.val, n2.id, n2.ref from n1 inner join n2 on n1.val = n2.ref order by n1.id;
19
+ → [{"id":1,"val":10,"id:1":1,"ref":10},{"id":3,"val":30,"id:1":3,"ref":30}]
20
+
21
+ -- LEFT JOIN: rows with null val get null on right side
22
+ select n1.id, n1.val, n2.id, n2.ref from n1 left join n2 on n1.val = n2.ref order by n1.id;
23
+ → [{"id":1,"val":10,"id:1":1,"ref":10},{"id":2,"val":null,"id:1":null,"ref":null},{"id":3,"val":30,"id:1":3,"ref":30},{"id":4,"val":null,"id:1":null,"ref":null}]
24
+
25
+ -- Both sides NULL: verify NULLs don't join (NULL ≠ NULL)
26
+ select count(*) as cnt from n1 inner join n2 on n1.val = n2.ref;
27
+ → [{"cnt":2}]
28
+
29
+ drop table n2;
30
+
31
+ -- =============================================================================
32
+ -- NULL in GROUP BY key
33
+ -- =============================================================================
34
+
35
+ -- NULLs grouped together into one group (NULLs first in default ordering)
36
+ select val, count(*) as cnt from n1 group by val order by val;
37
+ → [{"val":null,"cnt":2},{"val":10,"cnt":1},{"val":30,"cnt":1}]
38
+
39
+ -- =============================================================================
40
+ -- NULL in ORDER BY
41
+ -- =============================================================================
42
+
43
+ -- Default ASC: NULLs come first
44
+ select id, val from n1 order by val, id;
45
+ → [{"id":2,"val":null},{"id":4,"val":null},{"id":1,"val":10},{"id":3,"val":30}]
46
+
47
+ -- NULLS FIRST explicit (same as default ASC)
48
+ select id, val from n1 order by val nulls first, id;
49
+ → [{"id":2,"val":null},{"id":4,"val":null},{"id":1,"val":10},{"id":3,"val":30}]
50
+
51
+ -- NULLS LAST moves NULLs to end
52
+ select id, val from n1 order by val nulls last, id;
53
+ → [{"id":1,"val":10},{"id":3,"val":30},{"id":2,"val":null},{"id":4,"val":null}]
54
+
55
+ -- DESC with NULLS FIRST on text column
56
+ select id, txt from n1 order by txt desc nulls first, id;
57
+ → [{"id":3,"txt":null},{"id":4,"txt":null},{"id":2,"txt":"b"},{"id":1,"txt":"a"}]
58
+
59
+ -- DESC with NULLS LAST moves NULLs to end
60
+ select id, val from n1 order by val desc nulls last, id;
61
+ → [{"id":3,"val":30},{"id":1,"val":10},{"id":2,"val":null},{"id":4,"val":null}]
62
+
63
+ -- DESC with NULLS LAST on text column
64
+ select id, txt from n1 order by txt desc nulls last, id;
65
+ → [{"id":2,"txt":"b"},{"id":1,"txt":"a"},{"id":3,"txt":null},{"id":4,"txt":null}]
66
+
67
+ -- =============================================================================
68
+ -- NULL in CASE WHEN
69
+ -- =============================================================================
70
+
71
+ -- NULL condition is falsy → else branch
72
+ select case when null then 'yes' else 'no' end as r;
73
+ → [{"r":"no"}]
74
+
75
+ -- IS NULL in CASE WHEN
76
+ select id, case when val is null then 'missing' else 'present' end as status from n1 order by id;
77
+ → [{"id":1,"status":"present"},{"id":2,"status":"missing"},{"id":3,"status":"present"},{"id":4,"status":"missing"}]
78
+
79
+ -- Simple CASE: NULL ≠ NULL so 'no match'
80
+ select case null when null then 'match' else 'no match' end as r;
81
+ → [{"r":"no match"}]
82
+
83
+ -- CASE with NULL result branch
84
+ select id, case when id = 2 then null else val end as r from n1 order by id;
85
+ → [{"id":1,"r":10},{"id":2,"r":null},{"id":3,"r":30},{"id":4,"r":null}]
86
+
87
+ -- =============================================================================
88
+ -- NULL in IN list and as IN operand
89
+ -- =============================================================================
90
+
91
+ -- NULL in IN list doesn't match NULL vals; only exact matches
92
+ select id, val from n1 where val in (10, null, 30) order by id;
93
+ → [{"id":1,"val":10},{"id":3,"val":30}]
94
+
95
+ -- NOT IN with NULL in list: returns no rows
96
+ -- val NOT IN (10, NULL) → val<>10 AND val<>NULL → unknown for all non-10 values
97
+ select id, val from n1 where val not in (10, null) order by id;
98
+ → []
99
+
100
+ -- NULL as IN operand: always unknown
101
+ select * from n1 where null in (1, 2, 3);
102
+ → []
103
+
104
+ -- =============================================================================
105
+ -- NULL in aggregate arguments
106
+ -- =============================================================================
107
+
108
+ -- count(col) skips NULLs
109
+ select count(val) as cnt from n1;
110
+ → [{"cnt":2}]
111
+
112
+ -- count(*) counts all rows
113
+ select count(*) as cnt from n1;
114
+ → [{"cnt":4}]
115
+
116
+ -- sum skips NULLs
117
+ select sum(val) as s from n1;
118
+ → [{"s":40}]
119
+
120
+ -- avg skips NULLs (40/2 = 20)
121
+ select avg(val) as a from n1;
122
+ → [{"a":20}]
123
+
124
+ -- min skips NULLs
125
+ select min(val) as mn from n1;
126
+ → [{"mn":10}]
127
+
128
+ -- max skips NULLs
129
+ select max(val) as mx from n1;
130
+ → [{"mx":30}]
131
+
132
+ -- group_concat skips NULLs
133
+ select group_concat(txt, ',') as g from n1;
134
+ → [{"g":"a,b"}]
135
+
136
+ -- =============================================================================
137
+ -- NULL in window functions
138
+ -- =============================================================================
139
+
140
+ -- PARTITION BY groups NULLs together
141
+ select id, val, row_number() over (partition by val order by id) as rn from n1 order by id;
142
+ → [{"id":1,"val":10,"rn":1},{"id":2,"val":null,"rn":1},{"id":3,"val":30,"rn":1},{"id":4,"val":null,"rn":2}]
143
+
144
+ -- RANK with NULLs: null vals get same rank
145
+ select id, val, rank() over (order by val) as rnk from n1 order by id;
146
+ → [{"id":1,"val":10,"rnk":3},{"id":2,"val":null,"rnk":1},{"id":3,"val":30,"rnk":4},{"id":4,"val":null,"rnk":1}]
147
+
148
+ -- =============================================================================
149
+ -- NULL in COALESCE chains
150
+ -- =============================================================================
151
+
152
+ select coalesce(null) as r;
153
+ → [{"r":null}]
154
+
155
+ select coalesce(null, null, null) as r;
156
+ → [{"r":null}]
157
+
158
+ select coalesce(null, null, 'found') as r;
159
+ → [{"r":"found"}]
160
+
161
+ -- Per-row cascade: first non-null wins
162
+ select id, coalesce(val, txt, 'default') as r from n1 order by id;
163
+ → [{"id":1,"r":10},{"id":2,"r":"b"},{"id":3,"r":30},{"id":4,"r":"default"}]
164
+
165
+ -- =============================================================================
166
+ -- NULL with every comparison operator
167
+ -- =============================================================================
168
+
169
+ select null = null as r;
170
+ → [{"r":null}]
171
+
172
+ select null <> null as r;
173
+ → [{"r":null}]
174
+
175
+ select null < 1 as r;
176
+ → [{"r":null}]
177
+
178
+ select null > 1 as r;
179
+ → [{"r":null}]
180
+
181
+ select null <= 1 as r;
182
+ → [{"r":null}]
183
+
184
+ select null >= 1 as r;
185
+ → [{"r":null}]
186
+
187
+ select null is null as r;
188
+ → [{"r":true}]
189
+
190
+ select null is not null as r;
191
+ → [{"r":false}]
192
+
193
+ select 1 is null as r;
194
+ → [{"r":false}]
195
+
196
+ select 1 is not null as r;
197
+ → [{"r":true}]
198
+
199
+ -- =============================================================================
200
+ -- NULL in DISTINCT
201
+ -- =============================================================================
202
+
203
+ -- NULLs are equal for DISTINCT: only one NULL in output
204
+ select distinct val from n1 order by val;
205
+ → [{"val":null},{"val":10},{"val":30}]
206
+
207
+ -- =============================================================================
208
+ -- NULL in subqueries
209
+ -- =============================================================================
210
+
211
+ -- EXISTS with subquery returning null row: true (row exists, value doesn't matter)
212
+ select exists (select null) as r;
213
+ → [{"r":true}]
214
+
215
+ -- Scalar subquery returning null
216
+ select (select null) as r;
217
+ → [{"r":null}]
218
+
219
+ -- IN with null subquery result: unknown
220
+ select 1 in (select null) as r;
221
+ → [{"r":null}]
222
+
223
+ -- =============================================================================
224
+ -- Cleanup
225
+ -- =============================================================================
226
+
227
+ drop table n1;
@@ -0,0 +1,151 @@
1
+ -- where-null-comparisons.sqllogic - WHERE-clause three-valued logic for NULL operands
2
+ -- Distilled from SQLite test/where5.test and test/null.test
3
+
4
+ create table wn (id integer primary key, val integer null, txt text null);
5
+ insert into wn values (1, 10, 'a'), (2, null, 'b'), (3, 30, null), (4, null, null);
6
+
7
+ -- =============================================================================
8
+ -- col <op> NULL is unknown -> WHERE filters out all rows
9
+ -- =============================================================================
10
+
11
+ select id from wn where val = null order by id;
12
+ → []
13
+
14
+ select id from wn where val != null order by id;
15
+ → []
16
+
17
+ select id from wn where val <> null order by id;
18
+ → []
19
+
20
+ select id from wn where val < null order by id;
21
+ → []
22
+
23
+ select id from wn where val <= null order by id;
24
+ → []
25
+
26
+ select id from wn where val > null order by id;
27
+ → []
28
+
29
+ select id from wn where val >= null order by id;
30
+ → []
31
+
32
+ select id from wn where txt = null order by id;
33
+ → []
34
+
35
+ -- =============================================================================
36
+ -- NULL <op> col / NULL <op> NULL is unknown -> no rows
37
+ -- =============================================================================
38
+
39
+ select id from wn where null = val order by id;
40
+ → []
41
+
42
+ select id from wn where null < val order by id;
43
+ → []
44
+
45
+ select id from wn where null = null order by id;
46
+ → []
47
+
48
+ select id from wn where null != null order by id;
49
+ → []
50
+
51
+ -- Bare NULL in WHERE is falsy
52
+ select id from wn where null order by id;
53
+ → []
54
+
55
+ -- NOT NULL in WHERE is also unknown -> no rows
56
+ select id from wn where not null order by id;
57
+ → []
58
+
59
+ -- =============================================================================
60
+ -- Arithmetic propagating NULL into a comparison
61
+ -- =============================================================================
62
+
63
+ select id from wn where val + null > 5 order by id;
64
+ → []
65
+
66
+ select id from wn where val + null is null order by id;
67
+ → [{"id":1},{"id":2},{"id":3},{"id":4}]
68
+
69
+ select id from wn where (val * 0) = null order by id;
70
+ → []
71
+
72
+ -- =============================================================================
73
+ -- NOT around a NULL-producing comparison stays unknown
74
+ -- =============================================================================
75
+
76
+ select id from wn where not (val = null) order by id;
77
+ → []
78
+
79
+ select id from wn where not (val < null) order by id;
80
+ → []
81
+
82
+ select id from wn where not (val + null > 5) order by id;
83
+ → []
84
+
85
+ -- =============================================================================
86
+ -- IS / IS NOT are null-safe and produce TRUE/FALSE, never NULL
87
+ -- =============================================================================
88
+
89
+ select id from wn where val is null order by id;
90
+ → [{"id":2},{"id":4}]
91
+
92
+ select id from wn where val is not null order by id;
93
+ → [{"id":1},{"id":3}]
94
+
95
+ -- (Quereus parser restricts IS to IS NULL / IS NOT NULL — null-safe equality form not supported)
96
+
97
+ -- IS NULL inside a NOT is still TRUE/FALSE
98
+ select id from wn where not (val is null) order by id;
99
+ → [{"id":1},{"id":3}]
100
+
101
+ select id from wn where not (val is not null) order by id;
102
+ → [{"id":2},{"id":4}]
103
+
104
+ -- =============================================================================
105
+ -- Compound with AND/OR: unknown short-circuits AND but not OR-with-true
106
+ -- =============================================================================
107
+
108
+ -- val > 5 AND val = NULL: AND of (true|null) and unknown -> all unknown
109
+ select id from wn where val > 5 and val = null order by id;
110
+ → []
111
+
112
+ -- val > 5 OR val = NULL: OR of (true|null) and unknown -> id=1,3 keep true; id=2,4 stay null
113
+ select id from wn where val > 5 or val = null order by id;
114
+ → [{"id":1},{"id":3}]
115
+
116
+ -- TRUE OR unknown -> TRUE: id=1 wins via val=10; rest stay unknown
117
+ select id from wn where val = 10 or val = null order by id;
118
+ → [{"id":1}]
119
+
120
+ -- =============================================================================
121
+ -- NULL comparisons against key columns must not become seek bounds
122
+ -- (key ordering sorts NULL below everything, so a pushed `> NULL` lower bound
123
+ -- would wrongly match every row)
124
+ -- =============================================================================
125
+
126
+ select id from wn where id > null order by id;
127
+ → []
128
+
129
+ select id from wn where null < id order by id;
130
+ → []
131
+
132
+ select id from wn where id >= null order by id;
133
+ → []
134
+
135
+ select id from wn where id between null and 3 order by id;
136
+ → []
137
+
138
+ select id from wn where id between 1 and null order by id;
139
+ → []
140
+
141
+ select id from wn where (+ null) < id order by id;
142
+ → []
143
+
144
+ -- Sanity: non-NULL bounds on the same column still seek correctly
145
+ select id from wn where id > 3 order by id;
146
+ → [{"id":4}]
147
+
148
+ -- The same assertions against a SECONDARY-INDEXED column live in
149
+ -- 21.1.1-where-null-comparisons-secondary-index (they need standalone CREATE INDEX).
150
+
151
+ drop table wn;
@@ -0,0 +1,35 @@
1
+ -- 21.1.1-where-null-comparisons-secondary-index.sqllogic
2
+ --
3
+ -- requires-capability: standalone-index-ddl
4
+ --
5
+ -- Carved out of 21.1-where-null-comparisons: that file's three-valued-logic
6
+ -- coverage, including "a NULL bound must not become a seek bound", is already
7
+ -- made against the PRIMARY KEY column with no index DDL. This section repeats the
8
+ -- same assertions one level down, on a column reachable only through a standalone
9
+ -- secondary index, so it moves here instead of costing a backend without
10
+ -- first-class CREATE INDEX the whole NULL-comparison file.
11
+ --
12
+ -- Subject: a NULL comparison against a SECONDARY-INDEXED column must not be pushed
13
+ -- down as a seek bound either (key ordering sorts NULL below everything, so a
14
+ -- pushed `> NULL` lower bound would wrongly match every row).
15
+
16
+ create table wn (id integer primary key, val integer null, txt text null);
17
+ insert into wn values (1, 10, 'a'), (2, null, 'b'), (3, 30, null), (4, null, null);
18
+
19
+ create index wn_val on wn (val);
20
+
21
+ select id from wn where val > null order by id;
22
+ → []
23
+
24
+ select id from wn where null < val order by id;
25
+ → []
26
+
27
+ select id from wn where val between null and 30 order by id;
28
+ → []
29
+
30
+ -- Sanity: non-NULL bounds on the same column still seek correctly
31
+ select id from wn where val between 10 and 30 order by id;
32
+ → [{"id":1},{"id":3}]
33
+
34
+ drop index wn_val;
35
+ drop table wn;
@@ -0,0 +1,157 @@
1
+ -- between-edges.sqllogic - BETWEEN edge cases beyond the basic operator
2
+ -- Distilled from SQLite test/between.test
3
+
4
+ create table bt (id integer primary key, val integer null, lo integer null, hi integer null);
5
+ insert into bt values
6
+ (1, 5, 1, 10),
7
+ (2, 15, 5, 12),
8
+ (3, 8, null, 10),
9
+ (4, 8, 5, null),
10
+ (5, null, 1, 10),
11
+ (6, 25, 30, 20);
12
+
13
+ -- =============================================================================
14
+ -- Basic NULL propagation in BETWEEN operands (in WHERE: filters out)
15
+ -- =============================================================================
16
+
17
+ -- value is NULL -> unknown -> no row
18
+ select id from bt where val between 1 and 100 order by id;
19
+ → [{"id":1},{"id":2},{"id":3},{"id":4},{"id":6}]
20
+
21
+ -- lower bound is NULL: row 3 (val=8, lo=null, hi=10): 8 BETWEEN null AND 10 -> unknown
22
+ -- row 2 (val=15, lo=5, hi=12): 15 between 5 and 12 -> false
23
+ -- row 6 (val=25, lo=30, hi=20): reversed bounds -> false
24
+ select id from bt where val between lo and hi order by id;
25
+ → [{"id":1}]
26
+
27
+ -- upper bound is NULL alone, value satisfies low side:
28
+ -- 8 BETWEEN 5 AND null -> unknown -> excluded
29
+ select id from bt where id = 4 and val between lo and hi;
30
+ → []
31
+
32
+ -- =============================================================================
33
+ -- BETWEEN as a SELECT expression: NULL in any operand returns NULL
34
+ -- =============================================================================
35
+
36
+ select null between 1 and 10 as r;
37
+ → [{"r":null}]
38
+
39
+ select 5 between null and 10 as r;
40
+ → [{"r":null}]
41
+
42
+ select 5 between 1 and null as r;
43
+ → [{"r":null}]
44
+
45
+ select 50 between 1 and null as r;
46
+ → [{"r":null}]
47
+
48
+ select null between null and null as r;
49
+ → [{"r":null}]
50
+
51
+ -- =============================================================================
52
+ -- Reversed bounds (lower > upper): always false, never matches
53
+ -- =============================================================================
54
+
55
+ select id from bt where val between 10 and 5;
56
+ → []
57
+
58
+ select 5 between 10 and 1 as r;
59
+ → [{"r":false}]
60
+
61
+ -- NOT BETWEEN with reversed bounds: rows with non-null val all qualify (NOT false = true);
62
+ -- rows with null val stay unknown
63
+ select id from bt where val not between 10 and 5 order by id;
64
+ → [{"id":1},{"id":2},{"id":3},{"id":4},{"id":6}]
65
+
66
+ -- BETWEEN against column-stored reversed bounds (id=6 has lo=30, hi=20)
67
+ select id from bt where id = 6 and val between lo and hi;
68
+ → []
69
+
70
+ -- =============================================================================
71
+ -- NOT BETWEEN preserves unknown for NULL operands
72
+ -- =============================================================================
73
+
74
+ -- Row 5 has val=null: NOT (null between 1 and 10) -> NOT unknown -> unknown -> excluded
75
+ select id from bt where val not between 1 and 10 order by id;
76
+ → [{"id":2},{"id":6}]
77
+
78
+ select null not between 1 and 10 as r;
79
+ → [{"r":null}]
80
+
81
+ -- =============================================================================
82
+ -- Expression bounds (arithmetic in lower / upper / both)
83
+ -- =============================================================================
84
+
85
+ create table bx (id integer primary key, x integer, a integer, b integer);
86
+ insert into bx values (1, 5, 2, 10), (2, 15, 8, 12), (3, 22, 3, 30);
87
+
88
+ select id from bx where x between a + 1 and 100 order by id;
89
+ → [{"id":1},{"id":2},{"id":3}]
90
+
91
+ select id from bx where x between 0 and b * 2 order by id;
92
+ → [{"id":1},{"id":2},{"id":3}]
93
+
94
+ select id from bx where x between a + 3 and b * 2 order by id;
95
+ → [{"id":1},{"id":2},{"id":3}]
96
+
97
+ -- LHS is also an expression
98
+ select id from bx where (x - 5) between a and b order by id;
99
+ → [{"id":2},{"id":3}]
100
+
101
+ drop table bx;
102
+
103
+ -- =============================================================================
104
+ -- BETWEEN with TEXT operands and lexicographic ordering
105
+ -- =============================================================================
106
+
107
+ create table bs (id integer primary key, s text null);
108
+ insert into bs values (1, 'apple'), (2, 'mango'), (3, 'zebra'), (4, null);
109
+
110
+ select id from bs where s between 'banana' and 'orange' order by id;
111
+ → [{"id":2}]
112
+
113
+ select id from bs where s not between 'banana' and 'orange' order by id;
114
+ → [{"id":1},{"id":3}]
115
+
116
+ -- Reversed lexicographic bounds: empty
117
+ select id from bs where s between 'z' and 'a' order by id;
118
+ → []
119
+
120
+ drop table bs;
121
+
122
+ -- =============================================================================
123
+ -- BETWEEN inside HAVING and CASE
124
+ -- =============================================================================
125
+
126
+ create table bg (id integer primary key, grp text, n integer);
127
+ insert into bg values (1, 'a', 2), (2, 'a', 4), (3, 'b', 7), (4, 'b', 9), (5, 'c', 1);
128
+
129
+ select grp, sum(n) as s from bg group by grp having sum(n) between 5 and 10 order by grp;
130
+ → [{"grp":"a","s":6}]
131
+
132
+ select id, case when n between 3 and 8 then 'mid' else 'edge' end as bucket from bg order by id;
133
+ → [{"id":1,"bucket":"edge"},{"id":2,"bucket":"mid"},{"id":3,"bucket":"mid"},{"id":4,"bucket":"edge"},{"id":5,"bucket":"edge"}]
134
+
135
+ drop table bg;
136
+
137
+ -- =============================================================================
138
+ -- BETWEEN in JOIN ON clause (range join)
139
+ -- =============================================================================
140
+
141
+ create table bj_l (id integer primary key, x integer);
142
+ create table bj_r (id integer primary key, lo integer, hi integer, tag text);
143
+ insert into bj_l values (1, 5), (2, 15), (3, 25);
144
+ insert into bj_r values (10, 1, 10, 'low'), (20, 11, 20, 'mid'), (30, 21, 30, 'high');
145
+
146
+ select bj_l.id as lid, bj_r.tag from bj_l join bj_r on bj_l.x between bj_r.lo and bj_r.hi order by lid;
147
+ → [{"lid":1,"tag":"low"},{"lid":2,"tag":"mid"},{"lid":3,"tag":"high"}]
148
+
149
+ -- LEFT JOIN with BETWEEN ON clause: unmatched left rows preserved
150
+ insert into bj_l values (4, 100);
151
+ select bj_l.id as lid, bj_r.tag from bj_l left join bj_r on bj_l.x between bj_r.lo and bj_r.hi order by lid;
152
+ → [{"lid":1,"tag":"low"},{"lid":2,"tag":"mid"},{"lid":3,"tag":"high"},{"lid":4,"tag":null}]
153
+
154
+ drop table bj_l;
155
+ drop table bj_r;
156
+
157
+ drop table bt;