@quereus/quereus 3.3.0 → 4.1.0

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 (900) hide show
  1. package/README.md +7 -0
  2. package/dist/src/common/datatype.d.ts +12 -0
  3. package/dist/src/common/datatype.d.ts.map +1 -1
  4. package/dist/src/common/datatype.js.map +1 -1
  5. package/dist/src/common/types.d.ts +24 -0
  6. package/dist/src/common/types.d.ts.map +1 -1
  7. package/dist/src/common/types.js.map +1 -1
  8. package/dist/src/core/database-assertions.d.ts +37 -9
  9. package/dist/src/core/database-assertions.d.ts.map +1 -1
  10. package/dist/src/core/database-assertions.js +62 -110
  11. package/dist/src/core/database-assertions.js.map +1 -1
  12. package/dist/src/core/database-events.d.ts +163 -0
  13. package/dist/src/core/database-events.d.ts.map +1 -1
  14. package/dist/src/core/database-events.js +235 -21
  15. package/dist/src/core/database-events.js.map +1 -1
  16. package/dist/src/core/database-external-changes.d.ts +28 -0
  17. package/dist/src/core/database-external-changes.d.ts.map +1 -0
  18. package/dist/src/core/database-external-changes.js +242 -0
  19. package/dist/src/core/database-external-changes.js.map +1 -0
  20. package/dist/src/core/database-internal.d.ts +50 -1
  21. package/dist/src/core/database-internal.d.ts.map +1 -1
  22. package/dist/src/core/database-materialized-views.d.ts +1253 -0
  23. package/dist/src/core/database-materialized-views.d.ts.map +1 -0
  24. package/dist/src/core/database-materialized-views.js +3064 -0
  25. package/dist/src/core/database-materialized-views.js.map +1 -0
  26. package/dist/src/core/database-options.d.ts +4 -0
  27. package/dist/src/core/database-options.d.ts.map +1 -1
  28. package/dist/src/core/database-options.js +10 -0
  29. package/dist/src/core/database-options.js.map +1 -1
  30. package/dist/src/core/database-transaction.d.ts +19 -3
  31. package/dist/src/core/database-transaction.d.ts.map +1 -1
  32. package/dist/src/core/database-transaction.js +30 -3
  33. package/dist/src/core/database-transaction.js.map +1 -1
  34. package/dist/src/core/database-watchers.d.ts +19 -0
  35. package/dist/src/core/database-watchers.d.ts.map +1 -1
  36. package/dist/src/core/database-watchers.js +63 -3
  37. package/dist/src/core/database-watchers.js.map +1 -1
  38. package/dist/src/core/database.d.ts +204 -11
  39. package/dist/src/core/database.d.ts.map +1 -1
  40. package/dist/src/core/database.js +493 -29
  41. package/dist/src/core/database.js.map +1 -1
  42. package/dist/src/core/derived-row-validator.d.ts +137 -0
  43. package/dist/src/core/derived-row-validator.d.ts.map +1 -0
  44. package/dist/src/core/derived-row-validator.js +314 -0
  45. package/dist/src/core/derived-row-validator.js.map +1 -0
  46. package/dist/src/core/statement.d.ts.map +1 -1
  47. package/dist/src/core/statement.js +30 -9
  48. package/dist/src/core/statement.js.map +1 -1
  49. package/dist/src/emit/ast-stringify.d.ts +135 -1
  50. package/dist/src/emit/ast-stringify.d.ts.map +1 -1
  51. package/dist/src/emit/ast-stringify.js +793 -118
  52. package/dist/src/emit/ast-stringify.js.map +1 -1
  53. package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
  54. package/dist/src/func/builtins/aggregate.js +11 -10
  55. package/dist/src/func/builtins/aggregate.js.map +1 -1
  56. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
  57. package/dist/src/func/builtins/builtin-window-functions.js +32 -0
  58. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
  59. package/dist/src/func/builtins/explain.d.ts +3 -0
  60. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  61. package/dist/src/func/builtins/explain.js +229 -0
  62. package/dist/src/func/builtins/explain.js.map +1 -1
  63. package/dist/src/func/builtins/index.d.ts.map +1 -1
  64. package/dist/src/func/builtins/index.js +10 -2
  65. package/dist/src/func/builtins/index.js.map +1 -1
  66. package/dist/src/func/builtins/json.d.ts.map +1 -1
  67. package/dist/src/func/builtins/json.js +3 -2
  68. package/dist/src/func/builtins/json.js.map +1 -1
  69. package/dist/src/func/builtins/mutation.d.ts +2 -0
  70. package/dist/src/func/builtins/mutation.d.ts.map +1 -0
  71. package/dist/src/func/builtins/mutation.js +53 -0
  72. package/dist/src/func/builtins/mutation.js.map +1 -0
  73. package/dist/src/func/builtins/schema.d.ts +2 -0
  74. package/dist/src/func/builtins/schema.d.ts.map +1 -1
  75. package/dist/src/func/builtins/schema.js +716 -27
  76. package/dist/src/func/builtins/schema.js.map +1 -1
  77. package/dist/src/func/builtins/string.js +1 -1
  78. package/dist/src/func/builtins/string.js.map +1 -1
  79. package/dist/src/func/registration.d.ts +13 -0
  80. package/dist/src/func/registration.d.ts.map +1 -1
  81. package/dist/src/func/registration.js +5 -0
  82. package/dist/src/func/registration.js.map +1 -1
  83. package/dist/src/index.d.ts +25 -6
  84. package/dist/src/index.d.ts.map +1 -1
  85. package/dist/src/index.js +27 -3
  86. package/dist/src/index.js.map +1 -1
  87. package/dist/src/parser/ast.d.ts +353 -21
  88. package/dist/src/parser/ast.d.ts.map +1 -1
  89. package/dist/src/parser/index.d.ts +14 -1
  90. package/dist/src/parser/index.d.ts.map +1 -1
  91. package/dist/src/parser/index.js +19 -0
  92. package/dist/src/parser/index.js.map +1 -1
  93. package/dist/src/parser/lexer.d.ts +9 -0
  94. package/dist/src/parser/lexer.d.ts.map +1 -1
  95. package/dist/src/parser/lexer.js +9 -0
  96. package/dist/src/parser/lexer.js.map +1 -1
  97. package/dist/src/parser/parser.d.ts +276 -7
  98. package/dist/src/parser/parser.d.ts.map +1 -1
  99. package/dist/src/parser/parser.js +1387 -469
  100. package/dist/src/parser/parser.js.map +1 -1
  101. package/dist/src/parser/visitor.d.ts.map +1 -1
  102. package/dist/src/parser/visitor.js +12 -8
  103. package/dist/src/parser/visitor.js.map +1 -1
  104. package/dist/src/planner/analysis/assertion-classifier.d.ts.map +1 -1
  105. package/dist/src/planner/analysis/assertion-classifier.js +4 -0
  106. package/dist/src/planner/analysis/assertion-classifier.js.map +1 -1
  107. package/dist/src/planner/analysis/assertion-hoist-cache.d.ts.map +1 -1
  108. package/dist/src/planner/analysis/assertion-hoist-cache.js +8 -4
  109. package/dist/src/planner/analysis/assertion-hoist-cache.js.map +1 -1
  110. package/dist/src/planner/analysis/authored-inverse.d.ts +22 -0
  111. package/dist/src/planner/analysis/authored-inverse.d.ts.map +1 -0
  112. package/dist/src/planner/analysis/authored-inverse.js +267 -0
  113. package/dist/src/planner/analysis/authored-inverse.js.map +1 -0
  114. package/dist/src/planner/analysis/change-scope.d.ts +34 -4
  115. package/dist/src/planner/analysis/change-scope.d.ts.map +1 -1
  116. package/dist/src/planner/analysis/change-scope.js +108 -7
  117. package/dist/src/planner/analysis/change-scope.js.map +1 -1
  118. package/dist/src/planner/analysis/check-extraction.d.ts +36 -2
  119. package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -1
  120. package/dist/src/planner/analysis/check-extraction.js +174 -46
  121. package/dist/src/planner/analysis/check-extraction.js.map +1 -1
  122. package/dist/src/planner/analysis/coarsened-key.d.ts +109 -0
  123. package/dist/src/planner/analysis/coarsened-key.d.ts.map +1 -0
  124. package/dist/src/planner/analysis/coarsened-key.js +228 -0
  125. package/dist/src/planner/analysis/coarsened-key.js.map +1 -0
  126. package/dist/src/planner/analysis/comparison-collation.d.ts +216 -0
  127. package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -0
  128. package/dist/src/planner/analysis/comparison-collation.js +341 -0
  129. package/dist/src/planner/analysis/comparison-collation.js.map +1 -0
  130. package/dist/src/planner/analysis/constraint-extractor.d.ts +3 -1
  131. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  132. package/dist/src/planner/analysis/constraint-extractor.js +192 -9
  133. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  134. package/dist/src/planner/analysis/coverage-prover.d.ts +321 -0
  135. package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -0
  136. package/dist/src/planner/analysis/coverage-prover.js +1038 -0
  137. package/dist/src/planner/analysis/coverage-prover.js.map +1 -0
  138. package/dist/src/planner/analysis/key-filter.d.ts +22 -0
  139. package/dist/src/planner/analysis/key-filter.d.ts.map +1 -0
  140. package/dist/src/planner/analysis/key-filter.js +105 -0
  141. package/dist/src/planner/analysis/key-filter.js.map +1 -0
  142. package/dist/src/planner/analysis/partial-unique-extraction.d.ts +36 -1
  143. package/dist/src/planner/analysis/partial-unique-extraction.d.ts.map +1 -1
  144. package/dist/src/planner/analysis/partial-unique-extraction.js +148 -22
  145. package/dist/src/planner/analysis/partial-unique-extraction.js.map +1 -1
  146. package/dist/src/planner/analysis/predicate-normalizer.d.ts.map +1 -1
  147. package/dist/src/planner/analysis/predicate-normalizer.js +30 -1
  148. package/dist/src/planner/analysis/predicate-normalizer.js.map +1 -1
  149. package/dist/src/planner/analysis/predicate-shape.d.ts +36 -1
  150. package/dist/src/planner/analysis/predicate-shape.d.ts.map +1 -1
  151. package/dist/src/planner/analysis/predicate-shape.js +51 -13
  152. package/dist/src/planner/analysis/predicate-shape.js.map +1 -1
  153. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +314 -0
  154. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -0
  155. package/dist/src/planner/analysis/query-rewrite-matcher.js +1081 -0
  156. package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -0
  157. package/dist/src/planner/analysis/scalar-invertibility.d.ts +92 -0
  158. package/dist/src/planner/analysis/scalar-invertibility.d.ts.map +1 -0
  159. package/dist/src/planner/analysis/scalar-invertibility.js +129 -0
  160. package/dist/src/planner/analysis/scalar-invertibility.js.map +1 -0
  161. package/dist/src/planner/analysis/update-lineage.d.ts +196 -0
  162. package/dist/src/planner/analysis/update-lineage.d.ts.map +1 -0
  163. package/dist/src/planner/analysis/update-lineage.js +322 -0
  164. package/dist/src/planner/analysis/update-lineage.js.map +1 -0
  165. package/dist/src/planner/analysis/view-complement.d.ts +42 -0
  166. package/dist/src/planner/analysis/view-complement.d.ts.map +1 -0
  167. package/dist/src/planner/analysis/view-complement.js +54 -0
  168. package/dist/src/planner/analysis/view-complement.js.map +1 -0
  169. package/dist/src/planner/building/alter-table.d.ts +1 -1
  170. package/dist/src/planner/building/alter-table.d.ts.map +1 -1
  171. package/dist/src/planner/building/alter-table.js +211 -2
  172. package/dist/src/planner/building/alter-table.js.map +1 -1
  173. package/dist/src/planner/building/block.d.ts.map +1 -1
  174. package/dist/src/planner/building/block.js +18 -1
  175. package/dist/src/planner/building/block.js.map +1 -1
  176. package/dist/src/planner/building/constraint-builder.d.ts +33 -5
  177. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  178. package/dist/src/planner/building/constraint-builder.js +63 -28
  179. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  180. package/dist/src/planner/building/create-view.d.ts +9 -0
  181. package/dist/src/planner/building/create-view.d.ts.map +1 -1
  182. package/dist/src/planner/building/create-view.js +41 -12
  183. package/dist/src/planner/building/create-view.js.map +1 -1
  184. package/dist/src/planner/building/ddl.d.ts.map +1 -1
  185. package/dist/src/planner/building/ddl.js +94 -0
  186. package/dist/src/planner/building/ddl.js.map +1 -1
  187. package/dist/src/planner/building/declare-schema.d.ts +1 -0
  188. package/dist/src/planner/building/declare-schema.d.ts.map +1 -1
  189. package/dist/src/planner/building/declare-schema.js +4 -1
  190. package/dist/src/planner/building/declare-schema.js.map +1 -1
  191. package/dist/src/planner/building/default-scope.d.ts +26 -0
  192. package/dist/src/planner/building/default-scope.d.ts.map +1 -0
  193. package/dist/src/planner/building/default-scope.js +41 -0
  194. package/dist/src/planner/building/default-scope.js.map +1 -0
  195. package/dist/src/planner/building/delete.d.ts +19 -1
  196. package/dist/src/planner/building/delete.d.ts.map +1 -1
  197. package/dist/src/planner/building/delete.js +109 -30
  198. package/dist/src/planner/building/delete.js.map +1 -1
  199. package/dist/src/planner/building/dml-target.d.ts +118 -0
  200. package/dist/src/planner/building/dml-target.d.ts.map +1 -0
  201. package/dist/src/planner/building/dml-target.js +282 -0
  202. package/dist/src/planner/building/dml-target.js.map +1 -0
  203. package/dist/src/planner/building/drop-index.d.ts.map +1 -1
  204. package/dist/src/planner/building/drop-index.js +4 -1
  205. package/dist/src/planner/building/drop-index.js.map +1 -1
  206. package/dist/src/planner/building/drop-view.d.ts.map +1 -1
  207. package/dist/src/planner/building/drop-view.js +4 -2
  208. package/dist/src/planner/building/drop-view.js.map +1 -1
  209. package/dist/src/planner/building/expression.d.ts.map +1 -1
  210. package/dist/src/planner/building/expression.js +60 -21
  211. package/dist/src/planner/building/expression.js.map +1 -1
  212. package/dist/src/planner/building/foreign-key-builder.d.ts +30 -0
  213. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
  214. package/dist/src/planner/building/foreign-key-builder.js +160 -129
  215. package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
  216. package/dist/src/planner/building/insert.d.ts +45 -2
  217. package/dist/src/planner/building/insert.d.ts.map +1 -1
  218. package/dist/src/planner/building/insert.js +257 -88
  219. package/dist/src/planner/building/insert.js.map +1 -1
  220. package/dist/src/planner/building/lens-auxiliary-access.d.ts +22 -0
  221. package/dist/src/planner/building/lens-auxiliary-access.d.ts.map +1 -0
  222. package/dist/src/planner/building/lens-auxiliary-access.js +132 -0
  223. package/dist/src/planner/building/lens-auxiliary-access.js.map +1 -0
  224. package/dist/src/planner/building/materialized-view.d.ts +16 -0
  225. package/dist/src/planner/building/materialized-view.d.ts.map +1 -0
  226. package/dist/src/planner/building/materialized-view.js +57 -0
  227. package/dist/src/planner/building/materialized-view.js.map +1 -0
  228. package/dist/src/planner/building/returning-star.d.ts +32 -0
  229. package/dist/src/planner/building/returning-star.d.ts.map +1 -0
  230. package/dist/src/planner/building/returning-star.js +45 -0
  231. package/dist/src/planner/building/returning-star.js.map +1 -0
  232. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  233. package/dist/src/planner/building/select-aggregates.js +47 -0
  234. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  235. package/dist/src/planner/building/select-compound.d.ts.map +1 -1
  236. package/dist/src/planner/building/select-compound.js +84 -11
  237. package/dist/src/planner/building/select-compound.js.map +1 -1
  238. package/dist/src/planner/building/select-context.d.ts +10 -2
  239. package/dist/src/planner/building/select-context.d.ts.map +1 -1
  240. package/dist/src/planner/building/select-context.js +7 -1
  241. package/dist/src/planner/building/select-context.js.map +1 -1
  242. package/dist/src/planner/building/select-modifiers.js +6 -0
  243. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  244. package/dist/src/planner/building/select-ordinal.d.ts +18 -0
  245. package/dist/src/planner/building/select-ordinal.d.ts.map +1 -1
  246. package/dist/src/planner/building/select-ordinal.js +30 -0
  247. package/dist/src/planner/building/select-ordinal.js.map +1 -1
  248. package/dist/src/planner/building/select-projections.d.ts +8 -2
  249. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  250. package/dist/src/planner/building/select-projections.js +26 -4
  251. package/dist/src/planner/building/select-projections.js.map +1 -1
  252. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  253. package/dist/src/planner/building/select-window.js +8 -5
  254. package/dist/src/planner/building/select-window.js.map +1 -1
  255. package/dist/src/planner/building/select.d.ts.map +1 -1
  256. package/dist/src/planner/building/select.js +164 -59
  257. package/dist/src/planner/building/select.js.map +1 -1
  258. package/dist/src/planner/building/set-object-tags.d.ts +7 -0
  259. package/dist/src/planner/building/set-object-tags.d.ts.map +1 -0
  260. package/dist/src/planner/building/set-object-tags.js +38 -0
  261. package/dist/src/planner/building/set-object-tags.js.map +1 -0
  262. package/dist/src/planner/building/tag-diagnostics.d.ts +27 -0
  263. package/dist/src/planner/building/tag-diagnostics.d.ts.map +1 -0
  264. package/dist/src/planner/building/tag-diagnostics.js +37 -0
  265. package/dist/src/planner/building/tag-diagnostics.js.map +1 -0
  266. package/dist/src/planner/building/update.d.ts +18 -1
  267. package/dist/src/planner/building/update.d.ts.map +1 -1
  268. package/dist/src/planner/building/update.js +134 -58
  269. package/dist/src/planner/building/update.js.map +1 -1
  270. package/dist/src/planner/building/view-mutation-builder.d.ts +15 -0
  271. package/dist/src/planner/building/view-mutation-builder.d.ts.map +1 -0
  272. package/dist/src/planner/building/view-mutation-builder.js +1158 -0
  273. package/dist/src/planner/building/view-mutation-builder.js.map +1 -0
  274. package/dist/src/planner/building/with.d.ts +11 -0
  275. package/dist/src/planner/building/with.d.ts.map +1 -1
  276. package/dist/src/planner/building/with.js +48 -10
  277. package/dist/src/planner/building/with.js.map +1 -1
  278. package/dist/src/planner/cost/index.d.ts +83 -0
  279. package/dist/src/planner/cost/index.d.ts.map +1 -1
  280. package/dist/src/planner/cost/index.js +114 -0
  281. package/dist/src/planner/cost/index.js.map +1 -1
  282. package/dist/src/planner/framework/characteristics.d.ts +38 -4
  283. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  284. package/dist/src/planner/framework/characteristics.js +50 -6
  285. package/dist/src/planner/framework/characteristics.js.map +1 -1
  286. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  287. package/dist/src/planner/framework/pass.js +2 -1
  288. package/dist/src/planner/framework/pass.js.map +1 -1
  289. package/dist/src/planner/framework/registry.d.ts +39 -1
  290. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  291. package/dist/src/planner/framework/registry.js +18 -2
  292. package/dist/src/planner/framework/registry.js.map +1 -1
  293. package/dist/src/planner/mutation/backward-body.d.ts +131 -0
  294. package/dist/src/planner/mutation/backward-body.d.ts.map +1 -0
  295. package/dist/src/planner/mutation/backward-body.js +135 -0
  296. package/dist/src/planner/mutation/backward-body.js.map +1 -0
  297. package/dist/src/planner/mutation/cte-flatten.d.ts +17 -0
  298. package/dist/src/planner/mutation/cte-flatten.d.ts.map +1 -0
  299. package/dist/src/planner/mutation/cte-flatten.js +364 -0
  300. package/dist/src/planner/mutation/cte-flatten.js.map +1 -0
  301. package/dist/src/planner/mutation/decomposition.d.ts +273 -0
  302. package/dist/src/planner/mutation/decomposition.d.ts.map +1 -0
  303. package/dist/src/planner/mutation/decomposition.js +1719 -0
  304. package/dist/src/planner/mutation/decomposition.js.map +1 -0
  305. package/dist/src/planner/mutation/lens-enforcement.d.ts +165 -0
  306. package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -0
  307. package/dist/src/planner/mutation/lens-enforcement.js +745 -0
  308. package/dist/src/planner/mutation/lens-enforcement.js.map +1 -0
  309. package/dist/src/planner/mutation/multi-source.d.ts +568 -0
  310. package/dist/src/planner/mutation/multi-source.d.ts.map +1 -0
  311. package/dist/src/planner/mutation/multi-source.js +2915 -0
  312. package/dist/src/planner/mutation/multi-source.js.map +1 -0
  313. package/dist/src/planner/mutation/mutation-diagnostic.d.ts +37 -0
  314. package/dist/src/planner/mutation/mutation-diagnostic.d.ts.map +1 -0
  315. package/dist/src/planner/mutation/mutation-diagnostic.js +24 -0
  316. package/dist/src/planner/mutation/mutation-diagnostic.js.map +1 -0
  317. package/dist/src/planner/mutation/mutation-tags.d.ts +33 -0
  318. package/dist/src/planner/mutation/mutation-tags.d.ts.map +1 -0
  319. package/dist/src/planner/mutation/mutation-tags.js +31 -0
  320. package/dist/src/planner/mutation/mutation-tags.js.map +1 -0
  321. package/dist/src/planner/mutation/propagate.d.ts +97 -0
  322. package/dist/src/planner/mutation/propagate.d.ts.map +1 -0
  323. package/dist/src/planner/mutation/propagate.js +220 -0
  324. package/dist/src/planner/mutation/propagate.js.map +1 -0
  325. package/dist/src/planner/mutation/scope-transform.d.ts +181 -0
  326. package/dist/src/planner/mutation/scope-transform.d.ts.map +1 -0
  327. package/dist/src/planner/mutation/scope-transform.js +574 -0
  328. package/dist/src/planner/mutation/scope-transform.js.map +1 -0
  329. package/dist/src/planner/mutation/set-op.d.ts +242 -0
  330. package/dist/src/planner/mutation/set-op.d.ts.map +1 -0
  331. package/dist/src/planner/mutation/set-op.js +1687 -0
  332. package/dist/src/planner/mutation/set-op.js.map +1 -0
  333. package/dist/src/planner/mutation/single-source.d.ts +261 -0
  334. package/dist/src/planner/mutation/single-source.d.ts.map +1 -0
  335. package/dist/src/planner/mutation/single-source.js +1096 -0
  336. package/dist/src/planner/mutation/single-source.js.map +1 -0
  337. package/dist/src/planner/nodes/aggregate-node.js +3 -3
  338. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  339. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  340. package/dist/src/planner/nodes/alias-node.js +5 -1
  341. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  342. package/dist/src/planner/nodes/alter-table-node.d.ts +124 -1
  343. package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -1
  344. package/dist/src/planner/nodes/alter-table-node.js +27 -0
  345. package/dist/src/planner/nodes/alter-table-node.js.map +1 -1
  346. package/dist/src/planner/nodes/analyze-node.d.ts +2 -1
  347. package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -1
  348. package/dist/src/planner/nodes/analyze-node.js +18 -1
  349. package/dist/src/planner/nodes/analyze-node.js.map +1 -1
  350. package/dist/src/planner/nodes/asserted-keys-node.d.ts +43 -0
  351. package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -0
  352. package/dist/src/planner/nodes/asserted-keys-node.js +99 -0
  353. package/dist/src/planner/nodes/asserted-keys-node.js.map +1 -0
  354. package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
  355. package/dist/src/planner/nodes/async-gather-node.js +33 -8
  356. package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
  357. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  358. package/dist/src/planner/nodes/bloom-join-node.js +2 -1
  359. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  360. package/dist/src/planner/nodes/create-view-node.d.ts +7 -2
  361. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
  362. package/dist/src/planner/nodes/create-view-node.js +4 -1
  363. package/dist/src/planner/nodes/create-view-node.js.map +1 -1
  364. package/dist/src/planner/nodes/declarative-schema.d.ts +13 -1
  365. package/dist/src/planner/nodes/declarative-schema.d.ts.map +1 -1
  366. package/dist/src/planner/nodes/declarative-schema.js +32 -0
  367. package/dist/src/planner/nodes/declarative-schema.js.map +1 -1
  368. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  369. package/dist/src/planner/nodes/distinct-node.js +2 -0
  370. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  371. package/dist/src/planner/nodes/dml-executor-node.d.ts +29 -1
  372. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  373. package/dist/src/planner/nodes/dml-executor-node.js +27 -3
  374. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  375. package/dist/src/planner/nodes/eager-prefetch-node.d.ts.map +1 -1
  376. package/dist/src/planner/nodes/eager-prefetch-node.js +2 -0
  377. package/dist/src/planner/nodes/eager-prefetch-node.js.map +1 -1
  378. package/dist/src/planner/nodes/envelope-scan-node.d.ts +42 -0
  379. package/dist/src/planner/nodes/envelope-scan-node.d.ts.map +1 -0
  380. package/dist/src/planner/nodes/envelope-scan-node.js +62 -0
  381. package/dist/src/planner/nodes/envelope-scan-node.js.map +1 -0
  382. package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts.map +1 -1
  383. package/dist/src/planner/nodes/fanout-lookup-join-node.js +11 -1
  384. package/dist/src/planner/nodes/fanout-lookup-join-node.js.map +1 -1
  385. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  386. package/dist/src/planner/nodes/filter.js +63 -13
  387. package/dist/src/planner/nodes/filter.js.map +1 -1
  388. package/dist/src/planner/nodes/join-node.d.ts +41 -1
  389. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  390. package/dist/src/planner/nodes/join-node.js +78 -8
  391. package/dist/src/planner/nodes/join-node.js.map +1 -1
  392. package/dist/src/planner/nodes/join-utils.d.ts +33 -6
  393. package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
  394. package/dist/src/planner/nodes/join-utils.js +124 -9
  395. package/dist/src/planner/nodes/join-utils.js.map +1 -1
  396. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts +104 -0
  397. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts.map +1 -0
  398. package/dist/src/planner/nodes/lens-auxiliary-access-node.js +91 -0
  399. package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -0
  400. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  401. package/dist/src/planner/nodes/limit-offset.js +4 -5
  402. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  403. package/dist/src/planner/nodes/materialized-view-nodes.d.ts +69 -0
  404. package/dist/src/planner/nodes/materialized-view-nodes.d.ts.map +1 -0
  405. package/dist/src/planner/nodes/materialized-view-nodes.js +111 -0
  406. package/dist/src/planner/nodes/materialized-view-nodes.js.map +1 -0
  407. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  408. package/dist/src/planner/nodes/merge-join-node.js +2 -1
  409. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  410. package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
  411. package/dist/src/planner/nodes/ordinal-slice-node.js +2 -0
  412. package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
  413. package/dist/src/planner/nodes/plan-node-type.d.ts +9 -0
  414. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  415. package/dist/src/planner/nodes/plan-node-type.js +9 -0
  416. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  417. package/dist/src/planner/nodes/plan-node.d.ts +265 -5
  418. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  419. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  420. package/dist/src/planner/nodes/pragma.d.ts +2 -1
  421. package/dist/src/planner/nodes/pragma.d.ts.map +1 -1
  422. package/dist/src/planner/nodes/pragma.js +12 -0
  423. package/dist/src/planner/nodes/pragma.js.map +1 -1
  424. package/dist/src/planner/nodes/project-node.d.ts +14 -1
  425. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  426. package/dist/src/planner/nodes/project-node.js +85 -11
  427. package/dist/src/planner/nodes/project-node.js.map +1 -1
  428. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  429. package/dist/src/planner/nodes/reference.js +62 -27
  430. package/dist/src/planner/nodes/reference.js.map +1 -1
  431. package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
  432. package/dist/src/planner/nodes/retrieve-node.js +7 -0
  433. package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
  434. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  435. package/dist/src/planner/nodes/returning-node.js +10 -3
  436. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  437. package/dist/src/planner/nodes/scalar.d.ts +20 -0
  438. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  439. package/dist/src/planner/nodes/scalar.js +71 -14
  440. package/dist/src/planner/nodes/scalar.js.map +1 -1
  441. package/dist/src/planner/nodes/set-object-tags-node.d.ts +39 -0
  442. package/dist/src/planner/nodes/set-object-tags-node.d.ts.map +1 -0
  443. package/dist/src/planner/nodes/set-object-tags-node.js +41 -0
  444. package/dist/src/planner/nodes/set-object-tags-node.js.map +1 -0
  445. package/dist/src/planner/nodes/set-operation-node.d.ts +123 -1
  446. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  447. package/dist/src/planner/nodes/set-operation-node.js +291 -18
  448. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  449. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  450. package/dist/src/planner/nodes/single-row.js +3 -0
  451. package/dist/src/planner/nodes/single-row.js.map +1 -1
  452. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  453. package/dist/src/planner/nodes/sort.js +7 -6
  454. package/dist/src/planner/nodes/sort.js.map +1 -1
  455. package/dist/src/planner/nodes/subquery.d.ts +2 -0
  456. package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
  457. package/dist/src/planner/nodes/subquery.js +18 -2
  458. package/dist/src/planner/nodes/subquery.js.map +1 -1
  459. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  460. package/dist/src/planner/nodes/table-access-nodes.js +23 -3
  461. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  462. package/dist/src/planner/nodes/table-function-call.js +6 -0
  463. package/dist/src/planner/nodes/table-function-call.js.map +1 -1
  464. package/dist/src/planner/nodes/values-node.d.ts +1 -0
  465. package/dist/src/planner/nodes/values-node.d.ts.map +1 -1
  466. package/dist/src/planner/nodes/values-node.js +16 -6
  467. package/dist/src/planner/nodes/values-node.js.map +1 -1
  468. package/dist/src/planner/nodes/view-mutation-node.d.ts +259 -0
  469. package/dist/src/planner/nodes/view-mutation-node.d.ts.map +1 -0
  470. package/dist/src/planner/nodes/view-mutation-node.js +273 -0
  471. package/dist/src/planner/nodes/view-mutation-node.js.map +1 -0
  472. package/dist/src/planner/nodes/window-function.d.ts +17 -1
  473. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  474. package/dist/src/planner/nodes/window-function.js +15 -1
  475. package/dist/src/planner/nodes/window-function.js.map +1 -1
  476. package/dist/src/planner/nodes/window-node.js +2 -2
  477. package/dist/src/planner/nodes/window-node.js.map +1 -1
  478. package/dist/src/planner/optimizer.d.ts.map +1 -1
  479. package/dist/src/planner/optimizer.js +372 -39
  480. package/dist/src/planner/optimizer.js.map +1 -1
  481. package/dist/src/planner/planning-context.d.ts +1 -1
  482. package/dist/src/planner/planning-context.d.ts.map +1 -1
  483. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts +70 -0
  484. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts.map +1 -0
  485. package/dist/src/planner/rules/access/lens-access-form-matcher.js +156 -0
  486. package/dist/src/planner/rules/access/lens-access-form-matcher.js.map +1 -0
  487. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts +31 -0
  488. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts.map +1 -0
  489. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js +176 -0
  490. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js.map +1 -0
  491. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  492. package/dist/src/planner/rules/access/rule-select-access-path.js +435 -37
  493. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  494. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -1
  495. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +9 -0
  496. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -1
  497. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts +39 -0
  498. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -0
  499. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +616 -0
  500. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -0
  501. package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts.map +1 -1
  502. package/dist/src/planner/rules/cache/rule-scalar-cse.js +8 -1
  503. package/dist/src/planner/rules/cache/rule-scalar-cse.js.map +1 -1
  504. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +36 -0
  505. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
  506. package/dist/src/planner/rules/join/equi-pair-extractor.js +38 -1
  507. package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
  508. package/dist/src/planner/rules/join/rule-fanout-batched-outer.d.ts.map +1 -1
  509. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +10 -0
  510. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js.map +1 -1
  511. package/dist/src/planner/rules/join/rule-fanout-lookup-join.d.ts.map +1 -1
  512. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js +19 -1
  513. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js.map +1 -1
  514. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts +130 -0
  515. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts.map +1 -0
  516. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js +206 -0
  517. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js.map +1 -0
  518. package/dist/src/planner/rules/join/rule-join-elimination.d.ts +67 -14
  519. package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -1
  520. package/dist/src/planner/rules/join/rule-join-elimination.js +81 -25
  521. package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -1
  522. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts +84 -0
  523. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts.map +1 -0
  524. package/dist/src/planner/rules/join/rule-join-existence-pruning.js +138 -0
  525. package/dist/src/planner/rules/join/rule-join-existence-pruning.js.map +1 -0
  526. package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -1
  527. package/dist/src/planner/rules/join/rule-join-greedy-commute.js +9 -1
  528. package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -1
  529. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -1
  530. package/dist/src/planner/rules/join/rule-join-physical-selection.js +12 -1
  531. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
  532. package/dist/src/planner/rules/join/rule-lateral-top1-asof.d.ts.map +1 -1
  533. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js +4 -0
  534. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js.map +1 -1
  535. package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts.map +1 -1
  536. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +4 -0
  537. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
  538. package/dist/src/planner/rules/join/rule-quickpick-enumeration.d.ts.map +1 -1
  539. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js +10 -0
  540. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js.map +1 -1
  541. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts +286 -0
  542. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts.map +1 -0
  543. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js +548 -0
  544. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js.map +1 -0
  545. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.d.ts.map +1 -1
  546. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js +9 -1
  547. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js.map +1 -1
  548. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.d.ts.map +1 -1
  549. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js +7 -0
  550. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js.map +1 -1
  551. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.d.ts.map +1 -1
  552. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js +10 -1
  553. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js.map +1 -1
  554. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -1
  555. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +9 -0
  556. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -1
  557. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts.map +1 -1
  558. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +18 -0
  559. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js.map +1 -1
  560. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -1
  561. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +7 -0
  562. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -1
  563. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -1
  564. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +9 -0
  565. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
  566. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +13 -3
  567. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
  568. package/dist/src/planner/rules/retrieve/rule-projection-pruning.d.ts.map +1 -1
  569. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js +14 -0
  570. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js.map +1 -1
  571. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +1 -1
  572. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +4 -4
  573. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js.map +1 -1
  574. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -1
  575. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +8 -0
  576. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -1
  577. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -1
  578. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +7 -0
  579. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -1
  580. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  581. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +12 -0
  582. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  583. package/dist/src/planner/type-utils.d.ts +14 -0
  584. package/dist/src/planner/type-utils.d.ts.map +1 -1
  585. package/dist/src/planner/type-utils.js +66 -21
  586. package/dist/src/planner/type-utils.js.map +1 -1
  587. package/dist/src/planner/util/fd-utils.d.ts +177 -43
  588. package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
  589. package/dist/src/planner/util/fd-utils.js +396 -101
  590. package/dist/src/planner/util/fd-utils.js.map +1 -1
  591. package/dist/src/planner/util/ind-utils.d.ts +27 -1
  592. package/dist/src/planner/util/ind-utils.d.ts.map +1 -1
  593. package/dist/src/planner/util/ind-utils.js +80 -6
  594. package/dist/src/planner/util/ind-utils.js.map +1 -1
  595. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  596. package/dist/src/planner/util/key-utils.js +81 -12
  597. package/dist/src/planner/util/key-utils.js.map +1 -1
  598. package/dist/src/planner/util/set-op-wrapper.d.ts +37 -0
  599. package/dist/src/planner/util/set-op-wrapper.d.ts.map +1 -0
  600. package/dist/src/planner/util/set-op-wrapper.js +82 -0
  601. package/dist/src/planner/util/set-op-wrapper.js.map +1 -0
  602. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  603. package/dist/src/planner/validation/plan-validator.js +1 -0
  604. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  605. package/dist/src/runtime/context-helpers.d.ts +13 -1
  606. package/dist/src/runtime/context-helpers.d.ts.map +1 -1
  607. package/dist/src/runtime/context-helpers.js +7 -1
  608. package/dist/src/runtime/context-helpers.js.map +1 -1
  609. package/dist/src/runtime/delta-executor.d.ts +30 -1
  610. package/dist/src/runtime/delta-executor.d.ts.map +1 -1
  611. package/dist/src/runtime/delta-executor.js +29 -4
  612. package/dist/src/runtime/delta-executor.js.map +1 -1
  613. package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
  614. package/dist/src/runtime/emit/add-constraint.js +38 -5
  615. package/dist/src/runtime/emit/add-constraint.js.map +1 -1
  616. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  617. package/dist/src/runtime/emit/aggregate.js +10 -8
  618. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  619. package/dist/src/runtime/emit/alter-table.d.ts +1 -1
  620. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  621. package/dist/src/runtime/emit/alter-table.js +664 -108
  622. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  623. package/dist/src/runtime/emit/analyze.d.ts.map +1 -1
  624. package/dist/src/runtime/emit/analyze.js +2 -1
  625. package/dist/src/runtime/emit/analyze.js.map +1 -1
  626. package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
  627. package/dist/src/runtime/emit/asof-scan.js +18 -5
  628. package/dist/src/runtime/emit/asof-scan.js.map +1 -1
  629. package/dist/src/runtime/emit/asserted-keys.d.ts +13 -0
  630. package/dist/src/runtime/emit/asserted-keys.d.ts.map +1 -0
  631. package/dist/src/runtime/emit/asserted-keys.js +13 -0
  632. package/dist/src/runtime/emit/asserted-keys.js.map +1 -0
  633. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  634. package/dist/src/runtime/emit/between.js +24 -19
  635. package/dist/src/runtime/emit/between.js.map +1 -1
  636. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  637. package/dist/src/runtime/emit/binary.js +5 -9
  638. package/dist/src/runtime/emit/binary.js.map +1 -1
  639. package/dist/src/runtime/emit/block.d.ts.map +1 -1
  640. package/dist/src/runtime/emit/block.js +11 -2
  641. package/dist/src/runtime/emit/block.js.map +1 -1
  642. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
  643. package/dist/src/runtime/emit/bloom-join.js +8 -2
  644. package/dist/src/runtime/emit/bloom-join.js.map +1 -1
  645. package/dist/src/runtime/emit/constraint-check.js +15 -0
  646. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  647. package/dist/src/runtime/emit/create-table.d.ts.map +1 -1
  648. package/dist/src/runtime/emit/create-table.js +8 -0
  649. package/dist/src/runtime/emit/create-table.js.map +1 -1
  650. package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
  651. package/dist/src/runtime/emit/create-view.js +16 -1
  652. package/dist/src/runtime/emit/create-view.js.map +1 -1
  653. package/dist/src/runtime/emit/dml-executor.d.ts +27 -0
  654. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  655. package/dist/src/runtime/emit/dml-executor.js +413 -193
  656. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  657. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
  658. package/dist/src/runtime/emit/drop-table.js +10 -0
  659. package/dist/src/runtime/emit/drop-table.js.map +1 -1
  660. package/dist/src/runtime/emit/drop-view.d.ts.map +1 -1
  661. package/dist/src/runtime/emit/drop-view.js +17 -0
  662. package/dist/src/runtime/emit/drop-view.js.map +1 -1
  663. package/dist/src/runtime/emit/envelope-scan.d.ts +13 -0
  664. package/dist/src/runtime/emit/envelope-scan.d.ts.map +1 -0
  665. package/dist/src/runtime/emit/envelope-scan.js +22 -0
  666. package/dist/src/runtime/emit/envelope-scan.js.map +1 -0
  667. package/dist/src/runtime/emit/join.d.ts +10 -2
  668. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  669. package/dist/src/runtime/emit/join.js +128 -38
  670. package/dist/src/runtime/emit/join.js.map +1 -1
  671. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts +16 -0
  672. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts.map +1 -0
  673. package/dist/src/runtime/emit/lens-auxiliary-access.js +16 -0
  674. package/dist/src/runtime/emit/lens-auxiliary-access.js.map +1 -0
  675. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +640 -0
  676. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -0
  677. package/dist/src/runtime/emit/materialized-view-helpers.js +2576 -0
  678. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -0
  679. package/dist/src/runtime/emit/materialized-view.d.ts +31 -0
  680. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -0
  681. package/dist/src/runtime/emit/materialized-view.js +187 -0
  682. package/dist/src/runtime/emit/materialized-view.js.map +1 -0
  683. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
  684. package/dist/src/runtime/emit/merge-join.js +15 -3
  685. package/dist/src/runtime/emit/merge-join.js.map +1 -1
  686. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  687. package/dist/src/runtime/emit/project.js +10 -5
  688. package/dist/src/runtime/emit/project.js.map +1 -1
  689. package/dist/src/runtime/emit/schema-declarative.d.ts +1 -0
  690. package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
  691. package/dist/src/runtime/emit/schema-declarative.js +101 -5
  692. package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
  693. package/dist/src/runtime/emit/set-object-tags.d.ts +16 -0
  694. package/dist/src/runtime/emit/set-object-tags.d.ts.map +1 -0
  695. package/dist/src/runtime/emit/set-object-tags.js +57 -0
  696. package/dist/src/runtime/emit/set-object-tags.js.map +1 -0
  697. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  698. package/dist/src/runtime/emit/set-operation.js +140 -24
  699. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  700. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  701. package/dist/src/runtime/emit/subquery.js +110 -5
  702. package/dist/src/runtime/emit/subquery.js.map +1 -1
  703. package/dist/src/runtime/emit/unary.d.ts.map +1 -1
  704. package/dist/src/runtime/emit/unary.js +34 -6
  705. package/dist/src/runtime/emit/unary.js.map +1 -1
  706. package/dist/src/runtime/emit/view-mutation.d.ts +70 -0
  707. package/dist/src/runtime/emit/view-mutation.d.ts.map +1 -0
  708. package/dist/src/runtime/emit/view-mutation.js +299 -0
  709. package/dist/src/runtime/emit/view-mutation.js.map +1 -0
  710. package/dist/src/runtime/emit/window.js +29 -5
  711. package/dist/src/runtime/emit/window.js.map +1 -1
  712. package/dist/src/runtime/foreign-key-actions.d.ts +66 -3
  713. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  714. package/dist/src/runtime/foreign-key-actions.js +580 -172
  715. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  716. package/dist/src/runtime/parallel-driver.d.ts +4 -1
  717. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  718. package/dist/src/runtime/parallel-driver.js +5 -1
  719. package/dist/src/runtime/parallel-driver.js.map +1 -1
  720. package/dist/src/runtime/register.d.ts.map +1 -1
  721. package/dist/src/runtime/register.js +17 -1
  722. package/dist/src/runtime/register.js.map +1 -1
  723. package/dist/src/runtime/types.d.ts +10 -0
  724. package/dist/src/runtime/types.d.ts.map +1 -1
  725. package/dist/src/runtime/types.js.map +1 -1
  726. package/dist/src/schema/basis-backfill.d.ts +63 -0
  727. package/dist/src/schema/basis-backfill.d.ts.map +1 -0
  728. package/dist/src/schema/basis-backfill.js +161 -0
  729. package/dist/src/schema/basis-backfill.js.map +1 -0
  730. package/dist/src/schema/catalog.d.ts +115 -1
  731. package/dist/src/schema/catalog.d.ts.map +1 -1
  732. package/dist/src/schema/catalog.js +249 -22
  733. package/dist/src/schema/catalog.js.map +1 -1
  734. package/dist/src/schema/change-events.d.ts +42 -1
  735. package/dist/src/schema/change-events.d.ts.map +1 -1
  736. package/dist/src/schema/change-events.js.map +1 -1
  737. package/dist/src/schema/column.d.ts +16 -0
  738. package/dist/src/schema/column.d.ts.map +1 -1
  739. package/dist/src/schema/column.js.map +1 -1
  740. package/dist/src/schema/constraint-builder.d.ts +182 -0
  741. package/dist/src/schema/constraint-builder.d.ts.map +1 -0
  742. package/dist/src/schema/constraint-builder.js +424 -0
  743. package/dist/src/schema/constraint-builder.js.map +1 -0
  744. package/dist/src/schema/ddl-generator.d.ts +86 -1
  745. package/dist/src/schema/ddl-generator.d.ts.map +1 -1
  746. package/dist/src/schema/ddl-generator.js +316 -20
  747. package/dist/src/schema/ddl-generator.js.map +1 -1
  748. package/dist/src/schema/declared-schema-manager.d.ts +51 -0
  749. package/dist/src/schema/declared-schema-manager.d.ts.map +1 -1
  750. package/dist/src/schema/declared-schema-manager.js +61 -0
  751. package/dist/src/schema/declared-schema-manager.js.map +1 -1
  752. package/dist/src/schema/derivation.d.ts +106 -0
  753. package/dist/src/schema/derivation.d.ts.map +1 -0
  754. package/dist/src/schema/derivation.js +25 -0
  755. package/dist/src/schema/derivation.js.map +1 -0
  756. package/dist/src/schema/function.d.ts +20 -0
  757. package/dist/src/schema/function.d.ts.map +1 -1
  758. package/dist/src/schema/function.js.map +1 -1
  759. package/dist/src/schema/lens-ack.d.ts +90 -0
  760. package/dist/src/schema/lens-ack.d.ts.map +1 -0
  761. package/dist/src/schema/lens-ack.js +361 -0
  762. package/dist/src/schema/lens-ack.js.map +1 -0
  763. package/dist/src/schema/lens-compiler.d.ts +62 -0
  764. package/dist/src/schema/lens-compiler.d.ts.map +1 -0
  765. package/dist/src/schema/lens-compiler.js +1594 -0
  766. package/dist/src/schema/lens-compiler.js.map +1 -0
  767. package/dist/src/schema/lens-fk-discovery.d.ts +175 -0
  768. package/dist/src/schema/lens-fk-discovery.d.ts.map +1 -0
  769. package/dist/src/schema/lens-fk-discovery.js +336 -0
  770. package/dist/src/schema/lens-fk-discovery.js.map +1 -0
  771. package/dist/src/schema/lens-prover.d.ts +336 -0
  772. package/dist/src/schema/lens-prover.d.ts.map +1 -0
  773. package/dist/src/schema/lens-prover.js +1988 -0
  774. package/dist/src/schema/lens-prover.js.map +1 -0
  775. package/dist/src/schema/lens.d.ts +254 -0
  776. package/dist/src/schema/lens.d.ts.map +1 -0
  777. package/dist/src/schema/lens.js +21 -0
  778. package/dist/src/schema/lens.js.map +1 -0
  779. package/dist/src/schema/manager.d.ts +676 -18
  780. package/dist/src/schema/manager.d.ts.map +1 -1
  781. package/dist/src/schema/manager.js +1573 -238
  782. package/dist/src/schema/manager.js.map +1 -1
  783. package/dist/src/schema/mapping-advertisement-tags.d.ts +39 -0
  784. package/dist/src/schema/mapping-advertisement-tags.d.ts.map +1 -0
  785. package/dist/src/schema/mapping-advertisement-tags.js +216 -0
  786. package/dist/src/schema/mapping-advertisement-tags.js.map +1 -0
  787. package/dist/src/schema/rename-rewriter.d.ts +45 -4
  788. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  789. package/dist/src/schema/rename-rewriter.js +412 -19
  790. package/dist/src/schema/rename-rewriter.js.map +1 -1
  791. package/dist/src/schema/reserved-tags-policy.d.ts +32 -0
  792. package/dist/src/schema/reserved-tags-policy.d.ts.map +1 -0
  793. package/dist/src/schema/reserved-tags-policy.js +34 -0
  794. package/dist/src/schema/reserved-tags-policy.js.map +1 -0
  795. package/dist/src/schema/reserved-tags.d.ts +170 -0
  796. package/dist/src/schema/reserved-tags.d.ts.map +1 -0
  797. package/dist/src/schema/reserved-tags.js +507 -0
  798. package/dist/src/schema/reserved-tags.js.map +1 -0
  799. package/dist/src/schema/schema-differ.d.ts +158 -2
  800. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  801. package/dist/src/schema/schema-differ.js +1460 -78
  802. package/dist/src/schema/schema-differ.js.map +1 -1
  803. package/dist/src/schema/schema-hasher.d.ts +8 -3
  804. package/dist/src/schema/schema-hasher.d.ts.map +1 -1
  805. package/dist/src/schema/schema-hasher.js +22 -2
  806. package/dist/src/schema/schema-hasher.js.map +1 -1
  807. package/dist/src/schema/schema.d.ts +25 -1
  808. package/dist/src/schema/schema.d.ts.map +1 -1
  809. package/dist/src/schema/schema.js +36 -2
  810. package/dist/src/schema/schema.js.map +1 -1
  811. package/dist/src/schema/table.d.ts +259 -10
  812. package/dist/src/schema/table.d.ts.map +1 -1
  813. package/dist/src/schema/table.js +309 -26
  814. package/dist/src/schema/table.js.map +1 -1
  815. package/dist/src/schema/unique-enforcement.d.ts +78 -0
  816. package/dist/src/schema/unique-enforcement.d.ts.map +1 -0
  817. package/dist/src/schema/unique-enforcement.js +93 -0
  818. package/dist/src/schema/unique-enforcement.js.map +1 -0
  819. package/dist/src/schema/view.d.ts +83 -2
  820. package/dist/src/schema/view.d.ts.map +1 -1
  821. package/dist/src/schema/view.js +67 -1
  822. package/dist/src/schema/view.js.map +1 -1
  823. package/dist/src/schema/window-function.d.ts +9 -1
  824. package/dist/src/schema/window-function.d.ts.map +1 -1
  825. package/dist/src/schema/window-function.js.map +1 -1
  826. package/dist/src/util/comparison.d.ts +24 -0
  827. package/dist/src/util/comparison.d.ts.map +1 -1
  828. package/dist/src/util/comparison.js +34 -0
  829. package/dist/src/util/comparison.js.map +1 -1
  830. package/dist/src/util/mutation-statement.d.ts.map +1 -1
  831. package/dist/src/util/mutation-statement.js +4 -1
  832. package/dist/src/util/mutation-statement.js.map +1 -1
  833. package/dist/src/util/serialization.d.ts +9 -0
  834. package/dist/src/util/serialization.d.ts.map +1 -1
  835. package/dist/src/util/serialization.js +26 -0
  836. package/dist/src/util/serialization.js.map +1 -1
  837. package/dist/src/vtab/backing-host.d.ts +286 -0
  838. package/dist/src/vtab/backing-host.d.ts.map +1 -0
  839. package/dist/src/vtab/backing-host.js +118 -0
  840. package/dist/src/vtab/backing-host.js.map +1 -0
  841. package/dist/src/vtab/best-access-plan.d.ts +21 -0
  842. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  843. package/dist/src/vtab/best-access-plan.js.map +1 -1
  844. package/dist/src/vtab/capabilities.d.ts +5 -5
  845. package/dist/src/vtab/capabilities.d.ts.map +1 -1
  846. package/dist/src/vtab/mapping-advertisement.d.ts +163 -0
  847. package/dist/src/vtab/mapping-advertisement.d.ts.map +1 -0
  848. package/dist/src/vtab/mapping-advertisement.js +2 -0
  849. package/dist/src/vtab/mapping-advertisement.js.map +1 -0
  850. package/dist/src/vtab/memory/index.d.ts +64 -4
  851. package/dist/src/vtab/memory/index.d.ts.map +1 -1
  852. package/dist/src/vtab/memory/index.js +119 -12
  853. package/dist/src/vtab/memory/index.js.map +1 -1
  854. package/dist/src/vtab/memory/layer/base.d.ts +38 -1
  855. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  856. package/dist/src/vtab/memory/layer/base.js +112 -24
  857. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  858. package/dist/src/vtab/memory/layer/manager.d.ts +291 -4
  859. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  860. package/dist/src/vtab/memory/layer/manager.js +1050 -91
  861. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  862. package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
  863. package/dist/src/vtab/memory/layer/plan-filter.js +35 -6
  864. package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
  865. package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
  866. package/dist/src/vtab/memory/layer/scan-layer.js +66 -14
  867. package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
  868. package/dist/src/vtab/memory/layer/scan-plan.d.ts +14 -0
  869. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
  870. package/dist/src/vtab/memory/layer/scan-plan.js +27 -4
  871. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
  872. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  873. package/dist/src/vtab/memory/layer/transaction.js +5 -1
  874. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  875. package/dist/src/vtab/memory/module.d.ts +17 -0
  876. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  877. package/dist/src/vtab/memory/module.js +82 -3
  878. package/dist/src/vtab/memory/module.js.map +1 -1
  879. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  880. package/dist/src/vtab/memory/table.js +15 -5
  881. package/dist/src/vtab/memory/table.js.map +1 -1
  882. package/dist/src/vtab/memory/types.d.ts +20 -2
  883. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  884. package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
  885. package/dist/src/vtab/memory/utils/predicate.js +46 -24
  886. package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
  887. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts +31 -0
  888. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts.map +1 -0
  889. package/dist/src/vtab/memory/utils/primary-key-encode.js +101 -0
  890. package/dist/src/vtab/memory/utils/primary-key-encode.js.map +1 -0
  891. package/dist/src/vtab/memory/utils/primary-key.d.ts +8 -0
  892. package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
  893. package/dist/src/vtab/memory/utils/primary-key.js +12 -5
  894. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  895. package/dist/src/vtab/module.d.ts +203 -4
  896. package/dist/src/vtab/module.d.ts.map +1 -1
  897. package/dist/src/vtab/table.d.ts +9 -0
  898. package/dist/src/vtab/table.d.ts.map +1 -1
  899. package/dist/src/vtab/table.js.map +1 -1
  900. package/package.json +17 -16
@@ -16,9 +16,12 @@ import { RetrieveNode } from '../../nodes/retrieve-node.js';
16
16
  import { RemoteQueryNode } from '../../nodes/remote-query-node.js';
17
17
  import { SeqScanNode, IndexScanNode, IndexSeekNode, EmptyResultNode } from '../../nodes/table-access-nodes.js';
18
18
  import { seqScanCost } from '../../cost/index.js';
19
+ import { compareSqlValues, normalizeCollationName } from '../../../util/comparison.js';
19
20
  import { FilterNode } from '../../nodes/filter.js';
20
21
  import { extractConstraintsForTable, createTableInfoFromNode } from '../../analysis/constraint-extractor.js';
21
- import { LiteralNode } from '../../nodes/scalar.js';
22
+ import { LiteralNode, BinaryOpNode, BetweenNode } from '../../nodes/scalar.js';
23
+ import { InNode } from '../../nodes/subquery.js';
24
+ import { effectiveBetweenBoundCollation, effectiveComparisonCollation, effectiveInCollation } from '../../analysis/comparison-collation.js';
22
25
  import { IndexConstraintOp } from '../../../common/constants.js';
23
26
  const log = createLogger('optimizer:rule:select-access-path');
24
27
  /**
@@ -177,27 +180,7 @@ function selectPhysicalNode(tableRef, accessPlan, constraints) {
177
180
  // Empty result optimization (e.g., IS NULL on NOT NULL column)
178
181
  if (accessPlan.rows === 0 && accessPlan.handledFilters.every(h => h)) {
179
182
  log('Using empty result (impossible predicate detected)');
180
- const emptyFilterInfo = {
181
- idxNum: 0,
182
- idxStr: 'empty',
183
- constraints: [],
184
- args: [],
185
- indexInfoOutput: {
186
- nConstraint: 0,
187
- aConstraint: [],
188
- nOrderBy: 0,
189
- aOrderBy: [],
190
- aConstraintUsage: [],
191
- idxNum: 0,
192
- idxStr: 'empty',
193
- orderByConsumed: false,
194
- estimatedCost: 0,
195
- estimatedRows: 0n,
196
- idxFlags: 0,
197
- colUsed: 0n,
198
- }
199
- };
200
- return new EmptyResultNode(tableRef.scope, tableRef, emptyFilterInfo, 0);
183
+ return createEmptyResultNode(tableRef);
201
184
  }
202
185
  // Create a default FilterInfo for the physical nodes
203
186
  const filterInfo = {
@@ -238,6 +221,9 @@ function selectPhysicalNode(tableRef, accessPlan, constraints) {
238
221
  */
239
222
  function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInfo, providesOrdering) {
240
223
  const advertisement = extractAdvertisement(accessPlan);
224
+ // Whether this module's runtime honours the index collation for range bounds —
225
+ // gates the collation-matched non-BINARY range/prefix seek (see classifyConstraintCover).
226
+ const honorsCollatedRangeBounds = accessPlan.honorsCollatedRangeBounds === true;
241
227
  const seekCols = accessPlan.seekColumnIndexes;
242
228
  // Map accessPlan.indexName to physical node indexName ('_primary_' → 'primary')
243
229
  const physicalIndexName = accessPlan.indexName === '_primary_' ? 'primary' : accessPlan.indexName;
@@ -272,29 +258,57 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
272
258
  }
273
259
  }
274
260
  if (allEquality && eqBySeekCol.size === seekCols.length) {
261
+ // Collation-cover analysis: a seek over an index whose per-column collation
262
+ // differs from the predicate's effective comparison collation is NOT a
263
+ // complete substitute for the predicate. Decline (scan + residual) on an
264
+ // unsafe mismatch; keep the seek and re-apply a residual when the index is a
265
+ // provable superset (BINARY predicate over a coarser index). See
266
+ // `index-collation-mismatch-residual-filter`.
267
+ const cover = classifyCollationCover(seekCols.map(colIdx => ({ colIdx, constraint: eqBySeekCol.get(colIdx) })), true, indexColumnCollationLookup(tableRef.tableSchema, accessPlan), honorsCollatedRangeBounds);
268
+ if (!cover.useIndex) {
269
+ log('Declining index seek on %s (collation mismatch) — sequential scan + residual', physicalIndexName);
270
+ const scan = createSeqScan(tableRef);
271
+ return cover.residual ? new FilterNode(tableRef.scope, scan, cover.residual) : scan;
272
+ }
273
+ const finishSeek = (leaf) => cover.residual ? new FilterNode(tableRef.scope, leaf, cover.residual) : leaf;
275
274
  // Check for multi-value IN on a single-column seek (simple case)
276
275
  const hasMultiValueIn = [...eqBySeekCol.values()].some(c => c.op === 'IN' && Array.isArray(c.value) && c.value.length > 1);
277
276
  if (hasMultiValueIn && seekCols.length === 1) {
278
277
  // Multi-seek: IN on single-column index
279
278
  const colIdx = seekCols[0];
280
279
  const inConstraint = eqBySeekCol.get(colIdx);
281
- const inValues = inConstraint.value;
282
- // Use valueExpr nodes when available (mixed-binding IN from OR collapse),
283
- // otherwise construct literal nodes from values
284
- const seekKeys = Array.isArray(inConstraint.valueExpr)
285
- ? inConstraint.valueExpr
286
- : inValues.map(v => literalFromValue(tableRef.scope, v));
287
- const inConstraints = inValues.map((_v, i) => ({
280
+ const rawValues = inConstraint.value;
281
+ let seekKeys;
282
+ if (Array.isArray(inConstraint.valueExpr)) {
283
+ // Mixed-binding IN (from OR collapse): some values are dynamic, so the
284
+ // runtime scan-layer dedup/NULL-skip stays authoritative — keep the raw
285
+ // list and let it perform set-membership at execution time.
286
+ seekKeys = inConstraint.valueExpr;
287
+ }
288
+ else {
289
+ // Pure-literal IN: collapse duplicate literals and drop NULLs so the
290
+ // advertised inCount reflects the effective distinct non-null seek count.
291
+ const effectiveValues = reduceLiteralSeekValues(rawValues);
292
+ if (effectiveValues.length === 0) {
293
+ // Every seek key is NULL ⇒ no row can match. Emit an empty result
294
+ // rather than a zero-key multi-seek (inCount=0 would parse back to no
295
+ // equalityKeys and degrade to an unbounded full-index walk).
296
+ log('IN-list is entirely NULL literals on %s — using empty result', physicalIndexName);
297
+ return createEmptyResultNode(tableRef);
298
+ }
299
+ seekKeys = effectiveValues.map(v => literalFromValue(tableRef.scope, v));
300
+ }
301
+ const inConstraints = seekKeys.map((_sk, i) => ({
288
302
  constraint: { iColumn: colIdx, op: IndexConstraintOp.EQ, usable: true },
289
303
  argvIndex: i + 1,
290
304
  }));
291
305
  const fi = {
292
306
  ...filterInfo,
293
307
  constraints: inConstraints,
294
- idxStr: `idx=${idxStrName}(0);plan=5;inCount=${inValues.length}`,
308
+ idxStr: `idx=${idxStrName}(0);plan=5;inCount=${seekKeys.length}`,
295
309
  };
296
- log('Using index multi-seek on %s (IN with %d values)', physicalIndexName, inValues.length);
297
- return new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement);
310
+ log('Using index multi-seek on %s (IN with %d values)', physicalIndexName, seekKeys.length);
311
+ return finishSeek(new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement));
298
312
  }
299
313
  if (hasMultiValueIn && seekCols.length > 1) {
300
314
  // Composite IN multi-seek: generate cross-product of all column values
@@ -314,9 +328,39 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
314
328
  columnValues.push({ colIdx, values: [val] });
315
329
  }
316
330
  }
317
- // Compute cross-product of value indices
318
- const crossProduct = cartesianProduct(columnValues.map(cv => cv.values.map((_v, i) => i)));
319
331
  const seekWidth = seekCols.length;
332
+ // A column is pure-literal iff its constraint carries no value expression
333
+ // (a `valueExpr` is present only for dynamic/parameter or mixed bindings).
334
+ // When every component is literal we can reduce the cross-product at plan
335
+ // time; otherwise the runtime scan-layer dedup/NULL-skip is authoritative.
336
+ const allLiteral = seekCols.every(colIdx => eqBySeekCol.get(colIdx).valueExpr === undefined);
337
+ if (allLiteral) {
338
+ // Build the cross-product of actual literal tuples, then drop any tuple
339
+ // with a NULL component and collapse duplicates so inCount reflects the
340
+ // effective distinct non-null seek count.
341
+ const valueTuples = cartesianProduct(columnValues.map(cv => cv.values));
342
+ const effectiveTuples = reduceLiteralSeekTuples(valueTuples);
343
+ if (effectiveTuples.length === 0) {
344
+ // Every cross-product tuple is NULL-bearing ⇒ no row can match.
345
+ log('Composite IN cross-product on %s is entirely NULL-bearing — using empty result', physicalIndexName);
346
+ return createEmptyResultNode(tableRef);
347
+ }
348
+ const seekKeys = effectiveTuples.flatMap(tuple => tuple.map(v => literalFromValue(tableRef.scope, v)));
349
+ const seekConstraints = seekKeys.map((_sk, i) => ({
350
+ constraint: { iColumn: seekCols[i % seekWidth], op: IndexConstraintOp.EQ, usable: true },
351
+ argvIndex: i + 1,
352
+ }));
353
+ const fi = {
354
+ ...filterInfo,
355
+ constraints: seekConstraints,
356
+ idxStr: `idx=${idxStrName}(0);plan=5;inCount=${effectiveTuples.length};seekWidth=${seekWidth}`,
357
+ };
358
+ log('Using composite index multi-seek on %s (cross-product of %d distinct non-null seeks, width %d)', physicalIndexName, effectiveTuples.length, seekWidth);
359
+ return finishSeek(new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement));
360
+ }
361
+ // Dynamic/mixed composite: keep the raw cross-product over value indices and
362
+ // let the runtime perform set-membership at execution time.
363
+ const crossProduct = cartesianProduct(columnValues.map(cv => cv.values.map((_v, i) => i)));
320
364
  // Build seekKeys — one ScalarPlanNode per value in flattened cross-product
321
365
  const seekKeys = crossProduct.flatMap(combo => combo.map((valueIdx, colPos) => {
322
366
  const cv = columnValues[colPos];
@@ -336,7 +380,15 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
336
380
  idxStr: `idx=${idxStrName}(0);plan=5;inCount=${crossProduct.length};seekWidth=${seekWidth}`,
337
381
  };
338
382
  log('Using composite index multi-seek on %s (cross-product of %d seeks, width %d)', physicalIndexName, crossProduct.length, seekWidth);
339
- return new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement);
383
+ return finishSeek(new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement));
384
+ }
385
+ // A literal NULL in any seek column makes the (row-value) equality UNKNOWN ⇒
386
+ // no row can match. Emit an empty result rather than a doomed point-seek so
387
+ // EXPLAIN stays honest (EmptyResult, not a degraded IndexSeek/SeqScan). A
388
+ // dynamic `valueExpr` is left to the scan-layer runtime guard (Part A).
389
+ if ([...eqBySeekCol.values()].some(isLiteralNullEquality)) {
390
+ log('Equality seek on %s has a literal NULL key — using empty result', physicalIndexName);
391
+ return createEmptyResultNode(tableRef);
340
392
  }
341
393
  // Standard equality seek on all seek columns
342
394
  const seekKeys = seekCols.map(colIdx => {
@@ -356,7 +408,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
356
408
  idxStr: `idx=${idxStrName}(0);plan=2`,
357
409
  };
358
410
  log('Using index seek on %s (equality)', physicalIndexName);
359
- return new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement);
411
+ return finishSeek(new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement));
360
412
  }
361
413
  // Check for prefix-equality + trailing-range pattern
362
414
  if (!allEquality && seekCols.length > 1) {
@@ -377,6 +429,44 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
377
429
  }
378
430
  }
379
431
  if (prefixEqCols.length > 0 && trailingRangeCol !== undefined) {
432
+ // A literal NULL in any prefix-equality column makes every row-value
433
+ // comparison UNKNOWN ⇒ no match. Emit an empty result rather than relying
434
+ // on the runtime prefix walk breaking on the first row. Part A does not
435
+ // cover this path (it walks via `equalityPrefix`, not `equalityKey`), so
436
+ // the plan-time check is the robustness guarantee here.
437
+ const prefixHasLiteralNull = prefixEqCols.some(colIdx => {
438
+ const c = (constraintsByCol.get(colIdx) ?? []).find(c => (c.op === '=' || (c.op === 'IN' && Array.isArray(c.value) && c.value.length === 1)) &&
439
+ handledByCol.has(c.columnIndex));
440
+ return c !== undefined && isLiteralNullEquality(c);
441
+ });
442
+ if (prefixHasLiteralNull) {
443
+ log('Prefix-range seek on %s has a literal NULL prefix key — using empty result', physicalIndexName);
444
+ return createEmptyResultNode(tableRef);
445
+ }
446
+ // Collation-cover: any collation mismatch on a prefix-range seek reorders
447
+ // the walked index window (it is no longer a contiguous superset), so it
448
+ // cannot be salvaged with a residual — decline to a scan + residual.
449
+ {
450
+ const consumed = [];
451
+ for (const colIdx of prefixEqCols) {
452
+ const c = (constraintsByCol.get(colIdx) ?? []).find(c => (c.op === '=' || (c.op === 'IN' && Array.isArray(c.value) && c.value.length === 1)) &&
453
+ handledByCol.has(c.columnIndex));
454
+ consumed.push({ colIdx, constraint: c });
455
+ }
456
+ const trailing = constraintsByCol.get(trailingRangeCol) ?? [];
457
+ const lo = trailing.find(c => (c.op === '>' || c.op === '>=') && handledByCol.has(c.columnIndex));
458
+ const hi = trailing.find(c => (c.op === '<' || c.op === '<=') && handledByCol.has(c.columnIndex));
459
+ if (lo)
460
+ consumed.push({ colIdx: trailingRangeCol, constraint: lo });
461
+ if (hi)
462
+ consumed.push({ colIdx: trailingRangeCol, constraint: hi });
463
+ const cover = classifyCollationCover(consumed, false, indexColumnCollationLookup(tableRef.tableSchema, accessPlan), honorsCollatedRangeBounds);
464
+ if (!cover.useIndex) {
465
+ log('Declining prefix-range seek on %s (collation mismatch) — sequential scan + residual', physicalIndexName);
466
+ const scan = createSeqScan(tableRef);
467
+ return cover.residual ? new FilterNode(tableRef.scope, scan, cover.residual) : scan;
468
+ }
469
+ }
380
470
  const seekKeys = [];
381
471
  const allConstraints = [];
382
472
  let argv = 1;
@@ -424,6 +514,22 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
424
514
  const colConstraints = constraintsByCol.get(rangeCol) ?? [];
425
515
  const lower = colConstraints.find(c => (c.op === '>' || c.op === '>=') && handledByCol.has(c.columnIndex));
426
516
  const upper = colConstraints.find(c => (c.op === '<' || c.op === '<=') && handledByCol.has(c.columnIndex));
517
+ // Collation-cover: a range seek under a collation that differs from the
518
+ // predicate's reorders the index window, so it is never a superset — decline
519
+ // to a scan + residual on any mismatch.
520
+ {
521
+ const consumed = [];
522
+ if (lower)
523
+ consumed.push({ colIdx: rangeCol, constraint: lower });
524
+ if (upper)
525
+ consumed.push({ colIdx: rangeCol, constraint: upper });
526
+ const cover = classifyCollationCover(consumed, false, indexColumnCollationLookup(tableRef.tableSchema, accessPlan), honorsCollatedRangeBounds);
527
+ if (!cover.useIndex) {
528
+ log('Declining range seek on %s (collation mismatch) — sequential scan + residual', physicalIndexName);
529
+ const scan = createSeqScan(tableRef);
530
+ return cover.residual ? new FilterNode(tableRef.scope, scan, cover.residual) : scan;
531
+ }
532
+ }
427
533
  const seekKeys = [];
428
534
  const rangeConstraints = [];
429
535
  let argv = 1;
@@ -450,6 +556,17 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
450
556
  seekCols.includes(c.columnIndex) && handledByCol.has(c.columnIndex));
451
557
  if (orRangeConstraint && orRangeConstraint.ranges) {
452
558
  const ranges = orRangeConstraint.ranges;
559
+ // Collation-cover: an OR_RANGE seek walks multiple index windows whose order
560
+ // follows the index collation; any mismatch makes them non-supersets, so
561
+ // decline to a scan + residual.
562
+ {
563
+ const cover = classifyCollationCover([{ colIdx: orRangeConstraint.columnIndex, constraint: orRangeConstraint }], false, indexColumnCollationLookup(tableRef.tableSchema, accessPlan), honorsCollatedRangeBounds);
564
+ if (!cover.useIndex) {
565
+ log('Declining OR_RANGE seek on %s (collation mismatch) — sequential scan + residual', physicalIndexName);
566
+ const scan = createSeqScan(tableRef);
567
+ return cover.residual ? new FilterNode(tableRef.scope, scan, cover.residual) : scan;
568
+ }
569
+ }
453
570
  // Build seekKeys: for each range, emit lower value then upper value
454
571
  // Encode which ops each range has in rangeOps string
455
572
  const seekKeys = [];
@@ -508,6 +625,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
508
625
  */
509
626
  function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo, providesOrdering) {
510
627
  const advertisement = extractAdvertisement(accessPlan);
628
+ const honorsCollatedRangeBounds = accessPlan.honorsCollatedRangeBounds === true;
511
629
  // Analyze the access plan to determine node type
512
630
  const handledByCol = new Set();
513
631
  constraints.forEach((c, i) => {
@@ -525,6 +643,25 @@ function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo,
525
643
  const coversPk = pkCols.length > 0 && pkCols.every(pk => eqByCol.has(pk.index));
526
644
  const treatAsHandledPk = coversPk && pkCols.every(pk => handledByCol.has(pk.index) || eqByCol.has(pk.index));
527
645
  if ((hasEqualityConstraints && coversPk || treatAsHandledPk) && maybeRows <= 10) {
646
+ // A literal NULL in any PK column makes the point-seek UNKNOWN ⇒ no row can
647
+ // match. Emit an empty result instead of a doomed seek (mirrors the
648
+ // index-aware path; the scan-layer runtime guard covers the dynamic case).
649
+ if (pkCols.some(pk => {
650
+ const c = eqByCol.get(pk.index);
651
+ return c !== undefined && isLiteralNullEquality(c);
652
+ })) {
653
+ log('PK equality seek has a literal NULL key — using empty result (legacy)');
654
+ return createEmptyResultNode(tableRef);
655
+ }
656
+ // Collation-cover: a PK seek whose column collation differs from the
657
+ // predicate's effective collation over/under-fetches. Keep the seek + residual
658
+ // for a coarser PK collation; decline to a scan + residual otherwise.
659
+ const cover = classifyCollationCover(pkCols.map(pk => ({ colIdx: pk.index, constraint: eqByCol.get(pk.index) })), true, primaryKeyCollationLookup(tableRef.tableSchema), honorsCollatedRangeBounds);
660
+ if (!cover.useIndex) {
661
+ log('Declining PK index seek (collation mismatch) — sequential scan + residual (legacy)');
662
+ const scan = createSeqScan(tableRef);
663
+ return cover.residual ? new FilterNode(tableRef.scope, scan, cover.residual) : scan;
664
+ }
528
665
  const seekKeys = pkCols.map(pk => {
529
666
  const c = eqByCol.get(pk.index);
530
667
  if (c.valueExpr && !Array.isArray(c.valueExpr))
@@ -541,7 +678,8 @@ function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo,
541
678
  idxStr: 'idx=_primary_(0);plan=2',
542
679
  };
543
680
  log('Using index seek on primary key (legacy)');
544
- return new IndexSeekNode(tableRef.scope, tableRef, fi, 'primary', seekKeys, false, providesOrdering, accessPlan.cost, advertisement);
681
+ const pkSeek = new IndexSeekNode(tableRef.scope, tableRef, fi, 'primary', seekKeys, false, providesOrdering, accessPlan.cost, advertisement);
682
+ return cover.residual ? new FilterNode(tableRef.scope, pkSeek, cover.residual) : pkSeek;
545
683
  }
546
684
  if (hasRangeConstraints) {
547
685
  const rangeCols = constraints
@@ -550,6 +688,21 @@ function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo,
550
688
  const primaryFirstCol = (tableRef.tableSchema.primaryKeyDefinition?.[0]?.index) ?? (rangeCols[0]?.columnIndex ?? 0);
551
689
  const lower = rangeCols.find(c => c.columnIndex === primaryFirstCol && (c.op === '>' || c.op === '>='));
552
690
  const upper = rangeCols.find(c => c.columnIndex === primaryFirstCol && (c.op === '<' || c.op === '<='));
691
+ // Collation-cover: a PK range seek under a mismatched collation reorders the
692
+ // walked window, so decline to a scan + residual on any mismatch.
693
+ {
694
+ const consumed = [];
695
+ if (lower)
696
+ consumed.push({ colIdx: primaryFirstCol, constraint: lower });
697
+ if (upper)
698
+ consumed.push({ colIdx: primaryFirstCol, constraint: upper });
699
+ const cover = classifyCollationCover(consumed, false, primaryKeyCollationLookup(tableRef.tableSchema), honorsCollatedRangeBounds);
700
+ if (!cover.useIndex) {
701
+ log('Declining PK range seek (collation mismatch) — sequential scan + residual (legacy)');
702
+ const scan = createSeqScan(tableRef);
703
+ return cover.residual ? new FilterNode(tableRef.scope, scan, cover.residual) : scan;
704
+ }
705
+ }
553
706
  const seekKeys = [];
554
707
  const rangeConstraints = [];
555
708
  let argv = 1;
@@ -639,4 +792,249 @@ function literalFromValue(scope, value) {
639
792
  const lit = { type: 'literal', value };
640
793
  return new LiteralNode(scope, lit);
641
794
  }
795
+ /**
796
+ * Build the canonical empty-relation leaf used when a predicate is provably
797
+ * unsatisfiable (e.g. an IN-list whose literals are all NULL — every seek key
798
+ * is skipped at runtime). Shared by the impossible-predicate optimization and
799
+ * the literal-IN reduction below.
800
+ */
801
+ function createEmptyResultNode(tableRef) {
802
+ const emptyFilterInfo = {
803
+ idxNum: 0,
804
+ idxStr: 'empty',
805
+ constraints: [],
806
+ args: [],
807
+ indexInfoOutput: {
808
+ nConstraint: 0,
809
+ aConstraint: [],
810
+ nOrderBy: 0,
811
+ aOrderBy: [],
812
+ aConstraintUsage: [],
813
+ idxNum: 0,
814
+ idxStr: 'empty',
815
+ orderByConsumed: false,
816
+ estimatedCost: 0,
817
+ estimatedRows: 0n,
818
+ idxFlags: 0,
819
+ colUsed: 0n,
820
+ }
821
+ };
822
+ return new EmptyResultNode(tableRef.scope, tableRef, emptyFilterInfo, 0);
823
+ }
824
+ /**
825
+ * True when an equality constraint resolves to a *literal* SQL NULL — `col = null`
826
+ * or single-value `col IN (null)` carrying no dynamic value expression. SQL NULL
827
+ * equality is UNKNOWN under three-valued logic, so such a point-seek matches no
828
+ * row; the planner emits an {@link createEmptyResultNode} instead of a doomed
829
+ * point-seek (mirrors the all-NULL IN-list reduction in {@link reduceLiteralSeekValues}).
830
+ *
831
+ * A dynamic single `valueExpr` (parameter/correlated binding) is deliberately NOT
832
+ * treated as literal: its NULL-ness is unknown at plan time and is handled by the
833
+ * scan-layer runtime guard (`seekKeyHasNull`) instead. This mirrors the
834
+ * literal-vs-dynamic discrimination used where `seekKeys` are materialized
835
+ * (`c.valueExpr && !Array.isArray(c.valueExpr)` ⇒ dynamic). A dynamic single-value
836
+ * `IN (?)` carries an *array* `valueExpr` and an `undefined` placeholder value, so
837
+ * the effective-value check below also rejects it.
838
+ */
839
+ function isLiteralNullEquality(c) {
840
+ if (c.valueExpr && !Array.isArray(c.valueExpr))
841
+ return false;
842
+ const val = c.op === 'IN' && Array.isArray(c.value)
843
+ ? c.value[0]
844
+ : c.value;
845
+ return val === null;
846
+ }
847
+ /**
848
+ * Reduce a list of *literal* IN seek values to the effective distinct, non-null
849
+ * set, so the multi-seek's advertised `inCount` matches the number of seeks the
850
+ * runtime actually performs. Mirrors the runtime set-membership semantics in
851
+ * `scan-layer.ts`: a NULL seek key contributes no match (skipped), and duplicate
852
+ * seek keys collapse.
853
+ *
854
+ * This is a strict *subset* of the runtime dedup — it only collapses values that
855
+ * are equal under the default binary comparator, since the column's collation is
856
+ * unknown at plan time. The runtime remains the authority and may collapse
857
+ * further (e.g. NOCASE case-variants that hit the same index entry). Literal-only:
858
+ * dynamic/parameter seek values are never reduced here.
859
+ */
860
+ function reduceLiteralSeekValues(values) {
861
+ const result = [];
862
+ for (const v of values) {
863
+ if (v === null)
864
+ continue;
865
+ if (result.some(kept => compareSqlValues(kept, v) === 0))
866
+ continue;
867
+ result.push(v);
868
+ }
869
+ return result;
870
+ }
871
+ /**
872
+ * Composite analogue of {@link reduceLiteralSeekValues}: drop any cross-product
873
+ * tuple with a NULL component (mirrors `scan-layer.ts`'s `seekKeyHasNull` for
874
+ * row-value seeks — a NULL component makes the comparison NULL ⇒ no match) and
875
+ * collapse duplicate tuples. Tuples are compared componentwise under the default
876
+ * binary comparator; literal-only, same subset rationale as the scalar case.
877
+ */
878
+ function reduceLiteralSeekTuples(tuples) {
879
+ const result = [];
880
+ for (const tuple of tuples) {
881
+ if (tuple.some(v => v === null))
882
+ continue;
883
+ const isDup = result.some(kept => kept.length === tuple.length && kept.every((kv, i) => compareSqlValues(kv, tuple[i]) === 0));
884
+ if (isDup)
885
+ continue;
886
+ result.push(tuple);
887
+ }
888
+ return result;
889
+ }
890
+ /**
891
+ * Resolve a predicate constraint's effective comparison collation at plan time
892
+ * via the shared helpers in `analysis/comparison-collation.ts` (one resolution
893
+ * for plan-time facts and runtime behavior — they cannot drift): the symmetric
894
+ * provenance lattice (explicit COLLATE > declared column collation > defaults
895
+ * > BINARY). An IN merges the condition with every listed value / the subquery
896
+ * column (`emitIn`); a BETWEEN bound resolves against the tested expression
897
+ * per bound (`emitBetween`). The result is normalized.
898
+ */
899
+ function effectivePredicateCollation(constraint) {
900
+ const src = constraint.sourceExpression;
901
+ if (src instanceof BinaryOpNode) {
902
+ return effectiveComparisonCollation(src.left, src.right);
903
+ }
904
+ if (src instanceof InNode) {
905
+ return effectiveInCollation(src);
906
+ }
907
+ if (src instanceof BetweenNode) {
908
+ // BETWEEN desugars to `expr >= lo AND expr <= hi`; each comparison
909
+ // resolves its collation independently through the lattice.
910
+ // extractBetweenConstraints emits two constraints sharing this BetweenNode
911
+ // source — `op: '>='`/`'>'` for the lower bound, `'<='`/`'<'` for the
912
+ // upper — so the constraint's op selects which bound's collation applies. A
913
+ // `COLLATE` on a bound survives folding (it rides on the bound's type), so
914
+ // the bound collation can and must reach this point.
915
+ const bound = (constraint.op === '<=' || constraint.op === '<') ? src.upper : src.lower;
916
+ return effectiveBetweenBoundCollation(src.expr, bound);
917
+ }
918
+ // OR_RANGE carries an OR BinaryOpNode source (handled above); any other shape
919
+ // defaults to BINARY, which only ever drives a (safe) decline on mismatch.
920
+ return 'BINARY';
921
+ }
922
+ /**
923
+ * Build a collation lookup for the columns of a module-provided index. Secondary
924
+ * index columns carry their own (already-normalized) collation; the primary key
925
+ * (`_primary_`/`primary`) falls back to the table column's declared collation.
926
+ */
927
+ function indexColumnCollationLookup(tableSchema, accessPlan) {
928
+ const indexName = accessPlan.indexName;
929
+ const isPrimary = indexName === '_primary_' || indexName === 'primary';
930
+ const index = isPrimary ? undefined : tableSchema.indexes?.find(i => i.name === indexName);
931
+ return (colIdx) => {
932
+ if (isPrimary) {
933
+ return normalizeCollationName(tableSchema.columns[colIdx]?.collation ?? 'BINARY');
934
+ }
935
+ const idxCol = index?.columns.find(c => c.index === colIdx);
936
+ return normalizeCollationName(idxCol?.collation ?? 'BINARY');
937
+ };
938
+ }
939
+ /**
940
+ * Build a collation lookup for primary-key columns (used by the legacy seek path,
941
+ * which addresses the PK directly without a module-provided index identity).
942
+ */
943
+ function primaryKeyCollationLookup(tableSchema) {
944
+ return (colIdx) => normalizeCollationName(tableSchema.columns[colIdx]?.collation ?? 'BINARY');
945
+ }
946
+ /**
947
+ * Cover relation for a single seek column. See {@link CollationCover}.
948
+ *
949
+ * `honorsCollatedRangeBounds` is the module's advertisement (off by default) that its
950
+ * runtime filters range bounds under the index collation rather than BINARY; it gates
951
+ * the non-BINARY range MATCH and is ignored for equality.
952
+ */
953
+ function classifyConstraintCover(predColl, indexColl, isEquality, honorsCollatedRangeBounds) {
954
+ if (isEquality) {
955
+ if (predColl === indexColl)
956
+ return 'MATCH';
957
+ // BINARY equality ⟹ equal under any collation, so a non-BINARY index over-fetches
958
+ // a superset that an equality residual can recover. NOCASE/RTRIM are mutually
959
+ // incomparable and a finer index under-fetches — neither is salvageable.
960
+ if (predColl === 'BINARY' && indexColl !== 'BINARY') {
961
+ return 'COARSER_SAFE';
962
+ }
963
+ return 'MISMATCH_UNSAFE';
964
+ }
965
+ // Range (non-equality) seek. A BINARY-over-BINARY range always reproduces the
966
+ // predicate. A collation-MATCHED non-BINARY range (predColl === indexColl ≠ BINARY)
967
+ // reproduces it ONLY when the module's runtime filters the bounds — and
968
+ // early-terminates the walk — under that same index collation; the in-memory vtab
969
+ // does (`plan-filter.ts` / `scan-layer.ts`, threaded via `scan-plan.ts`), as does
970
+ // the store (collation-aware post-fetch filter, `StoreTable.compareValues`), and both
971
+ // advertise `honorsCollatedRangeBounds`, whereas a module that bound-filters BINARY
972
+ // would under-fetch case/space variants. Any collation MISMATCH reorders the walked
973
+ // window relative to the predicate's intended order and is never a recoverable
974
+ // superset (unlike a COARSER_SAFE equality), so it always declines.
975
+ if (predColl === indexColl && (predColl === 'BINARY' || honorsCollatedRangeBounds))
976
+ return 'MATCH';
977
+ return 'MISMATCH_UNSAFE';
978
+ }
979
+ /**
980
+ * Classify a seek's consumed constraints by the collation-cover relation and derive
981
+ * an aggregate decision:
982
+ * - any `MISMATCH_UNSAFE` → decline the seek; the caller scans and re-applies the
983
+ * AND of *all* consumed constraints as a residual (so the scan stays filtered).
984
+ * - else all `MATCH` → use the seek with no residual.
985
+ * - else (some `COARSER_SAFE`) → use the seek but re-apply the AND of the
986
+ * `COARSER_SAFE` constraints as a residual to discard the over-fetched rows.
987
+ *
988
+ * `isEquality` gates the `COARSER_SAFE` class: a coarser index can only over-fetch a
989
+ * *superset* for an equality/IN seek. For a range/prefix-range/OR_RANGE seek a
990
+ * collation mismatch reorders the index, so the walked window is not a superset and
991
+ * any mismatch is `MISMATCH_UNSAFE`. `honorsCollatedRangeBounds` (the module's
992
+ * advertisement, off by default) gates the collation-matched non-BINARY range MATCH;
993
+ * it is forwarded to {@link classifyConstraintCover} and ignored for equality.
994
+ */
995
+ function classifyCollationCover(consumed, isEquality, collationForColumn, honorsCollatedRangeBounds) {
996
+ const allResiduals = [];
997
+ const coarserResiduals = [];
998
+ let anyUnsafe = false;
999
+ for (const { colIdx, constraint } of consumed) {
1000
+ allResiduals.push(constraint.sourceExpression);
1001
+ const predColl = effectivePredicateCollation(constraint);
1002
+ const indexColl = collationForColumn(colIdx);
1003
+ const cover = classifyConstraintCover(predColl, indexColl, isEquality, honorsCollatedRangeBounds);
1004
+ if (cover === 'COARSER_SAFE') {
1005
+ coarserResiduals.push(constraint.sourceExpression);
1006
+ }
1007
+ else if (cover === 'MISMATCH_UNSAFE') {
1008
+ anyUnsafe = true;
1009
+ }
1010
+ }
1011
+ if (anyUnsafe) {
1012
+ return { useIndex: false, residual: combineResidualExpressions(allResiduals) };
1013
+ }
1014
+ if (coarserResiduals.length > 0) {
1015
+ return { useIndex: true, residual: combineResidualExpressions(coarserResiduals) };
1016
+ }
1017
+ return { useIndex: true };
1018
+ }
1019
+ /**
1020
+ * AND-combine residual `sourceExpression`s into one predicate, de-duplicating by
1021
+ * identity (a BETWEEN yields two constraints sharing one source node). Mirrors the
1022
+ * `combineParts`/`combineResiduals` shape in constraint-extractor.ts.
1023
+ */
1024
+ function combineResidualExpressions(exprs) {
1025
+ const unique = [];
1026
+ for (const e of exprs) {
1027
+ if (!unique.includes(e))
1028
+ unique.push(e);
1029
+ }
1030
+ if (unique.length === 0)
1031
+ return undefined;
1032
+ let acc = unique[0];
1033
+ for (let i = 1; i < unique.length; i++) {
1034
+ const right = unique[i];
1035
+ const ast = { type: 'binary', operator: 'AND', left: acc.expression, right: right.expression };
1036
+ acc = new BinaryOpNode(acc.scope, ast, acc, right);
1037
+ }
1038
+ return acc;
1039
+ }
642
1040
  //# sourceMappingURL=rule-select-access-path.js.map