@quereus/quereus 4.20.1 → 4.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/README.md +2 -0
  2. package/package.json +7 -4
  3. package/test/README.md +173 -0
  4. package/test/logic/01-basic.sqllogic +39 -0
  5. package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
  6. package/test/logic/01.2-strings.sqllogic +43 -0
  7. package/test/logic/01.5-insert-select.sqllogic +237 -0
  8. package/test/logic/01.6-update-extras.sqllogic +118 -0
  9. package/test/logic/01.7-update-from.sqllogic +67 -0
  10. package/test/logic/01.8-delete-extras.sqllogic +122 -0
  11. package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
  12. package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
  13. package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
  14. package/test/logic/01.9-query-expr-values.sqllogic +111 -0
  15. package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
  16. package/test/logic/02-filters.sqllogic +54 -0
  17. package/test/logic/02-smoke.sqllogic +62 -0
  18. package/test/logic/02.1-bind-parameters.sqllogic +223 -0
  19. package/test/logic/03-expressions.sqllogic +190 -0
  20. package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
  21. package/test/logic/03.4-defaults.sqllogic +554 -0
  22. package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
  23. package/test/logic/03.5-tvf.sqllogic +61 -0
  24. package/test/logic/03.6-type-system.sqllogic +544 -0
  25. package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
  26. package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
  27. package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
  28. package/test/logic/03.8-not-precedence.sqllogic +255 -0
  29. package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
  30. package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
  31. package/test/logic/04-order-by.sqllogic +38 -0
  32. package/test/logic/04-transactions.sqllogic +239 -0
  33. package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
  34. package/test/logic/05-vtab_memory.sqllogic +50 -0
  35. package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
  36. package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
  37. package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
  38. package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
  39. package/test/logic/06-builtin_functions.sqllogic +149 -0
  40. package/test/logic/06.1-string-functions.sqllogic +92 -0
  41. package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
  42. package/test/logic/06.2-math-functions.sqllogic +82 -0
  43. package/test/logic/06.3-schema.sqllogic +48 -0
  44. package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
  45. package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
  46. package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
  47. package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
  48. package/test/logic/06.3.4-view-info.sqllogic +378 -0
  49. package/test/logic/06.3.5-column-info.sqllogic +347 -0
  50. package/test/logic/06.3.6-schema-views.sqllogic +29 -0
  51. package/test/logic/06.4-schema-search-path.sqllogic +354 -0
  52. package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
  53. package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
  54. package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
  55. package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
  56. package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
  57. package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
  58. package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
  59. package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
  60. package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
  61. package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
  62. package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
  63. package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
  64. package/test/logic/06.7-json-extended.sqllogic +53 -0
  65. package/test/logic/06.8-json-path-operators.sqllogic +99 -0
  66. package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
  67. package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
  68. package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
  69. package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
  70. package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
  71. package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
  72. package/test/logic/07-aggregates.sqllogic +193 -0
  73. package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
  74. package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
  75. package/test/logic/07.3-group-by-extras.sqllogic +602 -0
  76. package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
  77. package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
  78. package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
  79. package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
  80. package/test/logic/07.5-window.sqllogic +1941 -0
  81. package/test/logic/07.5.1-window-named.sqllogic +13 -0
  82. package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
  83. package/test/logic/07.6-subqueries.sqllogic +78 -0
  84. package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
  85. package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
  86. package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
  87. package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
  88. package/test/logic/07.7.1-in-extras.sqllogic +158 -0
  89. package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
  90. package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
  91. package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
  92. package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
  93. package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
  94. package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
  95. package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
  96. package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
  97. package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
  98. package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
  99. package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
  100. package/test/logic/07.9-in-value-list.sqllogic +154 -0
  101. package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
  102. package/test/logic/08-views.sqllogic +64 -0
  103. package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
  104. package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
  105. package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
  106. package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
  107. package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
  108. package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
  109. package/test/logic/09-set_operations.sqllogic +244 -0
  110. package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
  111. package/test/logic/10-distinct_datatypes.sqllogic +127 -0
  112. package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
  113. package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
  114. package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
  115. package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
  116. package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
  117. package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
  118. package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
  119. package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
  120. package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
  121. package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
  122. package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
  123. package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
  124. package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
  125. package/test/logic/10.2-column-features.sqllogic +365 -0
  126. package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
  127. package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
  128. package/test/logic/10.3-function-features.sqllogic +247 -0
  129. package/test/logic/10.4-schema-scale.sqllogic +168 -0
  130. package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
  131. package/test/logic/10.5-indexes.sqllogic +164 -0
  132. package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
  133. package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
  134. package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
  135. package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
  136. package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
  137. package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
  138. package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
  139. package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
  140. package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
  141. package/test/logic/100.1-where-extras.sqllogic +163 -0
  142. package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
  143. package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
  144. package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
  145. package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
  146. package/test/logic/102-unique-constraints.sqllogic +145 -0
  147. package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
  148. package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
  149. package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
  150. package/test/logic/102.2-unique-collation.sqllogic +181 -0
  151. package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
  152. package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
  153. package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
  154. package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
  155. package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
  156. package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
  157. package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
  158. package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
  159. package/test/logic/108-cardinality-estimation.sqllogic +146 -0
  160. package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
  161. package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
  162. package/test/logic/11-joins.sqllogic +86 -0
  163. package/test/logic/11.1-join-using.sqllogic +267 -0
  164. package/test/logic/11.2-comma-join.sqllogic +35 -0
  165. package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
  166. package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
  167. package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
  168. package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
  169. package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
  170. package/test/logic/12-empty-primary-key.sqllogic +124 -0
  171. package/test/logic/12-join_padding_order.sqllogic +58 -0
  172. package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
  173. package/test/logic/13-cte.sqllogic +137 -0
  174. package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
  175. package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
  176. package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
  177. package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
  178. package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
  179. package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
  180. package/test/logic/13.4-cte-extras.sqllogic +98 -0
  181. package/test/logic/13.5-cte-join-order.sqllogic +166 -0
  182. package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
  183. package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
  184. package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
  185. package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
  186. package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
  187. package/test/logic/14-utilities.sqllogic +168 -0
  188. package/test/logic/15-timespan.sqllogic +279 -0
  189. package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
  190. package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
  191. package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
  192. package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
  193. package/test/logic/16-epoch.sqllogic +187 -0
  194. package/test/logic/17-weekday-modifier.sqllogic +78 -0
  195. package/test/logic/18-json-string-escapes.sqllogic +86 -0
  196. package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
  197. package/test/logic/20-empty-single-row.sqllogic +261 -0
  198. package/test/logic/21-null-edge-cases.sqllogic +227 -0
  199. package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
  200. package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
  201. package/test/logic/21.2-between-edges.sqllogic +157 -0
  202. package/test/logic/22-boundary-values.sqllogic +175 -0
  203. package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
  204. package/test/logic/24-builtin-branches.sqllogic +611 -0
  205. package/test/logic/24.1-substr-extras.sqllogic +75 -0
  206. package/test/logic/24.2-random-extras.sqllogic +39 -0
  207. package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
  208. package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
  209. package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
  210. package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
  211. package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
  212. package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
  213. package/test/logic/26-join-edge-cases.sqllogic +333 -0
  214. package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
  215. package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
  216. package/test/logic/26.3-join-on-constants.sqllogic +61 -0
  217. package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
  218. package/test/logic/27-window-edge-cases.sqllogic +206 -0
  219. package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
  220. package/test/logic/27.2-window-exclude.sqllogic +13 -0
  221. package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
  222. package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
  223. package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
  224. package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
  225. package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
  226. package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
  227. package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
  228. package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
  229. package/test/logic/40-constraints.sqllogic +418 -0
  230. package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
  231. package/test/logic/40.2-check-extras.sqllogic +683 -0
  232. package/test/logic/41-alter-table.sqllogic +191 -0
  233. package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
  234. package/test/logic/41-fk-cross-schema.sqllogic +155 -0
  235. package/test/logic/41-fk-extended-targets.sqllogic +173 -0
  236. package/test/logic/41-foreign-keys.sqllogic +1001 -0
  237. package/test/logic/41-generated-column-errors.sqllogic +225 -0
  238. package/test/logic/41-generated-column-extras.sqllogic +598 -0
  239. package/test/logic/41-generated-column-scope.sqllogic +329 -0
  240. package/test/logic/41-generated-columns.sqllogic +361 -0
  241. package/test/logic/41.1-alter-pk.sqllogic +230 -0
  242. package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
  243. package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
  244. package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
  245. package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
  246. package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
  247. package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
  248. package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
  249. package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
  250. package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
  251. package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
  252. package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
  253. package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
  254. package/test/logic/41.2-alter-column.sqllogic +382 -0
  255. package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
  256. package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
  257. package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
  258. package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
  259. package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
  260. package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
  261. package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
  262. package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
  263. package/test/logic/41.5-alter-misc.sqllogic +48 -0
  264. package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
  265. package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
  266. package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
  267. package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
  268. package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
  269. package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
  270. package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
  271. package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
  272. package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
  273. package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
  274. package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
  275. package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
  276. package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
  277. package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
  278. package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
  279. package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
  280. package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
  281. package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
  282. package/test/logic/42-committed-snapshot.sqllogic +254 -0
  283. package/test/logic/42-returning.sqllogic +159 -0
  284. package/test/logic/42.1-returning-extras.sqllogic +232 -0
  285. package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
  286. package/test/logic/43-default-nullability.sqllogic +131 -0
  287. package/test/logic/43-transition-constraints.sqllogic +341 -0
  288. package/test/logic/43.1-default-collation.sqllogic +140 -0
  289. package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
  290. package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
  291. package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
  292. package/test/logic/44-determinism-validation.sqllogic +164 -0
  293. package/test/logic/44-orthogonality.sqllogic +146 -0
  294. package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
  295. package/test/logic/45-udf-determinism.sqllogic +39 -0
  296. package/test/logic/46-mutation-context.sqllogic +595 -0
  297. package/test/logic/47-upsert.sqllogic +255 -0
  298. package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
  299. package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
  300. package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
  301. package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
  302. package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
  303. package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
  304. package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
  305. package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
  306. package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
  307. package/test/logic/49-reference-graph.sqllogic +84 -0
  308. package/test/logic/50-declarative-schema.sqllogic +2550 -0
  309. package/test/logic/50-metadata-tags.sqllogic +1033 -0
  310. package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
  311. package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
  312. package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
  313. package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
  314. package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
  315. package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
  316. package/test/logic/51-lens-foundation.sqllogic +147 -0
  317. package/test/logic/51-materialized-views.sqllogic +376 -0
  318. package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
  319. package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
  320. package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
  321. package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
  322. package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
  323. package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
  324. package/test/logic/52-lens-overrides.sqllogic +566 -0
  325. package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
  326. package/test/logic/53-reserved-tags.sqllogic +252 -0
  327. package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
  328. package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
  329. package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
  330. package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
  331. package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
  332. package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
  333. package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
  334. package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
  335. package/test/logic/55-lens-prover.sqllogic +202 -0
  336. package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
  337. package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
  338. package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
  339. package/test/logic/81-quickpick.sqllogic +24 -0
  340. package/test/logic/82-bloom-join.sqllogic +185 -0
  341. package/test/logic/83-merge-join.sqllogic +280 -0
  342. package/test/logic/84-asof-scan.sqllogic +238 -0
  343. package/test/logic/84-key-cardinality.sqllogic +50 -0
  344. package/test/logic/85-relational-const-folding.sqllogic +51 -0
  345. package/test/logic/86-scalar-cse.sqllogic +42 -0
  346. package/test/logic/90-error_paths.sqllogic +114 -0
  347. package/test/logic/90.1-parse-errors.sqllogic +77 -0
  348. package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
  349. package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
  350. package/test/logic/90.3-expression-errors.sqllogic +43 -0
  351. package/test/logic/90.4-dml-errors.sqllogic +47 -0
  352. package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
  353. package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
  354. package/test/logic/90.6-select-error-paths.sqllogic +57 -0
  355. package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
  356. package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
  357. package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
  358. package/test/logic/93.1-view-error-paths.sqllogic +74 -0
  359. package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
  360. package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
  361. package/test/logic/93.4-view-mutation.sqllogic +4881 -0
  362. package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
  363. package/test/logic/93.5-authored-inverse.sqllogic +415 -0
  364. package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
  365. package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
  366. package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
  367. package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
  368. package/test/logic/95-assertions.sqllogic +1417 -0
  369. package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
  370. package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
  371. package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
  372. package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
  373. package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
  374. package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
  375. package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
  376. package/test/logic/drop-unique-index.sqllogic +88 -0
  377. package/test/logic/pushdown-test.sqllogic +36 -0
@@ -0,0 +1,43 @@
1
+ -- 90.3-expression-errors.sqllogic - Expression, subquery, and aggregate error paths
2
+
3
+ -- Scalar subquery with multiple columns
4
+ SELECT (SELECT 1, 2);
5
+ -- error: Scalar subquery must return exactly one column
6
+
7
+ -- IN subquery with multiple columns
8
+ SELECT 1 WHERE 1 IN (SELECT 1, 2);
9
+ -- error: IN subquery must return exactly one column
10
+
11
+ -- Duplicate CTE name
12
+ WITH c AS (SELECT 1 AS x), c AS (SELECT 2 AS x) SELECT * FROM c;
13
+ -- error: Duplicate CTE name 'c' in WITH clause
14
+
15
+ -- Aggregate function in WHERE clause
16
+ CREATE TABLE t_agg_ctx (id INTEGER PRIMARY KEY, val INTEGER);
17
+ INSERT INTO t_agg_ctx VALUES (1, 10), (2, 20);
18
+ -- run
19
+
20
+ SELECT * FROM t_agg_ctx WHERE count(*) > 1;
21
+ -- error: not allowed in this context
22
+
23
+ -- Window function requiring ORDER BY
24
+ SELECT rank() OVER () FROM t_agg_ctx;
25
+ -- error: requires ORDER BY clause
26
+
27
+ -- OLD qualifier in INSERT RETURNING
28
+ INSERT INTO t_agg_ctx VALUES (3, 30) RETURNING OLD.id;
29
+ -- error: OLD qualifier cannot be used in INSERT RETURNING clause
30
+
31
+ -- Cleanup
32
+ DROP TABLE t_agg_ctx;
33
+ -- run
34
+
35
+ -- NEW qualifier in DELETE RETURNING
36
+ CREATE TABLE t_del_ret (id INTEGER PRIMARY KEY, val INTEGER);
37
+ INSERT INTO t_del_ret VALUES (1, 10);
38
+ -- run
39
+
40
+ DELETE FROM t_del_ret WHERE id = 1 RETURNING NEW.id;
41
+ -- error: NEW qualifier cannot be used in DELETE RETURNING clause
42
+
43
+ DROP TABLE t_del_ret;
@@ -0,0 +1,47 @@
1
+ -- 90.4-dml-errors.sqllogic - DML error paths (INSERT, UPDATE, DELETE edge cases)
2
+
3
+ -- VALUES clause column count mismatch (fewer values than columns)
4
+ CREATE TABLE t_vals (a INTEGER, b INTEGER, c INTEGER);
5
+ -- run
6
+
7
+ INSERT INTO t_vals VALUES (1, 2);
8
+ -- error: Column count mismatch
9
+
10
+ -- VALUES clause column count mismatch (more values than columns)
11
+ INSERT INTO t_vals VALUES (1, 2, 3, 4);
12
+ -- error: Column count mismatch
13
+
14
+ DROP TABLE t_vals;
15
+ -- run
16
+
17
+ -- INSERT with explicit column referencing non-existent column
18
+ CREATE TABLE t_insert_col (id INTEGER PRIMARY KEY, name TEXT);
19
+ -- run
20
+
21
+ INSERT INTO t_insert_col (id, missing_col) VALUES (1, 'x');
22
+ -- error: not found
23
+
24
+ DROP TABLE t_insert_col;
25
+ -- run
26
+
27
+ -- ON CONFLICT target with non-existent column
28
+ CREATE TABLE t_upsert_bad (id INTEGER PRIMARY KEY, val INTEGER);
29
+ -- run
30
+
31
+ INSERT INTO t_upsert_bad (id, val) VALUES (1, 10) ON CONFLICT (missing_col) DO NOTHING;
32
+ -- error: not found
33
+
34
+ DROP TABLE t_upsert_bad;
35
+ -- run
36
+
37
+ -- Mutating subquery without RETURNING clause
38
+ CREATE TABLE t_mut_src (id INTEGER PRIMARY KEY, val INTEGER);
39
+ CREATE TABLE t_mut_dst (id INTEGER PRIMARY KEY, val INTEGER);
40
+ INSERT INTO t_mut_src VALUES (1, 10);
41
+ -- run
42
+
43
+ INSERT INTO t_mut_dst SELECT * FROM (DELETE FROM t_mut_src WHERE id = 1);
44
+ -- error: must have a RETURNING clause
45
+
46
+ DROP TABLE t_mut_src;
47
+ DROP TABLE t_mut_dst;
@@ -0,0 +1,37 @@
1
+ -- adapted from SQLite test/join.test, join7.test, joinB.test, joinH.test
2
+ -- RIGHT [OUTER] JOIN and FULL [OUTER] JOIN now execute in the nested-loop join
3
+ -- emitter (read path). NATURAL JOIN remains unparsed and is pinned as an error.
4
+
5
+ create table uj_l (id integer primary key, val text);
6
+ create table uj_r (id integer primary key, val text);
7
+
8
+ insert into uj_l values (1, 'L1'), (2, 'L2');
9
+ insert into uj_r values (1, 'R1'), (3, 'R3');
10
+ -- run
11
+
12
+ -- RIGHT JOIN: every right row appears; right id=3 has no left match → null-left.
13
+ select uj_l.id as l, uj_r.id as r from uj_l right join uj_r on uj_l.id = uj_r.id order by uj_r.id;
14
+ → [{"l":1,"r":1},{"l":null,"r":3}]
15
+
16
+ -- RIGHT OUTER JOIN: same path, same rows.
17
+ select uj_l.id as l, uj_r.id as r from uj_l right outer join uj_r on uj_l.id = uj_r.id order by uj_r.id;
18
+ → [{"l":1,"r":1},{"l":null,"r":3}]
19
+
20
+ -- FULL OUTER JOIN: matched (1,1), left id=2 unmatched (2,NULL), right id=3 unmatched (NULL,3).
21
+ select uj_l.id as l, uj_r.id as r from uj_l full outer join uj_r on uj_l.id = uj_r.id order by coalesce(uj_l.id, uj_r.id);
22
+ → [{"l":1,"r":1},{"l":2,"r":null},{"l":null,"r":3}]
23
+
24
+ -- FULL JOIN (no OUTER keyword): same path, same rows.
25
+ select uj_l.id as l, uj_r.id as r from uj_l full join uj_r on uj_l.id = uj_r.id order by coalesce(uj_l.id, uj_r.id);
26
+ → [{"l":1,"r":1},{"l":2,"r":null},{"l":null,"r":3}]
27
+
28
+ -- NATURAL JOIN: still not parsed (out of scope for this ticket).
29
+ select * from uj_l natural join uj_r;
30
+ -- error: NATURAL
31
+
32
+ -- NATURAL LEFT JOIN: still not parsed.
33
+ select * from uj_l natural left join uj_r;
34
+ -- error: NATURAL
35
+
36
+ drop table uj_l;
37
+ drop table uj_r;
@@ -0,0 +1,157 @@
1
+ -- Read-path coverage for RIGHT / FULL outer joins in the nested-loop emitter
2
+ -- (runtime/emit/join.ts). Companion to 90.5, which flips the basic RIGHT/FULL
3
+ -- cases; this file pins column order, the empty-side matrix, no-match, many-to-many
4
+ -- (fan-out), USING, and existence (`exists … as`) flag semantics.
5
+
6
+ -- ===== select * column order: left columns first, then right columns =====
7
+ -- `a right/full join b` returns `a.*` then `b.*` (the JoinNode attribute order),
8
+ -- not the scan/drive order. Distinct column names avoid `:N` disambiguation so the
9
+ -- per-name values directly confirm left attrs occupy the left positions.
10
+
11
+ create table so_l (lid integer primary key, lval text);
12
+ create table so_r (rid integer primary key, rval text);
13
+ insert into so_l values (1, 'L1'), (2, 'L2');
14
+ insert into so_r values (1, 'R1'), (3, 'R3');
15
+ -- run
16
+
17
+ -- RIGHT: matched (1) plus right id=3 null-extended on the left.
18
+ select * from so_l right join so_r on so_l.lid = so_r.rid order by so_r.rid;
19
+ → [{"lid":1,"lval":"L1","rid":1,"rval":"R1"},{"lid":null,"lval":null,"rid":3,"rval":"R3"}]
20
+
21
+ -- FULL: matched (1), left id=2 null-right, right id=3 null-left.
22
+ select * from so_l full join so_r on so_l.lid = so_r.rid order by coalesce(so_l.lid, so_r.rid);
23
+ → [{"lid":1,"lval":"L1","rid":1,"rval":"R1"},{"lid":2,"lval":"L2","rid":null,"rval":null},{"lid":null,"lval":null,"rid":3,"rval":"R3"}]
24
+
25
+ drop table so_l;
26
+ drop table so_r;
27
+ -- run
28
+
29
+ -- ===== Empty-side matrix =====
30
+
31
+ create table es_full (k integer primary key, v text);
32
+ create table es_empty (k integer primary key, v text);
33
+ create table es_empty2 (k integer primary key, v text);
34
+ insert into es_full values (1, 'a'), (2, 'b');
35
+ -- run
36
+
37
+ -- left empty + RIGHT: every right row appears, null-extended on the left.
38
+ select es_empty.k as lk, es_full.k as rk from es_empty right join es_full on es_empty.k = es_full.k order by es_full.k;
39
+ → [{"lk":null,"rk":1},{"lk":null,"rk":2}]
40
+
41
+ -- right empty + RIGHT: no rows at all.
42
+ select es_full.k as lk, es_empty.k as rk from es_full right join es_empty on es_full.k = es_empty.k order by es_empty.k;
43
+ → []
44
+
45
+ -- both empty + FULL: no rows.
46
+ select a.k as lk, b.k as rk from es_empty a full join es_empty2 b on a.k = b.k;
47
+ → []
48
+
49
+ -- left non-empty + right empty + FULL: every left row null-extended on the right (trailing pass only).
50
+ select es_full.k as lk, es_empty.k as rk from es_full full join es_empty on es_full.k = es_empty.k order by es_full.k;
51
+ → [{"lk":1,"rk":null},{"lk":2,"rk":null}]
52
+
53
+ -- left empty + FULL: every right row null-extended on the left (no trailing rows).
54
+ select es_empty.k as lk, es_full.k as rk from es_empty full join es_full on es_empty.k = es_full.k order by es_full.k;
55
+ → [{"lk":null,"rk":1},{"lk":null,"rk":2}]
56
+
57
+ drop table es_full;
58
+ drop table es_empty;
59
+ drop table es_empty2;
60
+ -- run
61
+
62
+ -- ===== No match at all =====
63
+
64
+ create table nm_l (id integer primary key);
65
+ create table nm_r (id integer primary key);
66
+ insert into nm_l values (1), (2);
67
+ insert into nm_r values (3), (4);
68
+ -- run
69
+
70
+ -- RIGHT, predicate matches nothing: all right rows null-left.
71
+ select nm_l.id as l, nm_r.id as r from nm_l right join nm_r on nm_l.id = nm_r.id order by nm_r.id;
72
+ → [{"l":null,"r":3},{"l":null,"r":4}]
73
+
74
+ -- FULL, predicate matches nothing: all right null-left AND all left null-right.
75
+ select nm_l.id as l, nm_r.id as r from nm_l full join nm_r on nm_l.id = nm_r.id order by coalesce(nm_l.id, nm_r.id);
76
+ → [{"l":1,"r":null},{"l":2,"r":null},{"l":null,"r":3},{"l":null,"r":4}]
77
+
78
+ drop table nm_l;
79
+ drop table nm_r;
80
+ -- run
81
+
82
+ -- ===== Many-to-many (duplicate join keys): one row per match, no spurious null-extension =====
83
+
84
+ create table mm_l (id integer primary key, k integer);
85
+ create table mm_r (id integer primary key, k integer);
86
+ -- k=1 twice on each side; k=2 only on right; k=3 only on left.
87
+ insert into mm_l values (1, 1), (2, 1), (3, 3);
88
+ insert into mm_r values (10, 1), (11, 1), (12, 2);
89
+ -- run
90
+
91
+ -- RIGHT: right rows 10 & 11 (k=1) each match BOTH left k=1 rows (2 each); right row
92
+ -- 12 (k=2) has no match → one null-left row. No matched right row is null-extended.
93
+ select mm_l.id as lid, mm_r.id as rid from mm_l right join mm_r on mm_l.k = mm_r.k order by mm_r.id, mm_l.id;
94
+ → [{"lid":1,"rid":10},{"lid":2,"rid":10},{"lid":1,"rid":11},{"lid":2,"rid":11},{"lid":null,"rid":12}]
95
+
96
+ -- FULL: the same matched/null-left rows, plus left row 3 (k=3) null-right exactly once.
97
+ select mm_l.id as lid, mm_r.id as rid from mm_l full join mm_r on mm_l.k = mm_r.k order by coalesce(mm_r.id, 999), coalesce(mm_l.id, 999);
98
+ → [{"lid":1,"rid":10},{"lid":2,"rid":10},{"lid":1,"rid":11},{"lid":2,"rid":11},{"lid":null,"rid":12},{"lid":3,"rid":null}]
99
+
100
+ drop table mm_l;
101
+ drop table mm_r;
102
+ -- run
103
+
104
+ -- ===== USING join (order-agnostic equality in the right-driven loop) =====
105
+
106
+ create table us_l (id integer primary key, val text);
107
+ create table us_r (id integer primary key, val text);
108
+ insert into us_l values (1, 'L1'), (2, 'L2');
109
+ insert into us_r values (1, 'R1'), (3, 'R3');
110
+ -- run
111
+
112
+ -- right join … using (id): same shape as the ON form; right id=3 null-left.
113
+ select us_l.id as l, us_r.id as r from us_l right join us_r using (id) order by us_r.id;
114
+ → [{"l":1,"r":1},{"l":null,"r":3}]
115
+
116
+ -- full join … using (id): both unmatched sides surface.
117
+ select us_l.id as l, us_r.id as r from us_l full join us_r using (id) order by coalesce(us_l.id, us_r.id);
118
+ → [{"l":1,"r":1},{"l":2,"r":null},{"l":null,"r":3}]
119
+
120
+ drop table us_l;
121
+ drop table us_r;
122
+ -- run
123
+
124
+ -- ===== Existence flags on RIGHT (non-preserved side = left) =====
125
+ -- `exists as h` resolves to the only null-extendable side (left) of a RIGHT join.
126
+ -- A matched row sets h=true; a left-null-extended row sets h=false.
127
+
128
+ create table ex_l (id integer primary key, val text);
129
+ create table ex_r (id integer primary key, val text);
130
+ insert into ex_l values (1, 'L1');
131
+ insert into ex_r values (1, 'R1'), (2, 'R2');
132
+ -- run
133
+
134
+ select ex_r.id as r, h from ex_l right join ex_r on ex_l.id = ex_r.id exists as h order by ex_r.id;
135
+ → [{"r":1,"h":true},{"r":2,"h":false}]
136
+
137
+ drop table ex_l;
138
+ drop table ex_r;
139
+ -- run
140
+
141
+ -- ===== Existence flags on FULL (both sides null-extendable) =====
142
+ -- fl = "left present", fr = "right present". Matched → both true; right-only row →
143
+ -- fl false, fr true; left-only row → fl true, fr false.
144
+
145
+ create table fe_l (id integer primary key);
146
+ create table fe_r (id integer primary key);
147
+ insert into fe_l values (1), (2);
148
+ insert into fe_r values (1), (3);
149
+ -- run
150
+
151
+ select fe_l.id as l, fe_r.id as r, fl, fr
152
+ from fe_l full join fe_r on fe_l.id = fe_r.id exists left as fl, exists right as fr
153
+ order by coalesce(fe_l.id, fe_r.id);
154
+ → [{"l":1,"r":1,"fl":true,"fr":true},{"l":2,"r":null,"fl":true,"fr":false},{"l":null,"r":3,"fl":false,"fr":true}]
155
+
156
+ drop table fe_l;
157
+ drop table fe_r;
@@ -0,0 +1,57 @@
1
+ -- adapted from SQLite test/select1.test, test/select5.test, test/e_select.test
2
+ -- SELECT-side error paths: wrong-arity aggregate calls, ORDER BY positional
3
+ -- references that are out of range, and aggregate references in disallowed
4
+ -- contexts.
5
+
6
+ create table eptab (id integer primary key, a integer, b integer);
7
+ insert into eptab values (1, 11, 22), (2, 33, 44);
8
+
9
+ -- count() with two arguments is rejected
10
+ select count(a, b) from eptab;
11
+ -- error: count
12
+
13
+ -- sum() with two arguments is rejected
14
+ select sum(a, b) from eptab;
15
+ -- error: sum
16
+
17
+ -- min(*) and max(*) — the star form is reserved for count() only
18
+ select min(*) from eptab;
19
+ -- error: min
20
+
21
+ select max(*) from eptab;
22
+ -- error: max
23
+
24
+ -- Out-of-range / zero / negative ordinal references in GROUP BY and ORDER BY
25
+ -- raise an error at planning time.
26
+ select a from eptab group by 0;
27
+ -- error: GROUP BY position 0
28
+
29
+ select a from eptab group by 2;
30
+ -- error: GROUP BY position 2
31
+
32
+ select a from eptab order by -1;
33
+ -- error: ORDER BY position -1
34
+
35
+ select a from eptab order by 99;
36
+ -- error: ORDER BY position 99
37
+
38
+ drop table eptab;
39
+
40
+ -- =============================================================================
41
+ -- Compound SELECT column-count mismatch — branches must agree
42
+ -- =============================================================================
43
+
44
+ select 1
45
+ union
46
+ select 1, 2;
47
+ -- error: column
48
+
49
+ select 1, 2
50
+ intersect
51
+ select 1;
52
+ -- error: column
53
+
54
+ select 1, 2
55
+ except
56
+ select 1;
57
+ -- error: column
@@ -0,0 +1,159 @@
1
+ -- merge-join-edge-cases.sqllogic - Edge cases for join emitters (merge/hash)
2
+ -- Targets: merge-join.ts branches — self-joins, residual conditions, NULL keys, many-to-many
3
+
4
+ -- Self-join: cross-product within each group
5
+ CREATE TABLE mj_self (id INTEGER PRIMARY KEY, grp INTEGER, label TEXT);
6
+ INSERT INTO mj_self VALUES (1, 1, 'a'), (2, 1, 'b'), (3, 2, 'c'), (4, 2, 'd'), (5, 3, 'e');
7
+
8
+ SELECT a.id AS aid, b.id AS bid
9
+ FROM mj_self a JOIN mj_self b ON a.grp = b.grp
10
+ ORDER BY aid, bid;
11
+ → [{"aid":1,"bid":1},{"aid":1,"bid":2},{"aid":2,"bid":1},{"aid":2,"bid":2},{"aid":3,"bid":3},{"aid":3,"bid":4},{"aid":4,"bid":3},{"aid":4,"bid":4},{"aid":5,"bid":5}]
12
+
13
+ -- Self LEFT JOIN with residual condition: equi on grp, residual a.id != b.id
14
+ -- id=5 (grp=3) is the only row in its group, so residual filters out the self-match → NULL padded
15
+ SELECT a.id AS aid, b.id AS bid
16
+ FROM mj_self a LEFT JOIN mj_self b ON a.grp = b.grp AND a.id != b.id
17
+ ORDER BY aid, bid;
18
+ → [{"aid":1,"bid":2},{"aid":2,"bid":1},{"aid":3,"bid":4},{"aid":4,"bid":3},{"aid":5,"bid":null}]
19
+
20
+ -- JOIN with residual inequality: only pairs where left label < right label
21
+ SELECT a.id AS aid, b.id AS bid
22
+ FROM mj_self a JOIN mj_self b ON a.grp = b.grp AND a.label < b.label
23
+ ORDER BY aid, bid;
24
+ → [{"aid":1,"bid":2},{"aid":3,"bid":4}]
25
+
26
+ -- All-NULL join keys: NULLs never match per SQL standard
27
+ CREATE TABLE mj_allnull (id INTEGER PRIMARY KEY, val INTEGER NULL);
28
+ INSERT INTO mj_allnull VALUES (1, null), (2, null), (3, null);
29
+
30
+ SELECT a.id, b.id FROM mj_allnull a JOIN mj_allnull b ON a.val = b.val;
31
+ → []
32
+
33
+ -- LEFT JOIN with all-NULL keys: every left row is unmatched
34
+ SELECT a.id, b.id FROM mj_allnull a LEFT JOIN mj_allnull b ON a.val = b.val ORDER BY a.id;
35
+ → [{"id":1,"id:1":null},{"id":2,"id:1":null},{"id":3,"id:1":null}]
36
+
37
+ -- Mixed NULL and non-NULL join keys
38
+ CREATE TABLE mj_mixed (id INTEGER PRIMARY KEY, val INTEGER NULL);
39
+ INSERT INTO mj_mixed VALUES (1, 10), (2, null), (3, 20), (4, null), (5, 10);
40
+
41
+ -- INNER JOIN: NULLs excluded, matching non-NULLs produce cross-product
42
+ SELECT a.id AS aid, b.id AS bid
43
+ FROM mj_mixed a JOIN mj_mixed b ON a.val = b.val
44
+ ORDER BY aid, bid;
45
+ → [{"aid":1,"bid":1},{"aid":1,"bid":5},{"aid":3,"bid":3},{"aid":5,"bid":1},{"aid":5,"bid":5}]
46
+
47
+ -- LEFT JOIN: NULL-keyed rows get NULL padding, matched rows get cross-product
48
+ SELECT a.id AS aid, b.id AS bid
49
+ FROM mj_mixed a LEFT JOIN mj_mixed b ON a.val = b.val
50
+ ORDER BY aid, bid;
51
+ → [{"aid":1,"bid":1},{"aid":1,"bid":5},{"aid":2,"bid":null},{"aid":3,"bid":3},{"aid":4,"bid":null},{"aid":5,"bid":1},{"aid":5,"bid":5}]
52
+
53
+ -- Many-to-many with asymmetric cardinality
54
+ CREATE TABLE mj_m2m_l (id INTEGER PRIMARY KEY, key INTEGER);
55
+ CREATE TABLE mj_m2m_r (id INTEGER PRIMARY KEY, key INTEGER);
56
+ INSERT INTO mj_m2m_l VALUES (1, 10), (2, 10), (3, 10), (4, 20);
57
+ INSERT INTO mj_m2m_r VALUES (10, 10), (20, 10), (30, 20), (40, 20), (50, 20);
58
+
59
+ -- 3×2=6 for key=10, 1×3=3 for key=20 → total 9
60
+ SELECT count(*) AS cnt FROM mj_m2m_l l JOIN mj_m2m_r r ON l.key = r.key;
61
+ → [{"cnt":9}]
62
+
63
+ -- LEFT JOIN preserves all left rows with correct match counts
64
+ SELECT l.id, count(r.id) AS matches
65
+ FROM mj_m2m_l l LEFT JOIN mj_m2m_r r ON l.key = r.key
66
+ GROUP BY l.id ORDER BY l.id;
67
+ → [{"id":1,"matches":2},{"id":2,"matches":2},{"id":3,"matches":2},{"id":4,"matches":3}]
68
+
69
+ -- Join where one side is empty (inner and left)
70
+ CREATE TABLE mj_populated (id INTEGER PRIMARY KEY, val INTEGER);
71
+ CREATE TABLE mj_empty (id INTEGER PRIMARY KEY, val INTEGER);
72
+ INSERT INTO mj_populated VALUES (1, 10), (2, 20);
73
+
74
+ SELECT p.id FROM mj_populated p JOIN mj_empty e ON p.val = e.val;
75
+ → []
76
+
77
+ SELECT p.id, e.id AS eid FROM mj_populated p LEFT JOIN mj_empty e ON p.val = e.val ORDER BY p.id;
78
+ → [{"id":1,"eid":null},{"id":2,"eid":null}]
79
+
80
+ -- Both sides empty
81
+ SELECT a.id FROM mj_empty a JOIN mj_empty b ON a.val = b.val;
82
+ → []
83
+
84
+ -- Multi-column join with partial key matches
85
+ CREATE TABLE mj_mc_l (a INTEGER, b INTEGER, v TEXT, PRIMARY KEY (a, b));
86
+ CREATE TABLE mj_mc_r (x INTEGER, y INTEGER, w TEXT, PRIMARY KEY (x, y));
87
+
88
+ INSERT INTO mj_mc_l VALUES (1, 10, 'p'), (1, 20, 'q'), (2, 10, 'r');
89
+ INSERT INTO mj_mc_r VALUES (1, 10, 's'), (1, 30, 't'), (2, 10, 'u');
90
+
91
+ -- Only (1,10) and (2,10) match on both columns
92
+ SELECT l.v, r.w FROM mj_mc_l l JOIN mj_mc_r r ON l.a = r.x AND l.b = r.y ORDER BY l.a, l.b;
93
+ → [{"v":"p","w":"s"},{"v":"r","w":"u"}]
94
+
95
+ -- LEFT JOIN: (1,20) has no match on both columns → NULL padded
96
+ SELECT l.a, l.b, r.w FROM mj_mc_l l LEFT JOIN mj_mc_r r ON l.a = r.x AND l.b = r.y ORDER BY l.a, l.b;
97
+ → [{"a":1,"b":10,"w":"s"},{"a":1,"b":20,"w":null},{"a":2,"b":10,"w":"u"}]
98
+
99
+ -- DESC primary key: the scan's advertised ordering must carry the declared
100
+ -- direction, or a merge join built on it drops all but one matching row.
101
+ -- (bug-desc-pk-scan-advertises-ascending-order)
102
+ CREATE TABLE mj_dpk (id INTEGER, v TEXT, PRIMARY KEY (id DESC));
103
+ CREATE TABLE mj_small (id INTEGER PRIMARY KEY);
104
+ INSERT INTO mj_dpk VALUES (1, 'a'), (2, 'b'), (3, 'c');
105
+ INSERT INTO mj_small VALUES (1), (2), (3);
106
+
107
+ SELECT id FROM mj_dpk WHERE id IN (SELECT id FROM mj_small) ORDER BY id;
108
+ → [{"id":1},{"id":2},{"id":3}]
109
+
110
+ SELECT id FROM mj_dpk d WHERE EXISTS (SELECT 1 FROM mj_small s WHERE s.id = d.id) ORDER BY id;
111
+ → [{"id":1},{"id":2},{"id":3}]
112
+
113
+ SELECT d.id FROM mj_dpk d JOIN mj_small s ON s.id = d.id ORDER BY d.id;
114
+ → [{"id":1},{"id":2},{"id":3}]
115
+
116
+ SELECT d.id AS did, s.id AS sid FROM mj_dpk d LEFT JOIN mj_small s ON s.id = d.id ORDER BY d.id;
117
+ → [{"did":1,"sid":1},{"did":2,"sid":2},{"did":3,"sid":3}]
118
+
119
+ -- Sort absorption over the same advertisement: an ORDER BY must not be elided
120
+ -- against a stream that runs the other way.
121
+ SELECT id FROM mj_dpk ORDER BY id;
122
+ → [{"id":1},{"id":2},{"id":3}]
123
+
124
+ SELECT id FROM mj_dpk ORDER BY id DESC;
125
+ → [{"id":3},{"id":2},{"id":1}]
126
+
127
+ -- Composite PK with mixed directions: the advertisement is per-column, so the
128
+ -- ASC member and the DESC member must each carry their own direction.
129
+ CREATE TABLE mj_mixdir (a INTEGER, b INTEGER, v TEXT, PRIMARY KEY (a ASC, b DESC));
130
+ CREATE TABLE mj_mixdir_r (a INTEGER, b INTEGER, w TEXT, PRIMARY KEY (a ASC, b DESC));
131
+ INSERT INTO mj_mixdir VALUES (1, 10, 'p'), (1, 20, 'q'), (2, 10, 'r');
132
+ INSERT INTO mj_mixdir_r VALUES (1, 10, 's'), (1, 20, 't'), (2, 10, 'u');
133
+
134
+ SELECT l.v, r.w FROM mj_mixdir l JOIN mj_mixdir_r r ON l.a = r.a AND l.b = r.b ORDER BY l.a, l.b;
135
+ → [{"v":"p","w":"s"},{"v":"q","w":"t"},{"v":"r","w":"u"}]
136
+
137
+ SELECT l.a, l.b, r.w FROM mj_mixdir l LEFT JOIN mj_mixdir_r r ON l.a = r.a AND l.b = r.b ORDER BY l.a, l.b;
138
+ → [{"a":1,"b":10,"w":"s"},{"a":1,"b":20,"w":"t"},{"a":2,"b":10,"w":"u"}]
139
+
140
+ SELECT a, b FROM mj_mixdir ORDER BY a, b;
141
+ → [{"a":1,"b":10},{"a":1,"b":20},{"a":2,"b":10}]
142
+
143
+ SELECT a, b FROM mj_mixdir ORDER BY a, b DESC;
144
+ → [{"a":1,"b":20},{"a":1,"b":10},{"a":2,"b":10}]
145
+
146
+ -- Cleanup
147
+ DROP TABLE mj_self;
148
+ DROP TABLE mj_allnull;
149
+ DROP TABLE mj_mixed;
150
+ DROP TABLE mj_m2m_l;
151
+ DROP TABLE mj_m2m_r;
152
+ DROP TABLE mj_populated;
153
+ DROP TABLE mj_empty;
154
+ DROP TABLE mj_mc_l;
155
+ DROP TABLE mj_mc_r;
156
+ DROP TABLE mj_dpk;
157
+ DROP TABLE mj_small;
158
+ DROP TABLE mj_mixdir;
159
+ DROP TABLE mj_mixdir_r;
@@ -0,0 +1,139 @@
1
+ -- hash-aggregate-edge-cases.sqllogic - Edge cases for hash aggregate emitter
2
+ -- Targets: hash-aggregate.ts — empty input, NULL groups, DISTINCT aggregates, expression keys
3
+
4
+ -- Empty table with GROUP BY → no rows (not a single NULL row)
5
+ CREATE TABLE ha_empty (id INTEGER PRIMARY KEY, grp TEXT, val INTEGER NULL);
6
+
7
+ SELECT grp, count(*) AS cnt FROM ha_empty GROUP BY grp;
8
+ → []
9
+
10
+ SELECT grp, sum(val) AS total FROM ha_empty GROUP BY grp;
11
+ → []
12
+
13
+ DROP TABLE ha_empty;
14
+
15
+ -- All-NULL group key → single NULL group
16
+ CREATE TABLE ha_null_grp (id INTEGER PRIMARY KEY, grp TEXT NULL, val INTEGER);
17
+ INSERT INTO ha_null_grp VALUES (1, null, 10), (2, null, 20), (3, null, 30);
18
+
19
+ SELECT grp, count(*) AS cnt, sum(val) AS total FROM ha_null_grp GROUP BY grp;
20
+ → [{"grp":null,"cnt":3,"total":60}]
21
+
22
+ -- Multiple NULL groups and non-NULL groups coexist
23
+ INSERT INTO ha_null_grp VALUES (4, 'x', 40), (5, 'x', 50);
24
+
25
+ SELECT grp, count(*) AS cnt FROM ha_null_grp GROUP BY grp ORDER BY grp NULLS FIRST;
26
+ → [{"grp":null,"cnt":3},{"grp":"x","cnt":2}]
27
+
28
+ DROP TABLE ha_null_grp;
29
+
30
+ -- SUM(DISTINCT col) with NULLs: NULLs excluded from distinct tracking
31
+ CREATE TABLE ha_dist (id INTEGER PRIMARY KEY, val INTEGER NULL);
32
+ INSERT INTO ha_dist VALUES (1, 10), (2, 20), (3, 10), (4, null), (5, 20), (6, null);
33
+
34
+ SELECT sum(distinct val) AS sd FROM ha_dist;
35
+ → [{"sd":30}]
36
+
37
+ -- count(*) vs count(col) vs count(distinct col) with NULLs
38
+ SELECT count(*) AS c_star, count(val) AS c_val, count(distinct val) AS c_dval FROM ha_dist;
39
+ → [{"c_star":6,"c_val":4,"c_dval":2}]
40
+
41
+ -- AVG(DISTINCT col)
42
+ SELECT avg(distinct val) AS ad FROM ha_dist;
43
+ → [{"ad":15}]
44
+
45
+ -- Multiple DISTINCT aggregates in same query
46
+ SELECT count(distinct val) AS cd, sum(distinct val) AS sd, avg(distinct val) AS ad FROM ha_dist;
47
+ → [{"cd":2,"sd":30,"ad":15}]
48
+
49
+ DROP TABLE ha_dist;
50
+
51
+ -- SUM(DISTINCT) with GROUP BY
52
+ CREATE TABLE ha_dist_grp (id INTEGER PRIMARY KEY, grp TEXT, val INTEGER NULL);
53
+ INSERT INTO ha_dist_grp VALUES (1, 'a', 10), (2, 'a', 10), (3, 'a', 20), (4, 'b', 30), (5, 'b', null);
54
+
55
+ SELECT grp, sum(distinct val) AS sd, count(distinct val) AS cd FROM ha_dist_grp GROUP BY grp ORDER BY grp;
56
+ → [{"grp":"a","sd":30,"cd":2},{"grp":"b","sd":30,"cd":1}]
57
+
58
+ DROP TABLE ha_dist_grp;
59
+
60
+ -- All-NULL value column: aggregates return null (except count(*) and count)
61
+ CREATE TABLE ha_allnull (id INTEGER PRIMARY KEY, val INTEGER NULL);
62
+ INSERT INTO ha_allnull VALUES (1, null), (2, null), (3, null);
63
+
64
+ SELECT count(*) AS c_star, count(val) AS c_val, sum(val) AS s, avg(val) AS a, min(val) AS mn, max(val) AS mx FROM ha_allnull;
65
+ → [{"c_star":3,"c_val":0,"s":null,"a":null,"mn":null,"mx":null}]
66
+
67
+ DROP TABLE ha_allnull;
68
+
69
+ -- GROUP BY on expression
70
+ CREATE TABLE ha_expr (id INTEGER PRIMARY KEY, name TEXT, val INTEGER);
71
+ INSERT INTO ha_expr VALUES (1, 'a', 10), (2, 'bb', 20), (3, 'ccc', 30), (4, 'dd', 40);
72
+
73
+ SELECT length(name) AS name_len, sum(val) AS total FROM ha_expr GROUP BY length(name) ORDER BY length(name);
74
+ → [{"name_len":1,"total":10},{"name_len":2,"total":60},{"name_len":3,"total":30}]
75
+
76
+ DROP TABLE ha_expr;
77
+
78
+ -- Single-row groups (each row is its own group)
79
+ CREATE TABLE ha_single (id INTEGER PRIMARY KEY, val INTEGER);
80
+ INSERT INTO ha_single VALUES (1, 100), (2, 200), (3, 300);
81
+
82
+ SELECT id, count(*) AS cnt, sum(val) AS total FROM ha_single GROUP BY id ORDER BY id;
83
+ → [{"id":1,"cnt":1,"total":100},{"id":2,"cnt":1,"total":200},{"id":3,"cnt":1,"total":300}]
84
+
85
+ DROP TABLE ha_single;
86
+
87
+ -- HAVING that filters all groups → empty result
88
+ CREATE TABLE ha_having (id INTEGER PRIMARY KEY, grp TEXT, val INTEGER);
89
+ INSERT INTO ha_having VALUES (1, 'a', 10), (2, 'b', 20);
90
+
91
+ SELECT grp, sum(val) AS total FROM ha_having GROUP BY grp HAVING sum(val) > 1000;
92
+ → []
93
+
94
+ -- HAVING with DISTINCT aggregate
95
+ SELECT grp, count(distinct val) AS cd FROM ha_having GROUP BY grp HAVING count(distinct val) > 5;
96
+ → []
97
+
98
+ DROP TABLE ha_having;
99
+
100
+ -- Aggregate without GROUP BY on empty table: returns single row with initial values
101
+ CREATE TABLE ha_empty_agg (id INTEGER PRIMARY KEY, val INTEGER NULL);
102
+
103
+ SELECT count(*) AS cnt, sum(val) AS s, min(val) AS mn, max(val) AS mx FROM ha_empty_agg;
104
+ → [{"cnt":0,"s":null,"mn":null,"mx":null}]
105
+
106
+ DROP TABLE ha_empty_agg;
107
+
108
+ -- GROUP BY with multiple columns including NULL
109
+ CREATE TABLE ha_multi_grp (id INTEGER PRIMARY KEY, a TEXT NULL, b INTEGER NULL, val INTEGER);
110
+ INSERT INTO ha_multi_grp VALUES (1, 'x', 1, 10), (2, 'x', 1, 20), (3, 'x', null, 30), (4, null, 1, 40), (5, null, null, 50);
111
+
112
+ SELECT a, b, count(*) AS cnt, sum(val) AS total
113
+ FROM ha_multi_grp GROUP BY a, b ORDER BY a NULLS FIRST, b NULLS FIRST;
114
+ → [{"a":null,"b":null,"cnt":1,"total":50},{"a":null,"b":1,"cnt":1,"total":40},{"a":"x","b":null,"cnt":1,"total":30},{"a":"x","b":1,"cnt":2,"total":30}]
115
+
116
+ DROP TABLE ha_multi_grp;
117
+
118
+ -- group_concat(DISTINCT) — distinct string aggregation
119
+ CREATE TABLE ha_gc (id INTEGER PRIMARY KEY, grp TEXT, tag TEXT NULL);
120
+ INSERT INTO ha_gc VALUES (1, 'a', 'x'), (2, 'a', 'y'), (3, 'a', 'x'), (4, 'b', null), (5, 'b', 'z');
121
+
122
+ SELECT grp, group_concat(distinct tag) AS tags FROM ha_gc GROUP BY grp ORDER BY grp;
123
+ → [{"grp":"a","tags":"x,y"},{"grp":"b","tags":"z"}]
124
+
125
+ DROP TABLE ha_gc;
126
+
127
+ -- count(distinct blob_col) with GROUP BY — the DISTINCT tree's entry is the
128
+ -- bare BLOB scalar (a Uint8Array), which inheritree's default freeze-on-insert
129
+ -- could not store (bug-in-subquery-blob-values-crash). Exercises the shared
130
+ -- distinct-tree factory used by hash-aggregate's grouped path.
131
+ CREATE TABLE ha_blob_grp (id INTEGER PRIMARY KEY, grp TEXT, b BLOB NULL);
132
+ INSERT INTO ha_blob_grp VALUES
133
+ (1, 'a', x'6162'), (2, 'a', x'6162'), (3, 'a', x'6164'),
134
+ (4, 'b', x'6162'), (5, 'b', null);
135
+
136
+ SELECT grp, count(distinct b) AS cd FROM ha_blob_grp GROUP BY grp ORDER BY grp;
137
+ → [{"grp":"a","cd":2},{"grp":"b","cd":1}]
138
+
139
+ DROP TABLE ha_blob_grp;