@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,134 @@
1
+ -- filter-lost-under-index-order.sqllogic - a WHERE conjunct must survive ORDER BY absorption
2
+ --
3
+ -- Regression guard for `bug-filter-conjunct-lost-under-index-order`. When an
4
+ -- ORDER BY is satisfied by the table's own primary-key walk, `rule-grow-retrieve`
5
+ -- absorbs the Sort and commits the Retrieve to an index-style access plan. From
6
+ -- that point `Retrieve.source` is no longer read at physicalization — so a
7
+ -- predicate that `rule-predicate-pushdown` writes into it is silently discarded
8
+ -- and the query returns EVERY row. The sub-select conjunct is what forces the
9
+ -- residual predicate above the Retrieve where pushdown can re-attack it.
10
+ --
11
+ -- Invariant pinned here: for each shape, the `order by` variants return the same
12
+ -- row set as the same query with no `order by`.
13
+
14
+ create table o (id integer primary key, flag integer);
15
+ insert into o values (1, 1), (2, 1), (3, 0);
16
+
17
+ -- =============================================================================
18
+ -- Scalar sub-select conjunct + a column comparison the module does not handle.
19
+ -- All three ordering variants must agree.
20
+ -- =============================================================================
21
+
22
+ select id from o where flag = 0 and (select max(id) from o o2) > 0;
23
+ → [{"id":3}]
24
+
25
+ select id from o where flag = 0 and (select max(id) from o o2) > 0 order by id;
26
+ → [{"id":3}]
27
+
28
+ select id from o where flag = 0 and (select max(id) from o o2) > 0 order by id desc;
29
+ → [{"id":3}]
30
+
31
+ -- The filtered column in the select list: a different plan shape (the Project no
32
+ -- longer prunes `flag`), same requirement.
33
+
34
+ select id, flag from o where flag = 0 and (select max(id) from o o2) > 0;
35
+ → [{"id":3,"flag":0}]
36
+
37
+ select id, flag from o where flag = 0 and (select max(id) from o o2) > 0 order by id;
38
+ → [{"id":3,"flag":0}]
39
+
40
+ select id, flag from o where flag = 0 and (select max(id) from o o2) > 0 order by id desc;
41
+ → [{"id":3,"flag":0}]
42
+
43
+ -- Written the other way round: the sub-select conjunct first.
44
+
45
+ select id from o where (select max(id) from o o2) > 0 and flag = 0 order by id;
46
+ → [{"id":3}]
47
+
48
+ -- =============================================================================
49
+ -- EXISTS as the sub-select conjunct — same mechanism, different subquery node.
50
+ -- =============================================================================
51
+
52
+ select id from o where flag = 0 and exists (select 1 from o o2 where o2.id > 0);
53
+ → [{"id":3}]
54
+
55
+ select id from o where flag = 0 and exists (select 1 from o o2 where o2.id > 0) order by id;
56
+ → [{"id":3}]
57
+
58
+ select id from o where flag = 0 and exists (select 1 from o o2 where o2.id > 0) order by id desc;
59
+ → [{"id":3}]
60
+
61
+ -- A conjunct that keeps more than one row, so a dropped predicate cannot be
62
+ -- mistaken for a correct single-row answer.
63
+
64
+ select id from o where flag = 1 and (select max(id) from o o2) > 0 order by id;
65
+ → [{"id":1},{"id":2}]
66
+
67
+ select id from o where flag = 1 and (select max(id) from o o2) > 0 order by id desc;
68
+ → [{"id":2},{"id":1}]
69
+
70
+ drop table o;
71
+
72
+ -- =============================================================================
73
+ -- Three-conjunct shape: two pure predicates plus a sub-select. This one loses
74
+ -- the pushed conjunct even when the filtered column IS selected.
75
+ -- k = (id-1) % 3, so k = 2 holds for ids {3,6,9,12}; v % 5 = 2 for ids {2,7,12}.
76
+ -- =============================================================================
77
+
78
+ create table t (id integer primary key, k integer, v integer);
79
+ insert into t values
80
+ (1, 0, 1), (2, 1, 2), (3, 2, 3), (4, 0, 4), (5, 1, 5), (6, 2, 6),
81
+ (7, 0, 7), (8, 1, 8), (9, 2, 9), (10, 0, 10), (11, 1, 11), (12, 2, 12);
82
+
83
+ select id, k from t where k = 2 and v % 5 = 2 and (select count(*) from t t2) = 12;
84
+ → [{"id":12,"k":2}]
85
+
86
+ select id, k from t where k = 2 and v % 5 = 2 and (select count(*) from t t2) = 12 order by id;
87
+ → [{"id":12,"k":2}]
88
+
89
+ select id, k from t where k = 2 and v % 5 = 2 and (select count(*) from t t2) = 12 order by id desc;
90
+ → [{"id":12,"k":2}]
91
+
92
+ select id from t where (select count(*) from t t2) = 12 and k = 2 and v % 5 = 2 order by id;
93
+ → [{"id":12}]
94
+
95
+ -- Only the pure conjunct that the module cannot claim, plus the sub-select:
96
+ -- multiple surviving rows, ascending order absorbed by the primary-key walk.
97
+
98
+ select id from t where k = 2 and (select count(*) from t t2) = 12 order by id;
99
+ → [{"id":3},{"id":6},{"id":9},{"id":12}]
100
+
101
+ select id from t where k = 2 and (select count(*) from t t2) = 12 order by id desc;
102
+ → [{"id":12},{"id":9},{"id":6},{"id":3}]
103
+
104
+ -- LIMIT on top of the absorbed order. LimitOffset is the other operation
105
+ -- grow-retrieve can translate into an index-style context, so it re-probes the
106
+ -- already-committed access plan; the conjunct must survive that too.
107
+
108
+ select id from t where k = 2 and (select count(*) from t t2) = 12 order by id limit 2;
109
+ → [{"id":3},{"id":6}]
110
+
111
+ select id from t where k = 2 and (select count(*) from t t2) = 12 order by id limit 2 offset 1;
112
+ → [{"id":6},{"id":9}]
113
+
114
+ drop table t;
115
+
116
+ -- =============================================================================
117
+ -- The mutation planner walks the same Retrieve/access-path rules, so a dropped
118
+ -- conjunct there deletes or updates rows the WHERE clause excluded.
119
+ -- =============================================================================
120
+
121
+ create table m (id integer primary key, flag integer);
122
+ insert into m values (1, 1), (2, 1), (3, 0), (4, 0);
123
+
124
+ delete from m where flag = 0 and (select max(id) from m m2) > 0;
125
+
126
+ select id, flag from m order by id;
127
+ → [{"id":1,"flag":1},{"id":2,"flag":1}]
128
+
129
+ update m set flag = 9 where flag = 1 and (select max(id) from m m2) > 0;
130
+
131
+ select id, flag from m order by id;
132
+ → [{"id":1,"flag":9},{"id":2,"flag":9}]
133
+
134
+ drop table m;
@@ -0,0 +1,178 @@
1
+ -- 07.7.6-correlated-predicate-scope.sqllogic - a subquery's predicate must not
2
+ -- constrain the outer relation
3
+ --
4
+ -- Regression guard for `bug-correlated-predicate-hoisted-onto-outer`. When an
5
+ -- ORDER BY is satisfied by the outer table's primary-key walk, `rule-grow-retrieve`
6
+ -- takes the `trySortAbsorbViaIndexOrdering` path, which sweeps constraints out of a
7
+ -- whole subtree rather than out of one Filter's own predicate. A correlated subquery
8
+ -- body hangs off a scalar predicate, so that subtree contains the *inner* comparison
9
+ -- (`t.s = a.i`). Attributing it to the outer table `a` turned it into an unhandled
10
+ -- constraint, then into a residual predicate, and finally into a Filter reading
11
+ -- column `s` placed over the scan of `a` — which has no such column. The failure
12
+ -- surfaced as "No row context found for column s".
13
+ --
14
+ -- The correlated conjunct only survives inside the subquery when the comparison is
15
+ -- cross-type: with matching types (`t.id = a.i`) the decorrelation rule rewrites the
16
+ -- EXISTS into a semi join and there is nothing left inside a subquery to mis-attribute.
17
+ -- Both shapes are covered below so the decorrelating path stays exercised too.
18
+ --
19
+ -- Invariant pinned here (OPT-025): for each shape, the `order by` variants return the
20
+ -- same row set as the same query with no `order by`.
21
+
22
+ create table a (id integer primary key, i integer);
23
+ create table t (id integer primary key, s text);
24
+ insert into a values (1, 1), (2, 2), (3, 3);
25
+ insert into t values (1, '1'), (2, '2');
26
+
27
+ -- =============================================================================
28
+ -- EXISTS with a cross-type correlated comparison — the original repro.
29
+ -- =============================================================================
30
+
31
+ select a.id from a where exists (select 1 from t where t.s = a.i);
32
+ → [{"id":1},{"id":2}]
33
+
34
+ select a.id from a where exists (select 1 from t where t.s = a.i) order by a.id;
35
+ → [{"id":1},{"id":2}]
36
+
37
+ select a.id from a where exists (select 1 from t where t.s = a.i) order by a.id desc;
38
+ → [{"id":2},{"id":1}]
39
+
40
+ -- The correlated column in the select list: the Project no longer prunes `i`,
41
+ -- a different plan shape with the same requirement.
42
+
43
+ select a.id, a.i from a where exists (select 1 from t where t.s = a.i) order by a.id;
44
+ → [{"id":1,"i":1},{"id":2,"i":2}]
45
+
46
+ -- Written with the operands the other way round.
47
+
48
+ select a.id from a where exists (select 1 from t where a.i = t.s) order by a.id;
49
+ → [{"id":1},{"id":2}]
50
+
51
+ -- =============================================================================
52
+ -- NOT EXISTS over the same shape. Hoisting the inner predicate onto the outer
53
+ -- scan here yields a WRONG ANSWER rather than an error, so a row-set check is
54
+ -- the only thing that catches it.
55
+ -- =============================================================================
56
+
57
+ select a.id from a where not exists (select 1 from t where t.s = a.i);
58
+ → [{"id":3}]
59
+
60
+ select a.id from a where not exists (select 1 from t where t.s = a.i) order by a.id;
61
+ → [{"id":3}]
62
+
63
+ select a.id from a where not exists (select 1 from t where t.s = a.i) order by a.id desc;
64
+ → [{"id":3}]
65
+
66
+ -- =============================================================================
67
+ -- IN over a correlated subquery whose inner predicate is cross-type.
68
+ -- =============================================================================
69
+
70
+ select a.id from a where a.i in (select t.id from t where t.s = a.i);
71
+ → [{"id":1},{"id":2}]
72
+
73
+ select a.id from a where a.i in (select t.id from t where t.s = a.i) order by a.id;
74
+ → [{"id":1},{"id":2}]
75
+
76
+ select a.id from a where a.i in (select t.id from t where t.s = a.i) order by a.id desc;
77
+ → [{"id":2},{"id":1}]
78
+
79
+ -- =============================================================================
80
+ -- Same-type correlated predicate: the decorrelation rule turns this into a semi
81
+ -- join, so nothing is left inside a subquery. Kept so that path stays covered.
82
+ -- =============================================================================
83
+
84
+ select a.id from a where exists (select 1 from t where t.id = a.i);
85
+ → [{"id":1},{"id":2}]
86
+
87
+ select a.id from a where exists (select 1 from t where t.id = a.i) order by a.id;
88
+ → [{"id":1},{"id":2}]
89
+
90
+ select a.id from a where exists (select 1 from t where t.id = a.i) order by a.id desc;
91
+ → [{"id":2},{"id":1}]
92
+
93
+ select a.id from a where not exists (select 1 from t where t.id = a.i) order by a.id;
94
+ → [{"id":3}]
95
+
96
+ -- =============================================================================
97
+ -- An outer conjunct alongside the correlated subquery: the outer predicate is
98
+ -- genuinely a constraint on `a` and must still be applied, while the inner one
99
+ -- must still be ignored.
100
+ -- =============================================================================
101
+
102
+ select a.id from a where a.id > 1 and exists (select 1 from t where t.s = a.i) order by a.id;
103
+ → [{"id":2}]
104
+
105
+ select a.id from a where a.id > 1 and not exists (select 1 from t where t.s = a.i) order by a.id;
106
+ → [{"id":3}]
107
+
108
+ -- =============================================================================
109
+ -- An OUTER column compared to a CONSTANT inside the subquery body. This is the
110
+ -- shape the `correlated` guard in computeCoveredKeysForConstraints cannot catch:
111
+ -- the value side is a literal, so the constraint looks like an ordinary covering
112
+ -- equality on `a`. Only the scope gate keeps it inside the subquery. Under
113
+ -- NOT EXISTS the hoisted copy silently drops every row.
114
+ -- =============================================================================
115
+
116
+ select a.id from a where not exists (select 1 from t where a.i = 2);
117
+ → [{"id":1},{"id":3}]
118
+
119
+ select a.id from a where not exists (select 1 from t where a.i = 2) order by a.id;
120
+ → [{"id":1},{"id":3}]
121
+
122
+ select a.id from a where not exists (select 1 from t where a.i = 2) order by a.id desc;
123
+ → [{"id":3},{"id":1}]
124
+
125
+ select a.id from a where exists (select 1 from t where a.i = 2) order by a.id;
126
+ → [{"id":2}]
127
+
128
+ -- Mixed with a genuinely correlated conjunct, so the subquery cannot be reduced
129
+ -- to an outer-only test.
130
+
131
+ select a.id from a where not exists (select 1 from t where t.s = a.i and a.i = 2) order by a.id;
132
+ → [{"id":1},{"id":3}]
133
+
134
+ select a.id from a where exists (select 1 from t where t.s = a.i and a.i = 2) order by a.id;
135
+ → [{"id":2}]
136
+
137
+ -- =============================================================================
138
+ -- A self-referencing subquery over the SAME table as the outer relation. The
139
+ -- inner scan is a distinct TableReferenceNode with its own attribute ids, so
140
+ -- `a2.id = 2` never matched the outer instance even before the scope gate — these
141
+ -- pass pre-fix. Kept as cheap coverage that the gate did not break the self-
142
+ -- reference shape, not as a regression guard.
143
+ -- =============================================================================
144
+
145
+ select a.id from a where exists (select 1 from a a2 where a2.id = 2) order by a.id;
146
+ → [{"id":1},{"id":2},{"id":3}]
147
+
148
+ select a.id from a where not exists (select 1 from a a2 where a2.id = 99) order by a.id;
149
+ → [{"id":1},{"id":2},{"id":3}]
150
+
151
+ select a.id from a where exists (select 1 from a a2 where a2.id = a.i + 1) order by a.id;
152
+ → [{"id":1},{"id":2}]
153
+
154
+ drop table a;
155
+ drop table t;
156
+
157
+ -- =============================================================================
158
+ -- The mutation planner walks the same Retrieve/access-path rules, so the same
159
+ -- mis-attribution there would delete or update the wrong rows.
160
+ -- =============================================================================
161
+
162
+ create table m (id integer primary key, i integer);
163
+ create table n (id integer primary key, s text);
164
+ insert into m values (1, 1), (2, 2), (3, 3);
165
+ insert into n values (1, '1'), (2, '2');
166
+
167
+ delete from m where not exists (select 1 from n where n.s = m.i);
168
+
169
+ select id from m order by id;
170
+ → [{"id":1},{"id":2}]
171
+
172
+ update m set i = 9 where exists (select 1 from n where n.s = m.i and n.id = 1);
173
+
174
+ select id, i from m order by id;
175
+ → [{"id":1,"i":9},{"id":2,"i":2}]
176
+
177
+ drop table m;
178
+ drop table n;
@@ -0,0 +1,137 @@
1
+ -- 07.7.7-join-source-scope-shadowing.sqllogic - an inner join's own sources must
2
+ -- shadow a same-named source in the enclosing query
3
+ --
4
+ -- Second symptom of `bug-cte-reference-as-second-join-source-fails-at-runtime`, with no
5
+ -- CTE involved and — worse — no error: it silently returned wrong rows.
6
+ --
7
+ -- A join combines its two peer source scopes with MultiScope (first match wins). Each
8
+ -- source scope used to fall back to the *enclosing* query's scope, so when MultiScope
9
+ -- asked the LEFT peer about a name the left peer did not own, it forwarded the question
10
+ -- outward and answered from there instead of letting the RIGHT peer answer. When the
11
+ -- right peer's alias also names an outer source, the inner reference bound to the OUTER
12
+ -- one — turning an uncorrelated subquery into a correlated one.
13
+ --
14
+ -- Fix: a FROM source's scope holds only its own columns; the enclosing-query fallback is
15
+ -- composed once by the consumer (ShadowScope), after both peers have been consulted.
16
+ --
17
+ -- Invariant pinned here: the subquery below is uncorrelated (its `x` is its own `t1`), so
18
+ -- `n` is the same constant on every outer row. Pre-fix it returned 3, 3, 0.
19
+ --
20
+ -- The second half of the file pins the other side of the same invariant: peers-first is
21
+ -- not peers-only. An ON condition must still reach the enclosing query for a correlated
22
+ -- column or a bind parameter — the fallback moved one level later, it did not go away.
23
+
24
+ create table t1 (id integer primary key, v integer);
25
+ insert into t1 values (1, 10), (2, 20), (3, 30);
26
+
27
+ create table t2 (id integer primary key, v integer);
28
+ insert into t2 values (1, 100), (2, 200);
29
+
30
+ -- =============================================================================
31
+ -- Inner join's RIGHT peer aliased the same as an outer source. `x.id` inside the
32
+ -- subquery must be the inner `t1 as x`, giving 2 matches on every outer row.
33
+ -- =============================================================================
34
+
35
+ select x.id, (select count(*) from t2 join t1 as x on x.id = t2.id) as n
36
+ from t1 as x order by x.id;
37
+ → [{"id":1,"n":2},{"id":2,"n":2},{"id":3,"n":2}]
38
+
39
+ -- Operand-swapped condition — `x.id` is looked up second rather than first.
40
+
41
+ select x.id, (select count(*) from t2 join t1 as x on t2.id = x.id) as n
42
+ from t1 as x order by x.id;
43
+ → [{"id":1,"n":2},{"id":2,"n":2},{"id":3,"n":2}]
44
+
45
+ -- Non-key join column, so the join is not answered by a primary-key seek.
46
+
47
+ select x.id, (select count(*) from t2 join t1 as x on x.v = t2.v) as n
48
+ from t1 as x order by x.id;
49
+ → [{"id":1,"n":0},{"id":2,"n":0},{"id":3,"n":0}]
50
+
51
+ -- =============================================================================
52
+ -- Same shape with the inner LEFT peer an inline subquery source, which builds its
53
+ -- scope on a separate code path (the `subquerySource` branch of buildFrom).
54
+ -- =============================================================================
55
+
56
+ select x.id, (select count(*) from (select id from t2) s join t1 as x on x.id = s.id) as n
57
+ from t1 as x order by x.id;
58
+ → [{"id":1,"n":2},{"id":2,"n":2},{"id":3,"n":2}]
59
+
60
+ -- The inline subquery on the RIGHT instead: the outer `s` must not capture `s.id`.
61
+
62
+ select s.id, (select count(*) from t1 as x join (select id from t2) s on x.id = s.id) as n
63
+ from t1 as s order by s.id;
64
+ → [{"id":1,"n":2},{"id":2,"n":2},{"id":3,"n":2}]
65
+
66
+ -- =============================================================================
67
+ -- A genuinely correlated subquery over the same alias names still correlates —
68
+ -- the fix must not sever the enclosing-scope fallback, only reorder it after the
69
+ -- join's own peers. `outer_t.id` is not a name either inner peer owns.
70
+ -- =============================================================================
71
+
72
+ select outer_t.id,
73
+ (select count(*) from t2 join t1 as x on x.id = t2.id where x.id = outer_t.id) as n
74
+ from t1 as outer_t order by outer_t.id;
75
+ → [{"id":1,"n":1},{"id":2,"n":1},{"id":3,"n":0}]
76
+
77
+ -- LATERAL still sees the left peer's columns from the right peer's body.
78
+
79
+ select l.id, r.doubled from t1 as l
80
+ cross join lateral (select l.v * 2 as doubled) as r
81
+ order by l.id;
82
+ → [{"id":1,"doubled":20},{"id":2,"doubled":40},{"id":3,"doubled":60}]
83
+
84
+ -- =============================================================================
85
+ -- Reaching PAST both peers from an ON condition. Own-only peer scopes mean the
86
+ -- MultiScope of the two peers answers "no" for everything the join does not own,
87
+ -- so the ON condition's own context has to carry the enclosing-query fallback
88
+ -- itself (ShadowScope([MultiScope([left, right]), outerScope]) in buildJoin).
89
+ -- Without it nothing outside the join resolves in an ON clause at all.
90
+ -- =============================================================================
91
+
92
+ -- Qualified correlated outer column.
93
+
94
+ select o.id, (select count(*) from t2 join t1 as x on x.id = t2.id and x.id = o.id) as n
95
+ from t1 as o order by o.id;
96
+ → [{"id":1,"n":1},{"id":2,"n":1},{"id":3,"n":0}]
97
+
98
+ -- Unqualified correlated outer column, owned by neither peer. When both peers
99
+ -- chained to the enclosing scope, BOTH answered with the same outer symbol and
100
+ -- MultiScope called it "ambiguous column name: ov".
101
+
102
+ select o.id, (select count(*) from t2 join t1 as x on x.id = t2.id and x.v = ov) as n
103
+ from (select id, v as ov from t1) as o order by o.id;
104
+ → [{"id":1,"n":1},{"id":2,"n":1},{"id":3,"n":0}]
105
+
106
+ -- A bind parameter in an ON condition — resolved by the ParameterScope in the
107
+ -- enclosing chain, not by either peer. Positional order still counts the ON
108
+ -- clause's `?` before the WHERE clause's.
109
+
110
+ -- params: [2, 30]
111
+ select x.id from t2 join t1 as x on x.id = t2.id and t2.id = ? where x.v <> ?
112
+ order by x.id;
113
+ → [{"id":2}]
114
+
115
+ -- A scalar subquery inside an ON condition, correlated to the join's own LEFT peer.
116
+
117
+ select t2.id as a, x.id as b from t2
118
+ join t1 as x on x.id = (select max(t1b.id) from t1 as t1b where t1b.id = t2.id)
119
+ order by t2.id;
120
+ → [{"a":1,"b":1},{"a":2,"b":2}]
121
+
122
+ -- Three-way join: the outer join's ON reaches past a peer that is itself a join.
123
+
124
+ select o.id, (select count(*) from t2 join t1 as x on x.id = t2.id
125
+ join t1 as y on y.id = x.id and y.id = o.id) as n
126
+ from t1 as o order by o.id;
127
+ → [{"id":1,"n":1},{"id":2,"n":1},{"id":3,"n":0}]
128
+
129
+ -- Ambiguity between the two peers is still ambiguity: the enclosing fallback sits
130
+ -- BEHIND the MultiScope, so it must not answer after MultiScope has said "ambiguous".
131
+ -- `v` is owned by both peers here, and also by the enclosing `o`.
132
+
133
+ select o.id, (select count(*) from t1 join t2 on v = 100) as n from t1 as o;
134
+ -- error: ambiguous column name: v
135
+
136
+ drop table t2;
137
+ drop table t1;
@@ -0,0 +1,165 @@
1
+ -- 07.7.8-correlated-ref-to-computed-column.sqllogic - a correlated sub-query may
2
+ -- reference a column its enclosing query COMPUTES
3
+ --
4
+ -- Regression guard for `bug-correlated-subquery-cannot-read-outer-computed-column`.
5
+ -- Two predicate-pushdown rules decide whether a Filter may slide below the node that
6
+ -- computes a column, and both used to answer by walking the predicate's SCALAR tree
7
+ -- only, stopping at any relational child. A correlated reference inside an `exists` /
8
+ -- `in` / scalar-sub-query operand lives in exactly that relational subtree, so neither
9
+ -- rule saw it: the dependency set came back empty, the push went ahead, and the
10
+ -- reference landed BELOW the node defining the attribute it reads. The failure
11
+ -- surfaced as "No row context found for column <c>".
12
+ --
13
+ -- Both rules now collect dependencies across sub-query operands as well (see
14
+ -- src/planner/analysis/predicate-dependencies.ts), so the Filter stays put.
15
+ --
16
+ -- Sections:
17
+ -- 1. Filter vs a Project that computes the column (rule-predicate-pushdown)
18
+ -- 2. HAVING conjunct vs an aggregate (rule-aggregate-predicate-pushdown)
19
+ -- Each section covers the shapes that used to fail AND the shapes that already
20
+ -- worked — the fix must not degrade into a blanket refusal to push.
21
+ --
22
+ -- Plan-shape guards for the same statements live in
23
+ -- test/optimizer/predicate-pushdown.spec.ts and
24
+ -- test/optimizer/rule-aggregate-predicate-pushdown.spec.ts.
25
+
26
+ -- =============================================================================
27
+ -- 1. Correlated reference to a computed projection column.
28
+ --
29
+ -- `d` is minted by the sub-select's Project. `side` has exactly one row, so
30
+ -- `exists (select 1 from side where <cond on d>)` is just `<cond on d>` evaluated
31
+ -- once per outer row — the row set discriminates on the value of `d`.
32
+ -- =============================================================================
33
+
34
+ create table gt (id integer primary key, x integer);
35
+ create table side (tag text primary key);
36
+ insert into gt values (1, 10), (2, 20), (3, 0), (4, -5);
37
+ insert into side values ('one');
38
+
39
+ -- The original repro: EXISTS body reads the computed `d`.
40
+
41
+ select id from (select id, x * 2 as d from gt) t where exists (select 1 from side where t.d > 0);
42
+ → [{"id":1},{"id":2}]
43
+
44
+ select id from (select id, x * 2 as d from gt) t where exists (select 1 from side where t.d > 0) order by id desc;
45
+ → [{"id":2},{"id":1}]
46
+
47
+ -- The scalar-sub-query form of the same thing: `max(t.d)` over `side`'s single row
48
+ -- is `t.d` itself.
49
+
50
+ select id from (select id, x * 2 as d from gt) t where (select max(t.d) from side) > 0;
51
+ → [{"id":1},{"id":2}]
52
+
53
+ -- NOT EXISTS over the same shape — the complement, so a silently-empty or
54
+ -- silently-full result set is caught too.
55
+
56
+ select id from (select id, x * 2 as d from gt) t where not exists (select 1 from side where t.d > 0);
57
+ → [{"id":3},{"id":4}]
58
+
59
+ -- The IN form: the correlated operand hangs off an `InNode`, which reports its own
60
+ -- node type and exposes the relation only through `getChildren()`. The collector
61
+ -- recognizes the relational child structurally, so no per-node-type list can rot.
62
+
63
+ select id from (select id, x * 2 as d from gt) t where 1 in (select 1 from side where t.d > 0);
64
+ → [{"id":1},{"id":2}]
65
+
66
+ -- Correlation buried two levels down: the operand's WHOLE subtree is scanned for
67
+ -- outward references, not merely its top level.
68
+
69
+ select id from (select id, x * 2 as d from gt) t
70
+ where exists (select 1 from side where exists (select 1 from side s2 where t.d > 0));
71
+ → [{"id":1},{"id":2}]
72
+
73
+ -- Shapes that already worked and must keep working.
74
+
75
+ select id from (select id, x from gt) t where exists (select 1 from side where t.x > 0);
76
+ → [{"id":1},{"id":2}]
77
+
78
+ select id from (select id, x * 2 as d from gt) t where t.d in (select 20 union select 40);
79
+ → [{"id":1},{"id":2}]
80
+
81
+ select id from (select id, x * 2 as d from gt) t where t.d > 0;
82
+ → [{"id":1},{"id":2}]
83
+
84
+ -- The discriminating pair for "not a blanket refusal": the same Project computes
85
+ -- `d` and passes `x` through. Correlating on `x` is still pushable (it exists below
86
+ -- the Project); correlating on `d` is not. Both must return the same rows here.
87
+
88
+ select id, d from (select id, x, x * 2 as d from gt) t where exists (select 1 from side where t.x > 0);
89
+ → [{"id":1,"d":20},{"id":2,"d":40}]
90
+
91
+ select id, d from (select id, x, x * 2 as d from gt) t where exists (select 1 from side where t.d > 0);
92
+ → [{"id":1,"d":20},{"id":2,"d":40}]
93
+
94
+ drop table gt;
95
+ drop table side;
96
+
97
+ -- =============================================================================
98
+ -- 2. Correlated reference inside a HAVING conjunct.
99
+ --
100
+ -- `splitConjuncts` cannot break an `or` (or a `case`) apart, so one conjunct can
101
+ -- mix a top-level reference to a pushable GROUP BY column with a correlated
102
+ -- sub-query. Pushing it below the aggregate strands the correlated reference.
103
+ --
104
+ -- Groups: g=-1 (4 rows), g=0 (1 row), g=1 (2 rows), g=2 (1 row).
105
+ -- `side` holds 1, 2, 3.
106
+ -- =============================================================================
107
+
108
+ create table t (id integer primary key, g integer, v integer);
109
+ create table side (n integer primary key);
110
+ insert into t values (1, 1, 10), (2, 1, 20), (3, 2, 30), (4, 0, 40),
111
+ (5, -1, 50), (6, -1, 60), (7, -1, 70), (8, -1, 80);
112
+ insert into side values (1), (2), (3);
113
+
114
+ -- Correlated on the GROUP BY column. g=-1 and g=0 fail both halves of the `or`.
115
+
116
+ select g, count(*) as c from t group by g
117
+ having g > 1 or exists (select 1 from side where side.n = g) order by g;
118
+ → [{"g":1,"c":2},{"g":2,"c":1}]
119
+
120
+ -- Correlated on the AGGREGATE output. g=-1 has 4 rows and 4 is not in `side`.
121
+
122
+ select g, count(*) as c from t group by g
123
+ having g > 1 or exists (select 1 from side where side.n = count(*)) order by g;
124
+ → [{"g":0,"c":1},{"g":1,"c":2},{"g":2,"c":1}]
125
+
126
+ -- The `case` form: one conjunct, correlation buried in a WHEN.
127
+
128
+ select g, count(*) as c from t group by g
129
+ having (case when exists (select 1 from side where side.n = g) then g else 0 end) > 0 order by g;
130
+ → [{"g":1,"c":2},{"g":2,"c":1}]
131
+
132
+ -- Shapes that already worked and must keep working.
133
+
134
+ select g, count(*) as c from t group by g having g > 0 order by g;
135
+ → [{"g":1,"c":2},{"g":2,"c":1}]
136
+
137
+ select g, count(*) as c from t group by g
138
+ having exists (select 1 from side where side.n = g) order by g;
139
+ → [{"g":1,"c":2},{"g":2,"c":1}]
140
+
141
+ -- `and` splits into two conjuncts: `g > 0` pushes on its own and the correlated
142
+ -- half stays above, where decorrelation turns it into a hash join.
143
+
144
+ select g, count(*) as c from t group by g
145
+ having g > 0 and (select max(side.n) from side where side.n = g) is not null order by g;
146
+ → [{"g":1,"c":2},{"g":2,"c":1}]
147
+
148
+ -- An UNCORRELATED sub-query alongside `g > 0`. `and` splits the two apart, so each
149
+ -- half is judged on its own and the `g > 0` half still has to behave.
150
+
151
+ select g, count(*) as c from t group by g
152
+ having g > 0 and exists (select 1 from side where side.n = 1) order by g;
153
+ → [{"g":1,"c":2},{"g":2,"c":1}]
154
+
155
+ -- The same uncorrelated sub-query joined by `or`, so it CANNOT be split apart: one
156
+ -- conjunct that both names a pushable GROUP BY column and carries a sub-query. The
157
+ -- refusal above is about the correlation, not about carrying a sub-query, so this one
158
+ -- must still push. `side` holds 1, so the `exists` is true and every group survives.
159
+
160
+ select g, count(*) as c from t group by g
161
+ having g > 0 or exists (select 1 from side where side.n = 1) order by g;
162
+ → [{"g":-1,"c":4},{"g":0,"c":1},{"g":1,"c":2},{"g":2,"c":1}]
163
+
164
+ drop table t;
165
+ drop table side;