@quereus/quereus 3.2.1 → 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 (935) 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 -106
  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 +795 -120
  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 +277 -8
  98. package/dist/src/parser/parser.d.ts.map +1 -1
  99. package/dist/src/parser/parser.js +1393 -471
  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/binding-extractor.d.ts.map +1 -1
  115. package/dist/src/planner/analysis/binding-extractor.js +9 -6
  116. package/dist/src/planner/analysis/binding-extractor.js.map +1 -1
  117. package/dist/src/planner/analysis/change-scope.d.ts +34 -4
  118. package/dist/src/planner/analysis/change-scope.d.ts.map +1 -1
  119. package/dist/src/planner/analysis/change-scope.js +115 -7
  120. package/dist/src/planner/analysis/change-scope.js.map +1 -1
  121. package/dist/src/planner/analysis/check-extraction.d.ts +36 -2
  122. package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -1
  123. package/dist/src/planner/analysis/check-extraction.js +174 -46
  124. package/dist/src/planner/analysis/check-extraction.js.map +1 -1
  125. package/dist/src/planner/analysis/coarsened-key.d.ts +109 -0
  126. package/dist/src/planner/analysis/coarsened-key.d.ts.map +1 -0
  127. package/dist/src/planner/analysis/coarsened-key.js +228 -0
  128. package/dist/src/planner/analysis/coarsened-key.js.map +1 -0
  129. package/dist/src/planner/analysis/comparison-collation.d.ts +216 -0
  130. package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -0
  131. package/dist/src/planner/analysis/comparison-collation.js +341 -0
  132. package/dist/src/planner/analysis/comparison-collation.js.map +1 -0
  133. package/dist/src/planner/analysis/constraint-extractor.d.ts +13 -1
  134. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  135. package/dist/src/planner/analysis/constraint-extractor.js +220 -21
  136. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  137. package/dist/src/planner/analysis/coverage-prover.d.ts +321 -0
  138. package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -0
  139. package/dist/src/planner/analysis/coverage-prover.js +1038 -0
  140. package/dist/src/planner/analysis/coverage-prover.js.map +1 -0
  141. package/dist/src/planner/analysis/key-filter.d.ts +22 -0
  142. package/dist/src/planner/analysis/key-filter.d.ts.map +1 -0
  143. package/dist/src/planner/analysis/key-filter.js +105 -0
  144. package/dist/src/planner/analysis/key-filter.js.map +1 -0
  145. package/dist/src/planner/analysis/partial-unique-extraction.d.ts +36 -1
  146. package/dist/src/planner/analysis/partial-unique-extraction.d.ts.map +1 -1
  147. package/dist/src/planner/analysis/partial-unique-extraction.js +148 -22
  148. package/dist/src/planner/analysis/partial-unique-extraction.js.map +1 -1
  149. package/dist/src/planner/analysis/predicate-normalizer.d.ts.map +1 -1
  150. package/dist/src/planner/analysis/predicate-normalizer.js +30 -1
  151. package/dist/src/planner/analysis/predicate-normalizer.js.map +1 -1
  152. package/dist/src/planner/analysis/predicate-shape.d.ts +36 -1
  153. package/dist/src/planner/analysis/predicate-shape.d.ts.map +1 -1
  154. package/dist/src/planner/analysis/predicate-shape.js +51 -13
  155. package/dist/src/planner/analysis/predicate-shape.js.map +1 -1
  156. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +314 -0
  157. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -0
  158. package/dist/src/planner/analysis/query-rewrite-matcher.js +1081 -0
  159. package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -0
  160. package/dist/src/planner/analysis/scalar-invertibility.d.ts +92 -0
  161. package/dist/src/planner/analysis/scalar-invertibility.d.ts.map +1 -0
  162. package/dist/src/planner/analysis/scalar-invertibility.js +129 -0
  163. package/dist/src/planner/analysis/scalar-invertibility.js.map +1 -0
  164. package/dist/src/planner/analysis/update-lineage.d.ts +196 -0
  165. package/dist/src/planner/analysis/update-lineage.d.ts.map +1 -0
  166. package/dist/src/planner/analysis/update-lineage.js +322 -0
  167. package/dist/src/planner/analysis/update-lineage.js.map +1 -0
  168. package/dist/src/planner/analysis/view-complement.d.ts +42 -0
  169. package/dist/src/planner/analysis/view-complement.d.ts.map +1 -0
  170. package/dist/src/planner/analysis/view-complement.js +54 -0
  171. package/dist/src/planner/analysis/view-complement.js.map +1 -0
  172. package/dist/src/planner/building/alter-table.d.ts +1 -1
  173. package/dist/src/planner/building/alter-table.d.ts.map +1 -1
  174. package/dist/src/planner/building/alter-table.js +211 -2
  175. package/dist/src/planner/building/alter-table.js.map +1 -1
  176. package/dist/src/planner/building/block.d.ts.map +1 -1
  177. package/dist/src/planner/building/block.js +18 -1
  178. package/dist/src/planner/building/block.js.map +1 -1
  179. package/dist/src/planner/building/constraint-builder.d.ts +33 -5
  180. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  181. package/dist/src/planner/building/constraint-builder.js +63 -28
  182. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  183. package/dist/src/planner/building/create-view.d.ts +9 -0
  184. package/dist/src/planner/building/create-view.d.ts.map +1 -1
  185. package/dist/src/planner/building/create-view.js +41 -12
  186. package/dist/src/planner/building/create-view.js.map +1 -1
  187. package/dist/src/planner/building/ddl.d.ts.map +1 -1
  188. package/dist/src/planner/building/ddl.js +94 -0
  189. package/dist/src/planner/building/ddl.js.map +1 -1
  190. package/dist/src/planner/building/declare-schema.d.ts +1 -0
  191. package/dist/src/planner/building/declare-schema.d.ts.map +1 -1
  192. package/dist/src/planner/building/declare-schema.js +4 -1
  193. package/dist/src/planner/building/declare-schema.js.map +1 -1
  194. package/dist/src/planner/building/default-scope.d.ts +26 -0
  195. package/dist/src/planner/building/default-scope.d.ts.map +1 -0
  196. package/dist/src/planner/building/default-scope.js +41 -0
  197. package/dist/src/planner/building/default-scope.js.map +1 -0
  198. package/dist/src/planner/building/delete.d.ts +19 -1
  199. package/dist/src/planner/building/delete.d.ts.map +1 -1
  200. package/dist/src/planner/building/delete.js +116 -34
  201. package/dist/src/planner/building/delete.js.map +1 -1
  202. package/dist/src/planner/building/dml-target.d.ts +118 -0
  203. package/dist/src/planner/building/dml-target.d.ts.map +1 -0
  204. package/dist/src/planner/building/dml-target.js +282 -0
  205. package/dist/src/planner/building/dml-target.js.map +1 -0
  206. package/dist/src/planner/building/drop-index.d.ts.map +1 -1
  207. package/dist/src/planner/building/drop-index.js +4 -1
  208. package/dist/src/planner/building/drop-index.js.map +1 -1
  209. package/dist/src/planner/building/drop-view.d.ts.map +1 -1
  210. package/dist/src/planner/building/drop-view.js +4 -2
  211. package/dist/src/planner/building/drop-view.js.map +1 -1
  212. package/dist/src/planner/building/expression.d.ts.map +1 -1
  213. package/dist/src/planner/building/expression.js +60 -21
  214. package/dist/src/planner/building/expression.js.map +1 -1
  215. package/dist/src/planner/building/foreign-key-builder.d.ts +30 -0
  216. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
  217. package/dist/src/planner/building/foreign-key-builder.js +160 -129
  218. package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
  219. package/dist/src/planner/building/insert.d.ts +45 -2
  220. package/dist/src/planner/building/insert.d.ts.map +1 -1
  221. package/dist/src/planner/building/insert.js +257 -88
  222. package/dist/src/planner/building/insert.js.map +1 -1
  223. package/dist/src/planner/building/lens-auxiliary-access.d.ts +22 -0
  224. package/dist/src/planner/building/lens-auxiliary-access.d.ts.map +1 -0
  225. package/dist/src/planner/building/lens-auxiliary-access.js +132 -0
  226. package/dist/src/planner/building/lens-auxiliary-access.js.map +1 -0
  227. package/dist/src/planner/building/materialized-view.d.ts +16 -0
  228. package/dist/src/planner/building/materialized-view.d.ts.map +1 -0
  229. package/dist/src/planner/building/materialized-view.js +57 -0
  230. package/dist/src/planner/building/materialized-view.js.map +1 -0
  231. package/dist/src/planner/building/returning-star.d.ts +32 -0
  232. package/dist/src/planner/building/returning-star.d.ts.map +1 -0
  233. package/dist/src/planner/building/returning-star.js +45 -0
  234. package/dist/src/planner/building/returning-star.js.map +1 -0
  235. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  236. package/dist/src/planner/building/select-aggregates.js +51 -13
  237. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  238. package/dist/src/planner/building/select-compound.d.ts.map +1 -1
  239. package/dist/src/planner/building/select-compound.js +84 -11
  240. package/dist/src/planner/building/select-compound.js.map +1 -1
  241. package/dist/src/planner/building/select-context.d.ts +10 -2
  242. package/dist/src/planner/building/select-context.d.ts.map +1 -1
  243. package/dist/src/planner/building/select-context.js +7 -1
  244. package/dist/src/planner/building/select-context.js.map +1 -1
  245. package/dist/src/planner/building/select-modifiers.js +6 -0
  246. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  247. package/dist/src/planner/building/select-ordinal.d.ts +18 -0
  248. package/dist/src/planner/building/select-ordinal.d.ts.map +1 -1
  249. package/dist/src/planner/building/select-ordinal.js +30 -0
  250. package/dist/src/planner/building/select-ordinal.js.map +1 -1
  251. package/dist/src/planner/building/select-projections.d.ts +8 -2
  252. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  253. package/dist/src/planner/building/select-projections.js +26 -4
  254. package/dist/src/planner/building/select-projections.js.map +1 -1
  255. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  256. package/dist/src/planner/building/select-window.js +8 -5
  257. package/dist/src/planner/building/select-window.js.map +1 -1
  258. package/dist/src/planner/building/select.d.ts.map +1 -1
  259. package/dist/src/planner/building/select.js +164 -59
  260. package/dist/src/planner/building/select.js.map +1 -1
  261. package/dist/src/planner/building/set-object-tags.d.ts +7 -0
  262. package/dist/src/planner/building/set-object-tags.d.ts.map +1 -0
  263. package/dist/src/planner/building/set-object-tags.js +38 -0
  264. package/dist/src/planner/building/set-object-tags.js.map +1 -0
  265. package/dist/src/planner/building/tag-diagnostics.d.ts +27 -0
  266. package/dist/src/planner/building/tag-diagnostics.d.ts.map +1 -0
  267. package/dist/src/planner/building/tag-diagnostics.js +37 -0
  268. package/dist/src/planner/building/tag-diagnostics.js.map +1 -0
  269. package/dist/src/planner/building/update.d.ts +18 -1
  270. package/dist/src/planner/building/update.d.ts.map +1 -1
  271. package/dist/src/planner/building/update.js +134 -58
  272. package/dist/src/planner/building/update.js.map +1 -1
  273. package/dist/src/planner/building/view-mutation-builder.d.ts +15 -0
  274. package/dist/src/planner/building/view-mutation-builder.d.ts.map +1 -0
  275. package/dist/src/planner/building/view-mutation-builder.js +1158 -0
  276. package/dist/src/planner/building/view-mutation-builder.js.map +1 -0
  277. package/dist/src/planner/building/with.d.ts +11 -0
  278. package/dist/src/planner/building/with.d.ts.map +1 -1
  279. package/dist/src/planner/building/with.js +48 -10
  280. package/dist/src/planner/building/with.js.map +1 -1
  281. package/dist/src/planner/cost/index.d.ts +83 -0
  282. package/dist/src/planner/cost/index.d.ts.map +1 -1
  283. package/dist/src/planner/cost/index.js +114 -0
  284. package/dist/src/planner/cost/index.js.map +1 -1
  285. package/dist/src/planner/framework/characteristics.d.ts +38 -4
  286. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  287. package/dist/src/planner/framework/characteristics.js +50 -6
  288. package/dist/src/planner/framework/characteristics.js.map +1 -1
  289. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  290. package/dist/src/planner/framework/pass.js +2 -1
  291. package/dist/src/planner/framework/pass.js.map +1 -1
  292. package/dist/src/planner/framework/physical-utils.d.ts.map +1 -1
  293. package/dist/src/planner/framework/physical-utils.js +7 -1
  294. package/dist/src/planner/framework/physical-utils.js.map +1 -1
  295. package/dist/src/planner/framework/registry.d.ts +39 -1
  296. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  297. package/dist/src/planner/framework/registry.js +18 -2
  298. package/dist/src/planner/framework/registry.js.map +1 -1
  299. package/dist/src/planner/mutation/backward-body.d.ts +131 -0
  300. package/dist/src/planner/mutation/backward-body.d.ts.map +1 -0
  301. package/dist/src/planner/mutation/backward-body.js +135 -0
  302. package/dist/src/planner/mutation/backward-body.js.map +1 -0
  303. package/dist/src/planner/mutation/cte-flatten.d.ts +17 -0
  304. package/dist/src/planner/mutation/cte-flatten.d.ts.map +1 -0
  305. package/dist/src/planner/mutation/cte-flatten.js +364 -0
  306. package/dist/src/planner/mutation/cte-flatten.js.map +1 -0
  307. package/dist/src/planner/mutation/decomposition.d.ts +273 -0
  308. package/dist/src/planner/mutation/decomposition.d.ts.map +1 -0
  309. package/dist/src/planner/mutation/decomposition.js +1719 -0
  310. package/dist/src/planner/mutation/decomposition.js.map +1 -0
  311. package/dist/src/planner/mutation/lens-enforcement.d.ts +165 -0
  312. package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -0
  313. package/dist/src/planner/mutation/lens-enforcement.js +745 -0
  314. package/dist/src/planner/mutation/lens-enforcement.js.map +1 -0
  315. package/dist/src/planner/mutation/multi-source.d.ts +568 -0
  316. package/dist/src/planner/mutation/multi-source.d.ts.map +1 -0
  317. package/dist/src/planner/mutation/multi-source.js +2915 -0
  318. package/dist/src/planner/mutation/multi-source.js.map +1 -0
  319. package/dist/src/planner/mutation/mutation-diagnostic.d.ts +37 -0
  320. package/dist/src/planner/mutation/mutation-diagnostic.d.ts.map +1 -0
  321. package/dist/src/planner/mutation/mutation-diagnostic.js +24 -0
  322. package/dist/src/planner/mutation/mutation-diagnostic.js.map +1 -0
  323. package/dist/src/planner/mutation/mutation-tags.d.ts +33 -0
  324. package/dist/src/planner/mutation/mutation-tags.d.ts.map +1 -0
  325. package/dist/src/planner/mutation/mutation-tags.js +31 -0
  326. package/dist/src/planner/mutation/mutation-tags.js.map +1 -0
  327. package/dist/src/planner/mutation/propagate.d.ts +97 -0
  328. package/dist/src/planner/mutation/propagate.d.ts.map +1 -0
  329. package/dist/src/planner/mutation/propagate.js +220 -0
  330. package/dist/src/planner/mutation/propagate.js.map +1 -0
  331. package/dist/src/planner/mutation/scope-transform.d.ts +181 -0
  332. package/dist/src/planner/mutation/scope-transform.d.ts.map +1 -0
  333. package/dist/src/planner/mutation/scope-transform.js +574 -0
  334. package/dist/src/planner/mutation/scope-transform.js.map +1 -0
  335. package/dist/src/planner/mutation/set-op.d.ts +242 -0
  336. package/dist/src/planner/mutation/set-op.d.ts.map +1 -0
  337. package/dist/src/planner/mutation/set-op.js +1687 -0
  338. package/dist/src/planner/mutation/set-op.js.map +1 -0
  339. package/dist/src/planner/mutation/single-source.d.ts +261 -0
  340. package/dist/src/planner/mutation/single-source.d.ts.map +1 -0
  341. package/dist/src/planner/mutation/single-source.js +1096 -0
  342. package/dist/src/planner/mutation/single-source.js.map +1 -0
  343. package/dist/src/planner/nodes/aggregate-node.d.ts +6 -4
  344. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  345. package/dist/src/planner/nodes/aggregate-node.js +11 -9
  346. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  347. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  348. package/dist/src/planner/nodes/alias-node.js +5 -1
  349. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  350. package/dist/src/planner/nodes/alter-table-node.d.ts +124 -1
  351. package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -1
  352. package/dist/src/planner/nodes/alter-table-node.js +27 -0
  353. package/dist/src/planner/nodes/alter-table-node.js.map +1 -1
  354. package/dist/src/planner/nodes/analyze-node.d.ts +2 -1
  355. package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -1
  356. package/dist/src/planner/nodes/analyze-node.js +21 -1
  357. package/dist/src/planner/nodes/analyze-node.js.map +1 -1
  358. package/dist/src/planner/nodes/asserted-keys-node.d.ts +43 -0
  359. package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -0
  360. package/dist/src/planner/nodes/asserted-keys-node.js +99 -0
  361. package/dist/src/planner/nodes/asserted-keys-node.js.map +1 -0
  362. package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
  363. package/dist/src/planner/nodes/async-gather-node.js +33 -8
  364. package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
  365. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  366. package/dist/src/planner/nodes/bloom-join-node.js +2 -1
  367. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  368. package/dist/src/planner/nodes/create-view-node.d.ts +7 -2
  369. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
  370. package/dist/src/planner/nodes/create-view-node.js +4 -1
  371. package/dist/src/planner/nodes/create-view-node.js.map +1 -1
  372. package/dist/src/planner/nodes/declarative-schema.d.ts +13 -1
  373. package/dist/src/planner/nodes/declarative-schema.d.ts.map +1 -1
  374. package/dist/src/planner/nodes/declarative-schema.js +32 -0
  375. package/dist/src/planner/nodes/declarative-schema.js.map +1 -1
  376. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  377. package/dist/src/planner/nodes/distinct-node.js +2 -0
  378. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  379. package/dist/src/planner/nodes/dml-executor-node.d.ts +29 -1
  380. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  381. package/dist/src/planner/nodes/dml-executor-node.js +27 -3
  382. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  383. package/dist/src/planner/nodes/eager-prefetch-node.d.ts.map +1 -1
  384. package/dist/src/planner/nodes/eager-prefetch-node.js +2 -0
  385. package/dist/src/planner/nodes/eager-prefetch-node.js.map +1 -1
  386. package/dist/src/planner/nodes/envelope-scan-node.d.ts +42 -0
  387. package/dist/src/planner/nodes/envelope-scan-node.d.ts.map +1 -0
  388. package/dist/src/planner/nodes/envelope-scan-node.js +62 -0
  389. package/dist/src/planner/nodes/envelope-scan-node.js.map +1 -0
  390. package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts.map +1 -1
  391. package/dist/src/planner/nodes/fanout-lookup-join-node.js +11 -1
  392. package/dist/src/planner/nodes/fanout-lookup-join-node.js.map +1 -1
  393. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  394. package/dist/src/planner/nodes/filter.js +63 -13
  395. package/dist/src/planner/nodes/filter.js.map +1 -1
  396. package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -1
  397. package/dist/src/planner/nodes/hash-aggregate.js +6 -16
  398. package/dist/src/planner/nodes/hash-aggregate.js.map +1 -1
  399. package/dist/src/planner/nodes/join-node.d.ts +41 -1
  400. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  401. package/dist/src/planner/nodes/join-node.js +78 -8
  402. package/dist/src/planner/nodes/join-node.js.map +1 -1
  403. package/dist/src/planner/nodes/join-utils.d.ts +33 -6
  404. package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
  405. package/dist/src/planner/nodes/join-utils.js +131 -10
  406. package/dist/src/planner/nodes/join-utils.js.map +1 -1
  407. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts +104 -0
  408. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts.map +1 -0
  409. package/dist/src/planner/nodes/lens-auxiliary-access-node.js +91 -0
  410. package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -0
  411. package/dist/src/planner/nodes/limit-offset.d.ts +12 -0
  412. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  413. package/dist/src/planner/nodes/limit-offset.js +52 -3
  414. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  415. package/dist/src/planner/nodes/materialized-view-nodes.d.ts +69 -0
  416. package/dist/src/planner/nodes/materialized-view-nodes.d.ts.map +1 -0
  417. package/dist/src/planner/nodes/materialized-view-nodes.js +111 -0
  418. package/dist/src/planner/nodes/materialized-view-nodes.js.map +1 -0
  419. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  420. package/dist/src/planner/nodes/merge-join-node.js +2 -1
  421. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  422. package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
  423. package/dist/src/planner/nodes/ordinal-slice-node.js +2 -0
  424. package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
  425. package/dist/src/planner/nodes/plan-node-type.d.ts +9 -0
  426. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  427. package/dist/src/planner/nodes/plan-node-type.js +9 -0
  428. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  429. package/dist/src/planner/nodes/plan-node.d.ts +265 -5
  430. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  431. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  432. package/dist/src/planner/nodes/pragma.d.ts +2 -1
  433. package/dist/src/planner/nodes/pragma.d.ts.map +1 -1
  434. package/dist/src/planner/nodes/pragma.js +12 -0
  435. package/dist/src/planner/nodes/pragma.js.map +1 -1
  436. package/dist/src/planner/nodes/project-node.d.ts +14 -1
  437. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  438. package/dist/src/planner/nodes/project-node.js +103 -16
  439. package/dist/src/planner/nodes/project-node.js.map +1 -1
  440. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  441. package/dist/src/planner/nodes/reference.js +63 -30
  442. package/dist/src/planner/nodes/reference.js.map +1 -1
  443. package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
  444. package/dist/src/planner/nodes/retrieve-node.js +7 -0
  445. package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
  446. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  447. package/dist/src/planner/nodes/returning-node.js +10 -3
  448. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  449. package/dist/src/planner/nodes/scalar.d.ts +20 -0
  450. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  451. package/dist/src/planner/nodes/scalar.js +71 -14
  452. package/dist/src/planner/nodes/scalar.js.map +1 -1
  453. package/dist/src/planner/nodes/set-object-tags-node.d.ts +39 -0
  454. package/dist/src/planner/nodes/set-object-tags-node.d.ts.map +1 -0
  455. package/dist/src/planner/nodes/set-object-tags-node.js +41 -0
  456. package/dist/src/planner/nodes/set-object-tags-node.js.map +1 -0
  457. package/dist/src/planner/nodes/set-operation-node.d.ts +123 -1
  458. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  459. package/dist/src/planner/nodes/set-operation-node.js +302 -18
  460. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  461. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  462. package/dist/src/planner/nodes/single-row.js +3 -0
  463. package/dist/src/planner/nodes/single-row.js.map +1 -1
  464. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  465. package/dist/src/planner/nodes/sort.js +8 -7
  466. package/dist/src/planner/nodes/sort.js.map +1 -1
  467. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  468. package/dist/src/planner/nodes/stream-aggregate.js +8 -23
  469. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  470. package/dist/src/planner/nodes/subquery.d.ts +2 -0
  471. package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
  472. package/dist/src/planner/nodes/subquery.js +18 -2
  473. package/dist/src/planner/nodes/subquery.js.map +1 -1
  474. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  475. package/dist/src/planner/nodes/table-access-nodes.js +23 -3
  476. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  477. package/dist/src/planner/nodes/table-function-call.js +6 -0
  478. package/dist/src/planner/nodes/table-function-call.js.map +1 -1
  479. package/dist/src/planner/nodes/values-node.d.ts +3 -1
  480. package/dist/src/planner/nodes/values-node.d.ts.map +1 -1
  481. package/dist/src/planner/nodes/values-node.js +26 -0
  482. package/dist/src/planner/nodes/values-node.js.map +1 -1
  483. package/dist/src/planner/nodes/view-mutation-node.d.ts +259 -0
  484. package/dist/src/planner/nodes/view-mutation-node.d.ts.map +1 -0
  485. package/dist/src/planner/nodes/view-mutation-node.js +273 -0
  486. package/dist/src/planner/nodes/view-mutation-node.js.map +1 -0
  487. package/dist/src/planner/nodes/window-function.d.ts +17 -1
  488. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  489. package/dist/src/planner/nodes/window-function.js +15 -1
  490. package/dist/src/planner/nodes/window-function.js.map +1 -1
  491. package/dist/src/planner/nodes/window-node.js +3 -3
  492. package/dist/src/planner/nodes/window-node.js.map +1 -1
  493. package/dist/src/planner/optimizer.d.ts.map +1 -1
  494. package/dist/src/planner/optimizer.js +372 -39
  495. package/dist/src/planner/optimizer.js.map +1 -1
  496. package/dist/src/planner/planning-context.d.ts +1 -1
  497. package/dist/src/planner/planning-context.d.ts.map +1 -1
  498. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts +70 -0
  499. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts.map +1 -0
  500. package/dist/src/planner/rules/access/lens-access-form-matcher.js +156 -0
  501. package/dist/src/planner/rules/access/lens-access-form-matcher.js.map +1 -0
  502. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts +31 -0
  503. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts.map +1 -0
  504. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js +176 -0
  505. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js.map +1 -0
  506. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  507. package/dist/src/planner/rules/access/rule-select-access-path.js +435 -37
  508. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  509. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
  510. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +8 -27
  511. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
  512. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts +9 -3
  513. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -1
  514. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +56 -5
  515. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -1
  516. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts +39 -0
  517. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -0
  518. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +616 -0
  519. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -0
  520. package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts.map +1 -1
  521. package/dist/src/planner/rules/cache/rule-scalar-cse.js +8 -1
  522. package/dist/src/planner/rules/cache/rule-scalar-cse.js.map +1 -1
  523. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts +8 -7
  524. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -1
  525. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +14 -21
  526. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js.map +1 -1
  527. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +36 -0
  528. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
  529. package/dist/src/planner/rules/join/equi-pair-extractor.js +42 -5
  530. package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
  531. package/dist/src/planner/rules/join/rule-fanout-batched-outer.d.ts.map +1 -1
  532. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +10 -0
  533. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js.map +1 -1
  534. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js +25 -9
  535. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js.map +1 -1
  536. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts +130 -0
  537. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts.map +1 -0
  538. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js +206 -0
  539. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js.map +1 -0
  540. package/dist/src/planner/rules/join/rule-join-elimination.d.ts +67 -14
  541. package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -1
  542. package/dist/src/planner/rules/join/rule-join-elimination.js +81 -25
  543. package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -1
  544. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts +84 -0
  545. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts.map +1 -0
  546. package/dist/src/planner/rules/join/rule-join-existence-pruning.js +138 -0
  547. package/dist/src/planner/rules/join/rule-join-existence-pruning.js.map +1 -0
  548. package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -1
  549. package/dist/src/planner/rules/join/rule-join-greedy-commute.js +19 -1
  550. package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -1
  551. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -1
  552. package/dist/src/planner/rules/join/rule-join-physical-selection.js +14 -2
  553. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
  554. package/dist/src/planner/rules/join/rule-lateral-top1-asof.d.ts.map +1 -1
  555. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js +5 -2
  556. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js.map +1 -1
  557. package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts.map +1 -1
  558. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +4 -0
  559. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
  560. package/dist/src/planner/rules/join/rule-quickpick-enumeration.d.ts.map +1 -1
  561. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js +10 -0
  562. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js.map +1 -1
  563. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts +286 -0
  564. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts.map +1 -0
  565. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js +548 -0
  566. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js.map +1 -0
  567. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.d.ts.map +1 -1
  568. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js +9 -1
  569. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js.map +1 -1
  570. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.d.ts.map +1 -1
  571. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js +7 -0
  572. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js.map +1 -1
  573. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.d.ts.map +1 -1
  574. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js +10 -1
  575. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js.map +1 -1
  576. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -1
  577. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +10 -1
  578. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -1
  579. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts.map +1 -1
  580. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +18 -0
  581. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js.map +1 -1
  582. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -1
  583. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +7 -0
  584. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -1
  585. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -1
  586. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +9 -0
  587. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
  588. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +13 -3
  589. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
  590. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +2 -2
  591. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
  592. package/dist/src/planner/rules/retrieve/rule-projection-pruning.d.ts.map +1 -1
  593. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js +14 -0
  594. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js.map +1 -1
  595. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +16 -0
  596. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts.map +1 -1
  597. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +47 -4
  598. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js.map +1 -1
  599. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -1
  600. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +8 -0
  601. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -1
  602. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -1
  603. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +7 -0
  604. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -1
  605. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  606. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +12 -0
  607. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  608. package/dist/src/planner/rules/window/rule-monotonic-window.js +1 -1
  609. package/dist/src/planner/rules/window/rule-monotonic-window.js.map +1 -1
  610. package/dist/src/planner/type-utils.d.ts +14 -0
  611. package/dist/src/planner/type-utils.d.ts.map +1 -1
  612. package/dist/src/planner/type-utils.js +66 -21
  613. package/dist/src/planner/type-utils.js.map +1 -1
  614. package/dist/src/planner/util/fd-utils.d.ts +228 -36
  615. package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
  616. package/dist/src/planner/util/fd-utils.js +501 -84
  617. package/dist/src/planner/util/fd-utils.js.map +1 -1
  618. package/dist/src/planner/util/ind-utils.d.ts +27 -1
  619. package/dist/src/planner/util/ind-utils.d.ts.map +1 -1
  620. package/dist/src/planner/util/ind-utils.js +80 -6
  621. package/dist/src/planner/util/ind-utils.js.map +1 -1
  622. package/dist/src/planner/util/key-utils.d.ts +26 -3
  623. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  624. package/dist/src/planner/util/key-utils.js +182 -33
  625. package/dist/src/planner/util/key-utils.js.map +1 -1
  626. package/dist/src/planner/util/set-op-wrapper.d.ts +37 -0
  627. package/dist/src/planner/util/set-op-wrapper.d.ts.map +1 -0
  628. package/dist/src/planner/util/set-op-wrapper.js +82 -0
  629. package/dist/src/planner/util/set-op-wrapper.js.map +1 -0
  630. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  631. package/dist/src/planner/validation/plan-validator.js +1 -0
  632. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  633. package/dist/src/runtime/context-helpers.d.ts +13 -1
  634. package/dist/src/runtime/context-helpers.d.ts.map +1 -1
  635. package/dist/src/runtime/context-helpers.js +7 -1
  636. package/dist/src/runtime/context-helpers.js.map +1 -1
  637. package/dist/src/runtime/delta-executor.d.ts +30 -1
  638. package/dist/src/runtime/delta-executor.d.ts.map +1 -1
  639. package/dist/src/runtime/delta-executor.js +38 -4
  640. package/dist/src/runtime/delta-executor.js.map +1 -1
  641. package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
  642. package/dist/src/runtime/emit/add-constraint.js +38 -5
  643. package/dist/src/runtime/emit/add-constraint.js.map +1 -1
  644. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  645. package/dist/src/runtime/emit/aggregate.js +10 -8
  646. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  647. package/dist/src/runtime/emit/alter-table.d.ts +1 -1
  648. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  649. package/dist/src/runtime/emit/alter-table.js +664 -108
  650. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  651. package/dist/src/runtime/emit/analyze.d.ts.map +1 -1
  652. package/dist/src/runtime/emit/analyze.js +2 -1
  653. package/dist/src/runtime/emit/analyze.js.map +1 -1
  654. package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
  655. package/dist/src/runtime/emit/asof-scan.js +24 -9
  656. package/dist/src/runtime/emit/asof-scan.js.map +1 -1
  657. package/dist/src/runtime/emit/asserted-keys.d.ts +13 -0
  658. package/dist/src/runtime/emit/asserted-keys.d.ts.map +1 -0
  659. package/dist/src/runtime/emit/asserted-keys.js +13 -0
  660. package/dist/src/runtime/emit/asserted-keys.js.map +1 -0
  661. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  662. package/dist/src/runtime/emit/between.js +24 -19
  663. package/dist/src/runtime/emit/between.js.map +1 -1
  664. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  665. package/dist/src/runtime/emit/binary.js +24 -36
  666. package/dist/src/runtime/emit/binary.js.map +1 -1
  667. package/dist/src/runtime/emit/block.d.ts.map +1 -1
  668. package/dist/src/runtime/emit/block.js +11 -2
  669. package/dist/src/runtime/emit/block.js.map +1 -1
  670. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
  671. package/dist/src/runtime/emit/bloom-join.js +12 -4
  672. package/dist/src/runtime/emit/bloom-join.js.map +1 -1
  673. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  674. package/dist/src/runtime/emit/constraint-check.js +50 -1
  675. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  676. package/dist/src/runtime/emit/create-table.d.ts.map +1 -1
  677. package/dist/src/runtime/emit/create-table.js +8 -0
  678. package/dist/src/runtime/emit/create-table.js.map +1 -1
  679. package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
  680. package/dist/src/runtime/emit/create-view.js +16 -1
  681. package/dist/src/runtime/emit/create-view.js.map +1 -1
  682. package/dist/src/runtime/emit/delete.d.ts.map +1 -1
  683. package/dist/src/runtime/emit/delete.js +15 -5
  684. package/dist/src/runtime/emit/delete.js.map +1 -1
  685. package/dist/src/runtime/emit/dml-executor.d.ts +27 -0
  686. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  687. package/dist/src/runtime/emit/dml-executor.js +413 -193
  688. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  689. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
  690. package/dist/src/runtime/emit/drop-table.js +10 -0
  691. package/dist/src/runtime/emit/drop-table.js.map +1 -1
  692. package/dist/src/runtime/emit/drop-view.d.ts.map +1 -1
  693. package/dist/src/runtime/emit/drop-view.js +17 -0
  694. package/dist/src/runtime/emit/drop-view.js.map +1 -1
  695. package/dist/src/runtime/emit/envelope-scan.d.ts +13 -0
  696. package/dist/src/runtime/emit/envelope-scan.d.ts.map +1 -0
  697. package/dist/src/runtime/emit/envelope-scan.js +22 -0
  698. package/dist/src/runtime/emit/envelope-scan.js.map +1 -0
  699. package/dist/src/runtime/emit/join.d.ts +10 -2
  700. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  701. package/dist/src/runtime/emit/join.js +128 -38
  702. package/dist/src/runtime/emit/join.js.map +1 -1
  703. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts +16 -0
  704. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts.map +1 -0
  705. package/dist/src/runtime/emit/lens-auxiliary-access.js +16 -0
  706. package/dist/src/runtime/emit/lens-auxiliary-access.js.map +1 -0
  707. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +640 -0
  708. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -0
  709. package/dist/src/runtime/emit/materialized-view-helpers.js +2576 -0
  710. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -0
  711. package/dist/src/runtime/emit/materialized-view.d.ts +31 -0
  712. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -0
  713. package/dist/src/runtime/emit/materialized-view.js +187 -0
  714. package/dist/src/runtime/emit/materialized-view.js.map +1 -0
  715. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
  716. package/dist/src/runtime/emit/merge-join.js +19 -5
  717. package/dist/src/runtime/emit/merge-join.js.map +1 -1
  718. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  719. package/dist/src/runtime/emit/project.js +10 -5
  720. package/dist/src/runtime/emit/project.js.map +1 -1
  721. package/dist/src/runtime/emit/schema-declarative.d.ts +1 -0
  722. package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
  723. package/dist/src/runtime/emit/schema-declarative.js +101 -5
  724. package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
  725. package/dist/src/runtime/emit/set-object-tags.d.ts +16 -0
  726. package/dist/src/runtime/emit/set-object-tags.d.ts.map +1 -0
  727. package/dist/src/runtime/emit/set-object-tags.js +57 -0
  728. package/dist/src/runtime/emit/set-object-tags.js.map +1 -0
  729. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  730. package/dist/src/runtime/emit/set-operation.js +140 -24
  731. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  732. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  733. package/dist/src/runtime/emit/subquery.js +110 -5
  734. package/dist/src/runtime/emit/subquery.js.map +1 -1
  735. package/dist/src/runtime/emit/unary.d.ts.map +1 -1
  736. package/dist/src/runtime/emit/unary.js +34 -6
  737. package/dist/src/runtime/emit/unary.js.map +1 -1
  738. package/dist/src/runtime/emit/view-mutation.d.ts +70 -0
  739. package/dist/src/runtime/emit/view-mutation.d.ts.map +1 -0
  740. package/dist/src/runtime/emit/view-mutation.js +299 -0
  741. package/dist/src/runtime/emit/view-mutation.js.map +1 -0
  742. package/dist/src/runtime/emit/window.js +29 -5
  743. package/dist/src/runtime/emit/window.js.map +1 -1
  744. package/dist/src/runtime/foreign-key-actions.d.ts +66 -3
  745. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  746. package/dist/src/runtime/foreign-key-actions.js +580 -172
  747. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  748. package/dist/src/runtime/parallel-driver.d.ts +4 -1
  749. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  750. package/dist/src/runtime/parallel-driver.js +5 -1
  751. package/dist/src/runtime/parallel-driver.js.map +1 -1
  752. package/dist/src/runtime/register.d.ts.map +1 -1
  753. package/dist/src/runtime/register.js +17 -1
  754. package/dist/src/runtime/register.js.map +1 -1
  755. package/dist/src/runtime/types.d.ts +10 -0
  756. package/dist/src/runtime/types.d.ts.map +1 -1
  757. package/dist/src/runtime/types.js.map +1 -1
  758. package/dist/src/schema/basis-backfill.d.ts +63 -0
  759. package/dist/src/schema/basis-backfill.d.ts.map +1 -0
  760. package/dist/src/schema/basis-backfill.js +161 -0
  761. package/dist/src/schema/basis-backfill.js.map +1 -0
  762. package/dist/src/schema/catalog.d.ts +115 -1
  763. package/dist/src/schema/catalog.d.ts.map +1 -1
  764. package/dist/src/schema/catalog.js +249 -22
  765. package/dist/src/schema/catalog.js.map +1 -1
  766. package/dist/src/schema/change-events.d.ts +42 -1
  767. package/dist/src/schema/change-events.d.ts.map +1 -1
  768. package/dist/src/schema/change-events.js.map +1 -1
  769. package/dist/src/schema/column.d.ts +16 -0
  770. package/dist/src/schema/column.d.ts.map +1 -1
  771. package/dist/src/schema/column.js.map +1 -1
  772. package/dist/src/schema/constraint-builder.d.ts +182 -0
  773. package/dist/src/schema/constraint-builder.d.ts.map +1 -0
  774. package/dist/src/schema/constraint-builder.js +424 -0
  775. package/dist/src/schema/constraint-builder.js.map +1 -0
  776. package/dist/src/schema/ddl-generator.d.ts +86 -1
  777. package/dist/src/schema/ddl-generator.d.ts.map +1 -1
  778. package/dist/src/schema/ddl-generator.js +316 -20
  779. package/dist/src/schema/ddl-generator.js.map +1 -1
  780. package/dist/src/schema/declared-schema-manager.d.ts +51 -0
  781. package/dist/src/schema/declared-schema-manager.d.ts.map +1 -1
  782. package/dist/src/schema/declared-schema-manager.js +61 -0
  783. package/dist/src/schema/declared-schema-manager.js.map +1 -1
  784. package/dist/src/schema/derivation.d.ts +106 -0
  785. package/dist/src/schema/derivation.d.ts.map +1 -0
  786. package/dist/src/schema/derivation.js +25 -0
  787. package/dist/src/schema/derivation.js.map +1 -0
  788. package/dist/src/schema/function.d.ts +13 -0
  789. package/dist/src/schema/function.d.ts.map +1 -1
  790. package/dist/src/schema/function.js.map +1 -1
  791. package/dist/src/schema/lens-ack.d.ts +90 -0
  792. package/dist/src/schema/lens-ack.d.ts.map +1 -0
  793. package/dist/src/schema/lens-ack.js +361 -0
  794. package/dist/src/schema/lens-ack.js.map +1 -0
  795. package/dist/src/schema/lens-compiler.d.ts +62 -0
  796. package/dist/src/schema/lens-compiler.d.ts.map +1 -0
  797. package/dist/src/schema/lens-compiler.js +1594 -0
  798. package/dist/src/schema/lens-compiler.js.map +1 -0
  799. package/dist/src/schema/lens-fk-discovery.d.ts +175 -0
  800. package/dist/src/schema/lens-fk-discovery.d.ts.map +1 -0
  801. package/dist/src/schema/lens-fk-discovery.js +336 -0
  802. package/dist/src/schema/lens-fk-discovery.js.map +1 -0
  803. package/dist/src/schema/lens-prover.d.ts +336 -0
  804. package/dist/src/schema/lens-prover.d.ts.map +1 -0
  805. package/dist/src/schema/lens-prover.js +1988 -0
  806. package/dist/src/schema/lens-prover.js.map +1 -0
  807. package/dist/src/schema/lens.d.ts +254 -0
  808. package/dist/src/schema/lens.d.ts.map +1 -0
  809. package/dist/src/schema/lens.js +21 -0
  810. package/dist/src/schema/lens.js.map +1 -0
  811. package/dist/src/schema/manager.d.ts +676 -18
  812. package/dist/src/schema/manager.d.ts.map +1 -1
  813. package/dist/src/schema/manager.js +1573 -238
  814. package/dist/src/schema/manager.js.map +1 -1
  815. package/dist/src/schema/mapping-advertisement-tags.d.ts +39 -0
  816. package/dist/src/schema/mapping-advertisement-tags.d.ts.map +1 -0
  817. package/dist/src/schema/mapping-advertisement-tags.js +216 -0
  818. package/dist/src/schema/mapping-advertisement-tags.js.map +1 -0
  819. package/dist/src/schema/rename-rewriter.d.ts +45 -4
  820. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  821. package/dist/src/schema/rename-rewriter.js +412 -19
  822. package/dist/src/schema/rename-rewriter.js.map +1 -1
  823. package/dist/src/schema/reserved-tags-policy.d.ts +32 -0
  824. package/dist/src/schema/reserved-tags-policy.d.ts.map +1 -0
  825. package/dist/src/schema/reserved-tags-policy.js +34 -0
  826. package/dist/src/schema/reserved-tags-policy.js.map +1 -0
  827. package/dist/src/schema/reserved-tags.d.ts +170 -0
  828. package/dist/src/schema/reserved-tags.d.ts.map +1 -0
  829. package/dist/src/schema/reserved-tags.js +507 -0
  830. package/dist/src/schema/reserved-tags.js.map +1 -0
  831. package/dist/src/schema/schema-differ.d.ts +158 -2
  832. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  833. package/dist/src/schema/schema-differ.js +1460 -78
  834. package/dist/src/schema/schema-differ.js.map +1 -1
  835. package/dist/src/schema/schema-hasher.d.ts +8 -3
  836. package/dist/src/schema/schema-hasher.d.ts.map +1 -1
  837. package/dist/src/schema/schema-hasher.js +22 -2
  838. package/dist/src/schema/schema-hasher.js.map +1 -1
  839. package/dist/src/schema/schema.d.ts +25 -1
  840. package/dist/src/schema/schema.d.ts.map +1 -1
  841. package/dist/src/schema/schema.js +36 -2
  842. package/dist/src/schema/schema.js.map +1 -1
  843. package/dist/src/schema/table.d.ts +259 -10
  844. package/dist/src/schema/table.d.ts.map +1 -1
  845. package/dist/src/schema/table.js +309 -26
  846. package/dist/src/schema/table.js.map +1 -1
  847. package/dist/src/schema/unique-enforcement.d.ts +78 -0
  848. package/dist/src/schema/unique-enforcement.d.ts.map +1 -0
  849. package/dist/src/schema/unique-enforcement.js +93 -0
  850. package/dist/src/schema/unique-enforcement.js.map +1 -0
  851. package/dist/src/schema/view.d.ts +83 -2
  852. package/dist/src/schema/view.d.ts.map +1 -1
  853. package/dist/src/schema/view.js +67 -1
  854. package/dist/src/schema/view.js.map +1 -1
  855. package/dist/src/schema/window-function.d.ts +9 -1
  856. package/dist/src/schema/window-function.d.ts.map +1 -1
  857. package/dist/src/schema/window-function.js.map +1 -1
  858. package/dist/src/types/temporal-types.d.ts.map +1 -1
  859. package/dist/src/types/temporal-types.js +71 -36
  860. package/dist/src/types/temporal-types.js.map +1 -1
  861. package/dist/src/util/comparison.d.ts +24 -0
  862. package/dist/src/util/comparison.d.ts.map +1 -1
  863. package/dist/src/util/comparison.js +34 -0
  864. package/dist/src/util/comparison.js.map +1 -1
  865. package/dist/src/util/mutation-statement.d.ts.map +1 -1
  866. package/dist/src/util/mutation-statement.js +4 -1
  867. package/dist/src/util/mutation-statement.js.map +1 -1
  868. package/dist/src/util/serialization.d.ts +9 -0
  869. package/dist/src/util/serialization.d.ts.map +1 -1
  870. package/dist/src/util/serialization.js +26 -0
  871. package/dist/src/util/serialization.js.map +1 -1
  872. package/dist/src/vtab/backing-host.d.ts +286 -0
  873. package/dist/src/vtab/backing-host.d.ts.map +1 -0
  874. package/dist/src/vtab/backing-host.js +118 -0
  875. package/dist/src/vtab/backing-host.js.map +1 -0
  876. package/dist/src/vtab/best-access-plan.d.ts +21 -0
  877. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  878. package/dist/src/vtab/best-access-plan.js.map +1 -1
  879. package/dist/src/vtab/capabilities.d.ts +5 -5
  880. package/dist/src/vtab/capabilities.d.ts.map +1 -1
  881. package/dist/src/vtab/mapping-advertisement.d.ts +163 -0
  882. package/dist/src/vtab/mapping-advertisement.d.ts.map +1 -0
  883. package/dist/src/vtab/mapping-advertisement.js +2 -0
  884. package/dist/src/vtab/mapping-advertisement.js.map +1 -0
  885. package/dist/src/vtab/memory/index.d.ts +64 -4
  886. package/dist/src/vtab/memory/index.d.ts.map +1 -1
  887. package/dist/src/vtab/memory/index.js +119 -12
  888. package/dist/src/vtab/memory/index.js.map +1 -1
  889. package/dist/src/vtab/memory/layer/base.d.ts +38 -1
  890. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  891. package/dist/src/vtab/memory/layer/base.js +112 -24
  892. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  893. package/dist/src/vtab/memory/layer/manager.d.ts +291 -4
  894. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  895. package/dist/src/vtab/memory/layer/manager.js +1050 -91
  896. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  897. package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
  898. package/dist/src/vtab/memory/layer/plan-filter.js +35 -6
  899. package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
  900. package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
  901. package/dist/src/vtab/memory/layer/scan-layer.js +66 -14
  902. package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
  903. package/dist/src/vtab/memory/layer/scan-plan.d.ts +14 -0
  904. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
  905. package/dist/src/vtab/memory/layer/scan-plan.js +27 -4
  906. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
  907. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  908. package/dist/src/vtab/memory/layer/transaction.js +5 -1
  909. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  910. package/dist/src/vtab/memory/module.d.ts +17 -0
  911. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  912. package/dist/src/vtab/memory/module.js +82 -3
  913. package/dist/src/vtab/memory/module.js.map +1 -1
  914. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  915. package/dist/src/vtab/memory/table.js +15 -5
  916. package/dist/src/vtab/memory/table.js.map +1 -1
  917. package/dist/src/vtab/memory/types.d.ts +20 -2
  918. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  919. package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
  920. package/dist/src/vtab/memory/utils/predicate.js +46 -24
  921. package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
  922. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts +31 -0
  923. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts.map +1 -0
  924. package/dist/src/vtab/memory/utils/primary-key-encode.js +101 -0
  925. package/dist/src/vtab/memory/utils/primary-key-encode.js.map +1 -0
  926. package/dist/src/vtab/memory/utils/primary-key.d.ts +8 -0
  927. package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
  928. package/dist/src/vtab/memory/utils/primary-key.js +12 -5
  929. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  930. package/dist/src/vtab/module.d.ts +203 -4
  931. package/dist/src/vtab/module.d.ts.map +1 -1
  932. package/dist/src/vtab/table.d.ts +9 -0
  933. package/dist/src/vtab/table.d.ts.map +1 -1
  934. package/dist/src/vtab/table.js.map +1 -1
  935. 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.
528
620
  *
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`.
621
+ * `minimalCover` preserves the closure, so the minimized key keeps both
622
+ * coverage and the unique witness (witness determinants the unchanged
623
+ * closure).
624
+ *
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,159 @@ 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)
709
+ export function addSingletonFd(fds, columnCount) {
710
+ const singleton = singletonFd(columnCount);
711
+ return singleton ? addFd(fds, singleton) : fds.slice();
712
+ }
713
+ /**
714
+ * Normalize a list of candidate keys to the minimal, deduped set:
715
+ * - each key is sorted and de-duplicated internally,
716
+ * - duplicate keys collapse,
717
+ * - any key that is a (non-strict) superset of another retained key is
718
+ * dropped — only minimal keys survive.
719
+ *
720
+ * The empty key `[]` (proven ≤1-row) is a subset of every other key, so when
721
+ * present it subsumes them all and is the sole survivor.
722
+ */
723
+ function normalizeKeys(keys) {
724
+ const sorted = keys.map(k => Array.from(new Set(k)).sort((a, b) => a - b));
725
+ const uniq = [];
726
+ const seen = new Set();
727
+ for (const k of sorted) {
728
+ const sig = k.join(',');
729
+ if (seen.has(sig))
623
730
  continue;
624
- // Determinants closure must cover all columns.
625
- if (isSuperkey(new Set(fd.determinants), fds, columnCount))
731
+ seen.add(sig);
732
+ uniq.push(k);
733
+ }
734
+ const result = [];
735
+ for (const k of uniq) {
736
+ const kSet = new Set(k);
737
+ const subsumed = uniq.some(other => other !== k &&
738
+ other.length < k.length &&
739
+ other.every(c => kSet.has(c)));
740
+ if (!subsumed)
741
+ result.push(k);
742
+ }
743
+ return result;
744
+ }
745
+ function allColumns(columnCount) {
746
+ const cols = [];
747
+ for (let i = 0; i < columnCount; i++)
748
+ cols.push(i);
749
+ return cols;
750
+ }
751
+ /**
752
+ * Canonical minimal candidate keys of a relation, each a sorted readonly
753
+ * `number[]` of output column indices, normalized and deduped. This is the
754
+ * single uniqueness read path — it reconciles all three surfaces a uniqueness
755
+ * fact can live on (declared `RelationType.keys`, the `PhysicalProperties.fds`
756
+ * FD set, and `RelationType.isSet`) so consumers never have to "check all
757
+ * three" by hand.
758
+ *
759
+ * Keys are gathered cheap → expensive:
760
+ * 1. Declared `keys` (mapped to column indices). The empty key `[]`
761
+ * (TableDee / ≤1-row) is preserved as an empty entry and subsumes all.
762
+ * 2. The `∅ → all_cols` FD (`hasSingletonFd`) ⇒ the empty key `[]`.
763
+ * 3. FD-derived keys via `deriveKeysFromFds`.
764
+ * 4. All-columns fallback: if nothing smaller was found AND the relation is
765
+ * a set (`getType().isSet`), the all-columns key `[0..n-1]`.
766
+ *
767
+ * Result is `[]` (no entries) ⟺ the relation is a bag (no provable key).
768
+ *
769
+ * **Enumeration bound (soundness vs completeness):** deriving minimal keys
770
+ * from a general FD set is the candidate-key enumeration problem (NP-hard in
771
+ * column count). We do NOT enumerate column subsets — `deriveKeysFromFds`
772
+ * seeds one candidate per existing FD and minimizes within it, and the
773
+ * declared keys + all-columns fallback are always emitted regardless of
774
+ * FD-enumeration cost. Over-capping here costs **completeness only** (a real
775
+ * key may go unlisted), never **soundness** (a listed key always holds). Use
776
+ * `isUnique` for the soundness-critical "is this set a superkey?" question —
777
+ * it additionally consults FD closure, which can prove a superkey absent from
778
+ * this minimal list.
779
+ */
780
+ export function keysOf(rel) {
781
+ const type = rel.getType();
782
+ const columnCount = type.columns.length;
783
+ const fds = rel.physical?.fds;
784
+ const keys = [];
785
+ // 1. Declared keys (RelationType.keys). An empty ColRef[] ⇒ the empty key.
786
+ for (const key of type.keys) {
787
+ keys.push(key.map(ref => ref.index));
788
+ }
789
+ // 2. Provable ≤1-row (kind-aware) ⇒ the empty key.
790
+ if (hasSingletonFd(fds, columnCount, type.isSet)) {
791
+ keys.push([]);
792
+ }
793
+ // 3. FD-derived keys (already bounded to FDs with det.length < 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)) {
797
+ keys.push(k);
798
+ }
799
+ const normalized = normalizeKeys(keys);
800
+ // 4. All-columns fallback, gated on set-ness. Only when nothing smaller was
801
+ // found — a set always has the all-columns key, but it is the weakest one.
802
+ if (normalized.length === 0 && type.isSet && columnCount > 0) {
803
+ return [allColumns(columnCount)];
804
+ }
805
+ return normalized;
806
+ }
807
+ /**
808
+ * True iff `cols` is a superkey of `rel` — i.e., the relation has at most one
809
+ * row per distinct `cols` tuple. The soundness-critical uniqueness predicate.
810
+ *
811
+ * Returns true iff any of:
812
+ * - `cols` is a (non-strict) superset of some `keysOf(rel)` entry (covers
813
+ * declared keys, the ≤1-row empty key, FD-derived keys, and the
814
+ * all-columns/set key), OR
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.
818
+ *
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).
823
+ */
824
+ export function isUnique(cols, rel) {
825
+ const type = rel.getType();
826
+ const columnCount = type.columns.length;
827
+ const colSet = new Set(cols);
828
+ for (const key of keysOf(rel)) {
829
+ if (key.every(c => colSet.has(c)))
626
830
  return true;
627
831
  }
628
- 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);
629
850
  }
630
851
  /**
631
852
  * Walk `predicate` (assumed to be a normalized conjunction) and extract FDs,
@@ -643,6 +864,19 @@ export function isAssertedKey(attrs, fds, columnCount) {
643
864
  * equivalence pair `[col1, col2]`.
644
865
  *
645
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`.
646
880
  */
647
881
  export function extractEqualityFds(predicate, attrIdToIndex) {
648
882
  const fds = [];
@@ -660,6 +894,9 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
660
894
  }
661
895
  if (op !== '=')
662
896
  continue;
897
+ // Value-level facts only from value-discriminating comparisons (see doc).
898
+ if (!isValueDiscriminatingEquality(n.left, n.right))
899
+ continue;
663
900
  const lIsCol = n.left instanceof ColumnReferenceNode;
664
901
  const rIsCol = n.right instanceof ColumnReferenceNode;
665
902
  const lConst = constantValueOf(n.left);
@@ -668,8 +905,10 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
668
905
  const lIdx = attrIdToIndex.get(n.left.attributeId);
669
906
  const rIdx = attrIdToIndex.get(n.right.attributeId);
670
907
  if (lIdx !== undefined && rIdx !== undefined && lIdx !== rIdx) {
671
- fds.push({ determinants: [lIdx], dependents: [rIdx] });
672
- 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' });
673
912
  equivPairs.push([lIdx, rIdx]);
674
913
  }
675
914
  continue;
@@ -677,7 +916,9 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
677
916
  if (lIsCol && rConst !== undefined) {
678
917
  const lIdx = attrIdToIndex.get(n.left.attributeId);
679
918
  if (lIdx !== undefined) {
680
- 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' });
681
922
  constantBindings.push({ attrs: [lIdx], value: rConst });
682
923
  }
683
924
  continue;
@@ -685,7 +926,7 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
685
926
  if (rIsCol && lConst !== undefined) {
686
927
  const rIdx = attrIdToIndex.get(n.right.attributeId);
687
928
  if (rIdx !== undefined) {
688
- fds.push({ determinants: [], dependents: [rIdx] });
929
+ fds.push({ determinants: [], dependents: [rIdx], kind: 'determination' });
689
930
  constantBindings.push({ attrs: [rIdx], value: lConst });
690
931
  }
691
932
  continue;
@@ -693,7 +934,44 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
693
934
  }
694
935
  return { fds, equivPairs, constantBindings };
695
936
  }
696
- 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) {
697
975
  const literalEqs = new Map();
698
976
  const columnEqs = new Map();
699
977
  const isNullCols = new Set();
@@ -722,6 +1000,13 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
722
1000
  }
723
1001
  return undefined;
724
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');
725
1010
  const tightenLowerBound = (col, value, inclusive) => {
726
1011
  const cur = rangeBounds.get(col);
727
1012
  if (!cur) {
@@ -792,18 +1077,23 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
792
1077
  const lIdx = columnIndexOf(n.left);
793
1078
  const rIdx = columnIndexOf(n.right);
794
1079
  if (lIdx !== undefined && rIdx !== undefined) {
795
- 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
+ }
796
1085
  continue;
797
1086
  }
1087
+ const effColl = effectiveComparisonCollation(n.left, n.right);
798
1088
  if (lIdx !== undefined) {
799
1089
  const lit = literalSqlValueOf(n.right);
800
- if (lit !== undefined)
1090
+ if (lit !== undefined && equalityCollationOk(lIdx, effColl))
801
1091
  literalEqs.set(lIdx, lit);
802
1092
  continue;
803
1093
  }
804
1094
  if (rIdx !== undefined) {
805
1095
  const lit = literalSqlValueOf(n.left);
806
- if (lit !== undefined)
1096
+ if (lit !== undefined && equalityCollationOk(rIdx, effColl))
807
1097
  literalEqs.set(rIdx, lit);
808
1098
  }
809
1099
  continue;
@@ -825,16 +1115,21 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
825
1115
  if (op === '<' || op === '<=' || op === '>' || op === '>=') {
826
1116
  const lIdx = columnIndexOf(n.left);
827
1117
  const rIdx = columnIndexOf(n.right);
1118
+ const effColl = effectiveComparisonCollation(n.left, n.right);
828
1119
  if (lIdx !== undefined && rIdx === undefined) {
829
1120
  const lit = literalSqlValueOf(n.right);
830
1121
  if (lit === undefined || lit === null)
831
1122
  continue;
1123
+ if (!rangeCollationOk(lIdx, effColl, lit))
1124
+ continue;
832
1125
  recordComparison(lIdx, op, lit);
833
1126
  }
834
1127
  else if (rIdx !== undefined && lIdx === undefined) {
835
1128
  const lit = literalSqlValueOf(n.left);
836
1129
  if (lit === undefined || lit === null)
837
1130
  continue;
1131
+ if (!rangeCollationOk(rIdx, effColl, lit))
1132
+ continue;
838
1133
  recordComparison(rIdx, flipComparison(op), lit);
839
1134
  }
840
1135
  continue;
@@ -849,10 +1144,15 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
849
1144
  continue;
850
1145
  const lo = literalSqlValueOf(n.lower);
851
1146
  const hi = literalSqlValueOf(n.upper);
852
- 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)) {
853
1150
  tightenLowerBound(cIdx, lo, true);
854
- if (hi !== undefined && hi !== null)
1151
+ }
1152
+ if (hi !== undefined && hi !== null
1153
+ && rangeCollationOk(cIdx, effectiveBetweenBoundCollation(n.expr, n.upper), hi)) {
855
1154
  tightenUpperBound(cIdx, hi, true);
1155
+ }
856
1156
  continue;
857
1157
  }
858
1158
  if (n instanceof UnaryOpNode) {
@@ -889,6 +1189,12 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
889
1189
  const cIdx = columnIndexOf(n.condition);
890
1190
  if (cIdx === undefined)
891
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;
892
1198
  const set = new Set();
893
1199
  let allLiterals = true;
894
1200
  for (const v of n.values) {
@@ -966,9 +1272,13 @@ function bindingForColumn(col, bindings) {
966
1272
  * sound for numeric columns since the consumer matches `eq-literal{col, 0}`
967
1273
  * via strict `sqlValueEquals`, which treats TEXT `''`, BLOB, and boolean
968
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.
969
1279
  */
970
- export function predicateImpliesGuard(predicate, guard, ecs, bindings, attrIdToIndex, isColumnNonNullable, isColumnNumeric) {
971
- 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);
972
1282
  for (const clause of guard.clauses) {
973
1283
  if (!clauseEntailed(clause, facts, ecs, bindings, isColumnNonNullable)) {
974
1284
  return false;
@@ -1413,4 +1723,111 @@ export function shiftDomainConstraints(domains, offset) {
1413
1723
  return domains.slice();
1414
1724
  return domains.map(domain => ({ ...domain, column: domain.column + offset }));
1415
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
+ }
1416
1833
  //# sourceMappingURL=fd-utils.js.map