@quereus/quereus 4.4.0 → 4.5.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 (491) hide show
  1. package/README.md +6 -1
  2. package/dist/src/common/types.d.ts +9 -0
  3. package/dist/src/common/types.d.ts.map +1 -1
  4. package/dist/src/common/types.js.map +1 -1
  5. package/dist/src/core/database-events.d.ts +49 -0
  6. package/dist/src/core/database-events.d.ts.map +1 -1
  7. package/dist/src/core/database-events.js +148 -0
  8. package/dist/src/core/database-events.js.map +1 -1
  9. package/dist/src/core/database-materialized-views-analysis.d.ts.map +1 -1
  10. package/dist/src/core/database-materialized-views-analysis.js +1 -0
  11. package/dist/src/core/database-materialized-views-analysis.js.map +1 -1
  12. package/dist/src/core/database-materialized-views-plan-builders.d.ts +2 -1
  13. package/dist/src/core/database-materialized-views-plan-builders.d.ts.map +1 -1
  14. package/dist/src/core/database-materialized-views-plan-builders.js +26 -5
  15. package/dist/src/core/database-materialized-views-plan-builders.js.map +1 -1
  16. package/dist/src/core/database-materialized-views-plans.d.ts +6 -3
  17. package/dist/src/core/database-materialized-views-plans.d.ts.map +1 -1
  18. package/dist/src/core/database-materialized-views.d.ts +3 -2
  19. package/dist/src/core/database-materialized-views.d.ts.map +1 -1
  20. package/dist/src/core/database-materialized-views.js +26 -5
  21. package/dist/src/core/database-materialized-views.js.map +1 -1
  22. package/dist/src/core/database.d.ts +5 -0
  23. package/dist/src/core/database.d.ts.map +1 -1
  24. package/dist/src/core/database.js +21 -1
  25. package/dist/src/core/database.js.map +1 -1
  26. package/dist/src/core/internal-statement-cache.d.ts +18 -0
  27. package/dist/src/core/internal-statement-cache.d.ts.map +1 -0
  28. package/dist/src/core/internal-statement-cache.js +211 -0
  29. package/dist/src/core/internal-statement-cache.js.map +1 -0
  30. package/dist/src/func/builtins/aggregate.d.ts +13 -12
  31. package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
  32. package/dist/src/func/builtins/aggregate.js +45 -67
  33. package/dist/src/func/builtins/aggregate.js.map +1 -1
  34. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
  35. package/dist/src/func/builtins/builtin-window-functions.js +63 -48
  36. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
  37. package/dist/src/func/builtins/scalar.d.ts.map +1 -1
  38. package/dist/src/func/builtins/scalar.js +92 -3
  39. package/dist/src/func/builtins/scalar.js.map +1 -1
  40. package/dist/src/func/registration.d.ts +18 -1
  41. package/dist/src/func/registration.d.ts.map +1 -1
  42. package/dist/src/func/registration.js +26 -0
  43. package/dist/src/func/registration.js.map +1 -1
  44. package/dist/src/index.d.ts +10 -10
  45. package/dist/src/index.d.ts.map +1 -1
  46. package/dist/src/index.js +13 -12
  47. package/dist/src/index.js.map +1 -1
  48. package/dist/src/parser/parser.d.ts +6 -0
  49. package/dist/src/parser/parser.d.ts.map +1 -1
  50. package/dist/src/parser/parser.js +45 -34
  51. package/dist/src/parser/parser.js.map +1 -1
  52. package/dist/src/planner/analysis/coarsened-key.d.ts +4 -3
  53. package/dist/src/planner/analysis/coarsened-key.d.ts.map +1 -1
  54. package/dist/src/planner/analysis/coarsened-key.js +37 -3
  55. package/dist/src/planner/analysis/coarsened-key.js.map +1 -1
  56. package/dist/src/planner/analysis/comparison-collation.d.ts +35 -3
  57. package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -1
  58. package/dist/src/planner/analysis/comparison-collation.js +37 -3
  59. package/dist/src/planner/analysis/comparison-collation.js.map +1 -1
  60. package/dist/src/planner/analysis/coverage-prover.d.ts +13 -2
  61. package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -1
  62. package/dist/src/planner/analysis/coverage-prover.js +10 -14
  63. package/dist/src/planner/analysis/coverage-prover.js.map +1 -1
  64. package/dist/src/planner/analysis/expression-fingerprint.d.ts.map +1 -1
  65. package/dist/src/planner/analysis/expression-fingerprint.js +29 -0
  66. package/dist/src/planner/analysis/expression-fingerprint.js.map +1 -1
  67. package/dist/src/planner/analysis/predicate-conjuncts.d.ts +10 -4
  68. package/dist/src/planner/analysis/predicate-conjuncts.d.ts.map +1 -1
  69. package/dist/src/planner/analysis/predicate-conjuncts.js +28 -7
  70. package/dist/src/planner/analysis/predicate-conjuncts.js.map +1 -1
  71. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +6 -0
  72. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -1
  73. package/dist/src/planner/analysis/query-rewrite-matcher.js +19 -29
  74. package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -1
  75. package/dist/src/planner/analysis/sat-checker.d.ts.map +1 -1
  76. package/dist/src/planner/analysis/sat-checker.js +43 -4
  77. package/dist/src/planner/analysis/sat-checker.js.map +1 -1
  78. package/dist/src/planner/analysis/scalar-subqueries.d.ts +22 -3
  79. package/dist/src/planner/analysis/scalar-subqueries.d.ts.map +1 -1
  80. package/dist/src/planner/analysis/scalar-subqueries.js +32 -3
  81. package/dist/src/planner/analysis/scalar-subqueries.js.map +1 -1
  82. package/dist/src/planner/analysis/set-op-type-merge.d.ts +64 -0
  83. package/dist/src/planner/analysis/set-op-type-merge.d.ts.map +1 -0
  84. package/dist/src/planner/analysis/set-op-type-merge.js +97 -0
  85. package/dist/src/planner/analysis/set-op-type-merge.js.map +1 -0
  86. package/dist/src/planner/building/coercion.d.ts +78 -0
  87. package/dist/src/planner/building/coercion.d.ts.map +1 -0
  88. package/dist/src/planner/building/coercion.js +137 -0
  89. package/dist/src/planner/building/coercion.js.map +1 -0
  90. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  91. package/dist/src/planner/building/constraint-builder.js +5 -18
  92. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  93. package/dist/src/planner/building/delete.d.ts.map +1 -1
  94. package/dist/src/planner/building/delete.js +10 -3
  95. package/dist/src/planner/building/delete.js.map +1 -1
  96. package/dist/src/planner/building/expression.d.ts.map +1 -1
  97. package/dist/src/planner/building/expression.js +13 -35
  98. package/dist/src/planner/building/expression.js.map +1 -1
  99. package/dist/src/planner/building/foreign-key-builder.d.ts +44 -1
  100. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
  101. package/dist/src/planner/building/foreign-key-builder.js +54 -0
  102. package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
  103. package/dist/src/planner/building/function-call.d.ts.map +1 -1
  104. package/dist/src/planner/building/function-call.js +8 -0
  105. package/dist/src/planner/building/function-call.js.map +1 -1
  106. package/dist/src/planner/building/insert.d.ts.map +1 -1
  107. package/dist/src/planner/building/insert.js +9 -12
  108. package/dist/src/planner/building/insert.js.map +1 -1
  109. package/dist/src/planner/building/select-compound.d.ts.map +1 -1
  110. package/dist/src/planner/building/select-compound.js +10 -6
  111. package/dist/src/planner/building/select-compound.js.map +1 -1
  112. package/dist/src/planner/building/update.d.ts.map +1 -1
  113. package/dist/src/planner/building/update.js +13 -4
  114. package/dist/src/planner/building/update.js.map +1 -1
  115. package/dist/src/planner/cost/conjunct-cost.d.ts +42 -0
  116. package/dist/src/planner/cost/conjunct-cost.d.ts.map +1 -0
  117. package/dist/src/planner/cost/conjunct-cost.js +62 -0
  118. package/dist/src/planner/cost/conjunct-cost.js.map +1 -0
  119. package/dist/src/planner/framework/pass.js +3 -3
  120. package/dist/src/planner/mutation/propagate.d.ts.map +1 -1
  121. package/dist/src/planner/mutation/propagate.js +1 -0
  122. package/dist/src/planner/mutation/propagate.js.map +1 -1
  123. package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
  124. package/dist/src/planner/nodes/async-gather-node.js +19 -8
  125. package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
  126. package/dist/src/planner/nodes/bloom-join-node.d.ts +2 -0
  127. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  128. package/dist/src/planner/nodes/bloom-join-node.js +10 -5
  129. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  130. package/dist/src/planner/nodes/dml-executor-node.d.ts +0 -9
  131. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  132. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  133. package/dist/src/planner/nodes/join-node.d.ts +5 -0
  134. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  135. package/dist/src/planner/nodes/join-node.js +8 -1
  136. package/dist/src/planner/nodes/join-node.js.map +1 -1
  137. package/dist/src/planner/nodes/join-utils.d.ts +57 -0
  138. package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
  139. package/dist/src/planner/nodes/join-utils.js +47 -0
  140. package/dist/src/planner/nodes/join-utils.js.map +1 -1
  141. package/dist/src/planner/nodes/key-set-semi-join-node.d.ts +87 -0
  142. package/dist/src/planner/nodes/key-set-semi-join-node.d.ts.map +1 -0
  143. package/dist/src/planner/nodes/key-set-semi-join-node.js +137 -0
  144. package/dist/src/planner/nodes/key-set-semi-join-node.js.map +1 -0
  145. package/dist/src/planner/nodes/merge-join-node.d.ts +2 -0
  146. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  147. package/dist/src/planner/nodes/merge-join-node.js +14 -6
  148. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  149. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
  150. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  151. package/dist/src/planner/nodes/plan-node-type.js +1 -0
  152. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  153. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  154. package/dist/src/planner/nodes/scalar.js +26 -3
  155. package/dist/src/planner/nodes/scalar.js.map +1 -1
  156. package/dist/src/planner/nodes/set-operation-node.d.ts +68 -16
  157. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  158. package/dist/src/planner/nodes/set-operation-node.js +147 -26
  159. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  160. package/dist/src/planner/nodes/table-access-nodes.d.ts +19 -1
  161. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  162. package/dist/src/planner/nodes/table-access-nodes.js +13 -2
  163. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  164. package/dist/src/planner/optimizer.d.ts.map +1 -1
  165. package/dist/src/planner/optimizer.js +54 -12
  166. package/dist/src/planner/optimizer.js.map +1 -1
  167. package/dist/src/planner/rules/access/rule-key-set-seek.d.ts +68 -0
  168. package/dist/src/planner/rules/access/rule-key-set-seek.d.ts.map +1 -0
  169. package/dist/src/planner/rules/access/rule-key-set-seek.js +408 -0
  170. package/dist/src/planner/rules/access/rule-key-set-seek.js.map +1 -0
  171. package/dist/src/planner/rules/access/rule-monotonic-range-access.d.ts.map +1 -1
  172. package/dist/src/planner/rules/access/rule-monotonic-range-access.js +2 -2
  173. package/dist/src/planner/rules/access/rule-monotonic-range-access.js.map +1 -1
  174. package/dist/src/planner/rules/access/rule-select-access-path.d.ts +27 -0
  175. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  176. package/dist/src/planner/rules/access/rule-select-access-path.js +74 -29
  177. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  178. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -1
  179. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +23 -4
  180. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -1
  181. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.d.ts +10 -8
  182. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.d.ts.map +1 -1
  183. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.js +10 -8
  184. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.js.map +1 -1
  185. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +67 -41
  186. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
  187. package/dist/src/planner/rules/join/equi-pair-extractor.js +72 -36
  188. package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
  189. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -1
  190. package/dist/src/planner/rules/join/rule-join-physical-selection.js +14 -2
  191. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
  192. package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts.map +1 -1
  193. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +11 -1
  194. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
  195. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts +1 -1
  196. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +1 -1
  197. package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts +30 -0
  198. package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts.map +1 -0
  199. package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js +63 -0
  200. package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js.map +1 -0
  201. package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts +17 -1
  202. package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts.map +1 -1
  203. package/dist/src/planner/rules/predicate/rule-filter-selectivity.js +206 -12
  204. package/dist/src/planner/rules/predicate/rule-filter-selectivity.js.map +1 -1
  205. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +8 -1
  206. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
  207. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts +3 -1
  208. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts.map +1 -1
  209. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +13 -1
  210. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
  211. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
  212. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +18 -3
  213. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
  214. package/dist/src/planner/rules/shared/index-style-context.d.ts +17 -0
  215. package/dist/src/planner/rules/shared/index-style-context.d.ts.map +1 -1
  216. package/dist/src/planner/rules/shared/index-style-context.js +7 -0
  217. package/dist/src/planner/rules/shared/index-style-context.js.map +1 -1
  218. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.js +4 -0
  219. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.js.map +1 -1
  220. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts +24 -6
  221. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  222. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +175 -60
  223. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  224. package/dist/src/planner/stats/catalog-stats.d.ts +52 -0
  225. package/dist/src/planner/stats/catalog-stats.d.ts.map +1 -1
  226. package/dist/src/planner/stats/catalog-stats.js +151 -5
  227. package/dist/src/planner/stats/catalog-stats.js.map +1 -1
  228. package/dist/src/planner/stats/index.d.ts +15 -0
  229. package/dist/src/planner/stats/index.d.ts.map +1 -1
  230. package/dist/src/planner/stats/index.js.map +1 -1
  231. package/dist/src/planner/stats/selectivity-combine.d.ts +53 -0
  232. package/dist/src/planner/stats/selectivity-combine.d.ts.map +1 -0
  233. package/dist/src/planner/stats/selectivity-combine.js +75 -0
  234. package/dist/src/planner/stats/selectivity-combine.js.map +1 -0
  235. package/dist/src/planner/util/column-origins.d.ts +58 -0
  236. package/dist/src/planner/util/column-origins.d.ts.map +1 -0
  237. package/dist/src/planner/util/column-origins.js +90 -0
  238. package/dist/src/planner/util/column-origins.js.map +1 -0
  239. package/dist/src/runtime/deferred-constraint-queue.d.ts +40 -0
  240. package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
  241. package/dist/src/runtime/deferred-constraint-queue.js +91 -0
  242. package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
  243. package/dist/src/runtime/emit/aggregate-setup.d.ts +49 -0
  244. package/dist/src/runtime/emit/aggregate-setup.d.ts.map +1 -0
  245. package/dist/src/runtime/emit/aggregate-setup.js +99 -0
  246. package/dist/src/runtime/emit/aggregate-setup.js.map +1 -0
  247. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  248. package/dist/src/runtime/emit/aggregate.js +4 -69
  249. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  250. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  251. package/dist/src/runtime/emit/alter-table.js +354 -165
  252. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  253. package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
  254. package/dist/src/runtime/emit/asof-scan.js +11 -0
  255. package/dist/src/runtime/emit/asof-scan.js.map +1 -1
  256. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  257. package/dist/src/runtime/emit/between.js +7 -12
  258. package/dist/src/runtime/emit/between.js.map +1 -1
  259. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  260. package/dist/src/runtime/emit/binary.js +24 -25
  261. package/dist/src/runtime/emit/binary.js.map +1 -1
  262. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
  263. package/dist/src/runtime/emit/bloom-join.js +8 -16
  264. package/dist/src/runtime/emit/bloom-join.js.map +1 -1
  265. package/dist/src/runtime/emit/case.d.ts.map +1 -1
  266. package/dist/src/runtime/emit/case.js +40 -6
  267. package/dist/src/runtime/emit/case.js.map +1 -1
  268. package/dist/src/runtime/emit/cast.d.ts.map +1 -1
  269. package/dist/src/runtime/emit/cast.js +10 -23
  270. package/dist/src/runtime/emit/cast.js.map +1 -1
  271. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  272. package/dist/src/runtime/emit/constraint-check.js +72 -51
  273. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  274. package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
  275. package/dist/src/runtime/emit/create-view.js +6 -0
  276. package/dist/src/runtime/emit/create-view.js.map +1 -1
  277. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  278. package/dist/src/runtime/emit/distinct.js +6 -3
  279. package/dist/src/runtime/emit/distinct.js.map +1 -1
  280. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  281. package/dist/src/runtime/emit/dml-executor.js +188 -84
  282. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  283. package/dist/src/runtime/emit/filter.d.ts +18 -0
  284. package/dist/src/runtime/emit/filter.d.ts.map +1 -1
  285. package/dist/src/runtime/emit/filter.js +52 -10
  286. package/dist/src/runtime/emit/filter.js.map +1 -1
  287. package/dist/src/runtime/emit/hash-aggregate.d.ts.map +1 -1
  288. package/dist/src/runtime/emit/hash-aggregate.js +16 -65
  289. package/dist/src/runtime/emit/hash-aggregate.js.map +1 -1
  290. package/dist/src/runtime/emit/insert.d.ts.map +1 -1
  291. package/dist/src/runtime/emit/insert.js +18 -7
  292. package/dist/src/runtime/emit/insert.js.map +1 -1
  293. package/dist/src/runtime/emit/join-key-extractor.d.ts +46 -0
  294. package/dist/src/runtime/emit/join-key-extractor.d.ts.map +1 -0
  295. package/dist/src/runtime/emit/join-key-extractor.js +60 -0
  296. package/dist/src/runtime/emit/join-key-extractor.js.map +1 -0
  297. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  298. package/dist/src/runtime/emit/join.js +37 -11
  299. package/dist/src/runtime/emit/join.js.map +1 -1
  300. package/dist/src/runtime/emit/key-set-semi-join.d.ts +29 -0
  301. package/dist/src/runtime/emit/key-set-semi-join.d.ts.map +1 -0
  302. package/dist/src/runtime/emit/key-set-semi-join.js +143 -0
  303. package/dist/src/runtime/emit/key-set-semi-join.js.map +1 -0
  304. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +14 -1
  305. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
  306. package/dist/src/runtime/emit/materialized-view-helpers.js +33 -3
  307. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
  308. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
  309. package/dist/src/runtime/emit/materialized-view.js +47 -6
  310. package/dist/src/runtime/emit/materialized-view.js.map +1 -1
  311. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
  312. package/dist/src/runtime/emit/merge-join.js +32 -15
  313. package/dist/src/runtime/emit/merge-join.js.map +1 -1
  314. package/dist/src/runtime/emit/operand-comparator.d.ts +40 -0
  315. package/dist/src/runtime/emit/operand-comparator.d.ts.map +1 -0
  316. package/dist/src/runtime/emit/operand-comparator.js +59 -0
  317. package/dist/src/runtime/emit/operand-comparator.js.map +1 -0
  318. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  319. package/dist/src/runtime/emit/scan.js +11 -2
  320. package/dist/src/runtime/emit/scan.js.map +1 -1
  321. package/dist/src/runtime/emit/set-object-tags.d.ts +8 -0
  322. package/dist/src/runtime/emit/set-object-tags.d.ts.map +1 -1
  323. package/dist/src/runtime/emit/set-object-tags.js +8 -0
  324. package/dist/src/runtime/emit/set-object-tags.js.map +1 -1
  325. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  326. package/dist/src/runtime/emit/set-operation.js +7 -4
  327. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  328. package/dist/src/runtime/emit/sort.d.ts.map +1 -1
  329. package/dist/src/runtime/emit/sort.js +5 -2
  330. package/dist/src/runtime/emit/sort.js.map +1 -1
  331. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  332. package/dist/src/runtime/emit/subquery.js +113 -13
  333. package/dist/src/runtime/emit/subquery.js.map +1 -1
  334. package/dist/src/runtime/emit/temporal-arithmetic.d.ts +7 -0
  335. package/dist/src/runtime/emit/temporal-arithmetic.d.ts.map +1 -1
  336. package/dist/src/runtime/emit/temporal-arithmetic.js +15 -7
  337. package/dist/src/runtime/emit/temporal-arithmetic.js.map +1 -1
  338. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  339. package/dist/src/runtime/emit/update.js +44 -3
  340. package/dist/src/runtime/emit/update.js.map +1 -1
  341. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  342. package/dist/src/runtime/emit/window.js +72 -55
  343. package/dist/src/runtime/emit/window.js.map +1 -1
  344. package/dist/src/runtime/foreign-key-actions.d.ts +36 -1
  345. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  346. package/dist/src/runtime/foreign-key-actions.js +238 -116
  347. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  348. package/dist/src/runtime/parallel-driver.d.ts +10 -2
  349. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  350. package/dist/src/runtime/parallel-driver.js +12 -2
  351. package/dist/src/runtime/parallel-driver.js.map +1 -1
  352. package/dist/src/runtime/register.d.ts.map +1 -1
  353. package/dist/src/runtime/register.js +2 -0
  354. package/dist/src/runtime/register.js.map +1 -1
  355. package/dist/src/runtime/types.d.ts +25 -0
  356. package/dist/src/runtime/types.d.ts.map +1 -1
  357. package/dist/src/runtime/types.js.map +1 -1
  358. package/dist/src/schema/catalog-persistability.d.ts +58 -0
  359. package/dist/src/schema/catalog-persistability.d.ts.map +1 -0
  360. package/dist/src/schema/catalog-persistability.js +87 -0
  361. package/dist/src/schema/catalog-persistability.js.map +1 -0
  362. package/dist/src/schema/catalog.d.ts +17 -1
  363. package/dist/src/schema/catalog.d.ts.map +1 -1
  364. package/dist/src/schema/catalog.js +25 -3
  365. package/dist/src/schema/catalog.js.map +1 -1
  366. package/dist/src/schema/constraint-builder.d.ts +20 -22
  367. package/dist/src/schema/constraint-builder.d.ts.map +1 -1
  368. package/dist/src/schema/constraint-builder.js +43 -36
  369. package/dist/src/schema/constraint-builder.js.map +1 -1
  370. package/dist/src/schema/ddl-generator.d.ts +23 -0
  371. package/dist/src/schema/ddl-generator.d.ts.map +1 -1
  372. package/dist/src/schema/ddl-generator.js +27 -0
  373. package/dist/src/schema/ddl-generator.js.map +1 -1
  374. package/dist/src/schema/function.d.ts +39 -1
  375. package/dist/src/schema/function.d.ts.map +1 -1
  376. package/dist/src/schema/function.js.map +1 -1
  377. package/dist/src/schema/manager.d.ts +28 -0
  378. package/dist/src/schema/manager.d.ts.map +1 -1
  379. package/dist/src/schema/manager.js +82 -14
  380. package/dist/src/schema/manager.js.map +1 -1
  381. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  382. package/dist/src/schema/schema-differ.js +51 -12
  383. package/dist/src/schema/schema-differ.js.map +1 -1
  384. package/dist/src/schema/unique-enforcement.d.ts +31 -0
  385. package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
  386. package/dist/src/schema/unique-enforcement.js +37 -1
  387. package/dist/src/schema/unique-enforcement.js.map +1 -1
  388. package/dist/src/schema/window-function.d.ts +30 -10
  389. package/dist/src/schema/window-function.d.ts.map +1 -1
  390. package/dist/src/schema/window-function.js +20 -16
  391. package/dist/src/schema/window-function.js.map +1 -1
  392. package/dist/src/types/builtin-types.d.ts.map +1 -1
  393. package/dist/src/types/builtin-types.js +30 -4
  394. package/dist/src/types/builtin-types.js.map +1 -1
  395. package/dist/src/types/cast-semantics.d.ts +43 -0
  396. package/dist/src/types/cast-semantics.d.ts.map +1 -0
  397. package/dist/src/types/cast-semantics.js +59 -0
  398. package/dist/src/types/cast-semantics.js.map +1 -0
  399. package/dist/src/types/index.d.ts +1 -1
  400. package/dist/src/types/index.d.ts.map +1 -1
  401. package/dist/src/types/index.js +1 -1
  402. package/dist/src/types/index.js.map +1 -1
  403. package/dist/src/types/json-type.d.ts.map +1 -1
  404. package/dist/src/types/json-type.js +31 -10
  405. package/dist/src/types/json-type.js.map +1 -1
  406. package/dist/src/types/logical-type.d.ts +22 -0
  407. package/dist/src/types/logical-type.d.ts.map +1 -1
  408. package/dist/src/types/logical-type.js.map +1 -1
  409. package/dist/src/types/temporal-types.d.ts.map +1 -1
  410. package/dist/src/types/temporal-types.js +33 -11
  411. package/dist/src/types/temporal-types.js.map +1 -1
  412. package/dist/src/types/validation.d.ts +39 -1
  413. package/dist/src/types/validation.d.ts.map +1 -1
  414. package/dist/src/types/validation.js +60 -0
  415. package/dist/src/types/validation.js.map +1 -1
  416. package/dist/src/util/ast-spine-clone.d.ts +23 -0
  417. package/dist/src/util/ast-spine-clone.d.ts.map +1 -0
  418. package/dist/src/util/ast-spine-clone.js +41 -0
  419. package/dist/src/util/ast-spine-clone.js.map +1 -0
  420. package/dist/src/util/coercion.d.ts +13 -0
  421. package/dist/src/util/coercion.d.ts.map +1 -1
  422. package/dist/src/util/coercion.js +10 -1
  423. package/dist/src/util/coercion.js.map +1 -1
  424. package/dist/src/util/comparison.d.ts +114 -0
  425. package/dist/src/util/comparison.d.ts.map +1 -1
  426. package/dist/src/util/comparison.js +187 -27
  427. package/dist/src/util/comparison.js.map +1 -1
  428. package/dist/src/vtab/best-access-plan.d.ts +87 -0
  429. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  430. package/dist/src/vtab/best-access-plan.js +87 -0
  431. package/dist/src/vtab/best-access-plan.js.map +1 -1
  432. package/dist/src/vtab/manifest.d.ts +7 -0
  433. package/dist/src/vtab/manifest.d.ts.map +1 -1
  434. package/dist/src/vtab/memory/connection.d.ts +14 -1
  435. package/dist/src/vtab/memory/connection.d.ts.map +1 -1
  436. package/dist/src/vtab/memory/connection.js +20 -2
  437. package/dist/src/vtab/memory/connection.js.map +1 -1
  438. package/dist/src/vtab/memory/layer/base.d.ts +12 -5
  439. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  440. package/dist/src/vtab/memory/layer/base.js +20 -9
  441. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  442. package/dist/src/vtab/memory/layer/connection.d.ts +17 -0
  443. package/dist/src/vtab/memory/layer/connection.d.ts.map +1 -1
  444. package/dist/src/vtab/memory/layer/connection.js +26 -0
  445. package/dist/src/vtab/memory/layer/connection.js.map +1 -1
  446. package/dist/src/vtab/memory/layer/manager.d.ts +156 -31
  447. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  448. package/dist/src/vtab/memory/layer/manager.js +695 -158
  449. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  450. package/dist/src/vtab/memory/layer/plan-filter.d.ts +41 -20
  451. package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
  452. package/dist/src/vtab/memory/layer/plan-filter.js +57 -27
  453. package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
  454. package/dist/src/vtab/memory/layer/row-convert.d.ts +21 -0
  455. package/dist/src/vtab/memory/layer/row-convert.d.ts.map +1 -0
  456. package/dist/src/vtab/memory/layer/row-convert.js +30 -0
  457. package/dist/src/vtab/memory/layer/row-convert.js.map +1 -0
  458. package/dist/src/vtab/memory/layer/scan-layer.d.ts +6 -3
  459. package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
  460. package/dist/src/vtab/memory/layer/scan-layer.js +48 -34
  461. package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
  462. package/dist/src/vtab/memory/layer/transaction.d.ts +142 -19
  463. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  464. package/dist/src/vtab/memory/layer/transaction.js +237 -73
  465. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  466. package/dist/src/vtab/memory/module.d.ts +14 -2
  467. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  468. package/dist/src/vtab/memory/module.js +60 -41
  469. package/dist/src/vtab/memory/module.js.map +1 -1
  470. package/dist/src/vtab/memory/table.d.ts +1 -1
  471. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  472. package/dist/src/vtab/memory/table.js +12 -4
  473. package/dist/src/vtab/memory/table.js.map +1 -1
  474. package/dist/src/vtab/memory/types.d.ts +27 -1
  475. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  476. package/dist/src/vtab/memory/types.js +16 -1
  477. package/dist/src/vtab/memory/types.js.map +1 -1
  478. package/dist/src/vtab/memory/utils/primary-key.d.ts +9 -0
  479. package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
  480. package/dist/src/vtab/memory/utils/primary-key.js +11 -0
  481. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  482. package/dist/src/vtab/module.d.ts +63 -0
  483. package/dist/src/vtab/module.d.ts.map +1 -1
  484. package/dist/src/vtab/table.d.ts +33 -7
  485. package/dist/src/vtab/table.d.ts.map +1 -1
  486. package/dist/src/vtab/table.js.map +1 -1
  487. package/package.json +3 -3
  488. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts +0 -26
  489. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts.map +0 -1
  490. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js +0 -66
  491. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"dml-executor.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/dml-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAChF,OAAO,KAAK,EAAE,WAAW,EAA+C,MAAM,aAAa,CAAC;AAO5F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAuPzD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAQ7E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,eAAe,GAAG,WAAW,CA64BxF"}
1
+ {"version":3,"file":"dml-executor.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/dml-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAChF,OAAO,KAAK,EAAE,WAAW,EAA+C,MAAM,aAAa,CAAC;AAO5F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAoRzD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAQ7E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,eAAe,GAAG,WAAW,CAy+BxF"}
@@ -9,9 +9,11 @@ import { buildInsertStatement, buildUpdateStatement, buildDeleteStatement } from
9
9
  import { isMaintainedTable } from '../../schema/derivation.js';
10
10
  import { hasNativeEventSupport } from '../../util/event-support.js';
11
11
  import { sqlValueIdentical, compareSqlValuesFast, BINARY_COLLATION } from '../../util/comparison.js';
12
+ import { uniqueEnforcementComparators } from '../../schema/unique-enforcement.js';
12
13
  import { validateAndParse } from '../../types/validation.js';
13
14
  import { withAsyncRowContext } from '../context-helpers.js';
14
- import { executeForeignKeyActionsAndLens, assertTransitiveRestrictsForParentMutation } from '../foreign-key-actions.js';
15
+ import { executeForeignKeyActionsAndLens, assertTransitiveRestrictsForParentMutation, createParentRestrictBatch, accumulateParentRestrictKeys, flushParentRestrictBatch } from '../foreign-key-actions.js';
16
+ import { getBatchableRestrictFks } from '../../planner/building/foreign-key-builder.js';
15
17
  import { poisonResidualDeltaAccumulations } from '../../core/database-materialized-views-apply.js';
16
18
  /**
17
19
  * Module-scope counter producing unique statement-savepoint names across
@@ -22,36 +24,22 @@ import { poisonResidualDeltaAccumulations } from '../../core/database-materializ
22
24
  let stmtSavepointCounter = 0;
23
25
  /**
24
26
  * True when a proposed value equals the stored existing value at one conflict-target
25
- * column the way the targeted constraint ENFORCES: the column's affinity is applied to
26
- * the proposed value (which reaches the executor pre-affinity-coercion, while
27
- * `existing` is the already-coerced stored value), then the two are compared under the
28
- * column's precomputed enforcement collation.
27
+ * column the way the targeted constraint ENFORCES: through the column's precomputed
28
+ * comparator (declared-type `compare` for a semantic-ordering column, else the
29
+ * enforcement collation). Both sides are already in declared (stored) form
30
+ * `existing` is a stored row and the proposed row was converted by the INSERT
31
+ * emitter's static-type pass — so no per-row conversion happens here.
29
32
  *
30
- * `targetPos` indexes the clause's per-target metadata arrays (which are aligned with
31
- * `conflictTargetIndices`). When that metadata is absent — a defensively-old plan — it
32
- * degrades to BINARY with no coercion, i.e. exactly the byte-identity semantics of
33
- * `sqlValueIdentical`, preserving its numeric-storage-class tolerance via
34
- * {@link compareSqlValuesFast}. A coercion failure likewise falls back to the raw
35
- * proposed value (it then compares unequal and the caller aborts, as before).
33
+ * `targetPos` indexes the clause's per-target comparator array (aligned with
34
+ * `conflictTargetIndices`). When absent — a defensively-old plan — it degrades to
35
+ * BINARY, i.e. the byte-identity semantics of `sqlValueIdentical`, preserving its
36
+ * numeric-storage-class tolerance via {@link compareSqlValuesFast}.
36
37
  */
37
38
  function conflictTargetValuesMatch(existing, proposed, clause, targetPos) {
38
- const type = clause.conflictTargetTypes?.[targetPos];
39
- const collationFn = clause.conflictTargetCollationFns?.[targetPos] ?? BINARY_COLLATION;
40
- // NOTE: re-coerces the proposed value per conflicting row via validateAndParse; only
41
- // reached on the (cold) UNIQUE-violation-with-upsert-clause path, so it is off the
42
- // happy-path insert. If a workload ever hammers ON CONFLICT on a wide composite target,
43
- // precompute per-target coercion closures at emit instead of dispatching on type here.
44
- let coercedProposed = proposed;
45
- if (type) {
46
- try {
47
- coercedProposed = validateAndParse(proposed, type);
48
- }
49
- catch {
50
- // Coercion failed — compare the raw proposed value (aborts, as pre-fix).
51
- coercedProposed = proposed;
52
- }
53
- }
54
- return compareSqlValuesFast(existing, coercedProposed, collationFn) === 0;
39
+ const compare = clause.conflictTargetComparators?.[targetPos];
40
+ if (compare)
41
+ return compare(existing, proposed) === 0;
42
+ return compareSqlValuesFast(existing, proposed, BINARY_COLLATION) === 0;
55
43
  }
56
44
  /**
57
45
  * Returns true when the table's owning *module* natively emits data events.
@@ -120,6 +108,44 @@ async function resolveDmlSourceRows(ctx, vtab, tableSchema, rows) {
120
108
  throw e;
121
109
  }
122
110
  }
111
+ /**
112
+ * The row the substrate actually STORED for this write, which is what every
113
+ * post-write consumer must see. The executor's own writes are converted by the
114
+ * emitters up front (and passed with `preCoerced`), so for the standard
115
+ * backends `result.row` and the row we handed in now usually agree — but a
116
+ * module remains free to normalize further (or to ignore `preCoerced` and
117
+ * convert on its own), and `result.row` is its word on what landed.
118
+ *
119
+ * Falls back to the raw row when the substrate's row is the wrong width — a
120
+ * minimal test/sample module that echoes its input in a different shape. The
121
+ * absent case is only reached defensively: every caller has already
122
+ * short-circuited on a missing `result.row`, which the module contract
123
+ * reserves for "nothing was written" (see `VirtualTable.update`).
124
+ */
125
+ function storedRowOrRaw(resultRow, rawRow, columnCount) {
126
+ return resultRow && resultRow.length === columnCount ? resultRow : rawRow;
127
+ }
128
+ /**
129
+ * Rebuild the flat OLD/NEW row with its NEW section (indices n..2n-1) replaced by
130
+ * the substrate's stored row, so `RETURNING new.<col>` reports the same value and
131
+ * `typeof` as a subsequent `select`. Returns `flatRow` untouched when the stored
132
+ * row IS the raw NEW section (the fallback above), avoiding a per-row copy.
133
+ *
134
+ * NOTE: on a coercing substrate this allocates one array per written row (the
135
+ * DML executor previously yielded `flatRow` verbatim). It is one copy against a
136
+ * per-row `vtab.update()` await, so it does not register today; if bulk-INSERT
137
+ * throughput ever shows this as hot, have the substrates report which columns
138
+ * coercion actually changed and patch only those in place.
139
+ */
140
+ function withStoredNewSection(flatRow, storedRow, rawNewRow, columnCount) {
141
+ if (storedRow === rawNewRow)
142
+ return flatRow;
143
+ const out = flatRow.slice();
144
+ for (let i = 0; i < columnCount; i++) {
145
+ out[columnCount + i] = storedRow[i];
146
+ }
147
+ return out;
148
+ }
123
149
  /**
124
150
  * Emit an automatic data change event for modules without native event support.
125
151
  */
@@ -247,20 +273,29 @@ export function emitDmlExecutor(plan, ctx) {
247
273
  };
248
274
  // Resolve the per-target-column enforcement collation NAMES to functions once
249
275
  // here (recording the collation dependency so a redefined collation re-emits),
250
- // and carry the per-column logical types for affinity coercion. Consumed by
251
- // matchUpsertClause so a collation-equal / affinity-coerced conflict on the
252
- // targeted constraint routes to DO UPDATE / DO NOTHING instead of aborting.
276
+ // then build the per-column comparators through the shared UNIQUE-enforcement
277
+ // rule. Consumed by matchUpsertClause so a conflict the targeted constraint
278
+ // considers a duplicate collation-equal, or semantically equal under a
279
+ // semantic-ordering declared type — routes to DO UPDATE / DO NOTHING instead
280
+ // of aborting.
253
281
  if (clause.conflictTargetIndices && clause.conflictTargetCollations) {
254
- runtime.conflictTargetCollationFns = clause.conflictTargetCollations.map(name => ctx.resolveCollation(name ?? 'BINARY'));
255
- runtime.conflictTargetTypes = clause.conflictTargetTypes;
282
+ const collationFns = clause.conflictTargetCollations.map(name => ctx.resolveCollation(name ?? 'BINARY'));
283
+ runtime.conflictTargetComparators = uniqueEnforcementComparators(tableSchema.columns, clause.conflictTargetIndices, collationFns);
256
284
  }
257
285
  if (clause.action === 'update' && clause.assignments) {
258
286
  runtime.assignmentIndices = new Map();
287
+ runtime.assignmentCoercions = new Map();
259
288
  for (const [colIndex, valueNode] of clause.assignments) {
260
289
  const evaluatorIndex = upsertEvaluatorInstructions.length;
261
290
  const instruction = emitCallFromPlan(valueNode, ctx);
262
291
  upsertEvaluatorInstructions.push(instruction);
263
292
  runtime.assignmentIndices.set(colIndex, evaluatorIndex);
293
+ // Same static-type rule as emitUpdate: convert only when the
294
+ // assignment expression's type is not the column's declared type.
295
+ const column = tableSchema.columns[colIndex];
296
+ if (valueNode.getType().logicalType !== column.logicalType) {
297
+ runtime.assignmentCoercions.set(colIndex, column);
298
+ }
264
299
  }
265
300
  }
266
301
  if (clause.whereCondition) {
@@ -293,17 +328,13 @@ export function emitDmlExecutor(plan, ctx) {
293
328
  // No conflict target specified - matches any unique constraint
294
329
  return clause;
295
330
  }
296
- // Match when the proposed values equal the existing row at the clause's
297
- // conflict-target columns i.e. the conflict is on those columns
298
- // compared the way the constraint ENFORCES: the column's affinity is
299
- // applied to the (pre-affinity-coercion) proposed value, then it is compared
300
- // under the constraint's enforcement collation. This routes a collation-equal
301
- // (NOCASE case-variant, RTRIM trailing-space) or affinity-coerced (`'1'` vs a
302
- // stored INTEGER `1`) conflict on the targeted constraint to the DO UPDATE /
303
- // DO NOTHING arm rather than aborting with a UNIQUE error. The per-column
304
- // collation functions + logical types are precomputed at emit; a BINARY,
305
- // byte-identical key still compares 0 (well-formed seeds re-present
306
- // byte-identical literals, so seed idempotency is unaffected).
331
+ // The conflict is on this clause's target columns when the proposed row
332
+ // equals the existing one there, compared the way the constraint ENFORCES
333
+ // (see {@link conflictTargetValuesMatch}): an affinity-coerced, a
334
+ // collation-equal or a semantically-equal conflict all route to the DO
335
+ // UPDATE / DO NOTHING arm rather than aborting with a UNIQUE error, while
336
+ // a BINARY byte-identical key still compares 0 (so seed idempotency, which
337
+ // re-presents identical literals, is unaffected).
307
338
  //
308
339
  // NOTE: one residual corner remains out of scope — multi-constraint
309
340
  // coincidence. If an insert violates the targeted constraint AND another
@@ -344,22 +375,31 @@ export function emitDmlExecutor(plan, ctx) {
344
375
  // Evaluate assignment expressions with proper contexts
345
376
  for (const [colIndex, evaluatorIndex] of clause.assignmentIndices) {
346
377
  const evaluator = upsertEvaluators[evaluatorIndex];
347
- const value = await withAsyncRowContext(rctx, clause.existingRowDescriptor, () => existingRow, async () => {
378
+ let value = await withAsyncRowContext(rctx, clause.existingRowDescriptor, () => existingRow, async () => {
348
379
  return await withAsyncRowContext(rctx, clause.newRowDescriptor, () => proposedRow, async () => {
349
380
  return await evaluator(rctx);
350
381
  });
351
382
  });
383
+ // Convert to the declared column type when the assignment's static
384
+ // type requires it (see assignmentCoercions) — `existingRow` is a
385
+ // stored row, so the composed updatedRow is then fully declared-form.
386
+ const coerceColumn = clause.assignmentCoercions?.get(colIndex);
387
+ if (coerceColumn) {
388
+ value = validateAndParse(value, coerceColumn.logicalType, coerceColumn.name);
389
+ }
352
390
  updatedRow[colIndex] = value;
353
391
  }
354
392
  }
355
393
  // Extract the primary key from existing row
356
394
  const keyValues = pkColumnIndicesInSchema.map(idx => existingRow[idx]);
357
- // Perform the UPDATE operation
395
+ // Perform the UPDATE operation. `preCoerced`: the row is composed of
396
+ // stored cells plus assignments already converted above.
358
397
  const updateArgs = {
359
398
  operation: 'update',
360
399
  values: updatedRow,
361
400
  oldKeyValues: keyValues,
362
401
  onConflict: ConflictResolution.ABORT,
402
+ preCoerced: true,
363
403
  mutationStatement: vtab.wantStatements ?
364
404
  buildUpdateStatement(tableSchema, updatedRow, keyValues, contextRow) : undefined
365
405
  };
@@ -370,9 +410,12 @@ export function emitDmlExecutor(plan, ctx) {
370
410
  if (!updateResult.row) {
371
411
  return undefined;
372
412
  }
373
- // Build a flat row for RETURNING (OLD = existing, NEW = updated)
374
- const flatRow = [...existingRow, ...updatedRow];
375
- return { updatedRow, flatRow };
413
+ // Report the row the substrate STORED, not the one we composed — see
414
+ // storedRowOrRaw. `existingRow` is already a stored (coerced) row.
415
+ const storedRow = storedRowOrRaw(updateResult.row, updatedRow, tableSchema.columns.length);
416
+ // Build a flat row for RETURNING (OLD = existing, NEW = stored)
417
+ const flatRow = [...existingRow, ...storedRow];
418
+ return { updatedRow: storedRow, flatRow };
376
419
  }
377
420
  /**
378
421
  * Translate a generic ConstraintError into the right OR-clause subclass
@@ -427,7 +470,12 @@ export function emitDmlExecutor(plan, ctx) {
427
470
  // non-snapshot-isolated UPDATE/DELETE has drained its source up front to
428
471
  // separate the read phase from the write phase. `for await ... of`
429
472
  // consumes either — the savepoint/FAIL-mode logic below is unchanged.
430
- rows, isFailMode, processRow, deferredRebuilds, residualBatch, backingConnCache) {
473
+ rows, isFailMode, processRow, deferredRebuilds, residualBatch, backingConnCache,
474
+ // Set only when the statement uses batched parent-side RESTRICT
475
+ // enforcement (see getBatchableRestrictFks): flushes the accumulated
476
+ // key batch at the end-of-statement boundary. The gate excludes FAIL,
477
+ // so a non-null flush always runs under the statement savepoint.
478
+ flushFkBatch) {
431
479
  let failSavepointCounter = 0;
432
480
  // For non-FAIL modes wrap the whole statement so a mid-statement failure
433
481
  // unwinds partial writes from earlier rows. FAIL keeps prior rows, so it
@@ -493,7 +541,15 @@ export function emitDmlExecutor(plan, ctx) {
493
541
  yield rowToYield;
494
542
  }
495
543
  }
496
- // End-of-statement boundary: drain the deferred maintenance (residual key
544
+ // End-of-statement boundary. First the batched parent-side RESTRICT
545
+ // probe (fail fast — skip wasted MV work on a violation), then the
546
+ // deferred maintenance; both BEFORE the statement savepoint releases
547
+ // so a failure rolls the whole statement back. Inside the try, so an
548
+ // error routes to the rollback branch below.
549
+ if (flushFkBatch) {
550
+ await flushFkBatch();
551
+ }
552
+ // Drain the deferred maintenance (residual key
497
553
  // batch + full-rebuild set) NOW — after every source row has been applied
498
554
  // (so each recompute/rebuild reads all this statement's writes) and BEFORE
499
555
  // the statement savepoint releases (so a failed flush rolls the whole
@@ -612,6 +668,10 @@ export function emitDmlExecutor(plan, ctx) {
612
668
  // can fall back to per-constraint defaultConflict directives. The memory
613
669
  // module treats undefined as ABORT when no constraint default is set.
614
670
  onConflict: plan.onConflict,
671
+ // The emitters converted the NEW section to declared types up front
672
+ // (emitInsert / constraint-check DEFAULT substitution), so the storage
673
+ // layer must not convert again — JSON conversion is not repeatable.
674
+ preCoerced: true,
615
675
  mutationStatement
616
676
  };
617
677
  const result = await vtab.update(args);
@@ -648,35 +708,41 @@ export function emitDmlExecutor(plan, ctx) {
648
708
  if (!result.row) {
649
709
  return undefined;
650
710
  }
711
+ // Everything downstream of the write — change tracking, row-time MV
712
+ // maintenance, auto-events, and the row RETURNING projects — must see the
713
+ // row the substrate STORED, not the raw input we handed it. See
714
+ // storedRowOrRaw.
715
+ const numCols = tableSchema.columns.length;
716
+ const storedRow = storedRowOrRaw(result.row, newRow, numCols);
651
717
  // Internal REPLACE evictions (rows at OTHER PKs removed to resolve a non-PK
652
718
  // UNIQUE conflict) run the full delete pipeline here, before the new row's
653
719
  // own bookkeeping — evict-then-write, matching the substrate journal order.
654
720
  await processEvictions(ctx, needsAutoEvents, tableKey, result.evictedRows, backingConnCache, deferredRebuilds, residualBatch);
655
721
  const replacedRow = result.replacedRow;
656
722
  if (replacedRow) {
657
- const newKeyValues = pkColumnIndicesInSchema.map(idx => newRow[idx]);
658
- ctx.db._recordUpdate(tableKey, replacedRow, newRow, pkColumnIndicesInSchema);
659
- await maintainRowTimeStructures(ctx, tableKey, { op: 'update', oldRow: replacedRow, newRow }, backingConnCache, deferredRebuilds, residualBatch);
723
+ const newKeyValues = pkColumnIndicesInSchema.map(idx => storedRow[idx]);
724
+ ctx.db._recordUpdate(tableKey, replacedRow, storedRow, pkColumnIndicesInSchema);
725
+ await maintainRowTimeStructures(ctx, tableKey, { op: 'update', oldRow: replacedRow, newRow: storedRow }, backingConnCache, deferredRebuilds, residualBatch);
660
726
  await executeForeignKeyActionsAndLens(ctx.db, tableSchema, 'delete', replacedRow, undefined, plan.lensRouted);
661
727
  if (needsAutoEvents) {
662
728
  const changedColumns = [];
663
- for (let i = 0; i < tableSchema.columns.length; i++) {
664
- if (!sqlValueIdentical(replacedRow[i], newRow[i])) {
729
+ for (let i = 0; i < numCols; i++) {
730
+ if (!sqlValueIdentical(replacedRow[i], storedRow[i])) {
665
731
  changedColumns.push(tableSchema.columns[i].name);
666
732
  }
667
733
  }
668
- emitAutoDataEvent(ctx, tableSchema, 'update', newKeyValues, [...replacedRow], [...newRow], changedColumns);
734
+ emitAutoDataEvent(ctx, tableSchema, 'update', newKeyValues, [...replacedRow], [...storedRow], changedColumns);
669
735
  }
670
736
  }
671
737
  else {
672
- const pkValues = pkColumnIndicesInSchema.map(idx => newRow[idx]);
673
- ctx.db._recordInsert(tableKey, newRow, pkColumnIndicesInSchema);
674
- await maintainRowTimeStructures(ctx, tableKey, { op: 'insert', newRow }, backingConnCache, deferredRebuilds, residualBatch);
738
+ const pkValues = pkColumnIndicesInSchema.map(idx => storedRow[idx]);
739
+ ctx.db._recordInsert(tableKey, storedRow, pkColumnIndicesInSchema);
740
+ await maintainRowTimeStructures(ctx, tableKey, { op: 'insert', newRow: storedRow }, backingConnCache, deferredRebuilds, residualBatch);
675
741
  if (needsAutoEvents) {
676
- emitAutoDataEvent(ctx, tableSchema, 'insert', pkValues, undefined, [...newRow]);
742
+ emitAutoDataEvent(ctx, tableSchema, 'insert', pkValues, undefined, [...storedRow]);
677
743
  }
678
744
  }
679
- return flatRow;
745
+ return withStoredNewSection(flatRow, storedRow, newRow, numCols);
680
746
  }
681
747
  /**
682
748
  * Drive the full delete pipeline for every internal REPLACE eviction reported
@@ -731,6 +797,14 @@ export function emitDmlExecutor(plan, ctx) {
731
797
  const deferredRebuilds = new Set();
732
798
  const residualBatch = new Map();
733
799
  const isFailMode = plan.onConflict === ConflictResolution.FAIL;
800
+ // Batched parent-side RESTRICT enforcement (per-execution state, never on
801
+ // the emit closure — a re-run prepared statement must start empty). When
802
+ // the gate admits the statement, the per-row transitive pre-walk is
803
+ // replaced by key accumulation + one chunked probe per FK at the
804
+ // end-of-statement boundary. The plan side made the same gate decision
805
+ // and skipped the per-row NOT EXISTS checks.
806
+ const batchableFks = getBatchableRestrictFks(ctx.db.schemaManager, tableSchema, 'update', plan.onConflict, plan.lensRouted);
807
+ const fkRestrictBatch = batchableFks ? createParentRestrictBatch(batchableFks) : undefined;
734
808
  // Physical Halloween avoidance: unless the target module guarantees per-scan
735
809
  // snapshot isolation, fully drain the source match set (closing the scan
736
810
  // cursor) BEFORE applying any write — otherwise the first UPDATE invalidates
@@ -740,7 +814,7 @@ export function emitDmlExecutor(plan, ctx) {
740
814
  // the accepted cost of correctness (such a module cannot safely stream-update
741
815
  // anyway); memory tables set scanSnapshotIsolation and keep streaming.
742
816
  const sourceRows = await resolveDmlSourceRows(ctx, vtab, tableSchema, rows);
743
- yield* runWithStatementSavepoints(ctx, vtab, sourceRows, isFailMode, (flatRow) => processUpdateRow(ctx, vtab, needsAutoEvents, flatRow, contextRow, backingConnCache, deferredRebuilds, residualBatch), deferredRebuilds, residualBatch, backingConnCache);
817
+ yield* runWithStatementSavepoints(ctx, vtab, sourceRows, isFailMode, (flatRow) => processUpdateRow(ctx, vtab, needsAutoEvents, flatRow, contextRow, backingConnCache, deferredRebuilds, residualBatch, fkRestrictBatch), deferredRebuilds, residualBatch, backingConnCache, fkRestrictBatch ? () => flushParentRestrictBatch(ctx.db, tableSchema, 'update', fkRestrictBatch) : undefined);
744
818
  }
745
819
  /**
746
820
  * Performs a single row's UPDATE side-effects (RESTRICT pre-check +
@@ -750,7 +824,7 @@ export function emitDmlExecutor(plan, ctx) {
750
824
  * cannot recover from; the caller (runWithStatementSavepoints) translates it
751
825
  * for FAIL/ROLLBACK modes.
752
826
  */
753
- async function processUpdateRow(ctx, vtab, needsAutoEvents, flatRow, contextRow, backingConnCache, deferredRebuilds, residualBatch) {
827
+ async function processUpdateRow(ctx, vtab, needsAutoEvents, flatRow, contextRow, backingConnCache, deferredRebuilds, residualBatch, fkRestrictBatch) {
754
828
  const oldRow = extractOldRowFromFlat(flatRow, tableSchema.columns.length);
755
829
  const newRow = extractNewRowFromFlat(flatRow, tableSchema.columns.length);
756
830
  const tableKey = `${tableSchema.schemaName}.${tableSchema.name}`;
@@ -766,14 +840,23 @@ export function emitDmlExecutor(plan, ctx) {
766
840
  if (vtab.wantStatements) {
767
841
  mutationStatement = buildUpdateStatement(tableSchema, newRow, keyValues, contextRow);
768
842
  }
769
- // Defense-in-depth RESTRICT enforcement: the plan-time `NOT EXISTS`
770
- // check is the primary path, but some vtab modules evaluate the
771
- // embedded subquery differently from a plain row scan. Pre-walk
772
- // the transitive cascade closure so RESTRICTs at any depth fire
773
- // BEFORE vtab.updateneeded for rowid-mode backends (lamina)
774
- // where post-mutation OLD-value scans dereference through the
775
- // just-mutated parent and find zero rows.
776
- await assertTransitiveRestrictsForParentMutation(ctx.db, tableSchema, 'update', oldRow, newRow, plan.lensRouted);
843
+ // Parent-side RESTRICT enforcement. Batched statements accumulate the
844
+ // OLD referenced keys (probed once per FK at the end-of-statement
845
+ // boundary same pre-vtab observation point per row, so a row the vtab
846
+ // later reports not-found contributes identically to the per-row path).
847
+ // Otherwise: defense-in-depth per-row pre-walk the plan-time
848
+ // `NOT EXISTS` check is the primary path, but some vtab modules evaluate
849
+ // the embedded subquery differently from a plain row scan. Pre-walk the
850
+ // transitive cascade closure so RESTRICTs at any depth fire BEFORE
851
+ // vtab.update — needed for rowid-mode backends (lamina) where
852
+ // post-mutation OLD-value scans dereference through the just-mutated
853
+ // parent and find zero rows.
854
+ if (fkRestrictBatch) {
855
+ accumulateParentRestrictKeys(fkRestrictBatch, 'update', oldRow, newRow);
856
+ }
857
+ else {
858
+ await assertTransitiveRestrictsForParentMutation(ctx.db, tableSchema, 'update', oldRow, newRow, plan.lensRouted);
859
+ }
777
860
  const args = {
778
861
  operation: 'update',
779
862
  values: newRow,
@@ -782,6 +865,10 @@ export function emitDmlExecutor(plan, ctx) {
782
865
  // can fall back to per-constraint defaultConflict directives. The memory
783
866
  // module treats undefined as ABORT when no constraint default is set.
784
867
  onConflict: plan.onConflict,
868
+ // emitUpdate converted the NEW section to declared types (assigned
869
+ // columns by static type, unassigned columns are stored values) — the
870
+ // storage layer must not convert again.
871
+ preCoerced: true,
785
872
  mutationStatement
786
873
  };
787
874
  const result = await vtab.update(args);
@@ -793,6 +880,11 @@ export function emitDmlExecutor(plan, ctx) {
793
880
  if (!result.row) {
794
881
  return undefined;
795
882
  }
883
+ // Post-write bookkeeping and the RETURNING row must see the row the
884
+ // substrate STORED, not the raw input — see storedRowOrRaw. `oldRow` came
885
+ // from the source scan, so it is already a stored (coerced) row.
886
+ const numCols = tableSchema.columns.length;
887
+ const storedRow = storedRowOrRaw(result.row, newRow, numCols);
796
888
  // If the UPDATE moved this row onto an occupied PK under REPLACE,
797
889
  // the vtab returns the displaced row. Surface its deletion BEFORE
798
890
  // the move bookkeeping so change tracking, FK cascade, and auto-events
@@ -817,24 +909,24 @@ export function emitDmlExecutor(plan, ctx) {
817
909
  await processEvictions(ctx, needsAutoEvents, tableKey, result.evictedRows, backingConnCache, deferredRebuilds, residualBatch);
818
910
  // Track change (UPDATE): pass full rows so the change capture can
819
911
  // project the columns any active subscription cares about.
820
- ctx.db._recordUpdate(tableKey, oldRow, newRow, pkColumnIndicesInSchema);
821
- await maintainRowTimeStructures(ctx, tableKey, { op: 'update', oldRow, newRow }, backingConnCache, deferredRebuilds, residualBatch);
912
+ ctx.db._recordUpdate(tableKey, oldRow, storedRow, pkColumnIndicesInSchema);
913
+ await maintainRowTimeStructures(ctx, tableKey, { op: 'update', oldRow, newRow: storedRow }, backingConnCache, deferredRebuilds, residualBatch);
822
914
  // Execute FK cascading actions (CASCADE, SET NULL, SET DEFAULT)
823
- await executeForeignKeyActionsAndLens(ctx.db, tableSchema, 'update', oldRow, newRow, plan.lensRouted);
915
+ await executeForeignKeyActionsAndLens(ctx.db, tableSchema, 'update', oldRow, storedRow, plan.lensRouted);
824
916
  // Emit auto event for modules without native event support
825
917
  if (needsAutoEvents) {
826
918
  // Compute changed columns
827
919
  const changedColumns = [];
828
- for (let i = 0; i < tableSchema.columns.length; i++) {
920
+ for (let i = 0; i < numCols; i++) {
829
921
  const oldVal = oldRow[i];
830
- const newVal = newRow[i];
922
+ const newVal = storedRow[i];
831
923
  if (!sqlValueIdentical(oldVal, newVal)) {
832
924
  changedColumns.push(tableSchema.columns[i].name);
833
925
  }
834
926
  }
835
- emitAutoDataEvent(ctx, tableSchema, 'update', keyValues, [...oldRow], [...newRow], changedColumns);
927
+ emitAutoDataEvent(ctx, tableSchema, 'update', keyValues, [...oldRow], [...storedRow], changedColumns);
836
928
  }
837
- return flatRow;
929
+ return withStoredNewSection(flatRow, storedRow, newRow, numCols);
838
930
  }
839
931
  // DELETE ----------------------------------------------------
840
932
  async function* runDelete(ctx, rows, ...contextEvaluators) {
@@ -849,12 +941,17 @@ export function emitDmlExecutor(plan, ctx) {
849
941
  const deferredRebuilds = new Set();
850
942
  const residualBatch = new Map();
851
943
  const isFailMode = plan.onConflict === ConflictResolution.FAIL;
944
+ // Batched parent-side RESTRICT enforcement — see the matching note in
945
+ // runUpdate (per-execution state; one chunked probe per FK at the
946
+ // end-of-statement boundary when the gate admits the statement).
947
+ const batchableFks = getBatchableRestrictFks(ctx.db.schemaManager, tableSchema, 'delete', plan.onConflict, plan.lensRouted);
948
+ const fkRestrictBatch = batchableFks ? createParentRestrictBatch(batchableFks) : undefined;
852
949
  // Physical Halloween avoidance — see the matching note in runUpdate. Unless
853
950
  // the target module guarantees per-scan snapshot isolation, drain the source
854
951
  // match set (closing the scan cursor) before applying any DELETE, so the
855
952
  // first delete cannot invalidate the cursor path the scan is still walking.
856
953
  const sourceRows = await resolveDmlSourceRows(ctx, vtab, tableSchema, rows);
857
- yield* runWithStatementSavepoints(ctx, vtab, sourceRows, isFailMode, (flatRow) => processDeleteRow(ctx, vtab, needsAutoEvents, flatRow, contextRow, backingConnCache, deferredRebuilds, residualBatch), deferredRebuilds, residualBatch, backingConnCache);
954
+ yield* runWithStatementSavepoints(ctx, vtab, sourceRows, isFailMode, (flatRow) => processDeleteRow(ctx, vtab, needsAutoEvents, flatRow, contextRow, backingConnCache, deferredRebuilds, residualBatch, fkRestrictBatch), deferredRebuilds, residualBatch, backingConnCache, fkRestrictBatch ? () => flushParentRestrictBatch(ctx.db, tableSchema, 'delete', fkRestrictBatch) : undefined);
858
955
  }
859
956
  /**
860
957
  * Performs a single row's DELETE side-effects (RESTRICT pre-check +
@@ -864,7 +961,7 @@ export function emitDmlExecutor(plan, ctx) {
864
961
  * (runWithStatementSavepoints) translates constraint violations for
865
962
  * FAIL/ROLLBACK modes.
866
963
  */
867
- async function processDeleteRow(ctx, vtab, needsAutoEvents, flatRow, contextRow, backingConnCache, deferredRebuilds, residualBatch) {
964
+ async function processDeleteRow(ctx, vtab, needsAutoEvents, flatRow, contextRow, backingConnCache, deferredRebuilds, residualBatch, fkRestrictBatch) {
868
965
  const oldRow = extractOldRowFromFlat(flatRow, tableSchema.columns.length);
869
966
  const tableKey = `${tableSchema.schemaName}.${tableSchema.name}`;
870
967
  const keyValues = pkColumnIndicesInSchema.map(pkColIdx => {
@@ -878,14 +975,21 @@ export function emitDmlExecutor(plan, ctx) {
878
975
  if (vtab.wantStatements) {
879
976
  mutationStatement = buildDeleteStatement(tableSchema, keyValues, contextRow);
880
977
  }
881
- // Defense-in-depth RESTRICT enforcement see comment on the UPDATE
882
- // path above.
883
- await assertTransitiveRestrictsForParentMutation(ctx.db, tableSchema, 'delete', oldRow, undefined, plan.lensRouted);
978
+ // Parent-side RESTRICT enforcement: batched key accumulation, or the
979
+ // per-row defense-in-depth pre-walk — see comment on the UPDATE path above.
980
+ if (fkRestrictBatch) {
981
+ accumulateParentRestrictKeys(fkRestrictBatch, 'delete', oldRow);
982
+ }
983
+ else {
984
+ await assertTransitiveRestrictsForParentMutation(ctx.db, tableSchema, 'delete', oldRow, undefined, plan.lensRouted);
985
+ }
884
986
  const args = {
885
987
  operation: 'delete',
886
988
  values: undefined,
887
989
  oldKeyValues: keyValues,
888
990
  onConflict: plan.onConflict ?? ConflictResolution.ABORT,
991
+ // The key cells come from the scanned OLD row — already stored form.
992
+ preCoerced: true,
889
993
  mutationStatement
890
994
  };
891
995
  const result = await vtab.update(args);