@quereus/quereus 2.9.0 → 3.0.1

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 (356) hide show
  1. package/README.md +224 -222
  2. package/dist/src/core/database-assertions.d.ts +36 -16
  3. package/dist/src/core/database-assertions.d.ts.map +1 -1
  4. package/dist/src/core/database-assertions.js +222 -118
  5. package/dist/src/core/database-assertions.js.map +1 -1
  6. package/dist/src/core/database-transaction.d.ts +96 -13
  7. package/dist/src/core/database-transaction.d.ts.map +1 -1
  8. package/dist/src/core/database-transaction.js +294 -35
  9. package/dist/src/core/database-transaction.js.map +1 -1
  10. package/dist/src/core/database-watchers.d.ts +58 -0
  11. package/dist/src/core/database-watchers.d.ts.map +1 -0
  12. package/dist/src/core/database-watchers.js +206 -0
  13. package/dist/src/core/database-watchers.js.map +1 -0
  14. package/dist/src/core/database.d.ts +78 -5
  15. package/dist/src/core/database.d.ts.map +1 -1
  16. package/dist/src/core/database.js +120 -20
  17. package/dist/src/core/database.js.map +1 -1
  18. package/dist/src/core/statement.d.ts +9 -0
  19. package/dist/src/core/statement.d.ts.map +1 -1
  20. package/dist/src/core/statement.js +29 -0
  21. package/dist/src/core/statement.js.map +1 -1
  22. package/dist/src/core/table-handle.d.ts +45 -0
  23. package/dist/src/core/table-handle.d.ts.map +1 -0
  24. package/dist/src/core/table-handle.js +54 -0
  25. package/dist/src/core/table-handle.js.map +1 -0
  26. package/dist/src/func/builtins/conversion.d.ts.map +1 -1
  27. package/dist/src/func/builtins/conversion.js +12 -1
  28. package/dist/src/func/builtins/conversion.js.map +1 -1
  29. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  30. package/dist/src/func/builtins/explain.js +22 -8
  31. package/dist/src/func/builtins/explain.js.map +1 -1
  32. package/dist/src/func/builtins/generation.d.ts.map +1 -1
  33. package/dist/src/func/builtins/generation.js +26 -1
  34. package/dist/src/func/builtins/generation.js.map +1 -1
  35. package/dist/src/func/builtins/index.d.ts.map +1 -1
  36. package/dist/src/func/builtins/index.js +5 -1
  37. package/dist/src/func/builtins/index.js.map +1 -1
  38. package/dist/src/func/builtins/json-tvf.d.ts.map +1 -1
  39. package/dist/src/func/builtins/json-tvf.js +16 -2
  40. package/dist/src/func/builtins/json-tvf.js.map +1 -1
  41. package/dist/src/func/builtins/schema.d.ts +4 -0
  42. package/dist/src/func/builtins/schema.d.ts.map +1 -1
  43. package/dist/src/func/builtins/schema.js +270 -11
  44. package/dist/src/func/builtins/schema.js.map +1 -1
  45. package/dist/src/func/registration.d.ts +19 -1
  46. package/dist/src/func/registration.d.ts.map +1 -1
  47. package/dist/src/func/registration.js +8 -3
  48. package/dist/src/func/registration.js.map +1 -1
  49. package/dist/src/index.d.ts +7 -1
  50. package/dist/src/index.d.ts.map +1 -1
  51. package/dist/src/index.js +5 -0
  52. package/dist/src/index.js.map +1 -1
  53. package/dist/src/parser/parser.d.ts.map +1 -1
  54. package/dist/src/parser/parser.js +12 -4
  55. package/dist/src/parser/parser.js.map +1 -1
  56. package/dist/src/planner/analysis/assertion-classifier.d.ts +71 -0
  57. package/dist/src/planner/analysis/assertion-classifier.d.ts.map +1 -0
  58. package/dist/src/planner/analysis/assertion-classifier.js +286 -0
  59. package/dist/src/planner/analysis/assertion-classifier.js.map +1 -0
  60. package/dist/src/planner/analysis/assertion-hoist-cache.d.ts +34 -0
  61. package/dist/src/planner/analysis/assertion-hoist-cache.d.ts.map +1 -0
  62. package/dist/src/planner/analysis/assertion-hoist-cache.js +119 -0
  63. package/dist/src/planner/analysis/assertion-hoist-cache.js.map +1 -0
  64. package/dist/src/planner/analysis/binding-extractor.d.ts +58 -0
  65. package/dist/src/planner/analysis/binding-extractor.d.ts.map +1 -0
  66. package/dist/src/planner/analysis/binding-extractor.js +110 -0
  67. package/dist/src/planner/analysis/binding-extractor.js.map +1 -0
  68. package/dist/src/planner/analysis/change-scope.d.ts +184 -0
  69. package/dist/src/planner/analysis/change-scope.d.ts.map +1 -0
  70. package/dist/src/planner/analysis/change-scope.js +825 -0
  71. package/dist/src/planner/analysis/change-scope.js.map +1 -0
  72. package/dist/src/planner/analysis/check-extraction.d.ts +29 -0
  73. package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -0
  74. package/dist/src/planner/analysis/check-extraction.js +420 -0
  75. package/dist/src/planner/analysis/check-extraction.js.map +1 -0
  76. package/dist/src/planner/analysis/constraint-extractor.d.ts +47 -7
  77. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  78. package/dist/src/planner/analysis/constraint-extractor.js +186 -93
  79. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  80. package/dist/src/planner/analysis/partial-unique-extraction.d.ts +68 -0
  81. package/dist/src/planner/analysis/partial-unique-extraction.d.ts.map +1 -0
  82. package/dist/src/planner/analysis/partial-unique-extraction.js +347 -0
  83. package/dist/src/planner/analysis/partial-unique-extraction.js.map +1 -0
  84. package/dist/src/planner/analysis/predicate-conjuncts.d.ts +14 -0
  85. package/dist/src/planner/analysis/predicate-conjuncts.d.ts.map +1 -0
  86. package/dist/src/planner/analysis/predicate-conjuncts.js +31 -0
  87. package/dist/src/planner/analysis/predicate-conjuncts.js.map +1 -0
  88. package/dist/src/planner/analysis/predicate-shape.d.ts +52 -0
  89. package/dist/src/planner/analysis/predicate-shape.d.ts.map +1 -0
  90. package/dist/src/planner/analysis/predicate-shape.js +119 -0
  91. package/dist/src/planner/analysis/predicate-shape.js.map +1 -0
  92. package/dist/src/planner/analysis/sat-checker.d.ts +43 -0
  93. package/dist/src/planner/analysis/sat-checker.d.ts.map +1 -0
  94. package/dist/src/planner/analysis/sat-checker.js +393 -0
  95. package/dist/src/planner/analysis/sat-checker.js.map +1 -0
  96. package/dist/src/planner/building/table.d.ts.map +1 -1
  97. package/dist/src/planner/building/table.js +1 -1
  98. package/dist/src/planner/building/table.js.map +1 -1
  99. package/dist/src/planner/framework/characteristics.d.ts +10 -1
  100. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  101. package/dist/src/planner/framework/characteristics.js +24 -5
  102. package/dist/src/planner/framework/characteristics.js.map +1 -1
  103. package/dist/src/planner/framework/context.d.ts +1 -8
  104. package/dist/src/planner/framework/context.d.ts.map +1 -1
  105. package/dist/src/planner/framework/context.js +4 -21
  106. package/dist/src/planner/framework/context.js.map +1 -1
  107. package/dist/src/planner/framework/pass.d.ts +18 -2
  108. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  109. package/dist/src/planner/framework/pass.js +145 -46
  110. package/dist/src/planner/framework/pass.js.map +1 -1
  111. package/dist/src/planner/framework/physical-utils.d.ts +0 -9
  112. package/dist/src/planner/framework/physical-utils.d.ts.map +1 -1
  113. package/dist/src/planner/framework/physical-utils.js +0 -31
  114. package/dist/src/planner/framework/physical-utils.js.map +1 -1
  115. package/dist/src/planner/nodes/aggregate-node.d.ts +25 -0
  116. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  117. package/dist/src/planner/nodes/aggregate-node.js +75 -8
  118. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  119. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  120. package/dist/src/planner/nodes/alias-node.js +6 -1
  121. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  122. package/dist/src/planner/nodes/asof-scan-node.d.ts.map +1 -1
  123. package/dist/src/planner/nodes/asof-scan-node.js +17 -3
  124. package/dist/src/planner/nodes/asof-scan-node.js.map +1 -1
  125. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  126. package/dist/src/planner/nodes/bloom-join-node.js +19 -9
  127. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  128. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  129. package/dist/src/planner/nodes/distinct-node.js +10 -6
  130. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  131. package/dist/src/planner/nodes/empty-relation-node.d.ts +27 -0
  132. package/dist/src/planner/nodes/empty-relation-node.d.ts.map +1 -0
  133. package/dist/src/planner/nodes/empty-relation-node.js +61 -0
  134. package/dist/src/planner/nodes/empty-relation-node.js.map +1 -0
  135. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  136. package/dist/src/planner/nodes/filter.js +65 -5
  137. package/dist/src/planner/nodes/filter.js.map +1 -1
  138. package/dist/src/planner/nodes/hash-aggregate.d.ts +1 -1
  139. package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -1
  140. package/dist/src/planner/nodes/hash-aggregate.js +8 -6
  141. package/dist/src/planner/nodes/hash-aggregate.js.map +1 -1
  142. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  143. package/dist/src/planner/nodes/join-node.js +12 -9
  144. package/dist/src/planner/nodes/join-node.js.map +1 -1
  145. package/dist/src/planner/nodes/join-utils.d.ts +24 -1
  146. package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
  147. package/dist/src/planner/nodes/join-utils.js +86 -0
  148. package/dist/src/planner/nodes/join-utils.js.map +1 -1
  149. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  150. package/dist/src/planner/nodes/limit-offset.js +6 -1
  151. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  152. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  153. package/dist/src/planner/nodes/merge-join-node.js +19 -9
  154. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  155. package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
  156. package/dist/src/planner/nodes/ordinal-slice-node.js +5 -2
  157. package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
  158. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
  159. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  160. package/dist/src/planner/nodes/plan-node-type.js +1 -0
  161. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  162. package/dist/src/planner/nodes/plan-node.d.ts +186 -4
  163. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  164. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  165. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  166. package/dist/src/planner/nodes/project-node.js +75 -30
  167. package/dist/src/planner/nodes/project-node.js.map +1 -1
  168. package/dist/src/planner/nodes/reference.d.ts +24 -2
  169. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  170. package/dist/src/planner/nodes/reference.js +101 -1
  171. package/dist/src/planner/nodes/reference.js.map +1 -1
  172. package/dist/src/planner/nodes/retrieve-node.d.ts +9 -1
  173. package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
  174. package/dist/src/planner/nodes/retrieve-node.js +21 -0
  175. package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
  176. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  177. package/dist/src/planner/nodes/returning-node.js +64 -28
  178. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  179. package/dist/src/planner/nodes/scalar.d.ts +1 -0
  180. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  181. package/dist/src/planner/nodes/scalar.js +12 -0
  182. package/dist/src/planner/nodes/scalar.js.map +1 -1
  183. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  184. package/dist/src/planner/nodes/set-operation-node.js +15 -0
  185. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  186. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  187. package/dist/src/planner/nodes/single-row.js +3 -1
  188. package/dist/src/planner/nodes/single-row.js.map +1 -1
  189. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  190. package/dist/src/planner/nodes/sort.js +10 -3
  191. package/dist/src/planner/nodes/sort.js.map +1 -1
  192. package/dist/src/planner/nodes/stream-aggregate.d.ts +1 -1
  193. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  194. package/dist/src/planner/nodes/stream-aggregate.js +8 -8
  195. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  196. package/dist/src/planner/nodes/table-access-nodes.d.ts +3 -3
  197. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  198. package/dist/src/planner/nodes/table-access-nodes.js +26 -8
  199. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  200. package/dist/src/planner/nodes/table-function-call.d.ts +4 -1
  201. package/dist/src/planner/nodes/table-function-call.d.ts.map +1 -1
  202. package/dist/src/planner/nodes/table-function-call.js +224 -14
  203. package/dist/src/planner/nodes/table-function-call.js.map +1 -1
  204. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  205. package/dist/src/planner/nodes/window-node.js +9 -2
  206. package/dist/src/planner/nodes/window-node.js.map +1 -1
  207. package/dist/src/planner/optimizer-tuning.d.ts +29 -1
  208. package/dist/src/planner/optimizer-tuning.d.ts.map +1 -1
  209. package/dist/src/planner/optimizer-tuning.js +3 -0
  210. package/dist/src/planner/optimizer-tuning.js.map +1 -1
  211. package/dist/src/planner/optimizer.d.ts.map +1 -1
  212. package/dist/src/planner/optimizer.js +187 -0
  213. package/dist/src/planner/optimizer.js.map +1 -1
  214. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  215. package/dist/src/planner/rules/access/rule-select-access-path.js +22 -7
  216. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  217. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts +30 -0
  218. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -0
  219. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +116 -0
  220. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -0
  221. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts +7 -7
  222. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -1
  223. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +18 -16
  224. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js.map +1 -1
  225. package/dist/src/planner/rules/join/rule-join-elimination.d.ts +56 -0
  226. package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -0
  227. package/dist/src/planner/rules/join/rule-join-elimination.js +326 -0
  228. package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -0
  229. package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -1
  230. package/dist/src/planner/rules/join/rule-join-greedy-commute.js +10 -2
  231. package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -1
  232. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts +20 -0
  233. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -0
  234. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +181 -0
  235. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -0
  236. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts +46 -0
  237. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts.map +1 -0
  238. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +156 -0
  239. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js.map +1 -0
  240. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts +30 -0
  241. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -0
  242. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +60 -0
  243. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -0
  244. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts +45 -0
  245. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -0
  246. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +210 -0
  247. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -0
  248. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.d.ts +29 -0
  249. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.d.ts.map +1 -0
  250. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.js +161 -0
  251. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.js.map +1 -0
  252. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +39 -0
  253. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts.map +1 -0
  254. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +91 -0
  255. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js.map +1 -0
  256. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts +35 -0
  257. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -0
  258. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +74 -0
  259. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -0
  260. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts +27 -0
  261. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -0
  262. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +103 -0
  263. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -0
  264. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  265. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +1 -25
  266. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  267. package/dist/src/planner/scopes/global.js +2 -2
  268. package/dist/src/planner/scopes/global.js.map +1 -1
  269. package/dist/src/planner/type-utils.d.ts.map +1 -1
  270. package/dist/src/planner/type-utils.js +11 -0
  271. package/dist/src/planner/type-utils.js.map +1 -1
  272. package/dist/src/planner/util/fd-utils.d.ts +245 -0
  273. package/dist/src/planner/util/fd-utils.d.ts.map +1 -0
  274. package/dist/src/planner/util/fd-utils.js +1416 -0
  275. package/dist/src/planner/util/fd-utils.js.map +1 -0
  276. package/dist/src/planner/util/ind-utils.d.ts +79 -0
  277. package/dist/src/planner/util/ind-utils.d.ts.map +1 -0
  278. package/dist/src/planner/util/ind-utils.js +146 -0
  279. package/dist/src/planner/util/ind-utils.js.map +1 -0
  280. package/dist/src/planner/util/key-utils.d.ts +75 -14
  281. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  282. package/dist/src/planner/util/key-utils.js +234 -57
  283. package/dist/src/planner/util/key-utils.js.map +1 -1
  284. package/dist/src/runtime/delta-executor.d.ts +134 -0
  285. package/dist/src/runtime/delta-executor.d.ts.map +1 -0
  286. package/dist/src/runtime/delta-executor.js +382 -0
  287. package/dist/src/runtime/delta-executor.js.map +1 -0
  288. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  289. package/dist/src/runtime/emit/alter-table.js +70 -24
  290. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  291. package/dist/src/runtime/emit/create-assertion.d.ts.map +1 -1
  292. package/dist/src/runtime/emit/create-assertion.js +3 -2
  293. package/dist/src/runtime/emit/create-assertion.js.map +1 -1
  294. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  295. package/dist/src/runtime/emit/dml-executor.js +121 -41
  296. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  297. package/dist/src/runtime/emit/drop-assertion.js +1 -1
  298. package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
  299. package/dist/src/runtime/emit/empty-relation.d.ts +5 -0
  300. package/dist/src/runtime/emit/empty-relation.d.ts.map +1 -0
  301. package/dist/src/runtime/emit/empty-relation.js +11 -0
  302. package/dist/src/runtime/emit/empty-relation.js.map +1 -0
  303. package/dist/src/runtime/foreign-key-actions.d.ts +39 -0
  304. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  305. package/dist/src/runtime/foreign-key-actions.js +219 -1
  306. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  307. package/dist/src/runtime/register.d.ts.map +1 -1
  308. package/dist/src/runtime/register.js +2 -0
  309. package/dist/src/runtime/register.js.map +1 -1
  310. package/dist/src/schema/assertion.d.ts +8 -0
  311. package/dist/src/schema/assertion.d.ts.map +1 -1
  312. package/dist/src/schema/change-events.d.ts +5 -1
  313. package/dist/src/schema/change-events.d.ts.map +1 -1
  314. package/dist/src/schema/change-events.js.map +1 -1
  315. package/dist/src/schema/function.d.ts +65 -1
  316. package/dist/src/schema/function.d.ts.map +1 -1
  317. package/dist/src/schema/function.js +31 -0
  318. package/dist/src/schema/function.js.map +1 -1
  319. package/dist/src/schema/manager.d.ts +33 -0
  320. package/dist/src/schema/manager.d.ts.map +1 -1
  321. package/dist/src/schema/manager.js +95 -4
  322. package/dist/src/schema/manager.js.map +1 -1
  323. package/dist/src/schema/rename-rewriter.d.ts +32 -0
  324. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  325. package/dist/src/schema/rename-rewriter.js +392 -105
  326. package/dist/src/schema/rename-rewriter.js.map +1 -1
  327. package/dist/src/schema/table.d.ts +21 -2
  328. package/dist/src/schema/table.d.ts.map +1 -1
  329. package/dist/src/schema/table.js +17 -8
  330. package/dist/src/schema/table.js.map +1 -1
  331. package/dist/src/types/temporal-types.d.ts.map +1 -1
  332. package/dist/src/types/temporal-types.js +32 -0
  333. package/dist/src/types/temporal-types.js.map +1 -1
  334. package/dist/src/vtab/events.d.ts +9 -0
  335. package/dist/src/vtab/events.d.ts.map +1 -1
  336. package/dist/src/vtab/events.js +19 -0
  337. package/dist/src/vtab/events.js.map +1 -1
  338. package/dist/src/vtab/memory/layer/connection.d.ts +20 -8
  339. package/dist/src/vtab/memory/layer/connection.d.ts.map +1 -1
  340. package/dist/src/vtab/memory/layer/connection.js +95 -73
  341. package/dist/src/vtab/memory/layer/connection.js.map +1 -1
  342. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  343. package/dist/src/vtab/memory/layer/manager.js +91 -10
  344. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  345. package/dist/src/vtab/memory/layer/transaction.d.ts +0 -8
  346. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  347. package/dist/src/vtab/memory/layer/transaction.js +0 -15
  348. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  349. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  350. package/dist/src/vtab/memory/table.js +13 -2
  351. package/dist/src/vtab/memory/table.js.map +1 -1
  352. package/dist/src/vtab/memory/utils/predicate.d.ts +2 -1
  353. package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
  354. package/dist/src/vtab/memory/utils/predicate.js +32 -1
  355. package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
  356. package/package.json +3 -3
@@ -0,0 +1,825 @@
1
+ import { TableReferenceNode, ColumnReferenceNode, ParameterReferenceNode } from '../nodes/reference.js';
2
+ import { ScalarFunctionCallNode } from '../nodes/function.js';
3
+ import { PlanNodeType } from '../nodes/plan-node-type.js';
4
+ import { FunctionFlags } from '../../common/constants.js';
5
+ import { extractBindings } from './binding-extractor.js';
6
+ import { extractConstraintsForTable } from './constraint-extractor.js';
7
+ import { compareSqlValues } from '../../util/comparison.js';
8
+ import { getTypeOrDefault } from '../../types/registry.js';
9
+ function isParamScopeValue(v) {
10
+ return v !== null
11
+ && typeof v === 'object'
12
+ && !(v instanceof Uint8Array)
13
+ && !Array.isArray(v)
14
+ && 'kind' in v
15
+ && v.kind === 'param'
16
+ && 'index' in v
17
+ && 'type' in v;
18
+ }
19
+ function portableFromScalarType(t) {
20
+ const result = {
21
+ typeName: t.logicalType.name,
22
+ nullable: t.nullable,
23
+ ...(t.collationName !== undefined ? { collationName: t.collationName } : {}),
24
+ ...(t.isReadOnly !== undefined ? { isReadOnly: t.isReadOnly } : {}),
25
+ };
26
+ return result;
27
+ }
28
+ /**
29
+ * Reconstruct a full {@link ScalarType} from a {@link PortableScalarType} by
30
+ * resolving the logical type through the global type registry. Useful for
31
+ * callers that received a deserialized {@link ChangeScope} and need to feed
32
+ * the parameter type into other planner APIs.
33
+ */
34
+ export function scalarTypeFromPortable(p) {
35
+ const logical = getTypeOrDefault(p.typeName);
36
+ return {
37
+ typeClass: 'scalar',
38
+ logicalType: logical,
39
+ nullable: p.nullable,
40
+ ...(p.collationName !== undefined ? { collationName: p.collationName } : {}),
41
+ ...(p.isReadOnly !== undefined ? { isReadOnly: p.isReadOnly } : {}),
42
+ };
43
+ }
44
+ /* --- Constants ----------------------------------------------------------- */
45
+ const KNOWN_TIME_FUNCS = new Set([
46
+ 'now', 'current_timestamp', 'current_time', 'current_date',
47
+ 'date', 'time', 'datetime', 'julianday',
48
+ 'epoch_s', 'epoch_ms', 'epoch_s_frac',
49
+ 'strftime',
50
+ ]);
51
+ const KNOWN_RANDOM_FUNCS = new Set(['random', 'randomblob']);
52
+ const DML_NODE_TYPES = new Set([
53
+ PlanNodeType.Update,
54
+ PlanNodeType.Insert,
55
+ PlanNodeType.Delete,
56
+ PlanNodeType.UpdateExecutor,
57
+ ]);
58
+ /* --- Analyzer ------------------------------------------------------------ */
59
+ /**
60
+ * Walk a (post-analysis) plan and produce its `ChangeScope`. If `params`
61
+ * is supplied, parameter placeholders are substituted in-place and the
62
+ * corresponding indices are dropped from `unboundParameters`.
63
+ */
64
+ export function analyzeChangeScope(plan, options) {
65
+ const dmlWithoutReturning = isDmlWithoutReturning(plan);
66
+ const { perRelation } = extractBindings(plan);
67
+ const tableRefs = collectTableRefs(plan);
68
+ const columnsByRelKey = collectColumnReads(plan, tableRefs);
69
+ const nonDetSources = [];
70
+ const unboundParams = new Set();
71
+ collectNonDeterminism(plan, nonDetSources, unboundParams, perRelation);
72
+ const watches = [];
73
+ if (!dmlWithoutReturning) {
74
+ for (const ref of tableRefs) {
75
+ const relKey = relKeyFor(ref);
76
+ const mode = perRelation.get(relKey);
77
+ if (!mode)
78
+ continue;
79
+ const schemaName = ref.tableSchema.schemaName.toLowerCase();
80
+ const tableName = ref.tableSchema.name.toLowerCase();
81
+ const table = { schema: schemaName, table: tableName };
82
+ const colIndices = columnsByRelKey.get(relKey);
83
+ const columns = buildColumnSet(ref, colIndices);
84
+ const scope = buildScopeForMode(plan, ref, relKey, mode, unboundParams);
85
+ watches.push({ table, columns, scope });
86
+ }
87
+ }
88
+ let scope = {
89
+ watches: normalizeWatches(watches),
90
+ nonDeterministicSources: normalizeNonDet(nonDetSources),
91
+ unboundParameters: sortedDedupParamIndices(unboundParams),
92
+ };
93
+ if (options?.params !== undefined) {
94
+ scope = bindParameters(scope, options.params);
95
+ }
96
+ return scope;
97
+ }
98
+ /**
99
+ * Detects an UPDATE/INSERT/DELETE plan with no RETURNING clause: such a plan
100
+ * doesn't surface table state to the caller, so watches are empty (but
101
+ * parameters in the WHERE/SET clauses still count toward unboundParameters).
102
+ */
103
+ function isDmlWithoutReturning(plan) {
104
+ function hasReturning(node) {
105
+ if (node.nodeType === PlanNodeType.Returning)
106
+ return true;
107
+ for (const c of node.getChildren()) {
108
+ if (hasReturning(c))
109
+ return true;
110
+ }
111
+ return false;
112
+ }
113
+ function isDmlRoot(node) {
114
+ if (DML_NODE_TYPES.has(node.nodeType))
115
+ return true;
116
+ if (node.nodeType === PlanNodeType.Block) {
117
+ // A Block wraps one or more statements; check the last statement.
118
+ const stmts = node.statements;
119
+ if (stmts && stmts.length > 0) {
120
+ return isDmlRoot(stmts[stmts.length - 1]);
121
+ }
122
+ }
123
+ // Some DML may be wrapped by sinks/constraint-check nodes; recurse into
124
+ // a single relational child to find the inner DML.
125
+ const children = node.getChildren();
126
+ if (children.length === 1)
127
+ return isDmlRoot(children[0]);
128
+ return false;
129
+ }
130
+ if (!isDmlRoot(plan))
131
+ return false;
132
+ return !hasReturning(plan);
133
+ }
134
+ /* --- Plan walking helpers ------------------------------------------------ */
135
+ function relKeyFor(ref) {
136
+ const base = `${ref.tableSchema.schemaName}.${ref.tableSchema.name}`.toLowerCase();
137
+ return `${base}#${ref.id ?? 'unknown'}`;
138
+ }
139
+ function collectTableRefs(plan) {
140
+ const out = [];
141
+ const seen = new Set();
142
+ function walk(node) {
143
+ if (node instanceof TableReferenceNode) {
144
+ if (!seen.has(node)) {
145
+ seen.add(node);
146
+ out.push(node);
147
+ }
148
+ }
149
+ for (const c of node.getChildren())
150
+ walk(c);
151
+ }
152
+ walk(plan);
153
+ return out;
154
+ }
155
+ /**
156
+ * Walk the plan and, for each TableReference, collect the set of output
157
+ * column indices that any scalar expression in the plan reads.
158
+ */
159
+ function collectColumnReads(plan, tableRefs) {
160
+ const result = new Map();
161
+ const attrToRelKeyAndIdx = new Map();
162
+ for (const ref of tableRefs) {
163
+ const relKey = relKeyFor(ref);
164
+ const attrs = ref.getAttributes();
165
+ attrs.forEach((a, i) => attrToRelKeyAndIdx.set(a.id, { relKey, colIdx: i }));
166
+ }
167
+ function visit(node) {
168
+ if (node instanceof ColumnReferenceNode) {
169
+ const info = attrToRelKeyAndIdx.get(node.attributeId);
170
+ if (info) {
171
+ let s = result.get(info.relKey);
172
+ if (!s) {
173
+ s = new Set();
174
+ result.set(info.relKey, s);
175
+ }
176
+ s.add(info.colIdx);
177
+ }
178
+ }
179
+ for (const c of node.getChildren())
180
+ visit(c);
181
+ }
182
+ visit(plan);
183
+ return result;
184
+ }
185
+ /**
186
+ * Walk every scalar expression in the plan and collect non-deterministic
187
+ * sources (volatile functions, parameters used outside a row-binding equality).
188
+ */
189
+ function collectNonDeterminism(plan, out, unboundParams, perRelation) {
190
+ // Track parameters that *are* used as the value side of a row-binding
191
+ // equality predicate. These are already represented as ScopeValue.param
192
+ // placeholders inside the watch and don't need to also be flagged as
193
+ // nondeterministic sources (though they remain in unboundParameters).
194
+ const rowBindingParams = collectRowBindingParams(plan, perRelation);
195
+ function visit(node) {
196
+ if (node instanceof ScalarFunctionCallNode) {
197
+ const isDet = (node.functionSchema.flags & FunctionFlags.DETERMINISTIC) !== 0;
198
+ if (!isDet) {
199
+ const name = node.functionSchema.name.toLowerCase();
200
+ if (KNOWN_TIME_FUNCS.has(name)) {
201
+ out.push({ kind: 'time' });
202
+ }
203
+ else if (KNOWN_RANDOM_FUNCS.has(name)) {
204
+ out.push({ kind: 'random' });
205
+ }
206
+ else {
207
+ out.push({ kind: 'volatileUdf', name });
208
+ }
209
+ }
210
+ }
211
+ if (node instanceof ParameterReferenceNode) {
212
+ const id = node.nameOrIndex;
213
+ unboundParams.add(id);
214
+ if (!rowBindingParams.has(id)) {
215
+ out.push({ kind: 'parameter', index: id });
216
+ }
217
+ }
218
+ for (const c of node.getChildren())
219
+ visit(c);
220
+ }
221
+ visit(plan);
222
+ }
223
+ /** Collect every parameter id used as the value side of a row/group binding equality. */
224
+ function collectRowBindingParams(plan, perRelation) {
225
+ const result = new Set();
226
+ for (const [relKey, mode] of perRelation) {
227
+ if (mode.kind === 'global')
228
+ continue;
229
+ const constraints = extractConstraintsForTable(plan, relKey);
230
+ const keyCols = mode.kind === 'row' ? mode.keyColumns : mode.groupColumns;
231
+ for (const colIdx of keyCols) {
232
+ const match = constraints.find(c => c.columnIndex === colIdx && (c.op === '=' || c.op === 'IN'));
233
+ if (!match)
234
+ continue;
235
+ const ve = match.valueExpr;
236
+ if (!ve)
237
+ continue;
238
+ const exprs = Array.isArray(ve) ? ve : [ve];
239
+ for (const e of exprs) {
240
+ const id = extractParamId(e);
241
+ if (id !== undefined)
242
+ result.add(id);
243
+ }
244
+ }
245
+ }
246
+ return result;
247
+ }
248
+ function extractParamId(expr) {
249
+ // Unwrap a cast inserted by the planner for cross-category coercion.
250
+ const inner = expr.nodeType === PlanNodeType.Cast
251
+ ? expr.operand
252
+ : expr;
253
+ if (inner instanceof ParameterReferenceNode) {
254
+ return inner.nameOrIndex;
255
+ }
256
+ return undefined;
257
+ }
258
+ /* --- Scope building ------------------------------------------------------ */
259
+ function buildColumnSet(ref, indices) {
260
+ if (indices === undefined || indices.size === 0)
261
+ return 'all';
262
+ const attrs = ref.getAttributes();
263
+ const names = new Set();
264
+ for (const idx of indices) {
265
+ const attr = attrs[idx];
266
+ if (attr)
267
+ names.add(attr.name.toLowerCase());
268
+ }
269
+ return names;
270
+ }
271
+ function buildScopeForMode(plan, ref, relKey, mode, unboundParams) {
272
+ const attrs = ref.getAttributes();
273
+ const colName = (i) => attrs[i]?.name.toLowerCase() ?? `_col${i}`;
274
+ if (mode.kind === 'global') {
275
+ return { kind: 'full' };
276
+ }
277
+ if (mode.kind === 'row') {
278
+ const keyNames = mode.keyColumns.map(colName);
279
+ const values = extractRowKeyValues(plan, relKey, mode.keyColumns, unboundParams);
280
+ // If the binding-extractor classified this as 'row' but we couldn't
281
+ // decode literal/parameter values for every key column (e.g. equality
282
+ // against a complex expression like `pk = a + b`), an empty `values`
283
+ // array would mean "watch zero rows" — strictly less than what the
284
+ // query reads. Fall back to `full` to stay sound.
285
+ if (values.length === 0)
286
+ return { kind: 'full' };
287
+ return { kind: 'rows', key: keyNames, values };
288
+ }
289
+ // mode.kind === 'group'
290
+ const groupNames = mode.groupColumns.map(colName);
291
+ const values = extractRowKeyValues(plan, relKey, mode.groupColumns, unboundParams);
292
+ if (values.length > 0) {
293
+ return { kind: 'rowsByGroup', groupBy: groupNames, values };
294
+ }
295
+ return { kind: 'groups', groupBy: groupNames };
296
+ }
297
+ /**
298
+ * For each key column, pick the equality constraint and translate the
299
+ * RHS into a `ScopeValue` (literal or `param` placeholder). Returns one
300
+ * tuple per row-binding values combination present in the constraints.
301
+ */
302
+ function extractRowKeyValues(plan, relKey, keyColumns, unboundParams) {
303
+ const constraints = extractConstraintsForTable(plan, relKey);
304
+ // For each key column, gather candidate value expressions.
305
+ const perColValues = [];
306
+ for (const colIdx of keyColumns) {
307
+ const matches = constraints.filter(c => c.columnIndex === colIdx && (c.op === '=' || c.op === 'IN'));
308
+ if (matches.length === 0)
309
+ return [];
310
+ const colValues = new Set();
311
+ const ordered = [];
312
+ const push = (v) => {
313
+ const key = stringifyScopeValue(v);
314
+ if (!colValues.has(key)) {
315
+ colValues.add(key);
316
+ ordered.push(v);
317
+ }
318
+ };
319
+ for (const c of matches) {
320
+ if (c.op === 'IN' && Array.isArray(c.value)) {
321
+ const inExprs = Array.isArray(c.valueExpr) ? c.valueExpr : undefined;
322
+ for (let i = 0; i < c.value.length; i++) {
323
+ const v = c.value[i];
324
+ const exprAt = inExprs?.[i];
325
+ if (v !== undefined) {
326
+ push(v);
327
+ }
328
+ else if (exprAt) {
329
+ const sv = scopeValueFromExpr(exprAt, unboundParams);
330
+ if (sv === undefined)
331
+ return [];
332
+ push(sv);
333
+ }
334
+ else {
335
+ return [];
336
+ }
337
+ }
338
+ }
339
+ else if (c.op === '=') {
340
+ if (c.bindingKind === 'literal' || c.value !== undefined && !c.valueExpr) {
341
+ push(c.value);
342
+ }
343
+ else if (c.valueExpr && !Array.isArray(c.valueExpr)) {
344
+ const sv = scopeValueFromExpr(c.valueExpr, unboundParams);
345
+ if (sv === undefined)
346
+ return [];
347
+ push(sv);
348
+ }
349
+ else if (c.value !== undefined) {
350
+ push(c.value);
351
+ }
352
+ else {
353
+ return [];
354
+ }
355
+ }
356
+ }
357
+ perColValues.push(ordered);
358
+ }
359
+ // Take the cartesian product but only for single-column keys we keep
360
+ // independent rows; for multi-column keys without a matching tuple
361
+ // extraction the conservative thing is to produce the cross product.
362
+ const tuples = cartesianProduct(perColValues);
363
+ return sortAndDedupTuples(tuples);
364
+ }
365
+ function scopeValueFromExpr(expr, unboundParams) {
366
+ const inner = expr.nodeType === PlanNodeType.Cast
367
+ ? expr.operand
368
+ : expr;
369
+ if (inner instanceof ParameterReferenceNode) {
370
+ unboundParams.add(inner.nameOrIndex);
371
+ return { kind: 'param', index: inner.nameOrIndex, type: portableFromScalarType(inner.targetType) };
372
+ }
373
+ if (inner.nodeType === PlanNodeType.Literal) {
374
+ const lit = inner;
375
+ const v = lit.expression?.value;
376
+ if (v === undefined)
377
+ return undefined;
378
+ return v;
379
+ }
380
+ return undefined;
381
+ }
382
+ function cartesianProduct(input) {
383
+ if (input.length === 0)
384
+ return [];
385
+ if (input.some(arr => arr.length === 0))
386
+ return [];
387
+ const result = [[]];
388
+ for (const arr of input) {
389
+ const next = [];
390
+ for (const prefix of result) {
391
+ for (const v of arr) {
392
+ next.push([...prefix, v]);
393
+ }
394
+ }
395
+ result.length = 0;
396
+ result.push(...next);
397
+ }
398
+ return result;
399
+ }
400
+ /* --- Normalization, sorting, dedup --------------------------------------- */
401
+ function normalizeWatches(watches) {
402
+ return [...watches].sort(compareWatches);
403
+ }
404
+ function compareWatches(a, b) {
405
+ const sc = a.table.schema.localeCompare(b.table.schema);
406
+ if (sc !== 0)
407
+ return sc;
408
+ const tc = a.table.table.localeCompare(b.table.table);
409
+ if (tc !== 0)
410
+ return tc;
411
+ const ak = a.scope.kind;
412
+ const bk = b.scope.kind;
413
+ if (ak !== bk)
414
+ return ak.localeCompare(bk);
415
+ return scopeKeySerialization(a.scope).localeCompare(scopeKeySerialization(b.scope));
416
+ }
417
+ function scopeKeySerialization(scope) {
418
+ if (scope.kind === 'full')
419
+ return 'full';
420
+ if (scope.kind === 'groups')
421
+ return `groups:${scope.groupBy.join(',')}`;
422
+ if (scope.kind === 'rows')
423
+ return `rows:${scope.key.join(',')}:${tuplesKey(scope.values)}`;
424
+ return `rowsByGroup:${scope.groupBy.join(',')}:${tuplesKey(scope.values)}`;
425
+ }
426
+ function tuplesKey(values) {
427
+ return values.map(t => t.map(stringifyScopeValue).join('|')).join(';');
428
+ }
429
+ function stringifyScopeValue(v) {
430
+ if (isParamScopeValue(v)) {
431
+ return `@${v.index}`;
432
+ }
433
+ if (v === null)
434
+ return 'null';
435
+ if (typeof v === 'bigint')
436
+ return `b:${v.toString()}`;
437
+ if (typeof v === 'number')
438
+ return `n:${v}`;
439
+ if (typeof v === 'string')
440
+ return `s:${v}`;
441
+ if (typeof v === 'boolean')
442
+ return `B:${v}`;
443
+ if (v instanceof Uint8Array)
444
+ return `x:${Array.from(v).map(b => b.toString(16).padStart(2, '0')).join('')}`;
445
+ return `j:${JSON.stringify(v)}`;
446
+ }
447
+ function sortAndDedupTuples(tuples) {
448
+ const seen = new Map();
449
+ for (const t of tuples) {
450
+ const k = t.map(stringifyScopeValue).join('|');
451
+ if (!seen.has(k))
452
+ seen.set(k, t);
453
+ }
454
+ return [...seen.values()].sort(compareTuples);
455
+ }
456
+ function compareTuples(a, b) {
457
+ const len = Math.min(a.length, b.length);
458
+ for (let i = 0; i < len; i++) {
459
+ const ca = compareScopeValues(a[i], b[i]);
460
+ if (ca !== 0)
461
+ return ca;
462
+ }
463
+ return a.length - b.length;
464
+ }
465
+ function compareScopeValues(a, b) {
466
+ const aIsParam = isParamScopeValue(a);
467
+ const bIsParam = isParamScopeValue(b);
468
+ if (aIsParam && bIsParam) {
469
+ return String(a.index).localeCompare(String(b.index));
470
+ }
471
+ if (aIsParam)
472
+ return 1;
473
+ if (bIsParam)
474
+ return -1;
475
+ return compareSqlValues(a, b);
476
+ }
477
+ function normalizeNonDet(sources) {
478
+ const seen = new Map();
479
+ for (const s of sources) {
480
+ const k = nonDetKey(s);
481
+ if (!seen.has(k))
482
+ seen.set(k, s);
483
+ }
484
+ return [...seen.values()].sort((a, b) => nonDetKey(a).localeCompare(nonDetKey(b)));
485
+ }
486
+ function nonDetKey(s) {
487
+ switch (s.kind) {
488
+ case 'time': {
489
+ return 't';
490
+ }
491
+ case 'random': {
492
+ return 'r';
493
+ }
494
+ case 'volatileUdf': {
495
+ return `u:${s.name}`;
496
+ }
497
+ case 'parameter': {
498
+ return `p:${s.index}`;
499
+ }
500
+ }
501
+ }
502
+ function sortedDedupParamIndices(set) {
503
+ const arr = [...set];
504
+ arr.sort((a, b) => {
505
+ const aIsNum = typeof a === 'number';
506
+ const bIsNum = typeof b === 'number';
507
+ if (aIsNum && bIsNum)
508
+ return a - b;
509
+ if (aIsNum)
510
+ return -1;
511
+ if (bIsNum)
512
+ return 1;
513
+ return a.localeCompare(b);
514
+ });
515
+ return arr;
516
+ }
517
+ /* --- Composition helpers ------------------------------------------------- */
518
+ export function unionScopes(a, b) {
519
+ const byTable = new Map();
520
+ for (const w of a.watches)
521
+ byTable.set(tableKey(w.table), w);
522
+ for (const w of b.watches) {
523
+ const k = tableKey(w.table);
524
+ const prev = byTable.get(k);
525
+ byTable.set(k, prev ? unionWatch(prev, w) : w);
526
+ }
527
+ return {
528
+ watches: normalizeWatches([...byTable.values()]),
529
+ nonDeterministicSources: normalizeNonDet([...a.nonDeterministicSources, ...b.nonDeterministicSources]),
530
+ unboundParameters: sortedDedupParamIndices(new Set([...a.unboundParameters, ...b.unboundParameters])),
531
+ };
532
+ }
533
+ export function intersectScopes(a, b) {
534
+ const byTableA = new Map();
535
+ for (const w of a.watches)
536
+ byTableA.set(tableKey(w.table), w);
537
+ const out = [];
538
+ for (const w of b.watches) {
539
+ const k = tableKey(w.table);
540
+ const other = byTableA.get(k);
541
+ if (!other)
542
+ continue;
543
+ const merged = intersectWatch(other, w);
544
+ if (merged)
545
+ out.push(merged);
546
+ }
547
+ // Intersection of non-determinism is the set-intersection.
548
+ const bNonDet = new Set(b.nonDeterministicSources.map(nonDetKey));
549
+ const sharedNonDet = a.nonDeterministicSources.filter(s => bNonDet.has(nonDetKey(s)));
550
+ // Intersection of unbound parameters is the set-intersection.
551
+ const aParams = new Set(a.unboundParameters);
552
+ const sharedParams = new Set();
553
+ for (const p of b.unboundParameters)
554
+ if (aParams.has(p))
555
+ sharedParams.add(p);
556
+ return {
557
+ watches: normalizeWatches(out),
558
+ nonDeterministicSources: normalizeNonDet(sharedNonDet),
559
+ unboundParameters: sortedDedupParamIndices(sharedParams),
560
+ };
561
+ }
562
+ function tableKey(t) {
563
+ return `${t.schema}.${t.table}`;
564
+ }
565
+ function unionWatch(a, b) {
566
+ const columns = unionColumns(a.columns, b.columns);
567
+ const scope = unionWatchScope(a.scope, b.scope);
568
+ return { table: a.table, columns, scope };
569
+ }
570
+ function unionColumns(a, b) {
571
+ if (a === 'all' || b === 'all')
572
+ return 'all';
573
+ const out = new Set(a);
574
+ for (const c of b)
575
+ out.add(c);
576
+ return out;
577
+ }
578
+ function unionWatchScope(a, b) {
579
+ if (a.kind === 'full' || b.kind === 'full')
580
+ return { kind: 'full' };
581
+ if (a.kind === 'groups' && b.kind === 'groups') {
582
+ const aSet = new Set(a.groupBy);
583
+ const bSet = new Set(b.groupBy);
584
+ const aSubsetB = [...aSet].every(c => bSet.has(c));
585
+ const bSubsetA = [...bSet].every(c => aSet.has(c));
586
+ if (aSubsetB)
587
+ return { kind: 'groups', groupBy: a.groupBy };
588
+ if (bSubsetA)
589
+ return { kind: 'groups', groupBy: b.groupBy };
590
+ return { kind: 'full' };
591
+ }
592
+ if (a.kind === 'rows' && b.kind === 'rows') {
593
+ if (sameKey(a.key, b.key)) {
594
+ return { kind: 'rows', key: a.key, values: mergeValues(a.values, b.values) };
595
+ }
596
+ return { kind: 'full' };
597
+ }
598
+ if (a.kind === 'rowsByGroup' && b.kind === 'rowsByGroup') {
599
+ if (sameKey(a.groupBy, b.groupBy)) {
600
+ return { kind: 'rowsByGroup', groupBy: a.groupBy, values: mergeValues(a.values, b.values) };
601
+ }
602
+ return { kind: 'full' };
603
+ }
604
+ // Mixed shapes (rows vs groups, etc.) cannot be unioned narrowly.
605
+ return { kind: 'full' };
606
+ }
607
+ function intersectWatch(a, b) {
608
+ const columns = intersectColumns(a.columns, b.columns);
609
+ const scope = intersectWatchScope(a.scope, b.scope);
610
+ if (!scope)
611
+ return null;
612
+ return { table: a.table, columns, scope };
613
+ }
614
+ function intersectColumns(a, b) {
615
+ if (a === 'all')
616
+ return b;
617
+ if (b === 'all')
618
+ return a;
619
+ const out = new Set();
620
+ for (const c of a)
621
+ if (b.has(c))
622
+ out.add(c);
623
+ return out;
624
+ }
625
+ function intersectWatchScope(a, b) {
626
+ if (a.kind === 'full')
627
+ return b;
628
+ if (b.kind === 'full')
629
+ return a;
630
+ if (a.kind === 'groups' && b.kind === 'groups') {
631
+ const aSet = new Set(a.groupBy);
632
+ const bSet = new Set(b.groupBy);
633
+ const aSubsetB = [...aSet].every(c => bSet.has(c));
634
+ const bSubsetA = [...bSet].every(c => aSet.has(c));
635
+ // Intersect picks the *finer* (longer) groupBy that is a superset of the other.
636
+ if (aSubsetB)
637
+ return { kind: 'groups', groupBy: b.groupBy };
638
+ if (bSubsetA)
639
+ return { kind: 'groups', groupBy: a.groupBy };
640
+ return null;
641
+ }
642
+ if (a.kind === 'rows' && b.kind === 'rows') {
643
+ if (!sameKey(a.key, b.key))
644
+ return null;
645
+ const merged = intersectValues(a.values, b.values);
646
+ if (merged.length === 0)
647
+ return null;
648
+ return { kind: 'rows', key: a.key, values: merged };
649
+ }
650
+ if (a.kind === 'rowsByGroup' && b.kind === 'rowsByGroup') {
651
+ if (!sameKey(a.groupBy, b.groupBy))
652
+ return null;
653
+ const merged = intersectValues(a.values, b.values);
654
+ if (merged.length === 0)
655
+ return null;
656
+ return { kind: 'rowsByGroup', groupBy: a.groupBy, values: merged };
657
+ }
658
+ return null;
659
+ }
660
+ function sameKey(a, b) {
661
+ if (a.length !== b.length)
662
+ return false;
663
+ for (let i = 0; i < a.length; i++)
664
+ if (a[i] !== b[i])
665
+ return false;
666
+ return true;
667
+ }
668
+ function mergeValues(a, b) {
669
+ const seen = new Map();
670
+ for (const t of a) {
671
+ const k = t.map(stringifyScopeValue).join('|');
672
+ seen.set(k, t);
673
+ }
674
+ for (const t of b) {
675
+ const k = t.map(stringifyScopeValue).join('|');
676
+ if (!seen.has(k))
677
+ seen.set(k, t);
678
+ }
679
+ return [...seen.values()].sort(compareTuples);
680
+ }
681
+ function intersectValues(a, b) {
682
+ const bKeys = new Set(b.map(t => t.map(stringifyScopeValue).join('|')));
683
+ return a.filter(t => bKeys.has(t.map(stringifyScopeValue).join('|')));
684
+ }
685
+ /* --- Parameter binding --------------------------------------------------- */
686
+ export function bindParameters(scope, params) {
687
+ const lookup = (id) => {
688
+ if (Array.isArray(params)) {
689
+ if (typeof id !== 'number')
690
+ return undefined;
691
+ const v = params[id - 1];
692
+ return v;
693
+ }
694
+ if (typeof id === 'number') {
695
+ return params[id];
696
+ }
697
+ const key = id.startsWith(':') || id.startsWith('@') || id.startsWith('$')
698
+ ? id.substring(1)
699
+ : id;
700
+ const obj = params;
701
+ if (key in obj)
702
+ return obj[key];
703
+ if (id in obj)
704
+ return obj[id];
705
+ return undefined;
706
+ };
707
+ const substituteValue = (v) => {
708
+ if (isParamScopeValue(v)) {
709
+ const bound = lookup(v.index);
710
+ if (bound !== undefined)
711
+ return bound;
712
+ }
713
+ return v;
714
+ };
715
+ const substituteTuples = (tuples) => {
716
+ const out = tuples.map(t => t.map(substituteValue));
717
+ return sortAndDedupTuples(out);
718
+ };
719
+ const newWatches = scope.watches.map(w => {
720
+ let newScope = w.scope;
721
+ if (w.scope.kind === 'rows') {
722
+ newScope = { kind: 'rows', key: w.scope.key, values: substituteTuples(w.scope.values) };
723
+ }
724
+ else if (w.scope.kind === 'rowsByGroup') {
725
+ newScope = { kind: 'rowsByGroup', groupBy: w.scope.groupBy, values: substituteTuples(w.scope.values) };
726
+ }
727
+ return { table: w.table, columns: w.columns, scope: newScope };
728
+ });
729
+ const remainingUnbound = new Set();
730
+ for (const id of scope.unboundParameters) {
731
+ if (lookup(id) === undefined)
732
+ remainingUnbound.add(id);
733
+ }
734
+ const remainingNonDet = scope.nonDeterministicSources.filter(s => {
735
+ if (s.kind === 'parameter')
736
+ return lookup(s.index) === undefined;
737
+ return true;
738
+ });
739
+ return {
740
+ watches: normalizeWatches(newWatches),
741
+ nonDeterministicSources: normalizeNonDet(remainingNonDet),
742
+ unboundParameters: sortedDedupParamIndices(remainingUnbound),
743
+ };
744
+ }
745
+ /* --- Predicates ---------------------------------------------------------- */
746
+ export function isEmpty(scope) {
747
+ return scope.watches.length === 0
748
+ && scope.nonDeterministicSources.length === 0
749
+ && scope.unboundParameters.length === 0;
750
+ }
751
+ export function describesEverything(scope) {
752
+ if (scope.watches.length === 0)
753
+ return false;
754
+ return scope.watches.every(w => w.scope.kind === 'full' && w.columns === 'all');
755
+ }
756
+ export function serializeChangeScope(scope) {
757
+ return {
758
+ watches: scope.watches.map(w => ({
759
+ table: { schema: w.table.schema, table: w.table.table },
760
+ columns: w.columns === 'all' ? 'all' : [...w.columns].sort(),
761
+ scope: serializeScope(w.scope),
762
+ })),
763
+ nonDeterministicSources: [...scope.nonDeterministicSources],
764
+ unboundParameters: [...scope.unboundParameters],
765
+ };
766
+ }
767
+ function serializeScope(scope) {
768
+ if (scope.kind === 'full')
769
+ return { kind: 'full' };
770
+ if (scope.kind === 'groups')
771
+ return { kind: 'groups', groupBy: [...scope.groupBy] };
772
+ if (scope.kind === 'rows') {
773
+ return {
774
+ kind: 'rows',
775
+ key: [...scope.key],
776
+ values: scope.values.map(t => t.map(serializeScopeValue)),
777
+ };
778
+ }
779
+ return {
780
+ kind: 'rowsByGroup',
781
+ groupBy: [...scope.groupBy],
782
+ values: scope.values.map(t => t.map(serializeScopeValue)),
783
+ };
784
+ }
785
+ function serializeScopeValue(v) {
786
+ if (isParamScopeValue(v)) {
787
+ return { p: v.index, t: { ...v.type } };
788
+ }
789
+ return { v: v };
790
+ }
791
+ export function deserializeChangeScope(obj) {
792
+ return {
793
+ watches: obj.watches.map(w => ({
794
+ table: { schema: w.table.schema, table: w.table.table },
795
+ columns: w.columns === 'all' ? 'all' : new Set(w.columns),
796
+ scope: deserializeScope(w.scope),
797
+ })),
798
+ nonDeterministicSources: [...obj.nonDeterministicSources],
799
+ unboundParameters: [...obj.unboundParameters],
800
+ };
801
+ }
802
+ function deserializeScope(scope) {
803
+ if (scope.kind === 'full')
804
+ return { kind: 'full' };
805
+ if (scope.kind === 'groups')
806
+ return { kind: 'groups', groupBy: [...scope.groupBy] };
807
+ if (scope.kind === 'rows') {
808
+ return {
809
+ kind: 'rows',
810
+ key: [...scope.key],
811
+ values: scope.values.map(t => t.map(deserializeScopeValue)),
812
+ };
813
+ }
814
+ return {
815
+ kind: 'rowsByGroup',
816
+ groupBy: [...scope.groupBy],
817
+ values: scope.values.map(t => t.map(deserializeScopeValue)),
818
+ };
819
+ }
820
+ function deserializeScopeValue(v) {
821
+ if ('p' in v)
822
+ return { kind: 'param', index: v.p, type: { ...v.t } };
823
+ return v.v;
824
+ }
825
+ //# sourceMappingURL=change-scope.js.map