@quereus/quereus 3.3.0 → 4.0.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 +203 -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 +713 -26
  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 +9 -0
  80. package/dist/src/func/registration.d.ts.map +1 -1
  81. package/dist/src/func/registration.js +4 -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 +13 -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 +6 -5
@@ -8,8 +8,9 @@ import { createLogger } from '../../common/logger.js';
8
8
  import { ColumnReferenceNode, ParameterReferenceNode } from '../nodes/reference.js';
9
9
  import { BetweenNode, BinaryOpNode, CastNode, CollateNode, LiteralNode, UnaryOpNode } from '../nodes/scalar.js';
10
10
  import { InNode } from '../nodes/subquery.js';
11
- import { compareSqlValues } from '../../util/comparison.js';
11
+ import { compareSqlValues, normalizeCollationName } from '../../util/comparison.js';
12
12
  import { flipComparison } from '../analysis/predicate-shape.js';
13
+ import { effectiveBetweenBoundCollation, effectiveComparisonCollation, effectiveInCollation, isValueDiscriminatingEquality, operandCollation } from '../analysis/comparison-collation.js';
13
14
  const log = createLogger('planner:fd');
14
15
  /**
15
16
  * Per-node cap on the number of FDs we materialize. The propagation rules
@@ -51,6 +52,8 @@ export function computeClosure(attrs, fds) {
51
52
  * column indices, then concatenate with the existing FDs. For a class
52
53
  * `{c0, c1, ..., ck}` this emits `{ci} → {cj}` for every distinct ordered pair
53
54
  * — enough for `computeClosure` to derive every member from any one of them.
55
+ * EC-derived FDs are pure value claims (`kind: 'determination'`) — an equality
56
+ * never implies row-uniqueness of either endpoint.
54
57
  */
55
58
  export function expandEcsToFds(ecs, fds) {
56
59
  const out = fds.slice();
@@ -61,7 +64,7 @@ export function expandEcsToFds(ecs, fds) {
61
64
  for (let j = 0; j < cls.length; j++) {
62
65
  if (i === j)
63
66
  continue;
64
- out.push({ determinants: [cls[i]], dependents: [cls[j]] });
67
+ out.push({ determinants: [cls[i]], dependents: [cls[j]], kind: 'determination' });
65
68
  }
66
69
  }
67
70
  }
@@ -110,6 +113,9 @@ export function minimalCover(attrs, fds) {
110
113
  // collapse to one in `addFd` / `mergeFds`. The first-merged source wins —
111
114
  // table references merge declared-check contributions before hoisted
112
115
  // assertion contributions, so `declared-check` is preferred on collisions.
116
+ // `kind` and `valueEquality` are likewise NOT compared; `addFd` reconciles
117
+ // `kind` on collisions with an "'unique' wins" rule (uniqueness is a property
118
+ // of the determinant set, so equal-determinant claims compose).
113
119
  function fdsEqual(a, b) {
114
120
  if (a.determinants.length !== b.determinants.length)
115
121
  return false;
@@ -233,33 +239,52 @@ function dependentsSubset(sub, sup) {
233
239
  * Guard-aware: FDs with different `guard` predicates are kept side-by-side
234
240
  * even when their determinants/dependents match — they are logically distinct
235
241
  * facts and may be activated by different surrounding predicates.
242
+ *
243
+ * Kind reconciliation: on a merge between entries with equal determinants and
244
+ * guards, the surviving entry's `kind` is `'unique'` when EITHER side claims
245
+ * it — uniqueness is a property of the determinant set, so equal-determinant
246
+ * claims compose. This includes upgrading a kept 'determination' entry in
247
+ * place when the subsumed newcomer is 'unique'. Equal-determinant entries with
248
+ * incomparable dependent sets both survive and each keeps its own kind (a
249
+ * sound under-claim). Object identity is preserved when nothing changes.
236
250
  */
237
251
  export function addFd(fds, next, opts = {}) {
238
252
  if (next.dependents.length === 0)
239
253
  return fds.slice();
240
254
  const result = [];
241
255
  let subsumedByExisting = false;
256
+ // 'unique' wins on merge: a dropped-or-subsumed 'unique' twin upgrades the survivor.
257
+ let nextKind = next.kind;
242
258
  for (const existing of fds) {
243
259
  if (fdsEqual(existing, next)) {
244
260
  subsumedByExisting = true;
245
- result.push(existing);
261
+ result.push(next.kind === 'unique' && existing.kind !== 'unique'
262
+ ? { ...existing, kind: 'unique' }
263
+ : existing);
246
264
  continue;
247
265
  }
248
266
  if (determinantsEqual(existing.determinants, next.determinants) &&
249
267
  guardsEqual(existing.guard, next.guard)) {
250
268
  // Same determinants and guard: keep whichever has the larger dependent set.
251
269
  if (dependentsSubset(existing.dependents, next.dependents)) {
252
- // existing ⊂ next, drop existing
270
+ // existing ⊂ next, drop existing — its uniqueness claim survives on next.
271
+ if (existing.kind === 'unique')
272
+ nextKind = 'unique';
253
273
  continue;
254
274
  }
255
275
  if (dependentsSubset(next.dependents, existing.dependents)) {
256
276
  subsumedByExisting = true;
277
+ result.push(next.kind === 'unique' && existing.kind !== 'unique'
278
+ ? { ...existing, kind: 'unique' }
279
+ : existing);
280
+ continue;
257
281
  }
258
282
  }
259
283
  result.push(existing);
260
284
  }
261
- if (!subsumedByExisting)
262
- result.push(next);
285
+ if (!subsumedByExisting) {
286
+ result.push(nextKind === next.kind ? next : { ...next, kind: nextKind });
287
+ }
263
288
  return enforceCap(result, opts);
264
289
  }
265
290
  function enforceCap(fds, opts) {
@@ -275,12 +300,19 @@ function enforceCap(fds, opts) {
275
300
  };
276
301
  const preferred = fds.filter(fd => isSubsetOfAnyKey(fd.determinants));
277
302
  const other = fds.filter(fd => !isSubsetOfAnyKey(fd.determinants));
303
+ // Quality bias within each partition: keep 'unique' FDs ahead of plain
304
+ // determinations. Evicting a uniqueness witness can only cause downstream
305
+ // under-claims (sound), but it is cheap to avoid.
306
+ const uniqueFirst = (list) => [
307
+ ...list.filter(fd => fd.kind === 'unique'),
308
+ ...list.filter(fd => fd.kind !== 'unique'),
309
+ ];
278
310
  let kept;
279
311
  if (preferred.length >= cap) {
280
- kept = preferred.slice(0, cap);
312
+ kept = uniqueFirst(preferred).slice(0, cap);
281
313
  }
282
314
  else {
283
- kept = preferred.concat(other.slice(0, cap - preferred.length));
315
+ kept = preferred.concat(uniqueFirst(other).slice(0, cap - preferred.length));
284
316
  }
285
317
  log('FD cap reached: dropped %d FD(s) from %d', fds.length - kept.length, fds.length);
286
318
  return kept;
@@ -307,6 +339,14 @@ export function mergeFds(a, b, opts = {}) {
307
339
  * Guarded FDs additionally require every column referenced in `guard.clauses`
308
340
  * to be in the mapping — if any guard column is dropped the guard becomes
309
341
  * unobservable and the FD can never be re-activated downstream.
342
+ *
343
+ * Rebuilds via spread so `kind` / `source` / `valueEquality` survive verbatim.
344
+ * Preserving `kind` is sound: a projection maps rows 1:1 (no merge, no
345
+ * duplication), so determinant row-uniqueness survives whenever the
346
+ * determinants survive — which the determinant-loss drop above already
347
+ * requires. The empty-determinant exception keeps its kind too: a 'unique'
348
+ * singleton stays ≤1-row under projection; a 'determination' constant pin
349
+ * stays a mere pin.
310
350
  */
311
351
  export function projectFds(fds, mapping) {
312
352
  const result = [];
@@ -339,8 +379,8 @@ export function projectFds(fds, mapping) {
339
379
  newGuard = mappedGuard;
340
380
  }
341
381
  result.push(newGuard
342
- ? { determinants: newDet, dependents: newDep, guard: newGuard }
343
- : { determinants: newDet, dependents: newDep });
382
+ ? { ...fd, determinants: newDet, dependents: newDep, guard: newGuard }
383
+ : { ...fd, determinants: newDet, dependents: newDep });
344
384
  }
345
385
  return result;
346
386
  }
@@ -395,12 +435,18 @@ function projectClause(clause, mapping) {
395
435
  }
396
436
  }
397
437
  }
398
- /** Shift all column indices in `fds` (including any `guard` columns) by `offset`. */
438
+ /**
439
+ * Shift all column indices in `fds` (including any `guard` columns) by `offset`.
440
+ * Rebuilds via spread so `kind` / `source` / `valueEquality` survive verbatim —
441
+ * a shift is a pure column relabel, so every claim (uniqueness included) holds
442
+ * unchanged on the relabeled columns.
443
+ */
399
444
  export function shiftFds(fds, offset) {
400
445
  if (offset === 0)
401
446
  return fds.slice();
402
447
  return fds.map(fd => {
403
448
  const shifted = {
449
+ ...fd,
404
450
  determinants: fd.determinants.map(d => d + offset),
405
451
  dependents: fd.dependents.map(d => d + offset),
406
452
  };
@@ -428,14 +474,18 @@ function shiftClause(clause, offset) {
428
474
  }
429
475
  }
430
476
  /**
431
- * Return the unconditional twin of `fd` — drop the guard but keep determinants
432
- * and dependents. Used by Filter activation when the surrounding predicate
433
- * entails the guard.
477
+ * Return the unconditional twin of `fd` — drop the guard but keep every other
478
+ * field (`kind` / `source` / `valueEquality` survive verbatim). Used by Filter
479
+ * activation when the surrounding predicate entails the guard. Preserving
480
+ * 'unique' is sound at the activating Filter: its rows all satisfy the guard,
481
+ * and filtering only shrinks the row set — fan-out hazards are handled by the
482
+ * join-side downgrade, not here.
434
483
  */
435
484
  export function stripGuard(fd) {
436
485
  if (fd.guard === undefined)
437
486
  return fd;
438
- return { determinants: fd.determinants, dependents: fd.dependents };
487
+ const { guard: _guard, ...rest } = fd;
488
+ return rest;
439
489
  }
440
490
  /** Shift all column indices in `classes` by `offset`. */
441
491
  export function shiftEquivClasses(classes, offset) {
@@ -491,6 +541,11 @@ export function addEquivalence(classes, a, b) {
491
541
  * way to encode "K is a unique key on a relation": K determines every other
492
542
  * output column. K = ∅ produces the "at-most-one-row" singleton FD.
493
543
  *
544
+ * Emits `kind: 'unique'` — every caller passes a genuine key (declared or
545
+ * projected keys, fan-out-aware join `preservedKeys`, the aggregate group key,
546
+ * the set-op data-columns key, lens key obligations, TVF-declared keys), so
547
+ * the relation has at most one row per determinant tuple at the minting site.
548
+ *
494
549
  * Returns undefined when K covers every column (the all-columns case has no
495
550
  * non-trivial encoding — that case is communicated via `RelationType.isSet`
496
551
  * instead).
@@ -504,14 +559,19 @@ export function superkeyToFd(key, columnCount) {
504
559
  }
505
560
  if (dependents.length === 0)
506
561
  return undefined;
507
- return { determinants: key.slice(), dependents };
562
+ return { determinants: key.slice(), dependents, kind: 'unique' };
508
563
  }
509
564
  /**
510
- * True iff the closure of `attrs` under `fds` covers `{0..columnCount-1}` —
511
- * i.e., `attrs` is a superkey of the relation. Replaces the legacy "covers a
512
- * `uniqueKeys` entry" check; FDs are the canonical surface now.
565
+ * True iff the closure of `attrs` under `fds` covers `{0..columnCount-1}`.
566
+ * COVERAGE ONLY — this is a pure value-determination claim and says NOTHING
567
+ * about row-uniqueness: over a bag, a determination-only closure path can
568
+ * cover every column while the relation still holds duplicate rows. For the
569
+ * uniqueness question ("at most one row per attrs-tuple?") use
570
+ * `isUniqueDeterminant`. (Renamed from `isSuperkey`, whose name read as a
571
+ * uniqueness claim and invited exactly that misuse — ticket
572
+ * `fd-determination-reader-side-rule`.)
513
573
  */
514
- export function isSuperkey(attrs, fds, columnCount) {
574
+ export function closureCoversAll(attrs, fds, columnCount) {
515
575
  if (columnCount <= 0)
516
576
  return true;
517
577
  const closure = computeClosure(attrs, fds ?? []);
@@ -521,16 +581,52 @@ export function isSuperkey(attrs, fds, columnCount) {
521
581
  }
522
582
  return true;
523
583
  }
584
+ /**
585
+ * True iff `attrs` is provably row-unique on the relation: its FD closure
586
+ * covers every column AND uniqueness is reachable —
587
+ * - the relation is a set (two rows agreeing on `attrs` would agree on all
588
+ * columns = a duplicate, impossible in a set), or
589
+ * - some unguarded `kind: 'unique'` FD has determinants ⊆ closure(attrs)
590
+ * (rows agreeing on `attrs` agree on that unique determinant set; ≤1 row
591
+ * per its tuple ⇒ ≤1 row per attrs-tuple).
592
+ *
593
+ * Coverage alone (a determination-only closure path over a bag) proves
594
+ * nothing — that is the over-claim family the kind-aware readers exist to
595
+ * prevent (ticket `fd-determination-reader-side-rule`). This is the single
596
+ * reader-side uniqueness primitive; producers no longer gate determinations.
597
+ *
598
+ * Guarded FDs participate in neither branch: `computeClosure` skips them, and
599
+ * only UNguarded 'unique' FDs can witness (a guarded uniqueness claim holds
600
+ * only under its predicate, which this layer cannot see).
601
+ */
602
+ export function isUniqueDeterminant(attrs, fds, columnCount, isSet) {
603
+ const fdList = fds ?? [];
604
+ const closure = computeClosure(attrs, fdList);
605
+ for (let i = 0; i < columnCount; i++) {
606
+ if (!closure.has(i))
607
+ return false;
608
+ }
609
+ if (isSet)
610
+ return true;
611
+ return fdList.some(fd => fd.guard === undefined &&
612
+ fd.kind === 'unique' &&
613
+ fd.determinants.every(d => closure.has(d)));
614
+ }
524
615
  /**
525
616
  * Enumerate the minimal full-cover key sets discoverable from `fds`: for each
526
- * FD `K → Y` whose closure covers all columns, return `K` (greedily minimized
527
- * within `K`). Deduplicated by set equality.
617
+ * FD `K → Y` where `K` is a provably row-unique determinant
618
+ * (`isUniqueDeterminant` coverage AND uniqueness reachability), return `K`
619
+ * (greedily minimized within `K`). Deduplicated by set equality.
620
+ *
621
+ * `minimalCover` preserves the closure, so the minimized key keeps both
622
+ * coverage and the unique witness (witness determinants ⊆ the unchanged
623
+ * closure).
528
624
  *
529
- * Excludes the trivial "all-columns is a superkey" tautology — only FDs with
530
- * `K ⊊ all_cols` are considered, since the all-cols case is encoded via
531
- * `RelationType.isSet`.
625
+ * Excludes the trivial "all-columns is a key of a set" tautology — only FDs
626
+ * with `K ⊊ all_cols` are considered, since the all-cols case is encoded via
627
+ * `RelationType.isSet` (the `keysOf` fallback).
532
628
  */
533
- export function deriveKeysFromFds(fds, columnCount) {
629
+ export function deriveKeysFromFds(fds, columnCount, isSet) {
534
630
  if (!fds || fds.length === 0)
535
631
  return [];
536
632
  const results = [];
@@ -541,11 +637,9 @@ export function deriveKeysFromFds(fds, columnCount) {
541
637
  if (fd.determinants.length >= columnCount)
542
638
  continue;
543
639
  const det = new Set(fd.determinants);
544
- if (!isSuperkey(det, fds, columnCount))
640
+ if (!isUniqueDeterminant(det, fds, columnCount, isSet))
545
641
  continue;
546
642
  const minimal = minimalCover(det, fds);
547
- // Ensure the minimal cover still covers all columns (it should — minimalCover
548
- // only drops attrs whose removal doesn't change closure).
549
643
  const sorted = Array.from(minimal).sort((a, b) => a - b);
550
644
  const key = sorted.join(',');
551
645
  if (seen.has(key))
@@ -557,35 +651,42 @@ export function deriveKeysFromFds(fds, columnCount) {
557
651
  }
558
652
  /**
559
653
  * True iff the FD set encodes any non-trivial key — i.e., there exists some
560
- * FD whose determinants form a superkey of `columnCount` columns with the
561
- * determinant set strictly smaller than all columns. This is the FD-surface
562
- * replacement for "the relation has a known unique key smaller than its full
563
- * column list" (the old `uniqueKeys.length > 0` check), excluding the
564
- * tautological all-columns case which carries no information.
654
+ * FD whose determinants are a provably row-unique determinant set
655
+ * (`isUniqueDeterminant`) strictly smaller than all columns. This is the
656
+ * FD-surface replacement for "the relation has a known unique key smaller
657
+ * than its full column list" (the old `uniqueKeys.length > 0` check),
658
+ * excluding the tautological all-columns case which carries no information.
565
659
  */
566
- export function hasAnyKey(fds, columnCount) {
660
+ export function hasAnyKey(fds, columnCount, isSet) {
567
661
  if (!fds || fds.length === 0)
568
662
  return false;
569
663
  return fds.some(fd => fd.guard === undefined &&
570
664
  fd.determinants.length < columnCount &&
571
- isSuperkey(new Set(fd.determinants), fds, columnCount));
665
+ isUniqueDeterminant(new Set(fd.determinants), fds, columnCount, isSet));
572
666
  }
573
667
  /**
574
- * True iff the relation has at-most-one-row i.e., some FD `∅ → Y` exists
575
- * whose closure covers every column. Replaces the legacy `[[]]` singleton
576
- * marker on `uniqueKeys`.
668
+ * True iff the relation is provably at-most-one-row from its FD surface
669
+ * `isUniqueDeterminant(∅, …)`: the closure of the empty set covers every
670
+ * column AND uniqueness is reachable (the relation is a set, or an unguarded
671
+ * 'unique' FD witnesses). Replaces the legacy `[[]]` singleton marker on
672
+ * `uniqueKeys`.
673
+ *
674
+ * On a bag, constant pins (`∅ → col` determinations from `where a = 1`) no
675
+ * longer over-claim ≤1-row; on a set, pinning every column IS a sound ≤1-row
676
+ * derivation. Zero-column relations return false — the `∅ → all_cols` FD is
677
+ * unrepresentable there, so the ≤1-row claim rides `estimatedRows` instead
678
+ * (see `characteristics.guaranteesUniqueRows`).
577
679
  */
578
- export function hasSingletonFd(fds, columnCount) {
579
- if (!fds)
680
+ export function hasSingletonFd(fds, columnCount, isSet) {
681
+ if (columnCount <= 0)
580
682
  return false;
581
- return fds.some(fd => fd.guard === undefined &&
582
- fd.determinants.length === 0 &&
583
- isSuperkey(new Set(), fds, columnCount));
683
+ return isUniqueDeterminant(new Set(), fds, columnCount, isSet);
584
684
  }
585
685
  /**
586
686
  * Build the singleton FD `∅ → {0..columnCount-1}` that encodes
587
- * "at-most-one-row". Returns undefined when `columnCount === 0` (no
588
- * dependents).
687
+ * "at-most-one-row". `kind: 'unique'` row-unique ≤1 row, which is
688
+ * exactly what every caller asserts. Returns undefined when
689
+ * `columnCount === 0` (no dependents).
589
690
  */
590
691
  export function singletonFd(columnCount) {
591
692
  if (columnCount <= 0)
@@ -593,39 +694,21 @@ export function singletonFd(columnCount) {
593
694
  const dependents = [];
594
695
  for (let i = 0; i < columnCount; i++)
595
696
  dependents.push(i);
596
- return { determinants: [], dependents };
697
+ return { determinants: [], dependents, kind: 'unique' };
597
698
  }
598
699
  /**
599
- * True iff `attrs` is asserted to be a unique key by the FD set — i.e., there
600
- * exists some FD whose determinants are a subset of `attrs` and whose closure
601
- * covers all columns. Stricter than `isSuperkey`: the trivial "all-cols is a
602
- * superkey of itself" tautology does NOT count, because no FD makes that claim.
700
+ * Fold the singleton FD `∅ {0..columnCount-1}` ("at-most-one-row") into `fds`
701
+ * via `addFd`. The canonical producer-side spelling of the ≤1-row fact every
702
+ * `computePhysical` site that proves a relation emits ≤1 row should reach for
703
+ * this rather than open-coding `singletonFd` + `addFd`.
603
704
  *
604
- * Use this when you need a positive uniqueness claim (e.g., the
605
- * sort/window strict-monotonicOn check). For "would attrs functionally
606
- * determine the rest of the relation under closure?" use `isSuperkey` directly.
705
+ * A no-op returning a copy of `fds` when `columnCount === 0` (since
706
+ * `singletonFd(0)` is `undefined` — a zero-column relation cannot carry the
707
+ * marker). Pairs with the `hasSingletonFd` / `isAtMostOneRow` read surface.
607
708
  */
608
- export function isAssertedKey(attrs, fds, columnCount) {
609
- if (!fds || fds.length === 0)
610
- return false;
611
- for (const fd of fds) {
612
- if (fd.guard !== undefined)
613
- continue;
614
- // Determinants must be a subset of attrs.
615
- let subset = true;
616
- for (const d of fd.determinants) {
617
- if (!attrs.has(d)) {
618
- subset = false;
619
- break;
620
- }
621
- }
622
- if (!subset)
623
- continue;
624
- // Determinants closure must cover all columns.
625
- if (isSuperkey(new Set(fd.determinants), fds, columnCount))
626
- return true;
627
- }
628
- return false;
709
+ export function addSingletonFd(fds, columnCount) {
710
+ const singleton = singletonFd(columnCount);
711
+ return singleton ? addFd(fds, singleton) : fds.slice();
629
712
  }
630
713
  /**
631
714
  * Normalize a list of candidate keys to the minimal, deduped set:
@@ -703,12 +786,14 @@ export function keysOf(rel) {
703
786
  for (const key of type.keys) {
704
787
  keys.push(key.map(ref => ref.index));
705
788
  }
706
- // 2. `∅ → all_cols` ⇒ at-most-one-row ⇒ the empty key.
707
- if (hasSingletonFd(fds, columnCount)) {
789
+ // 2. Provable ≤1-row (kind-aware) ⇒ the empty key.
790
+ if (hasSingletonFd(fds, columnCount, type.isSet)) {
708
791
  keys.push([]);
709
792
  }
710
793
  // 3. FD-derived keys (already bounded to FDs with det.length < columnCount).
711
- for (const k of deriveKeysFromFds(fds, columnCount)) {
794
+ // `isSet` threads through so a determination-only covering determinant over
795
+ // a set (e.g. above a DISTINCT) derives a genuine key.
796
+ for (const k of deriveKeysFromFds(fds, columnCount, type.isSet)) {
712
797
  keys.push(k);
713
798
  }
714
799
  const normalized = normalizeKeys(keys);
@@ -727,14 +812,14 @@ export function keysOf(rel) {
727
812
  * - `cols` is a (non-strict) superset of some `keysOf(rel)` entry (covers
728
813
  * declared keys, the ≤1-row empty key, FD-derived keys, and the
729
814
  * all-columns/set key), OR
730
- * - `cols` is a **proper subset** of the columns whose FD closure covers all
731
- * columns (`isSuperkey`) — this proves a superkey even when it is absent
732
- * from the minimal `keysOf` list.
815
+ * - `cols` is a provably row-unique determinant (`isUniqueDeterminant`:
816
+ * closure coverage AND uniqueness reachability) — this proves a superkey
817
+ * even when it is absent from the minimal `keysOf` list.
733
818
  *
734
- * The closure branch is deliberately restricted to proper subsets: the closure
735
- * of the full column set is trivially the full set, so without the guard a bag
736
- * would be falsely reported unique on its all-columns set. The all-columns case
737
- * is handled soundly by the `keysOf` branch above, which gates it on `isSet`.
819
+ * No all-columns guard is needed on the closure branch: an all-columns probe
820
+ * on a bag fails `isUniqueDeterminant` on its own (no unique FD false; if a
821
+ * unique FD exists the relation cannot hold duplicate rows, so true is
822
+ * correct).
738
823
  */
739
824
  export function isUnique(cols, rel) {
740
825
  const type = rel.getType();
@@ -744,10 +829,24 @@ export function isUnique(cols, rel) {
744
829
  if (key.every(c => colSet.has(c)))
745
830
  return true;
746
831
  }
747
- if (colSet.size < columnCount && isSuperkey(colSet, rel.physical?.fds, columnCount)) {
748
- return true;
749
- }
750
- return false;
832
+ return isUniqueDeterminant(colSet, rel.physical?.fds, columnCount, type.isSet);
833
+ }
834
+ /**
835
+ * The single named spelling of the node-level "at-most-one-row" predicate:
836
+ * true iff `rel` is provably ≤1-row. Defined as `isUnique([], rel)` — the empty
837
+ * key is a subset of every column set, so a relation carrying it (via a declared
838
+ * empty key, the `∅ → all_cols` singleton FD, or any other channel `keysOf`
839
+ * reconciles) reports unique on the empty column list.
840
+ *
841
+ * Use this at node / rule level. The FD-only `hasSingletonFd` is the lower-level
842
+ * test `keysOf` itself calls; `isAtMostOneRow` is the surface consumers (joins,
843
+ * sort elimination) should reach for. Note it does **not** capture the
844
+ * zero-column `estimatedRows === 1` case — a zero-column relation has no
845
+ * representable empty key — so consumers needing that fallback keep their own
846
+ * check (see `characteristics.guaranteesUniqueRows`).
847
+ */
848
+ export function isAtMostOneRow(rel) {
849
+ return isUnique([], rel);
751
850
  }
752
851
  /**
753
852
  * Walk `predicate` (assumed to be a normalized conjunction) and extract FDs,
@@ -765,6 +864,19 @@ export function isUnique(cols, rel) {
765
864
  * equivalence pair `[col1, col2]`.
766
865
  *
767
866
  * Non-equality conjuncts contribute nothing.
867
+ *
868
+ * **Collation gate.** Every extracted fact is a VALUE-level claim (a pinned
869
+ * column has one value across rows; `col1 = col2` rows are value-equal), so a
870
+ * conjunct only contributes when its comparison is value-discriminating
871
+ * (`isValueDiscriminatingEquality`): for textual operands the effective
872
+ * comparison collation must be BINARY. A NOCASE/RTRIM comparison — via a
873
+ * `COLLATE` wrapper on either side or a non-BINARY declared column collation —
874
+ * passes value-DIFFERENT rows ('Bob' = 'bob' NOCASE), so its facts would
875
+ * over-claim (false ≤1-row keys, false EC-driven inferences, wrong insert
876
+ * defaults — ticket `collation-blind-equality-fact-extraction`). Declared-
877
+ * collation covered-key ≤1-row detection is NOT lost: it flows through the
878
+ * independent (and collation-sound) `extractConstraints` path in
879
+ * `FilterNode.computePhysical`.
768
880
  */
769
881
  export function extractEqualityFds(predicate, attrIdToIndex) {
770
882
  const fds = [];
@@ -782,6 +894,9 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
782
894
  }
783
895
  if (op !== '=')
784
896
  continue;
897
+ // Value-level facts only from value-discriminating comparisons (see doc).
898
+ if (!isValueDiscriminatingEquality(n.left, n.right))
899
+ continue;
785
900
  const lIsCol = n.left instanceof ColumnReferenceNode;
786
901
  const rIsCol = n.right instanceof ColumnReferenceNode;
787
902
  const lConst = constantValueOf(n.left);
@@ -790,8 +905,10 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
790
905
  const lIdx = attrIdToIndex.get(n.left.attributeId);
791
906
  const rIdx = attrIdToIndex.get(n.right.attributeId);
792
907
  if (lIdx !== undefined && rIdx !== undefined && lIdx !== rIdx) {
793
- fds.push({ determinants: [lIdx], dependents: [rIdx] });
794
- fds.push({ determinants: [rIdx], dependents: [lIdx] });
908
+ // Mirror FDs from `col1 = col2` are pure value claims — equality
909
+ // never makes either endpoint row-unique.
910
+ fds.push({ determinants: [lIdx], dependents: [rIdx], kind: 'determination' });
911
+ fds.push({ determinants: [rIdx], dependents: [lIdx], kind: 'determination' });
795
912
  equivPairs.push([lIdx, rIdx]);
796
913
  }
797
914
  continue;
@@ -799,7 +916,9 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
799
916
  if (lIsCol && rConst !== undefined) {
800
917
  const lIdx = attrIdToIndex.get(n.left.attributeId);
801
918
  if (lIdx !== undefined) {
802
- fds.push({ determinants: [], dependents: [lIdx] });
919
+ // `∅ col` from a constant pin is deliberately 'determination': a
920
+ // pinned column does NOT imply the relation has at most one row.
921
+ fds.push({ determinants: [], dependents: [lIdx], kind: 'determination' });
803
922
  constantBindings.push({ attrs: [lIdx], value: rConst });
804
923
  }
805
924
  continue;
@@ -807,7 +926,7 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
807
926
  if (rIsCol && lConst !== undefined) {
808
927
  const rIdx = attrIdToIndex.get(n.right.attributeId);
809
928
  if (rIdx !== undefined) {
810
- fds.push({ determinants: [], dependents: [rIdx] });
929
+ fds.push({ determinants: [], dependents: [rIdx], kind: 'determination' });
811
930
  constantBindings.push({ attrs: [rIdx], value: lConst });
812
931
  }
813
932
  continue;
@@ -815,7 +934,44 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
815
934
  }
816
935
  return { fds, equivPairs, constantBindings };
817
936
  }
818
- function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
937
+ /**
938
+ * Collect per-column facts from a filter predicate for guard discharge.
939
+ *
940
+ * **Collation gate (per conjunct).** A fact may only discharge a guard when
941
+ * the filter's runtime comparison keeps filter-rows ⊆ guard-scope-rows. The
942
+ * guard predicate is evaluated under the column's *declared* collation at
943
+ * enforcement time — index maintenance for partial-UNIQUE guards, write-time
944
+ * CHECK evaluation for implication-form CHECK guards (constraint-builder
945
+ * threads declared collations into the CHECK scope types) — and guard
946
+ * recognition (`partial-unique-extraction.ts`, `check-extraction.ts`) only
947
+ * accepts bare column/literal AST shapes, so guard comparisons resolve to the
948
+ * declared collation. Hence:
949
+ *
950
+ * - `col = lit` / singleton-IN facts: sound when the conjunct's effective
951
+ * comparison collation is BINARY (value-equality implies equality under any
952
+ * collation) OR equals the column's declared collation (same comparison the
953
+ * guard scope uses; the strict `sqlValueEquals` literal match at discharge
954
+ * then under-claims at worst). The previous code stripped `CollateNode`
955
+ * from the literal side unconditionally, so `b = 'bob' collate nocase`
956
+ * discharged a BINARY `eq-literal{b,'bob'}` guard while admitting rows
957
+ * outside the partial-index scope (ticket
958
+ * `collation-blind-equality-fact-extraction`, repro 4).
959
+ * - `col1 = col2` facts: sound when both columns' contributed collations are
960
+ * equal — then any operand-resolution order (filter conjunct or guard
961
+ * spelling) lands on the same collation.
962
+ * - range facts over TEXT bounds: the discharge subset check
963
+ * (`filterRangeSubsetOfGuardRange`) compares bounds under BINARY, so the
964
+ * filter's effective collation AND the column's declared collation must
965
+ * both be BINARY (a BINARY bound comparison does not bound a NOCASE-ordered
966
+ * row set). Non-text bounds are collation-inert and stay ungated. This is
967
+ * deliberately stricter than the equality gate — a completeness loss for
968
+ * collated text ranges, never a soundness one.
969
+ * - plain `col IN (lits)`: the runtime (`emitIn`) compares under the
970
+ * condition operand's collation, which for the only recognized shape (a
971
+ * bare column) IS the declared collation; listed values' COLLATE wrappers
972
+ * are inert. Gated uniformly anyway for future-proofing.
973
+ */
974
+ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric, declaredCollationOf) {
819
975
  const literalEqs = new Map();
820
976
  const columnEqs = new Map();
821
977
  const isNullCols = new Set();
@@ -844,6 +1000,13 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
844
1000
  }
845
1001
  return undefined;
846
1002
  };
1003
+ // Equality-fact gate: BINARY, or matching the column's declared collation
1004
+ // (the collation guard scopes are evaluated under). See the function doc.
1005
+ const equalityCollationOk = (col, effColl) => effColl === 'BINARY' || effColl === normalizeCollationName(declaredCollationOf(col));
1006
+ // Range-fact gate for TEXT bounds: the discharge subset check is BINARY, so
1007
+ // both the filter comparison and the guard-scope (declared) collation must be.
1008
+ const rangeCollationOk = (col, effColl, bound) => typeof bound !== 'string'
1009
+ || (effColl === 'BINARY' && normalizeCollationName(declaredCollationOf(col)) === 'BINARY');
847
1010
  const tightenLowerBound = (col, value, inclusive) => {
848
1011
  const cur = rangeBounds.get(col);
849
1012
  if (!cur) {
@@ -914,18 +1077,23 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
914
1077
  const lIdx = columnIndexOf(n.left);
915
1078
  const rIdx = columnIndexOf(n.right);
916
1079
  if (lIdx !== undefined && rIdx !== undefined) {
917
- addColumnEq(lIdx, rIdx);
1080
+ // Both sides are bare column refs; require their contributed
1081
+ // collations to agree so any resolution order matches the guard's.
1082
+ if (operandCollation(n.left) === operandCollation(n.right)) {
1083
+ addColumnEq(lIdx, rIdx);
1084
+ }
918
1085
  continue;
919
1086
  }
1087
+ const effColl = effectiveComparisonCollation(n.left, n.right);
920
1088
  if (lIdx !== undefined) {
921
1089
  const lit = literalSqlValueOf(n.right);
922
- if (lit !== undefined)
1090
+ if (lit !== undefined && equalityCollationOk(lIdx, effColl))
923
1091
  literalEqs.set(lIdx, lit);
924
1092
  continue;
925
1093
  }
926
1094
  if (rIdx !== undefined) {
927
1095
  const lit = literalSqlValueOf(n.left);
928
- if (lit !== undefined)
1096
+ if (lit !== undefined && equalityCollationOk(rIdx, effColl))
929
1097
  literalEqs.set(rIdx, lit);
930
1098
  }
931
1099
  continue;
@@ -947,16 +1115,21 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
947
1115
  if (op === '<' || op === '<=' || op === '>' || op === '>=') {
948
1116
  const lIdx = columnIndexOf(n.left);
949
1117
  const rIdx = columnIndexOf(n.right);
1118
+ const effColl = effectiveComparisonCollation(n.left, n.right);
950
1119
  if (lIdx !== undefined && rIdx === undefined) {
951
1120
  const lit = literalSqlValueOf(n.right);
952
1121
  if (lit === undefined || lit === null)
953
1122
  continue;
1123
+ if (!rangeCollationOk(lIdx, effColl, lit))
1124
+ continue;
954
1125
  recordComparison(lIdx, op, lit);
955
1126
  }
956
1127
  else if (rIdx !== undefined && lIdx === undefined) {
957
1128
  const lit = literalSqlValueOf(n.left);
958
1129
  if (lit === undefined || lit === null)
959
1130
  continue;
1131
+ if (!rangeCollationOk(rIdx, effColl, lit))
1132
+ continue;
960
1133
  recordComparison(rIdx, flipComparison(op), lit);
961
1134
  }
962
1135
  continue;
@@ -971,10 +1144,15 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
971
1144
  continue;
972
1145
  const lo = literalSqlValueOf(n.lower);
973
1146
  const hi = literalSqlValueOf(n.upper);
974
- if (lo !== undefined && lo !== null)
1147
+ // Per-bound effective collation (emitBetween: bound wins over expr).
1148
+ if (lo !== undefined && lo !== null
1149
+ && rangeCollationOk(cIdx, effectiveBetweenBoundCollation(n.expr, n.lower), lo)) {
975
1150
  tightenLowerBound(cIdx, lo, true);
976
- if (hi !== undefined && hi !== null)
1151
+ }
1152
+ if (hi !== undefined && hi !== null
1153
+ && rangeCollationOk(cIdx, effectiveBetweenBoundCollation(n.expr, n.upper), hi)) {
977
1154
  tightenUpperBound(cIdx, hi, true);
1155
+ }
978
1156
  continue;
979
1157
  }
980
1158
  if (n instanceof UnaryOpNode) {
@@ -1011,6 +1189,12 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
1011
1189
  const cIdx = columnIndexOf(n.condition);
1012
1190
  if (cIdx === undefined)
1013
1191
  continue;
1192
+ // emitIn resolves ONE collation through the provenance lattice over the
1193
+ // condition AND the listed values — a collate-wrapped element (folded
1194
+ // to a literal whose type carries rank-3 NOCASE) can outrank the bare
1195
+ // column recognized here, so this gate is load-bearing.
1196
+ if (!equalityCollationOk(cIdx, effectiveInCollation(n)))
1197
+ continue;
1014
1198
  const set = new Set();
1015
1199
  let allLiterals = true;
1016
1200
  for (const v of n.values) {
@@ -1088,9 +1272,13 @@ function bindingForColumn(col, bindings) {
1088
1272
  * sound for numeric columns since the consumer matches `eq-literal{col, 0}`
1089
1273
  * via strict `sqlValueEquals`, which treats TEXT `''`, BLOB, and boolean
1090
1274
  * `false` as unequal to integer 0.
1275
+ *
1276
+ * `declaredCollationOf(col)` reports the source's output column collation
1277
+ * (normalized or not; `'BINARY'` when undeclared). Used by the per-conjunct
1278
+ * collation gate in `buildPredicateFacts` — see its doc.
1091
1279
  */
1092
- export function predicateImpliesGuard(predicate, guard, ecs, bindings, attrIdToIndex, isColumnNonNullable, isColumnNumeric) {
1093
- const facts = buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric);
1280
+ export function predicateImpliesGuard(predicate, guard, ecs, bindings, attrIdToIndex, isColumnNonNullable, isColumnNumeric, declaredCollationOf) {
1281
+ const facts = buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric, declaredCollationOf);
1094
1282
  for (const clause of guard.clauses) {
1095
1283
  if (!clauseEntailed(clause, facts, ecs, bindings, isColumnNonNullable)) {
1096
1284
  return false;
@@ -1535,4 +1723,111 @@ export function shiftDomainConstraints(domains, offset) {
1535
1723
  return domains.slice();
1536
1724
  return domains.map(domain => ({ ...domain, column: domain.column + offset }));
1537
1725
  }
1726
+ /**
1727
+ * Per-node cap on the number of INDs we materialize, mirroring
1728
+ * `MAX_FDS_PER_NODE`. A safety valve for pathological plans; truncations are
1729
+ * logged under the `quereus:planner:fd` logger like the FD/binding/domain caps.
1730
+ */
1731
+ export const MAX_INDS_PER_NODE = 64;
1732
+ function sameOrderedList(a, b) {
1733
+ if (a.length !== b.length)
1734
+ return false;
1735
+ for (let i = 0; i < a.length; i++)
1736
+ if (a[i] !== b[i])
1737
+ return false;
1738
+ return true;
1739
+ }
1740
+ function indTargetsEqual(a, b) {
1741
+ if (a.kind !== b.kind)
1742
+ return false;
1743
+ if (a.kind === 'table' && b.kind === 'table') {
1744
+ return a.schema === b.schema && a.table === b.table && sameOrderedList(a.targetCols, b.targetCols);
1745
+ }
1746
+ if (a.kind === 'relation' && b.kind === 'relation') {
1747
+ return a.relationId === b.relationId && sameOrderedList(a.targetCols, b.targetCols);
1748
+ }
1749
+ return false;
1750
+ }
1751
+ /**
1752
+ * Structural equality for IND dedup. `cols` and `target.targetCols` are
1753
+ * compared as *ordered* lists — the positional pairing between them is
1754
+ * load-bearing (`cols[i]` is the child column matched to `targetCols[i]`), so a
1755
+ * reordering is a different fact and must not collapse. Stricter than
1756
+ * `fdsEqual`'s set comparison; over-keeping a reordered twin is harmless
1757
+ * (redundancy, capped), whereas collapsing distinct facts would lose an IND.
1758
+ */
1759
+ function indsEqual(a, b) {
1760
+ return a.nullRejecting === b.nullRejecting
1761
+ && sameOrderedList(a.cols, b.cols)
1762
+ && indTargetsEqual(a.target, b.target);
1763
+ }
1764
+ /**
1765
+ * Add a single IND, skipping it when a structurally-equal entry (per
1766
+ * `indsEqual`) already exists. Enforces the per-node cap; truncations are
1767
+ * logged. Mirrors `addFd` minus the determinant-subsumption logic (an IND has
1768
+ * no determinant/dependent split to subsume).
1769
+ */
1770
+ export function addInd(inds, next, opts = {}) {
1771
+ const result = inds.slice();
1772
+ if (!result.some(existing => indsEqual(existing, next))) {
1773
+ result.push(next);
1774
+ }
1775
+ return enforceIndCap(result, opts);
1776
+ }
1777
+ function enforceIndCap(inds, opts) {
1778
+ const cap = opts.cap ?? MAX_INDS_PER_NODE;
1779
+ if (inds.length <= cap)
1780
+ return inds;
1781
+ const kept = inds.slice(0, cap);
1782
+ log('IND cap reached: dropped %d IND(s) from %d', inds.length - kept.length, inds.length);
1783
+ return kept;
1784
+ }
1785
+ /** Merge two IND lists: concat with structural dedup via `addInd`, capped. */
1786
+ export function mergeInds(a, b, opts = {}) {
1787
+ let result = a.slice();
1788
+ for (const ind of b) {
1789
+ result = addInd(result, ind, opts);
1790
+ }
1791
+ return result;
1792
+ }
1793
+ /**
1794
+ * Project INDs through a column mapping (oldCol → newCol). An IND's `cols` is
1795
+ * **all-or-nothing**: drop the IND when ANY of its `cols` loses its mapping (the
1796
+ * relation no longer carries the witnessing columns) — there is no partial-
1797
+ * dependent survival as in `projectFds`. Survivors have their `cols` remapped to
1798
+ * output indices; `target.targetCols` index into the *target* relation, NOT this
1799
+ * relation's output, so they are NOT remapped. Result is deduped + capped.
1800
+ */
1801
+ export function projectInds(inds, mapping) {
1802
+ const out = [];
1803
+ for (const ind of inds) {
1804
+ const newCols = [];
1805
+ let miss = false;
1806
+ for (const c of ind.cols) {
1807
+ const m = mapping.get(c);
1808
+ if (m === undefined) {
1809
+ miss = true;
1810
+ break;
1811
+ }
1812
+ newCols.push(m);
1813
+ }
1814
+ if (miss)
1815
+ continue;
1816
+ out.push({ cols: newCols, target: ind.target, nullRejecting: ind.nullRejecting });
1817
+ }
1818
+ return mergeInds([], out);
1819
+ }
1820
+ /**
1821
+ * Shift each IND's `cols` by `offset` (mirrors `shiftFds` for join column
1822
+ * translation). `target.targetCols` are target-relative ⇒ NOT shifted.
1823
+ */
1824
+ export function shiftInds(inds, offset) {
1825
+ if (offset === 0)
1826
+ return inds.slice();
1827
+ return inds.map(ind => ({
1828
+ cols: ind.cols.map(c => c + offset),
1829
+ target: ind.target,
1830
+ nullRejecting: ind.nullRejecting,
1831
+ }));
1832
+ }
1538
1833
  //# sourceMappingURL=fd-utils.js.map