@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.
- package/README.md +6 -1
- package/dist/src/common/types.d.ts +9 -0
- package/dist/src/common/types.d.ts.map +1 -1
- package/dist/src/common/types.js.map +1 -1
- package/dist/src/core/database-events.d.ts +49 -0
- package/dist/src/core/database-events.d.ts.map +1 -1
- package/dist/src/core/database-events.js +148 -0
- package/dist/src/core/database-events.js.map +1 -1
- package/dist/src/core/database-materialized-views-analysis.d.ts.map +1 -1
- package/dist/src/core/database-materialized-views-analysis.js +1 -0
- package/dist/src/core/database-materialized-views-analysis.js.map +1 -1
- package/dist/src/core/database-materialized-views-plan-builders.d.ts +2 -1
- package/dist/src/core/database-materialized-views-plan-builders.d.ts.map +1 -1
- package/dist/src/core/database-materialized-views-plan-builders.js +26 -5
- package/dist/src/core/database-materialized-views-plan-builders.js.map +1 -1
- package/dist/src/core/database-materialized-views-plans.d.ts +6 -3
- package/dist/src/core/database-materialized-views-plans.d.ts.map +1 -1
- package/dist/src/core/database-materialized-views.d.ts +3 -2
- package/dist/src/core/database-materialized-views.d.ts.map +1 -1
- package/dist/src/core/database-materialized-views.js +26 -5
- package/dist/src/core/database-materialized-views.js.map +1 -1
- package/dist/src/core/database.d.ts +5 -0
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +21 -1
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/internal-statement-cache.d.ts +18 -0
- package/dist/src/core/internal-statement-cache.d.ts.map +1 -0
- package/dist/src/core/internal-statement-cache.js +211 -0
- package/dist/src/core/internal-statement-cache.js.map +1 -0
- package/dist/src/func/builtins/aggregate.d.ts +13 -12
- package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
- package/dist/src/func/builtins/aggregate.js +45 -67
- package/dist/src/func/builtins/aggregate.js.map +1 -1
- package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
- package/dist/src/func/builtins/builtin-window-functions.js +63 -48
- package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
- package/dist/src/func/builtins/scalar.d.ts.map +1 -1
- package/dist/src/func/builtins/scalar.js +92 -3
- package/dist/src/func/builtins/scalar.js.map +1 -1
- package/dist/src/func/registration.d.ts +18 -1
- package/dist/src/func/registration.d.ts.map +1 -1
- package/dist/src/func/registration.js +26 -0
- package/dist/src/func/registration.js.map +1 -1
- package/dist/src/index.d.ts +10 -10
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +13 -12
- package/dist/src/index.js.map +1 -1
- package/dist/src/parser/parser.d.ts +6 -0
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +45 -34
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/planner/analysis/coarsened-key.d.ts +4 -3
- package/dist/src/planner/analysis/coarsened-key.d.ts.map +1 -1
- package/dist/src/planner/analysis/coarsened-key.js +37 -3
- package/dist/src/planner/analysis/coarsened-key.js.map +1 -1
- package/dist/src/planner/analysis/comparison-collation.d.ts +35 -3
- package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -1
- package/dist/src/planner/analysis/comparison-collation.js +37 -3
- package/dist/src/planner/analysis/comparison-collation.js.map +1 -1
- package/dist/src/planner/analysis/coverage-prover.d.ts +13 -2
- package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -1
- package/dist/src/planner/analysis/coverage-prover.js +10 -14
- package/dist/src/planner/analysis/coverage-prover.js.map +1 -1
- package/dist/src/planner/analysis/expression-fingerprint.d.ts.map +1 -1
- package/dist/src/planner/analysis/expression-fingerprint.js +29 -0
- package/dist/src/planner/analysis/expression-fingerprint.js.map +1 -1
- package/dist/src/planner/analysis/predicate-conjuncts.d.ts +10 -4
- package/dist/src/planner/analysis/predicate-conjuncts.d.ts.map +1 -1
- package/dist/src/planner/analysis/predicate-conjuncts.js +28 -7
- package/dist/src/planner/analysis/predicate-conjuncts.js.map +1 -1
- package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +6 -0
- package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -1
- package/dist/src/planner/analysis/query-rewrite-matcher.js +19 -29
- package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -1
- package/dist/src/planner/analysis/sat-checker.d.ts.map +1 -1
- package/dist/src/planner/analysis/sat-checker.js +43 -4
- package/dist/src/planner/analysis/sat-checker.js.map +1 -1
- package/dist/src/planner/analysis/scalar-subqueries.d.ts +22 -3
- package/dist/src/planner/analysis/scalar-subqueries.d.ts.map +1 -1
- package/dist/src/planner/analysis/scalar-subqueries.js +32 -3
- package/dist/src/planner/analysis/scalar-subqueries.js.map +1 -1
- package/dist/src/planner/analysis/set-op-type-merge.d.ts +64 -0
- package/dist/src/planner/analysis/set-op-type-merge.d.ts.map +1 -0
- package/dist/src/planner/analysis/set-op-type-merge.js +97 -0
- package/dist/src/planner/analysis/set-op-type-merge.js.map +1 -0
- package/dist/src/planner/building/coercion.d.ts +78 -0
- package/dist/src/planner/building/coercion.d.ts.map +1 -0
- package/dist/src/planner/building/coercion.js +137 -0
- package/dist/src/planner/building/coercion.js.map +1 -0
- package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
- package/dist/src/planner/building/constraint-builder.js +5 -18
- package/dist/src/planner/building/constraint-builder.js.map +1 -1
- package/dist/src/planner/building/delete.d.ts.map +1 -1
- package/dist/src/planner/building/delete.js +10 -3
- package/dist/src/planner/building/delete.js.map +1 -1
- package/dist/src/planner/building/expression.d.ts.map +1 -1
- package/dist/src/planner/building/expression.js +13 -35
- package/dist/src/planner/building/expression.js.map +1 -1
- package/dist/src/planner/building/foreign-key-builder.d.ts +44 -1
- package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
- package/dist/src/planner/building/foreign-key-builder.js +54 -0
- package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
- package/dist/src/planner/building/function-call.d.ts.map +1 -1
- package/dist/src/planner/building/function-call.js +8 -0
- package/dist/src/planner/building/function-call.js.map +1 -1
- package/dist/src/planner/building/insert.d.ts.map +1 -1
- package/dist/src/planner/building/insert.js +9 -12
- package/dist/src/planner/building/insert.js.map +1 -1
- package/dist/src/planner/building/select-compound.d.ts.map +1 -1
- package/dist/src/planner/building/select-compound.js +10 -6
- package/dist/src/planner/building/select-compound.js.map +1 -1
- package/dist/src/planner/building/update.d.ts.map +1 -1
- package/dist/src/planner/building/update.js +13 -4
- package/dist/src/planner/building/update.js.map +1 -1
- package/dist/src/planner/cost/conjunct-cost.d.ts +42 -0
- package/dist/src/planner/cost/conjunct-cost.d.ts.map +1 -0
- package/dist/src/planner/cost/conjunct-cost.js +62 -0
- package/dist/src/planner/cost/conjunct-cost.js.map +1 -0
- package/dist/src/planner/framework/pass.js +3 -3
- package/dist/src/planner/mutation/propagate.d.ts.map +1 -1
- package/dist/src/planner/mutation/propagate.js +1 -0
- package/dist/src/planner/mutation/propagate.js.map +1 -1
- package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/async-gather-node.js +19 -8
- package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
- package/dist/src/planner/nodes/bloom-join-node.d.ts +2 -0
- package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/bloom-join-node.js +10 -5
- package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
- package/dist/src/planner/nodes/dml-executor-node.d.ts +0 -9
- package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
- package/dist/src/planner/nodes/join-node.d.ts +5 -0
- package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-node.js +8 -1
- package/dist/src/planner/nodes/join-node.js.map +1 -1
- package/dist/src/planner/nodes/join-utils.d.ts +57 -0
- package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-utils.js +47 -0
- package/dist/src/planner/nodes/join-utils.js.map +1 -1
- package/dist/src/planner/nodes/key-set-semi-join-node.d.ts +87 -0
- package/dist/src/planner/nodes/key-set-semi-join-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/key-set-semi-join-node.js +137 -0
- package/dist/src/planner/nodes/key-set-semi-join-node.js.map +1 -0
- package/dist/src/planner/nodes/merge-join-node.d.ts +2 -0
- package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/merge-join-node.js +14 -6
- package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
- package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.js +1 -0
- package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
- package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
- package/dist/src/planner/nodes/scalar.js +26 -3
- package/dist/src/planner/nodes/scalar.js.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.d.ts +68 -16
- package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.js +147 -26
- package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts +19 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.js +13 -2
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
- package/dist/src/planner/optimizer.d.ts.map +1 -1
- package/dist/src/planner/optimizer.js +54 -12
- package/dist/src/planner/optimizer.js.map +1 -1
- package/dist/src/planner/rules/access/rule-key-set-seek.d.ts +68 -0
- package/dist/src/planner/rules/access/rule-key-set-seek.d.ts.map +1 -0
- package/dist/src/planner/rules/access/rule-key-set-seek.js +408 -0
- package/dist/src/planner/rules/access/rule-key-set-seek.js.map +1 -0
- package/dist/src/planner/rules/access/rule-monotonic-range-access.d.ts.map +1 -1
- package/dist/src/planner/rules/access/rule-monotonic-range-access.js +2 -2
- package/dist/src/planner/rules/access/rule-monotonic-range-access.js.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.d.ts +27 -0
- package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.js +74 -29
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +23 -4
- package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.d.ts +10 -8
- package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.js +10 -8
- package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.js.map +1 -1
- package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +67 -41
- package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
- package/dist/src/planner/rules/join/equi-pair-extractor.js +72 -36
- package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
- package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-join-physical-selection.js +14 -2
- package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +11 -1
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts +1 -1
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts +30 -0
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js +63 -0
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts +17 -1
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.js +206 -12
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +8 -1
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts +3 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +13 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +18 -3
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
- package/dist/src/planner/rules/shared/index-style-context.d.ts +17 -0
- package/dist/src/planner/rules/shared/index-style-context.d.ts.map +1 -1
- package/dist/src/planner/rules/shared/index-style-context.js +7 -0
- package/dist/src/planner/rules/shared/index-style-context.js.map +1 -1
- package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.js +4 -0
- package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.js.map +1 -1
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts +24 -6
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +175 -60
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
- package/dist/src/planner/stats/catalog-stats.d.ts +52 -0
- package/dist/src/planner/stats/catalog-stats.d.ts.map +1 -1
- package/dist/src/planner/stats/catalog-stats.js +151 -5
- package/dist/src/planner/stats/catalog-stats.js.map +1 -1
- package/dist/src/planner/stats/index.d.ts +15 -0
- package/dist/src/planner/stats/index.d.ts.map +1 -1
- package/dist/src/planner/stats/index.js.map +1 -1
- package/dist/src/planner/stats/selectivity-combine.d.ts +53 -0
- package/dist/src/planner/stats/selectivity-combine.d.ts.map +1 -0
- package/dist/src/planner/stats/selectivity-combine.js +75 -0
- package/dist/src/planner/stats/selectivity-combine.js.map +1 -0
- package/dist/src/planner/util/column-origins.d.ts +58 -0
- package/dist/src/planner/util/column-origins.d.ts.map +1 -0
- package/dist/src/planner/util/column-origins.js +90 -0
- package/dist/src/planner/util/column-origins.js.map +1 -0
- package/dist/src/runtime/deferred-constraint-queue.d.ts +40 -0
- package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
- package/dist/src/runtime/deferred-constraint-queue.js +91 -0
- package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
- package/dist/src/runtime/emit/aggregate-setup.d.ts +49 -0
- package/dist/src/runtime/emit/aggregate-setup.d.ts.map +1 -0
- package/dist/src/runtime/emit/aggregate-setup.js +99 -0
- package/dist/src/runtime/emit/aggregate-setup.js.map +1 -0
- package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
- package/dist/src/runtime/emit/aggregate.js +4 -69
- package/dist/src/runtime/emit/aggregate.js.map +1 -1
- package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/alter-table.js +354 -165
- package/dist/src/runtime/emit/alter-table.js.map +1 -1
- package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/asof-scan.js +11 -0
- package/dist/src/runtime/emit/asof-scan.js.map +1 -1
- package/dist/src/runtime/emit/between.d.ts.map +1 -1
- package/dist/src/runtime/emit/between.js +7 -12
- package/dist/src/runtime/emit/between.js.map +1 -1
- package/dist/src/runtime/emit/binary.d.ts.map +1 -1
- package/dist/src/runtime/emit/binary.js +24 -25
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/bloom-join.js +8 -16
- package/dist/src/runtime/emit/bloom-join.js.map +1 -1
- package/dist/src/runtime/emit/case.d.ts.map +1 -1
- package/dist/src/runtime/emit/case.js +40 -6
- package/dist/src/runtime/emit/case.js.map +1 -1
- package/dist/src/runtime/emit/cast.d.ts.map +1 -1
- package/dist/src/runtime/emit/cast.js +10 -23
- package/dist/src/runtime/emit/cast.js.map +1 -1
- package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
- package/dist/src/runtime/emit/constraint-check.js +72 -51
- package/dist/src/runtime/emit/constraint-check.js.map +1 -1
- package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
- package/dist/src/runtime/emit/create-view.js +6 -0
- package/dist/src/runtime/emit/create-view.js.map +1 -1
- package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
- package/dist/src/runtime/emit/distinct.js +6 -3
- package/dist/src/runtime/emit/distinct.js.map +1 -1
- package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
- package/dist/src/runtime/emit/dml-executor.js +188 -84
- package/dist/src/runtime/emit/dml-executor.js.map +1 -1
- package/dist/src/runtime/emit/filter.d.ts +18 -0
- package/dist/src/runtime/emit/filter.d.ts.map +1 -1
- package/dist/src/runtime/emit/filter.js +52 -10
- package/dist/src/runtime/emit/filter.js.map +1 -1
- package/dist/src/runtime/emit/hash-aggregate.d.ts.map +1 -1
- package/dist/src/runtime/emit/hash-aggregate.js +16 -65
- package/dist/src/runtime/emit/hash-aggregate.js.map +1 -1
- package/dist/src/runtime/emit/insert.d.ts.map +1 -1
- package/dist/src/runtime/emit/insert.js +18 -7
- package/dist/src/runtime/emit/insert.js.map +1 -1
- package/dist/src/runtime/emit/join-key-extractor.d.ts +46 -0
- package/dist/src/runtime/emit/join-key-extractor.d.ts.map +1 -0
- package/dist/src/runtime/emit/join-key-extractor.js +60 -0
- package/dist/src/runtime/emit/join-key-extractor.js.map +1 -0
- package/dist/src/runtime/emit/join.d.ts.map +1 -1
- package/dist/src/runtime/emit/join.js +37 -11
- package/dist/src/runtime/emit/join.js.map +1 -1
- package/dist/src/runtime/emit/key-set-semi-join.d.ts +29 -0
- package/dist/src/runtime/emit/key-set-semi-join.d.ts.map +1 -0
- package/dist/src/runtime/emit/key-set-semi-join.js +143 -0
- package/dist/src/runtime/emit/key-set-semi-join.js.map +1 -0
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts +14 -1
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
- package/dist/src/runtime/emit/materialized-view-helpers.js +33 -3
- package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
- package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
- package/dist/src/runtime/emit/materialized-view.js +47 -6
- package/dist/src/runtime/emit/materialized-view.js.map +1 -1
- package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/merge-join.js +32 -15
- package/dist/src/runtime/emit/merge-join.js.map +1 -1
- package/dist/src/runtime/emit/operand-comparator.d.ts +40 -0
- package/dist/src/runtime/emit/operand-comparator.d.ts.map +1 -0
- package/dist/src/runtime/emit/operand-comparator.js +59 -0
- package/dist/src/runtime/emit/operand-comparator.js.map +1 -0
- package/dist/src/runtime/emit/scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/scan.js +11 -2
- package/dist/src/runtime/emit/scan.js.map +1 -1
- package/dist/src/runtime/emit/set-object-tags.d.ts +8 -0
- package/dist/src/runtime/emit/set-object-tags.d.ts.map +1 -1
- package/dist/src/runtime/emit/set-object-tags.js +8 -0
- package/dist/src/runtime/emit/set-object-tags.js.map +1 -1
- package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
- package/dist/src/runtime/emit/set-operation.js +7 -4
- package/dist/src/runtime/emit/set-operation.js.map +1 -1
- package/dist/src/runtime/emit/sort.d.ts.map +1 -1
- package/dist/src/runtime/emit/sort.js +5 -2
- package/dist/src/runtime/emit/sort.js.map +1 -1
- package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
- package/dist/src/runtime/emit/subquery.js +113 -13
- package/dist/src/runtime/emit/subquery.js.map +1 -1
- package/dist/src/runtime/emit/temporal-arithmetic.d.ts +7 -0
- package/dist/src/runtime/emit/temporal-arithmetic.d.ts.map +1 -1
- package/dist/src/runtime/emit/temporal-arithmetic.js +15 -7
- package/dist/src/runtime/emit/temporal-arithmetic.js.map +1 -1
- package/dist/src/runtime/emit/update.d.ts.map +1 -1
- package/dist/src/runtime/emit/update.js +44 -3
- package/dist/src/runtime/emit/update.js.map +1 -1
- package/dist/src/runtime/emit/window.d.ts.map +1 -1
- package/dist/src/runtime/emit/window.js +72 -55
- package/dist/src/runtime/emit/window.js.map +1 -1
- package/dist/src/runtime/foreign-key-actions.d.ts +36 -1
- package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
- package/dist/src/runtime/foreign-key-actions.js +238 -116
- package/dist/src/runtime/foreign-key-actions.js.map +1 -1
- package/dist/src/runtime/parallel-driver.d.ts +10 -2
- package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
- package/dist/src/runtime/parallel-driver.js +12 -2
- package/dist/src/runtime/parallel-driver.js.map +1 -1
- package/dist/src/runtime/register.d.ts.map +1 -1
- package/dist/src/runtime/register.js +2 -0
- package/dist/src/runtime/register.js.map +1 -1
- package/dist/src/runtime/types.d.ts +25 -0
- package/dist/src/runtime/types.d.ts.map +1 -1
- package/dist/src/runtime/types.js.map +1 -1
- package/dist/src/schema/catalog-persistability.d.ts +58 -0
- package/dist/src/schema/catalog-persistability.d.ts.map +1 -0
- package/dist/src/schema/catalog-persistability.js +87 -0
- package/dist/src/schema/catalog-persistability.js.map +1 -0
- package/dist/src/schema/catalog.d.ts +17 -1
- package/dist/src/schema/catalog.d.ts.map +1 -1
- package/dist/src/schema/catalog.js +25 -3
- package/dist/src/schema/catalog.js.map +1 -1
- package/dist/src/schema/constraint-builder.d.ts +20 -22
- package/dist/src/schema/constraint-builder.d.ts.map +1 -1
- package/dist/src/schema/constraint-builder.js +43 -36
- package/dist/src/schema/constraint-builder.js.map +1 -1
- package/dist/src/schema/ddl-generator.d.ts +23 -0
- package/dist/src/schema/ddl-generator.d.ts.map +1 -1
- package/dist/src/schema/ddl-generator.js +27 -0
- package/dist/src/schema/ddl-generator.js.map +1 -1
- package/dist/src/schema/function.d.ts +39 -1
- package/dist/src/schema/function.d.ts.map +1 -1
- package/dist/src/schema/function.js.map +1 -1
- package/dist/src/schema/manager.d.ts +28 -0
- package/dist/src/schema/manager.d.ts.map +1 -1
- package/dist/src/schema/manager.js +82 -14
- package/dist/src/schema/manager.js.map +1 -1
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +51 -12
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/schema/unique-enforcement.d.ts +31 -0
- package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
- package/dist/src/schema/unique-enforcement.js +37 -1
- package/dist/src/schema/unique-enforcement.js.map +1 -1
- package/dist/src/schema/window-function.d.ts +30 -10
- package/dist/src/schema/window-function.d.ts.map +1 -1
- package/dist/src/schema/window-function.js +20 -16
- package/dist/src/schema/window-function.js.map +1 -1
- package/dist/src/types/builtin-types.d.ts.map +1 -1
- package/dist/src/types/builtin-types.js +30 -4
- package/dist/src/types/builtin-types.js.map +1 -1
- package/dist/src/types/cast-semantics.d.ts +43 -0
- package/dist/src/types/cast-semantics.d.ts.map +1 -0
- package/dist/src/types/cast-semantics.js +59 -0
- package/dist/src/types/cast-semantics.js.map +1 -0
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +1 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/json-type.d.ts.map +1 -1
- package/dist/src/types/json-type.js +31 -10
- package/dist/src/types/json-type.js.map +1 -1
- package/dist/src/types/logical-type.d.ts +22 -0
- package/dist/src/types/logical-type.d.ts.map +1 -1
- package/dist/src/types/logical-type.js.map +1 -1
- package/dist/src/types/temporal-types.d.ts.map +1 -1
- package/dist/src/types/temporal-types.js +33 -11
- package/dist/src/types/temporal-types.js.map +1 -1
- package/dist/src/types/validation.d.ts +39 -1
- package/dist/src/types/validation.d.ts.map +1 -1
- package/dist/src/types/validation.js +60 -0
- package/dist/src/types/validation.js.map +1 -1
- package/dist/src/util/ast-spine-clone.d.ts +23 -0
- package/dist/src/util/ast-spine-clone.d.ts.map +1 -0
- package/dist/src/util/ast-spine-clone.js +41 -0
- package/dist/src/util/ast-spine-clone.js.map +1 -0
- package/dist/src/util/coercion.d.ts +13 -0
- package/dist/src/util/coercion.d.ts.map +1 -1
- package/dist/src/util/coercion.js +10 -1
- package/dist/src/util/coercion.js.map +1 -1
- package/dist/src/util/comparison.d.ts +114 -0
- package/dist/src/util/comparison.d.ts.map +1 -1
- package/dist/src/util/comparison.js +187 -27
- package/dist/src/util/comparison.js.map +1 -1
- package/dist/src/vtab/best-access-plan.d.ts +87 -0
- package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
- package/dist/src/vtab/best-access-plan.js +87 -0
- package/dist/src/vtab/best-access-plan.js.map +1 -1
- package/dist/src/vtab/manifest.d.ts +7 -0
- package/dist/src/vtab/manifest.d.ts.map +1 -1
- package/dist/src/vtab/memory/connection.d.ts +14 -1
- package/dist/src/vtab/memory/connection.d.ts.map +1 -1
- package/dist/src/vtab/memory/connection.js +20 -2
- package/dist/src/vtab/memory/connection.js.map +1 -1
- package/dist/src/vtab/memory/layer/base.d.ts +12 -5
- package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base.js +20 -9
- package/dist/src/vtab/memory/layer/base.js.map +1 -1
- package/dist/src/vtab/memory/layer/connection.d.ts +17 -0
- package/dist/src/vtab/memory/layer/connection.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/connection.js +26 -0
- package/dist/src/vtab/memory/layer/connection.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +156 -31
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +695 -158
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/dist/src/vtab/memory/layer/plan-filter.d.ts +41 -20
- package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/plan-filter.js +57 -27
- package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
- package/dist/src/vtab/memory/layer/row-convert.d.ts +21 -0
- package/dist/src/vtab/memory/layer/row-convert.d.ts.map +1 -0
- package/dist/src/vtab/memory/layer/row-convert.js +30 -0
- package/dist/src/vtab/memory/layer/row-convert.js.map +1 -0
- package/dist/src/vtab/memory/layer/scan-layer.d.ts +6 -3
- package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/scan-layer.js +48 -34
- package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.d.ts +142 -19
- package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.js +237 -73
- package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
- package/dist/src/vtab/memory/module.d.ts +14 -2
- package/dist/src/vtab/memory/module.d.ts.map +1 -1
- package/dist/src/vtab/memory/module.js +60 -41
- package/dist/src/vtab/memory/module.js.map +1 -1
- package/dist/src/vtab/memory/table.d.ts +1 -1
- package/dist/src/vtab/memory/table.d.ts.map +1 -1
- package/dist/src/vtab/memory/table.js +12 -4
- package/dist/src/vtab/memory/table.js.map +1 -1
- package/dist/src/vtab/memory/types.d.ts +27 -1
- package/dist/src/vtab/memory/types.d.ts.map +1 -1
- package/dist/src/vtab/memory/types.js +16 -1
- package/dist/src/vtab/memory/types.js.map +1 -1
- package/dist/src/vtab/memory/utils/primary-key.d.ts +9 -0
- package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/primary-key.js +11 -0
- package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
- package/dist/src/vtab/module.d.ts +63 -0
- package/dist/src/vtab/module.d.ts.map +1 -1
- package/dist/src/vtab/table.d.ts +33 -7
- package/dist/src/vtab/table.d.ts.map +1 -1
- package/dist/src/vtab/table.js.map +1 -1
- package/package.json +3 -3
- package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts +0 -26
- package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts.map +0 -1
- package/dist/src/planner/rules/cache/rule-in-subquery-cache.js +0 -66
- 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;
|
|
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
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
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
|
|
31
|
-
* `conflictTargetIndices`). When
|
|
32
|
-
*
|
|
33
|
-
*
|
|
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
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
//
|
|
251
|
-
// matchUpsertClause so a
|
|
252
|
-
//
|
|
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
|
-
|
|
255
|
-
runtime.
|
|
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
|
-
//
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
//
|
|
302
|
-
//
|
|
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
|
-
|
|
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
|
-
//
|
|
374
|
-
|
|
375
|
-
|
|
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
|
|
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 =>
|
|
658
|
-
ctx.db._recordUpdate(tableKey, replacedRow,
|
|
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 <
|
|
664
|
-
if (!sqlValueIdentical(replacedRow[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], [...
|
|
734
|
+
emitAutoDataEvent(ctx, tableSchema, 'update', newKeyValues, [...replacedRow], [...storedRow], changedColumns);
|
|
669
735
|
}
|
|
670
736
|
}
|
|
671
737
|
else {
|
|
672
|
-
const pkValues = pkColumnIndicesInSchema.map(idx =>
|
|
673
|
-
ctx.db._recordInsert(tableKey,
|
|
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, [...
|
|
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
|
-
//
|
|
770
|
-
//
|
|
771
|
-
//
|
|
772
|
-
//
|
|
773
|
-
//
|
|
774
|
-
//
|
|
775
|
-
//
|
|
776
|
-
|
|
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,
|
|
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,
|
|
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 <
|
|
920
|
+
for (let i = 0; i < numCols; i++) {
|
|
829
921
|
const oldVal = oldRow[i];
|
|
830
|
-
const newVal =
|
|
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], [...
|
|
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
|
-
//
|
|
882
|
-
// path above.
|
|
883
|
-
|
|
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);
|