@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,318 @@
1
+ -- adapted from SQLite test/having.test
2
+ -- HAVING edge cases: predicates over aggregate results, multiple aggregates in
3
+ -- one expression, NULL-aware predicates, and rejection of non-grouped columns.
4
+
5
+ create table he (id integer primary key, grp text, val integer null);
6
+ insert into he values
7
+ (1, 'a', 10),
8
+ (2, 'a', 20),
9
+ (3, 'b', null),
10
+ (4, 'b', null),
11
+ (5, 'c', 30),
12
+ (6, 'c', 40);
13
+
14
+ -- HAVING with IS NULL on aggregate output
15
+ -- Group 'b' has only NULL values, so min(val) is NULL
16
+ select grp from he group by grp having min(val) is null order by grp;
17
+ → [{"grp":"b"}]
18
+
19
+ -- HAVING with IS NOT NULL on aggregate
20
+ select grp from he group by grp having min(val) is not null order by grp;
21
+ → [{"grp":"a"},{"grp":"c"}]
22
+
23
+ -- HAVING comparing two aggregates
24
+ -- For 'a': sum=30, avg=15 → sum > avg*2? 30 > 30 → false
25
+ -- For 'c': sum=70, avg=35 → 70 > 70 → false
26
+ -- (none qualify)
27
+ select grp from he group by grp having sum(val) > avg(val) * 2 order by grp;
28
+ → []
29
+
30
+ -- HAVING comparing two aggregates with strict inequality
31
+ -- For 'a': sum=30 vs count(*)*5 = 10 → 30 > 10 true
32
+ -- For 'b': sum=NULL vs count(*)*5 = 10 → NULL>10 false
33
+ -- For 'c': sum=70 vs count(*)*5 = 10 → 70 > 10 true
34
+ select grp from he group by grp having sum(val) > count(*) * 5 order by grp;
35
+ → [{"grp":"a"},{"grp":"c"}]
36
+
37
+ -- HAVING uses an aggregate alias from the SELECT list
38
+ select grp, sum(val) as total from he group by grp having total > 30 order by grp;
39
+ → [{"grp":"c","total":70}]
40
+
41
+ -- HAVING with arithmetic on aggregates: average of squared sums per group
42
+ -- (a's sum=30, b's sum=NULL → treated as no contribution, c's sum=70)
43
+ select grp from he group by grp having sum(val) + count(*) > 35 order by grp;
44
+ → [{"grp":"c"}]
45
+
46
+ -- HAVING that filters out the only candidate group
47
+ select grp from he group by grp having sum(val) > 1000;
48
+ → []
49
+
50
+ drop table he;
51
+
52
+ -- =============================================================================
53
+ -- HAVING referencing a non-grouped column should be rejected
54
+ -- =============================================================================
55
+
56
+ create table hu (id integer primary key, grp text, val integer);
57
+ insert into hu values (1, 'a', 10), (2, 'a', 20);
58
+
59
+ -- HAVING referencing a non-grouped, non-aggregated column (id) is rejected.
60
+ select grp from hu group by grp having id > 0;
61
+ -- error: id
62
+
63
+ -- HAVING referencing a non-grouped column alongside an aggregate in SELECT.
64
+ select grp, sum(val) from hu group by grp having val > 0;
65
+ -- error: val
66
+
67
+ -- HAVING with a mix of grouped and ungrouped columns is rejected for the
68
+ -- ungrouped reference (the AND'd `grp` reference itself is fine).
69
+ select grp, sum(val) from hu group by grp having grp = 'a' and val > 0;
70
+ -- error: val
71
+
72
+ -- HAVING over the implicit single group (no GROUP BY, aggregate in SELECT)
73
+ -- may not reference bare columns.
74
+ select count(*) from hu having id > 0;
75
+ -- error: id
76
+
77
+ -- Positive: HAVING with an aggregate is fine.
78
+ select grp from hu group by grp having sum(val) > 0 order by grp;
79
+ → [{"grp":"a"}]
80
+
81
+ -- Positive: HAVING with a GROUP BY column is fine.
82
+ select grp from hu group by grp having grp = 'a';
83
+ → [{"grp":"a"}]
84
+
85
+ -- Positive: HAVING references the same expression that appears in GROUP BY
86
+ -- (fingerprint-match path). val=10 → 20, val=20 → 40; only `val=20` group qualifies.
87
+ select val * 2 as v2 from hu group by val * 2 having val * 2 > 30 order by v2;
88
+ → [{"v2":40}]
89
+
90
+ drop table hu;
91
+
92
+ -- =============================================================================
93
+ -- HAVING with bound parameters must resolve via the parameter scope
94
+ -- =============================================================================
95
+
96
+ create table hp (id integer, grp text, val integer);
97
+ insert into hp values (1,'a',10),(2,'a',20),(3,'b',5),(4,'b',5);
98
+
99
+ -- Anonymous ? parameter in HAVING: groups with count(*) matching the bound value.
100
+ -- params: [2]
101
+ select grp from hp group by grp having count(*) = ? order by grp;
102
+ → [{"grp":"a"},{"grp":"b"}]
103
+
104
+ -- Named parameter in HAVING: groups whose sum exceeds the bound threshold.
105
+ -- params: {"threshold":15}
106
+ select grp from hp group by grp having sum(val) > :threshold order by grp;
107
+ → [{"grp":"a"}]
108
+
109
+ -- Anonymous ? in both WHERE and HAVING: positional indexing must span clauses.
110
+ -- WHERE keeps only val >= 10 (rows 1,2 → group 'a' count 2; group 'b' empty),
111
+ -- then HAVING count(*) = 2 selects 'a'. Mirrors the original bug-report shape.
112
+ -- params: [10, 2]
113
+ select grp from hp where val >= ? group by grp having count(*) = ? order by grp;
114
+ → [{"grp":"a"}]
115
+
116
+ drop table hp;
117
+
118
+ -- =============================================================================
119
+ -- HAVING with NO aggregate and NO GROUP BY
120
+ --
121
+ -- Such a query is still an aggregate query: it has one implicit group over all
122
+ -- input rows, and HAVING filters that single group. It therefore yields at most
123
+ -- one row, and every clause above the aggregation is subject to the usual
124
+ -- coverage rule (only grouping columns — here, none — and aggregates).
125
+ -- Regression: the clause used to be dropped from the plan entirely, so the
126
+ -- query returned every input row unfiltered.
127
+ -- =============================================================================
128
+
129
+ create table hn (id integer primary key, grp text, val integer);
130
+ insert into hn values (1, 'x', 10), (2, 'y', 20), (3, 'x', 30);
131
+
132
+ create table hnempty (id integer primary key, val integer);
133
+
134
+ -- A bare column above the aggregation is rejected: the implicit group carries no
135
+ -- such column. The SELECT list is checked before HAVING is built, so when both name
136
+ -- an ungrouped column the SELECT-list message is the one raised -- same order as a
137
+ -- GROUP BY query, whose select list is checked at the same point.
138
+ select grp from hn having grp = 'x';
139
+ -- error: Column 'grp' must appear in the GROUP BY clause
140
+
141
+ select * from hn having grp = 'x';
142
+ -- error: Column 'id' must appear in the GROUP BY clause
143
+
144
+ -- ...including when the HAVING predicate itself is a constant, so the only ungrouped
145
+ -- reference is in the SELECT list.
146
+ select grp from hn having 1 = 0;
147
+ -- error: Column 'grp' must appear in the GROUP BY clause
148
+
149
+ select * from hn having 1 = 1;
150
+ -- error: Column 'id' must appear in the GROUP BY clause
151
+
152
+ -- With a select list that carries no bare column, HAVING's own check is what fires,
153
+ -- under its dedicated message.
154
+ select 1 as one from hn having grp = 'x';
155
+ -- error: HAVING references non-grouped column 'grp'
156
+
157
+ -- A SELECT-list alias in HAVING is not a way around the rule: it denotes the same
158
+ -- ungrouped column.
159
+ select val as v from hn having v = 10;
160
+ -- error: Column 'val' must appear in the GROUP BY clause
161
+
162
+ -- Constant-true predicate keeps the single implicit group.
163
+ select 1 as one from hn having 1 = 1;
164
+ → [{"one":1}]
165
+
166
+ -- Constant-false predicate filters it out. (Before the fix this returned all
167
+ -- three rows of `hn`.)
168
+ select 1 as one from hn having 1 = 0;
169
+ → []
170
+
171
+ -- The implicit group exists even over an empty table — aggregation over no rows
172
+ -- still produces exactly one group.
173
+ select 1 as one from hnempty having 1 = 1;
174
+ → [{"one":1}]
175
+
176
+ select 1 as one from hnempty having 1 = 0;
177
+ → []
178
+
179
+ -- A WHERE that removes every row does not remove the group either: WHERE runs below
180
+ -- the aggregation, so the implicit group is still formed over the (now empty) input.
181
+ select 1 as one from hn where val > 100 having 1 = 1;
182
+ → [{"one":1}]
183
+
184
+ select 1 as one from hn where val > 15 having 1 = 1;
185
+ → [{"one":1}]
186
+
187
+ -- A NULL predicate does not pass the filter, exactly as in WHERE.
188
+ select 1 as one from hn having null;
189
+ → []
190
+
191
+ -- The shape nested as a FROM-clause subquery: the outer query sees one row or none.
192
+ select count(*) as c from (select 1 as one from hn having 1 = 1);
193
+ → [{"c":1}]
194
+
195
+ select count(*) as c from (select 1 as one from hn having 1 = 0);
196
+ → [{"c":0}]
197
+
198
+ -- ...and as an arm of a compound select.
199
+ select 1 as one from hn having 1 = 0 union all select 2 as one from hn having 1 = 1;
200
+ → [{"one":2}]
201
+
202
+ -- ...and as the source of an INSERT.
203
+ create table hnsink (id integer primary key, v integer);
204
+ insert into hnsink (id, v) select 1, 1 from hn having 1 = 0;
205
+ select count(*) as c from hnsink;
206
+ → [{"c":0}]
207
+
208
+ insert into hnsink (id, v) select 1, 1 from hn having 1 = 1;
209
+ select count(*) as c from hnsink;
210
+ → [{"c":1}]
211
+
212
+ drop table hnsink;
213
+
214
+ -- A scalar subquery is a legal HAVING predicate here: it is not a bare column of
215
+ -- the aggregated row.
216
+ select 1 as one from hn having (select count(*) from hn) > 2;
217
+ → [{"one":1}]
218
+
219
+ select 1 as one from hn having (select count(*) from hn) > 5;
220
+ → []
221
+
222
+ -- Compositions above the aggregation: LIMIT, DISTINCT, ORDER BY.
223
+ select 1 as one from hn having 1 = 1 limit 1;
224
+ → [{"one":1}]
225
+
226
+ select distinct 1 as one from hn having 1 = 1;
227
+ → [{"one":1}]
228
+
229
+ -- ORDER BY over an ungrouped aggregate query sorts the *input* rows below the
230
+ -- aggregation (a documented Quereus extension), so naming `val` here is legal
231
+ -- and the single output row is unaffected.
232
+ select 1 as one from hn having 1 = 1 order by val;
233
+ → [{"one":1}]
234
+
235
+ -- The same shape as a view body.
236
+ create view hnv as select 1 as one from hn having 1 = 1;
237
+ select * from hnv;
238
+ → [{"one":1}]
239
+
240
+ drop view hnv;
241
+
242
+ -- A HAVING inside a subquery may reference an *enclosing* query's column, exactly
243
+ -- as WHERE may — that is a correlated outer reference, not an ungrouped local
244
+ -- column, and the coverage check must still tell the two apart when the subquery
245
+ -- has no aggregates at all.
246
+ select h.val from hn h where exists (select 1 from hn t having h.grp = 'x') order by h.val;
247
+ → [{"val":10},{"val":30}]
248
+
249
+ -- A window function over the implicit group runs over the *aggregated* row, not the
250
+ -- input rows: there is exactly one, so `count(*) over ()` is 1. (Before the fix this
251
+ -- ran over all three input rows and returned 3, three times.)
252
+ select count(*) over () as c from hn having 1 = 1;
253
+ → [{"c":1}]
254
+
255
+ -- ORDER BY by output ordinal and by select-list alias both resolve above the single
256
+ -- aggregated row. (Before the fix each returned three rows.)
257
+ select 1 as one from hn having 1 = 1 order by 1;
258
+ → [{"one":1}]
259
+
260
+ select 1 as one from hn having 1 = 1 order by one;
261
+ → [{"one":1}]
262
+
263
+ -- An ORDER BY may also name an AGGREGATE here. A HAVING makes this an aggregate
264
+ -- query on its own, so `count(*)` is legal in its ORDER BY exactly as it is in the
265
+ -- ORDER BY of a query that names an aggregate in its SELECT list -- the aggregate
266
+ -- is collected into the AggregateNode for the post-aggregate sort and stripped by
267
+ -- the final projection. (Before the fix, both the collection step and applyOrderBy
268
+ -- asked "does this query name an aggregate?" instead of "is this an aggregate
269
+ -- query?", so the aggregate was never collected and the sort key was rejected with
270
+ -- "Aggregate function count not allowed in this context".)
271
+ select 1 as one from hn having 1 = 1 order by count(*);
272
+ → [{"one":1}]
273
+
274
+ -- ...with more than one sort-only aggregate, and one of a different function.
275
+ select 1 as one from hn having 1 = 1 order by count(*), max(val);
276
+ → [{"one":1}]
277
+
278
+ -- ...and mixed with the select-list alias, which resolves on the final projection
279
+ -- while the aggregates resolve on the AggregateNode below it.
280
+ select 1 as one from hn having 1 = 1 order by count(*), one;
281
+ → [{"one":1}]
282
+
283
+ -- A HAVING that names an aggregate beside a column-free select list. The select
284
+ -- list carries no base-table column, so nothing is uncovered and the query is a
285
+ -- plain aggregate query whose single implicit group the predicate filters.
286
+ select 1 as one from hn having count(*) > 1;
287
+ → [{"one":1}]
288
+
289
+ select 1 as one from hn having count(*) > 5;
290
+ → []
291
+
292
+ select 'label' as k from hn having count(*) > 1 order by count(*);
293
+ → [{"k":"label"}]
294
+
295
+ -- ...and the same over an empty table, where the implicit group still exists but
296
+ -- its count is 0.
297
+ select 1 as one from hnempty having count(*) > 0;
298
+ → []
299
+
300
+ select 1 as one from hnempty having count(*) = 0;
301
+ → [{"one":1}]
302
+
303
+ -- Regression guards: adding an aggregate or a GROUP BY must not change any of the
304
+ -- long-standing behaviour.
305
+ select count(*) as c from hn having count(*) > 5;
306
+ → []
307
+
308
+ select count(*) as c from hn having count(*) > 1;
309
+ → [{"c":3}]
310
+
311
+ select grp, count(*) as c from hn group by grp having grp = 'x';
312
+ → [{"grp":"x","c":2}]
313
+
314
+ select count(*) as c from hn where grp = 'x' having count(*) > 1;
315
+ → [{"c":2}]
316
+
317
+ drop table hn;
318
+ drop table hnempty;
@@ -0,0 +1,16 @@
1
+ -- adapted from SQLite test/notnull2.test
2
+ -- IS NULL / IS NOT NULL evaluated under an aggregate over an empty NOT NULL
3
+ -- table. SQLite allows a bare column beside an aggregate without GROUP BY (its
4
+ -- "bare aggregate" mode, where the non-aggregate columns yield NULL on empty
5
+ -- input). Quereus rejects it by design: an ungrouped aggregate query has one
6
+ -- implicit group, which carries no base-table column, so `a` here is exactly as
7
+ -- uncovered as it would be under a GROUP BY that omits it -- and gets the same
8
+ -- message. A select-list item that references no column at all IS accepted
9
+ -- beside an aggregate; see 25.5. `a is null` is not one of those.
10
+
11
+ create table ag_t (a integer primary key, b text);
12
+
13
+ select a is null as a_is_null, a is not null as a_is_not_null, count(*) as n from ag_t;
14
+ -- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
15
+
16
+ drop table ag_t;
@@ -0,0 +1,55 @@
1
+ -- 25.4-groupby-fd-constant-empty.sqllogic
2
+ -- Regression: ruleGroupByFdSimplification must never drop *every* GROUP BY
3
+ -- column. When all group columns are equality-pinned to constants
4
+ -- (`where a = 0 and k = 6`), FD propagation gives each an empty-determinant FD
5
+ -- (`{} -> col`), minimalCover drains the cover, and the rule used to rebuild the
6
+ -- aggregate with an empty GROUP BY (a scalar aggregate). A scalar aggregate
7
+ -- emits one all-NULL `count=0` row over an empty input; a grouped query must
8
+ -- emit ZERO rows. Target: rule-groupby-fd-simplification.ts.
9
+
10
+ create table t (id integer primary key, a integer, b integer, k integer);
11
+ insert into t values (2, 3, 4, 2), (3, 7, 1, 9);
12
+
13
+ -- Multi-column, constant-pinned, EMPTY match -> [] (the regression).
14
+ -- Pre-fix this returned [{"a":null,"k":null,"c":0,"s":null}].
15
+ select a, k, count(*) as c, sum(b) as s from t where a = 0 and k = 6 group by a, k;
16
+ → []
17
+
18
+ -- Multi-column, constant-pinned, NON-EMPTY match -> exactly one group row.
19
+ -- Row id=3 (a=7, b=1, k=9) is the only match. Confirms the bail leaves the
20
+ -- non-empty result correct.
21
+ select a, k, count(*) as c, sum(b) as s from t where a = 7 and k = 9 group by a, k;
22
+ → [{"a":7,"k":9,"c":1,"s":1}]
23
+
24
+ -- Single-column control, EMPTY match -> [] (must stay correct; rule never fires
25
+ -- for a one-column GROUP BY because of the `groupBy.length <= 1` early return).
26
+ select k, count(*) as c, sum(a) as s from t where k = 6 group by k;
27
+ → []
28
+
29
+ -- Mixed: one constant-pinned column (`a`, dropped via the `{} -> a` FD and
30
+ -- re-emitted as MIN(a)) plus one free column (`b`, kept as the surviving group
31
+ -- key). Confirmed by plan dump to rewrite to `group by b -> min(a), count(*)`.
32
+ -- Over an EMPTY match (`a = 0` matches no row) the surviving key still gates row
33
+ -- production, so the result is zero rows — the partial-drop path must not
34
+ -- resurrect the spurious-row bug.
35
+ select a, b, count(*) as c from t where a = 0 group by a, b;
36
+ → []
37
+
38
+ drop table t;
39
+
40
+ -- Partial-drop coverage: the guard must only trigger when ALL grouping columns
41
+ -- would be dropped. Here `name` is functionally determined by the primary key
42
+ -- `id`, so the rule legitimately drops `name` (re-emitting MIN(name)) while
43
+ -- KEEPING `id` as the surviving group key.
44
+ create table u (id integer primary key, name text, dept text);
45
+ insert into u values (1, 'alice', 'eng'), (2, 'bob', 'sales');
46
+
47
+ select id, name, count(*) as c from u group by id, name order by id;
48
+ → [{"id":1,"name":"alice","c":1},{"id":2,"name":"bob","c":1}]
49
+
50
+ -- Same FD-simplifiable shape over an EMPTY match still yields zero rows: a
51
+ -- surviving key (`id`) gates row production, so no spurious row appears.
52
+ select id, name, count(*) as c from u where id = 99 group by id, name;
53
+ → []
54
+
55
+ drop table u;
@@ -0,0 +1,196 @@
1
+ -- =============================================================================
2
+ -- An ungrouped aggregate query (aggregates in the SELECT list, no GROUP BY) has
3
+ -- exactly ONE implicit group over all input rows. That group's row carries the
4
+ -- aggregate results and nothing else -- no base-table column.
5
+ --
6
+ -- So the rule the SELECT list is checked against is "does this item reference a
7
+ -- column of the query's input?", NOT "is this item an aggregate?":
8
+ --
9
+ -- * a column-free item -- a literal, an expression over literals, a call whose
10
+ -- arguments are column-free, a `case` over aggregates, a scalar subquery --
11
+ -- references nothing the implicit group lacks, and is ACCEPTED. That is
12
+ -- standard SQL and what SQLite and PostgreSQL do.
13
+ -- * a bare column reference is REJECTED, with the same message and source
14
+ -- position a GROUP BY query gets when it omits the column. Quereus
15
+ -- deliberately does not import SQLite's permissive "bare columns" rule,
16
+ -- which picks an arbitrary row of the group.
17
+ --
18
+ -- Regression: every accepted query below used to fail with "Cannot mix aggregate
19
+ -- and non-aggregate columns in SELECT list without GROUP BY", a blanket throw
20
+ -- that never asked whether the item named a column.
21
+ -- =============================================================================
22
+
23
+ create table uac (id integer primary key, a text, n integer);
24
+ insert into uac values (1, 'x', 10), (2, 'y', 20);
25
+
26
+ create table uacempty (id integer primary key, a text);
27
+
28
+ -- --- Accepted: column-free items beside an aggregate.
29
+
30
+ -- a string literal
31
+ select 'total' as label, count(*) as c from uac;
32
+ → [{"label":"total","c":2}]
33
+
34
+ -- an integer literal
35
+ select 1 as one, count(*) as c from uac;
36
+ → [{"one":1,"c":2}]
37
+
38
+ -- an expression over literals only
39
+ select 1 + 1 as two, count(*) as c from uac;
40
+ → [{"two":2,"c":2}]
41
+
42
+ -- a function call whose arguments are column-free
43
+ select abs(-1) as k, count(*) as c from uac;
44
+ → [{"k":1,"c":2}]
45
+
46
+ -- NULL is column-free too
47
+ select null as z, count(*) as c from uac;
48
+ → [{"z":null,"c":2}]
49
+
50
+ -- a cast over a literal
51
+ select cast(1 as text) as k, count(*) as c from uac;
52
+ → [{"k":"1","c":2}]
53
+
54
+ -- an IN list over literals
55
+ select 1 in (1, 2) as k, count(*) as c from uac;
56
+ → [{"k":true,"c":2}]
57
+
58
+ -- a COLLATE over a literal
59
+ select 'a' collate binary as k, count(*) as c from uac;
60
+ → [{"k":"a","c":2}]
61
+
62
+ -- more than one column-free item, and the aggregate not written first
63
+ select count(*) as c, 'a' as x, 'b' as y from uac;
64
+ → [{"c":2,"x":"a","y":"b"}]
65
+
66
+ -- several aggregates alongside
67
+ select 'summary' as label, count(*) as c, sum(n) as s, max(a) as m from uac;
68
+ → [{"label":"summary","c":2,"s":30,"m":"y"}]
69
+
70
+ -- --- Accepted: items that read the AGGREGATE results rather than input columns.
71
+
72
+ -- a `case` over an aggregate
73
+ select case when count(*) > 1 then 'many' else 'few' end as k, count(*) as c from uac;
74
+ → [{"k":"many","c":2}]
75
+
76
+ -- an arithmetic expression over an aggregate
77
+ select count(*) * 10 as k, count(*) as c from uac;
78
+ → [{"k":20,"c":2}]
79
+
80
+ -- --- Accepted: a scalar subquery is a relational subtree that resolves its own
81
+ -- --- scope, so it references no column of THIS query's input.
82
+
83
+ select (select count(*) from uac) as sub, count(*) as c from uac;
84
+ → [{"sub":2,"c":2}]
85
+
86
+ -- a correlated-looking subquery that is in fact uncorrelated
87
+ select (select max(n) from uac) as sub, sum(n) as s from uac;
88
+ → [{"sub":20,"s":30}]
89
+
90
+ -- ...but a GENUINELY correlated subquery, one that reads an ungrouped column of
91
+ -- THIS query, is rejected. The select-list walk stops at every relational child,
92
+ -- so it does not catch this; the finished-plan check (assertGroupedPlanCoverage)
93
+ -- is the one that does, and it reports the same message. This is the seam between
94
+ -- "the walk skipped it" and "the item is truly column-free", and the two must not
95
+ -- be confused.
96
+ select (select count(*) from uac t where t.a = uac.a) as sub, count(*) as c from uac;
97
+ -- error: Column 'uac.a' must appear in the GROUP BY clause or be used in an aggregate function
98
+
99
+ select (select count(*) from uac t where t.n > uac.n) as sub, count(*) as c from uac;
100
+ -- error: Column 'uac.n' must appear in the GROUP BY clause or be used in an aggregate function
101
+
102
+ -- --- KNOWN DIVERGENCE: a reference to an ENCLOSING query's column is constant
103
+ -- --- with respect to this query's implicit group, so it should be accepted here
104
+ -- --- exactly as it is in `having` (see 25.2) and in `where`. It is not: the
105
+ -- --- select-list walk flags any column reference its coverage set lacks, with no
106
+ -- --- notion of which query the reference belongs to, so an outer reference is
107
+ -- --- rejected as though it were an uncovered column of this query. SQLite accepts
108
+ -- --- both queries below (the first yields `x`, `y`). Tracked as
109
+ -- --- backlog/bug-outer-column-rejected-in-aggregate-select-list; these pins flip
110
+ -- --- from `-- error:` to result rows when it lands. Not a regression -- the old
111
+ -- --- blanket mixing throw rejected the ungrouped form too, and the GROUPED form
112
+ -- --- (second query) has always been rejected.
113
+
114
+ select a from uac where exists (select uac.a, count(*) from uac t);
115
+ -- error: Column 'uac.a' must appear in the GROUP BY clause or be used in an aggregate function
116
+
117
+ select a from uac where exists (select uac.a, count(*) from uac t group by t.a);
118
+ -- error: Column 'uac.a' must appear in the GROUP BY clause or be used in an aggregate function
119
+
120
+ -- --- Accepted: the column-free item survives the clauses that sit above the
121
+ -- --- aggregation.
122
+
123
+ select distinct 'k' as label, count(*) as c from uac;
124
+ → [{"label":"k","c":2}]
125
+
126
+ select 'k' as label, count(*) as c from uac limit 1;
127
+ → [{"label":"k","c":2}]
128
+
129
+ select 'k' as label, count(*) as c from uac limit 0;
130
+ → []
131
+
132
+ select 'k' as label, count(*) as c from uac order by count(*);
133
+ → [{"label":"k","c":2}]
134
+
135
+ select 'k' as label, count(*) as c from uac having count(*) > 1;
136
+ → [{"label":"k","c":2}]
137
+
138
+ select 'k' as label, count(*) as c from uac having count(*) > 5;
139
+ → []
140
+
141
+ -- --- Accepted: over an empty table the implicit group still exists, so the
142
+ -- --- column-free item is emitted beside a zero count.
143
+
144
+ select 'total' as label, count(*) as c from uacempty;
145
+ → [{"label":"total","c":0}]
146
+
147
+ -- --- Accepted: nested spellings, where another ProjectNode wraps the query.
148
+
149
+ select * from (select 'k' as label, count(*) as c from uac);
150
+ → [{"label":"k","c":2}]
151
+
152
+ -- ...and as an arm of a compound select.
153
+ select 'k' as label, count(*) as c from uac union all select 'j', count(*) from uac;
154
+ → [{"label":"k","c":2},{"label":"j","c":2}]
155
+
156
+ -- --- REJECTED: a bare column reference. This is the distinction the check makes,
157
+ -- --- and it must keep failing -- with the GROUP BY coverage message and the
158
+ -- --- offending column's own source position, not a generic mixing complaint.
159
+
160
+ select a, count(*) as c from uac;
161
+ -- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
162
+
163
+ -- the column need not be written first
164
+ select count(*) as c, a from uac;
165
+ -- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
166
+
167
+ -- a column buried inside an otherwise column-free expression is still a column
168
+ select 'p' || a as k, count(*) as c from uac;
169
+ -- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
170
+
171
+ -- ...including under a function call
172
+ select length(a) as k, count(*) as c from uac;
173
+ -- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
174
+
175
+ -- ...and inside a `case`
176
+ select case when n > 1 then 'big' else 'small' end as k, count(*) as c from uac;
177
+ -- error: Column 'n' must appear in the GROUP BY clause or be used in an aggregate function
178
+
179
+ -- a qualified spelling is the same column (the message echoes the spelling the
180
+ -- user wrote, so it names `uac.a` here)
181
+ select uac.a, count(*) as c from uac;
182
+ -- error: Column 'uac.a' must appear in the GROUP BY clause or be used in an aggregate function
183
+
184
+ -- `select *` beside an aggregate expands to bare columns and is rejected on the
185
+ -- first of them
186
+ select *, count(*) as c from uac;
187
+ -- error: Column 'id' must appear in the GROUP BY clause or be used in an aggregate function
188
+
189
+ -- --- Non-regression: adding the GROUP BY that covers the column accepts it, and
190
+ -- --- the column-free item rides along unchanged.
191
+
192
+ select 'k' as label, a, count(*) as c from uac group by a order by a;
193
+ → [{"label":"k","a":"x","c":1},{"label":"k","a":"y","c":1}]
194
+
195
+ drop table uac;
196
+ drop table uacempty;