@quereus/quereus 0.17.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -14
- package/dist/src/common/type-inference.d.ts +1 -0
- package/dist/src/common/type-inference.d.ts.map +1 -1
- package/dist/src/common/type-inference.js +6 -1
- package/dist/src/common/type-inference.js.map +1 -1
- package/dist/src/common/types.d.ts +10 -2
- package/dist/src/common/types.d.ts.map +1 -1
- package/dist/src/common/types.js +13 -1
- package/dist/src/common/types.js.map +1 -1
- package/dist/src/emit/ast-stringify.d.ts.map +1 -1
- package/dist/src/emit/ast-stringify.js +5 -0
- package/dist/src/emit/ast-stringify.js.map +1 -1
- package/dist/src/func/builtins/conversion.d.ts +2 -2
- package/dist/src/func/builtins/conversion.js +3 -3
- package/dist/src/func/builtins/conversion.js.map +1 -1
- package/dist/src/func/builtins/index.d.ts.map +1 -1
- package/dist/src/func/builtins/index.js +2 -1
- package/dist/src/func/builtins/index.js.map +1 -1
- package/dist/src/func/builtins/json-helpers.d.ts +10 -0
- package/dist/src/func/builtins/json-helpers.d.ts.map +1 -1
- package/dist/src/func/builtins/json-helpers.js +26 -0
- package/dist/src/func/builtins/json-helpers.js.map +1 -1
- package/dist/src/func/builtins/json-tvf.d.ts.map +1 -1
- package/dist/src/func/builtins/json-tvf.js +9 -15
- package/dist/src/func/builtins/json-tvf.js.map +1 -1
- package/dist/src/func/builtins/json.d.ts.map +1 -1
- package/dist/src/func/builtins/json.js +100 -227
- package/dist/src/func/builtins/json.js.map +1 -1
- package/dist/src/func/builtins/schema.d.ts.map +1 -1
- package/dist/src/func/builtins/schema.js +9 -0
- package/dist/src/func/builtins/schema.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/parser/lexer.d.ts +1 -0
- package/dist/src/parser/lexer.d.ts.map +1 -1
- package/dist/src/parser/lexer.js +2 -1
- package/dist/src/parser/lexer.js.map +1 -1
- package/dist/src/parser/parser.d.ts +12 -0
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +54 -1
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/planner/analysis/const-evaluator.d.ts +5 -0
- package/dist/src/planner/analysis/const-evaluator.d.ts.map +1 -1
- package/dist/src/planner/analysis/const-evaluator.js +106 -0
- package/dist/src/planner/analysis/const-evaluator.js.map +1 -1
- package/dist/src/planner/analysis/const-pass.d.ts +4 -2
- package/dist/src/planner/analysis/const-pass.d.ts.map +1 -1
- package/dist/src/planner/analysis/const-pass.js +23 -13
- package/dist/src/planner/analysis/const-pass.js.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.d.ts +19 -1
- package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.js +265 -14
- package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
- package/dist/src/planner/analysis/expression-fingerprint.d.ts +15 -0
- package/dist/src/planner/analysis/expression-fingerprint.d.ts.map +1 -0
- package/dist/src/planner/analysis/expression-fingerprint.js +126 -0
- package/dist/src/planner/analysis/expression-fingerprint.js.map +1 -0
- package/dist/src/planner/cost/index.d.ts +16 -0
- package/dist/src/planner/cost/index.d.ts.map +1 -1
- package/dist/src/planner/cost/index.js +22 -0
- package/dist/src/planner/cost/index.js.map +1 -1
- package/dist/src/planner/framework/pass.d.ts.map +1 -1
- package/dist/src/planner/framework/pass.js +4 -3
- package/dist/src/planner/framework/pass.js.map +1 -1
- package/dist/src/planner/nodes/hash-aggregate.d.ts +38 -0
- package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -0
- package/dist/src/planner/nodes/hash-aggregate.js +213 -0
- package/dist/src/planner/nodes/hash-aggregate.js.map +1 -0
- 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/stream-aggregate.js.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts +11 -0
- package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.js +32 -0
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
- package/dist/src/planner/nodes/values-node.d.ts +3 -1
- package/dist/src/planner/nodes/values-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/values-node.js +9 -2
- package/dist/src/planner/nodes/values-node.js.map +1 -1
- package/dist/src/planner/optimizer.d.ts.map +1 -1
- package/dist/src/planner/optimizer.js +35 -7
- package/dist/src/planner/optimizer.js.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.js +175 -5
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts +9 -11
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +54 -67
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts +19 -0
- package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts.map +1 -0
- package/dist/src/planner/rules/cache/rule-scalar-cse.js +245 -0
- package/dist/src/planner/rules/cache/rule-scalar-cse.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-filter-merge.d.ts +15 -0
- package/dist/src/planner/rules/predicate/rule-filter-merge.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-filter-merge.js +39 -0
- package/dist/src/planner/rules/predicate/rule-filter-merge.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts +1 -0
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +9 -0
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-projection-pruning.d.ts +17 -0
- package/dist/src/planner/rules/retrieve/rule-projection-pruning.d.ts.map +1 -0
- package/dist/src/planner/rules/retrieve/rule-projection-pruning.js +75 -0
- package/dist/src/planner/rules/retrieve/rule-projection-pruning.js.map +1 -0
- package/dist/src/runtime/emit/aggregate.d.ts +9 -0
- package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
- package/dist/src/runtime/emit/aggregate.js +2 -2
- package/dist/src/runtime/emit/aggregate.js.map +1 -1
- package/dist/src/runtime/emit/empty-result.d.ts +5 -0
- package/dist/src/runtime/emit/empty-result.d.ts.map +1 -0
- package/dist/src/runtime/emit/empty-result.js +11 -0
- package/dist/src/runtime/emit/empty-result.js.map +1 -0
- package/dist/src/runtime/emit/hash-aggregate.d.ts +5 -0
- package/dist/src/runtime/emit/hash-aggregate.d.ts.map +1 -0
- package/dist/src/runtime/emit/hash-aggregate.js +319 -0
- package/dist/src/runtime/emit/hash-aggregate.js.map +1 -0
- package/dist/src/runtime/register.d.ts.map +1 -1
- package/dist/src/runtime/register.js +4 -1
- package/dist/src/runtime/register.js.map +1 -1
- package/dist/src/types/json-type.d.ts +3 -3
- package/dist/src/types/json-type.d.ts.map +1 -1
- package/dist/src/types/json-type.js +44 -38
- package/dist/src/types/json-type.js.map +1 -1
- package/dist/src/types/logical-type.d.ts +2 -1
- package/dist/src/types/logical-type.d.ts.map +1 -1
- package/dist/src/types/logical-type.js +4 -0
- package/dist/src/types/logical-type.js.map +1 -1
- package/dist/src/util/comparison.d.ts +1 -1
- package/dist/src/util/comparison.d.ts.map +1 -1
- package/dist/src/util/comparison.js +22 -4
- package/dist/src/util/comparison.js.map +1 -1
- package/dist/src/vtab/best-access-plan.d.ts +1 -1
- package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base-cursor.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base-cursor.js +81 -6
- package/dist/src/vtab/memory/layer/base-cursor.js.map +1 -1
- package/dist/src/vtab/memory/layer/scan-plan.d.ts +9 -0
- package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/scan-plan.js +76 -9
- package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
- package/dist/src/vtab/memory/layer/transaction-cursor.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/transaction-cursor.js +79 -11
- package/dist/src/vtab/memory/layer/transaction-cursor.js.map +1 -1
- package/dist/src/vtab/memory/module.d.ts +4 -0
- package/dist/src/vtab/memory/module.d.ts.map +1 -1
- package/dist/src/vtab/memory/module.js +79 -11
- package/dist/src/vtab/memory/module.js.map +1 -1
- package/package.json +25 -5
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule: Scalar Common Subexpression Elimination (CSE)
|
|
3
|
+
*
|
|
4
|
+
* Detects duplicate scalar expression computations across a ProjectNode and
|
|
5
|
+
* its immediate relational child chain (Filter, Sort), then injects a
|
|
6
|
+
* lower ProjectNode that computes each deduplicated expression once.
|
|
7
|
+
*
|
|
8
|
+
* Guards:
|
|
9
|
+
* - Only deduplicate deterministic expressions
|
|
10
|
+
* - Skip bare column references and literals (cost 0, cheap to recompute)
|
|
11
|
+
* - Require at least 2 occurrences of the same fingerprint
|
|
12
|
+
*
|
|
13
|
+
* Pass: Structural (top-down), priority 22
|
|
14
|
+
* Node type: PlanNodeType.Project
|
|
15
|
+
*/
|
|
16
|
+
import type { PlanNode } from '../../nodes/plan-node.js';
|
|
17
|
+
import type { OptContext } from '../../framework/context.js';
|
|
18
|
+
export declare function ruleScalarCSE(node: PlanNode, _context: OptContext): PlanNode | null;
|
|
19
|
+
//# sourceMappingURL=rule-scalar-cse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-scalar-cse.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/cache/rule-scalar-cse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAiD,MAAM,0BAA0B,CAAC;AAExG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AA0F7D,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAkOnF"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule: Scalar Common Subexpression Elimination (CSE)
|
|
3
|
+
*
|
|
4
|
+
* Detects duplicate scalar expression computations across a ProjectNode and
|
|
5
|
+
* its immediate relational child chain (Filter, Sort), then injects a
|
|
6
|
+
* lower ProjectNode that computes each deduplicated expression once.
|
|
7
|
+
*
|
|
8
|
+
* Guards:
|
|
9
|
+
* - Only deduplicate deterministic expressions
|
|
10
|
+
* - Skip bare column references and literals (cost 0, cheap to recompute)
|
|
11
|
+
* - Require at least 2 occurrences of the same fingerprint
|
|
12
|
+
*
|
|
13
|
+
* Pass: Structural (top-down), priority 22
|
|
14
|
+
* Node type: PlanNodeType.Project
|
|
15
|
+
*/
|
|
16
|
+
import { createLogger } from '../../../common/logger.js';
|
|
17
|
+
import { PlanNode as PlanNodeClass } from '../../nodes/plan-node.js';
|
|
18
|
+
import { PlanNodeType } from '../../nodes/plan-node-type.js';
|
|
19
|
+
import { ProjectNode } from '../../nodes/project-node.js';
|
|
20
|
+
import { FilterNode } from '../../nodes/filter.js';
|
|
21
|
+
import { SortNode } from '../../nodes/sort.js';
|
|
22
|
+
import { ColumnReferenceNode } from '../../nodes/reference.js';
|
|
23
|
+
import { fingerprintExpression } from '../../analysis/expression-fingerprint.js';
|
|
24
|
+
const log = createLogger('optimizer:rule:scalar-cse');
|
|
25
|
+
/**
|
|
26
|
+
* Recursively collect all scalar subexpression locations from a scalar expression tree.
|
|
27
|
+
* Each subexpression that is non-trivial and deterministic gets its own location entry.
|
|
28
|
+
*/
|
|
29
|
+
function collectSubexpressions(root, owner, index, out) {
|
|
30
|
+
// Skip column references and literals - they're trivially cheap
|
|
31
|
+
if (root.nodeType === PlanNodeType.ColumnReference || root.nodeType === PlanNodeType.Literal) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Skip non-deterministic expressions
|
|
35
|
+
if (root.physical.deterministic === false) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
// Skip parameter references - cheap to evaluate
|
|
39
|
+
if (root.nodeType === PlanNodeType.ParameterReference) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
out.push({ owner, index, node: root });
|
|
43
|
+
// Recurse into children (scalar children only)
|
|
44
|
+
for (const child of root.getChildren()) {
|
|
45
|
+
if (child.getType().typeClass === 'scalar') {
|
|
46
|
+
collectSubexpressions(child, owner, index, out);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Collect the relational child chain under a ProjectNode.
|
|
52
|
+
* Returns [filter?, sort?, bottomSource] where filter/sort are optional
|
|
53
|
+
* intermediate nodes and bottomSource is the first non-Filter/non-Sort child.
|
|
54
|
+
*/
|
|
55
|
+
function collectChain(project) {
|
|
56
|
+
let current = project.source;
|
|
57
|
+
let filter = null;
|
|
58
|
+
let sort = null;
|
|
59
|
+
// Walk at most two levels: Filter then Sort, or Sort then Filter
|
|
60
|
+
for (let i = 0; i < 2; i++) {
|
|
61
|
+
if (!filter && current instanceof FilterNode) {
|
|
62
|
+
filter = current;
|
|
63
|
+
current = current.source;
|
|
64
|
+
}
|
|
65
|
+
else if (!sort && current instanceof SortNode) {
|
|
66
|
+
sort = current;
|
|
67
|
+
current = current.source;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { filter, sort, bottomSource: current };
|
|
74
|
+
}
|
|
75
|
+
export function ruleScalarCSE(node, _context) {
|
|
76
|
+
if (node.nodeType !== PlanNodeType.Project) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const project = node;
|
|
80
|
+
const { filter, sort, bottomSource } = collectChain(project);
|
|
81
|
+
// Collect all subexpressions from the chain
|
|
82
|
+
const allLocations = [];
|
|
83
|
+
// Collect from projections
|
|
84
|
+
for (let i = 0; i < project.projections.length; i++) {
|
|
85
|
+
collectSubexpressions(project.projections[i].node, 'project', i, allLocations);
|
|
86
|
+
}
|
|
87
|
+
// Collect from filter predicate
|
|
88
|
+
if (filter) {
|
|
89
|
+
collectSubexpressions(filter.predicate, 'filter', 0, allLocations);
|
|
90
|
+
}
|
|
91
|
+
// Collect from sort keys
|
|
92
|
+
if (sort) {
|
|
93
|
+
for (let i = 0; i < sort.sortKeys.length; i++) {
|
|
94
|
+
collectSubexpressions(sort.sortKeys[i].expression, 'sort', i, allLocations);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (allLocations.length === 0) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
// Group by fingerprint
|
|
101
|
+
const groups = new Map();
|
|
102
|
+
for (const loc of allLocations) {
|
|
103
|
+
const fp = fingerprintExpression(loc.node);
|
|
104
|
+
let group = groups.get(fp);
|
|
105
|
+
if (!group) {
|
|
106
|
+
group = [];
|
|
107
|
+
groups.set(fp, group);
|
|
108
|
+
}
|
|
109
|
+
group.push(loc);
|
|
110
|
+
}
|
|
111
|
+
// Find groups with duplicates (2+ locations with distinct node identities)
|
|
112
|
+
const duplicateGroups = [];
|
|
113
|
+
for (const [fingerprint, locations] of groups) {
|
|
114
|
+
// Deduplicate by node identity - same node object appearing in multiple positions
|
|
115
|
+
// counts as one, we need at least 2 distinct node instances
|
|
116
|
+
const uniqueNodes = new Set(locations.map(l => l.node));
|
|
117
|
+
if (uniqueNodes.size >= 2) {
|
|
118
|
+
duplicateGroups.push({ fingerprint, locations });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (duplicateGroups.length === 0) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
log('Found %d duplicate expression groups in Project chain', duplicateGroups.length);
|
|
125
|
+
// For each duplicate group, pick the canonical instance and create a computed column
|
|
126
|
+
const injectedProjections = [];
|
|
127
|
+
const injectedAttributes = [];
|
|
128
|
+
// Map from canonical node id to the new attribute/column ref info
|
|
129
|
+
const replacements = new Map();
|
|
130
|
+
// We'll build the injected projections: passthrough of bottomSource + computed columns
|
|
131
|
+
// First, collect passthrough from the bottomSource
|
|
132
|
+
const bottomAttrs = bottomSource.getAttributes();
|
|
133
|
+
// Index for the new columns starts after passthrough columns
|
|
134
|
+
let nextColIndex = bottomAttrs.length;
|
|
135
|
+
for (const group of duplicateGroups) {
|
|
136
|
+
const canonical = group.locations[0].node;
|
|
137
|
+
const attrId = PlanNodeClass.nextAttrId();
|
|
138
|
+
const alias = `$cse_${attrId}`;
|
|
139
|
+
const colRefExpr = {
|
|
140
|
+
type: 'column',
|
|
141
|
+
name: alias,
|
|
142
|
+
};
|
|
143
|
+
const colRef = new ColumnReferenceNode(project.scope, colRefExpr, canonical.getType(), attrId, nextColIndex);
|
|
144
|
+
injectedProjections.push({
|
|
145
|
+
node: canonical,
|
|
146
|
+
alias,
|
|
147
|
+
attributeId: attrId,
|
|
148
|
+
});
|
|
149
|
+
injectedAttributes.push({
|
|
150
|
+
id: attrId,
|
|
151
|
+
name: alias,
|
|
152
|
+
type: canonical.getType(),
|
|
153
|
+
sourceRelation: 'cse',
|
|
154
|
+
relationName: 'cse',
|
|
155
|
+
});
|
|
156
|
+
replacements.set(group.fingerprint, { attrId, colRef, canonical });
|
|
157
|
+
nextColIndex++;
|
|
158
|
+
}
|
|
159
|
+
// Build the passthrough projections for the injected ProjectNode
|
|
160
|
+
const passthroughProjections = bottomAttrs.map((attr, i) => {
|
|
161
|
+
const colRefExpr = {
|
|
162
|
+
type: 'column',
|
|
163
|
+
name: attr.name,
|
|
164
|
+
};
|
|
165
|
+
const colRef = new ColumnReferenceNode(project.scope, colRefExpr, attr.type, attr.id, i);
|
|
166
|
+
return {
|
|
167
|
+
node: colRef,
|
|
168
|
+
alias: attr.name,
|
|
169
|
+
attributeId: attr.id,
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
// Combine passthrough + computed projections
|
|
173
|
+
const allInjectedProjections = [...passthroughProjections, ...injectedProjections];
|
|
174
|
+
// Build predefined attributes for the injected ProjectNode
|
|
175
|
+
const predefinedAttributes = [
|
|
176
|
+
...bottomAttrs.map(a => ({ ...a })),
|
|
177
|
+
...injectedAttributes,
|
|
178
|
+
];
|
|
179
|
+
// Create the injected ProjectNode
|
|
180
|
+
const injectedProject = new ProjectNode(project.scope, bottomSource, allInjectedProjections, undefined, predefinedAttributes, true // preserveInputColumns
|
|
181
|
+
);
|
|
182
|
+
// Now replace all duplicate occurrences in the outer nodes with ColumnReferenceNodes
|
|
183
|
+
// We need to rebuild: project projections, filter predicate, sort keys
|
|
184
|
+
// Helper: replace all occurrences of any duplicate group's nodes with colRefs
|
|
185
|
+
function replaceAllDuplicates(expr) {
|
|
186
|
+
// Check if this exact expression matches a fingerprint group
|
|
187
|
+
if (expr.nodeType !== PlanNodeType.ColumnReference &&
|
|
188
|
+
expr.nodeType !== PlanNodeType.Literal &&
|
|
189
|
+
expr.nodeType !== PlanNodeType.ParameterReference &&
|
|
190
|
+
expr.physical.deterministic !== false) {
|
|
191
|
+
const fp = fingerprintExpression(expr);
|
|
192
|
+
const rep = replacements.get(fp);
|
|
193
|
+
if (rep) {
|
|
194
|
+
return rep.colRef;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Recurse into children
|
|
198
|
+
const children = expr.getChildren();
|
|
199
|
+
if (children.length === 0)
|
|
200
|
+
return expr;
|
|
201
|
+
const newChildren = [];
|
|
202
|
+
let changed = false;
|
|
203
|
+
for (const child of children) {
|
|
204
|
+
if (child.getType().typeClass === 'scalar') {
|
|
205
|
+
const replaced = replaceAllDuplicates(child);
|
|
206
|
+
newChildren.push(replaced);
|
|
207
|
+
if (replaced !== child)
|
|
208
|
+
changed = true;
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
newChildren.push(child);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (!changed)
|
|
215
|
+
return expr;
|
|
216
|
+
return expr.withChildren(newChildren);
|
|
217
|
+
}
|
|
218
|
+
// Rebuild sort (innermost in the outer chain, sits on injectedProject)
|
|
219
|
+
let newSortOrSource = injectedProject;
|
|
220
|
+
if (sort) {
|
|
221
|
+
const newSortKeys = sort.sortKeys.map(key => ({
|
|
222
|
+
expression: replaceAllDuplicates(key.expression),
|
|
223
|
+
direction: key.direction,
|
|
224
|
+
nulls: key.nulls,
|
|
225
|
+
}));
|
|
226
|
+
newSortOrSource = new SortNode(sort.scope, injectedProject, newSortKeys);
|
|
227
|
+
}
|
|
228
|
+
// Rebuild filter
|
|
229
|
+
let newFilterOrSource = newSortOrSource;
|
|
230
|
+
if (filter) {
|
|
231
|
+
const newPredicate = replaceAllDuplicates(filter.predicate);
|
|
232
|
+
newFilterOrSource = new FilterNode(filter.scope, newSortOrSource, newPredicate);
|
|
233
|
+
}
|
|
234
|
+
// Rebuild the outer project
|
|
235
|
+
const origAttributes = project.getAttributes();
|
|
236
|
+
const newProjections = project.projections.map((proj, i) => ({
|
|
237
|
+
node: replaceAllDuplicates(proj.node),
|
|
238
|
+
alias: proj.alias,
|
|
239
|
+
attributeId: origAttributes[i].id,
|
|
240
|
+
}));
|
|
241
|
+
const newProject = new ProjectNode(project.scope, newFilterOrSource, newProjections, undefined, origAttributes, project.preserveInputColumns);
|
|
242
|
+
log('Injected CSE ProjectNode with %d computed columns', injectedProjections.length);
|
|
243
|
+
return newProject;
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=rule-scalar-cse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-scalar-cse.js","sourceRoot":"","sources":["../../../../../src/planner/rules/cache/rule-scalar-cse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule: Filter Merge
|
|
3
|
+
*
|
|
4
|
+
* Merges adjacent Filter nodes into a single Filter with an AND-combined predicate.
|
|
5
|
+
*
|
|
6
|
+
* Filter(pred_outer) → Filter(pred_inner) → source
|
|
7
|
+
* becomes:
|
|
8
|
+
* Filter(pred_outer AND pred_inner) → source
|
|
9
|
+
*
|
|
10
|
+
* Always safe: the conjunction is semantically identical.
|
|
11
|
+
*/
|
|
12
|
+
import type { PlanNode } from '../../nodes/plan-node.js';
|
|
13
|
+
import type { OptContext } from '../../framework/context.js';
|
|
14
|
+
export declare function ruleFilterMerge(node: PlanNode, _context: OptContext): PlanNode | null;
|
|
15
|
+
//# sourceMappingURL=rule-filter-merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-filter-merge.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-filter-merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAQ7D,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAsBrF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule: Filter Merge
|
|
3
|
+
*
|
|
4
|
+
* Merges adjacent Filter nodes into a single Filter with an AND-combined predicate.
|
|
5
|
+
*
|
|
6
|
+
* Filter(pred_outer) → Filter(pred_inner) → source
|
|
7
|
+
* becomes:
|
|
8
|
+
* Filter(pred_outer AND pred_inner) → source
|
|
9
|
+
*
|
|
10
|
+
* Always safe: the conjunction is semantically identical.
|
|
11
|
+
*/
|
|
12
|
+
import { createLogger } from '../../../common/logger.js';
|
|
13
|
+
import { PlanNodeType } from '../../nodes/plan-node-type.js';
|
|
14
|
+
import { FilterNode } from '../../nodes/filter.js';
|
|
15
|
+
import { BinaryOpNode } from '../../nodes/scalar.js';
|
|
16
|
+
const log = createLogger('optimizer:rule:filter-merge');
|
|
17
|
+
export function ruleFilterMerge(node, _context) {
|
|
18
|
+
if (node.nodeType !== PlanNodeType.Filter)
|
|
19
|
+
return null;
|
|
20
|
+
let current = node;
|
|
21
|
+
if (current.source.nodeType !== PlanNodeType.Filter)
|
|
22
|
+
return null;
|
|
23
|
+
// Iteratively absorb all adjacent filters (handles triple+ stacks in one visit)
|
|
24
|
+
let predicate = current.predicate;
|
|
25
|
+
while (current.source.nodeType === PlanNodeType.Filter) {
|
|
26
|
+
const inner = current.source;
|
|
27
|
+
const ast = {
|
|
28
|
+
type: 'binary',
|
|
29
|
+
operator: 'AND',
|
|
30
|
+
left: predicate.expression,
|
|
31
|
+
right: inner.predicate.expression,
|
|
32
|
+
};
|
|
33
|
+
predicate = new BinaryOpNode(current.scope, ast, predicate, inner.predicate);
|
|
34
|
+
current = inner;
|
|
35
|
+
}
|
|
36
|
+
log('Merged adjacent filters into single AND predicate');
|
|
37
|
+
return new FilterNode(node.scope, current.source, predicate);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=rule-filter-merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-filter-merge.js","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-filter-merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD,MAAM,GAAG,GAAG,YAAY,CAAC,6BAA6B,CAAC,CAAC;AAExD,MAAM,UAAU,eAAe,CAAC,IAAc,EAAE,QAAoB;IACnE,IAAI,IAAI,CAAC,QAAQ,KAAK,YAAY,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,OAAO,GAAG,IAAkB,CAAC;IAEjC,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,KAAK,YAAY,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEjE,gFAAgF;IAChF,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAClC,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,KAAK,YAAY,CAAC,MAAM,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAoB,CAAC;QAC3C,MAAM,GAAG,GAAmB;YAC3B,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,KAAK;YACf,IAAI,EAAG,SAAiB,CAAC,UAAU;YACnC,KAAK,EAAG,KAAK,CAAC,SAAiB,CAAC,UAAU;SAC1C,CAAC;QACF,SAAS,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAC7E,OAAO,GAAG,KAAK,CAAC;IACjB,CAAC;IAED,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACzD,OAAO,IAAI,UAAU,CAAE,IAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Safe moves implemented now:
|
|
8
8
|
* - Across Sort: always safe (ordering unaffected by selection)
|
|
9
9
|
* - Across Distinct: safe for selection predicates (commute)
|
|
10
|
+
* - Across Alias: safe because AliasNode only renames relationName; attribute IDs are unchanged
|
|
10
11
|
* - Across Project: only if predicate references attribute IDs available below the Project source
|
|
11
12
|
* (we verify attribute-id coverage), and we keep predicate unchanged (IDs preserved by design)
|
|
12
13
|
* - Into Retrieve: wrap Retrieve.source with a Filter
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-predicate-pushdown.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-predicate-pushdown.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rule-predicate-pushdown.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-predicate-pushdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAsB,MAAM,0BAA0B,CAAC;AAE7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAgB7D,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAc3F"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Safe moves implemented now:
|
|
8
8
|
* - Across Sort: always safe (ordering unaffected by selection)
|
|
9
9
|
* - Across Distinct: safe for selection predicates (commute)
|
|
10
|
+
* - Across Alias: safe because AliasNode only renames relationName; attribute IDs are unchanged
|
|
10
11
|
* - Across Project: only if predicate references attribute IDs available below the Project source
|
|
11
12
|
* (we verify attribute-id coverage), and we keep predicate unchanged (IDs preserved by design)
|
|
12
13
|
* - Into Retrieve: wrap Retrieve.source with a Filter
|
|
@@ -23,6 +24,7 @@ import { SortNode } from '../../nodes/sort.js';
|
|
|
23
24
|
import { DistinctNode } from '../../nodes/distinct-node.js';
|
|
24
25
|
import { ProjectNode } from '../../nodes/project-node.js';
|
|
25
26
|
import { RetrieveNode } from '../../nodes/retrieve-node.js';
|
|
27
|
+
import { AliasNode } from '../../nodes/alias-node.js';
|
|
26
28
|
import { CapabilityDetectors } from '../../framework/characteristics.js';
|
|
27
29
|
import { normalizePredicate } from '../../analysis/predicate-normalizer.js';
|
|
28
30
|
import { collectBindingsInExpr } from '../../analysis/binding-collector.js';
|
|
@@ -65,6 +67,13 @@ function tryPushDown(child, predicate, scope) {
|
|
|
65
67
|
}
|
|
66
68
|
return new FilterNode(scope, updatedRetrieve, extraction.residualPredicate);
|
|
67
69
|
}
|
|
70
|
+
// Across AliasNode (view boundary)
|
|
71
|
+
if (child instanceof AliasNode) {
|
|
72
|
+
log('Pushing predicate below AliasNode');
|
|
73
|
+
const under = child.source;
|
|
74
|
+
const newUnder = new FilterNode(under.scope, under, predicate);
|
|
75
|
+
return new AliasNode(child.scope, newUnder, child.alias);
|
|
76
|
+
}
|
|
68
77
|
// Across Sort
|
|
69
78
|
if (child instanceof SortNode) {
|
|
70
79
|
log('Pushing predicate below Sort');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-predicate-pushdown.js","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-predicate-pushdown.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rule-predicate-pushdown.js","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-predicate-pushdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule: Projection Pruning
|
|
3
|
+
*
|
|
4
|
+
* When an outer ProjectNode references only a subset of an inner ProjectNode's
|
|
5
|
+
* output attributes, the inner projections that are not referenced can be removed.
|
|
6
|
+
*
|
|
7
|
+
* This commonly arises after view expansion:
|
|
8
|
+
* Project(outer: name) → Project(view: id, name, email, category, value) → Scan
|
|
9
|
+
* becomes:
|
|
10
|
+
* Project(outer: name) → Project(view: name) → Scan
|
|
11
|
+
*
|
|
12
|
+
* The rule only fires on ProjectNode whose source is also a ProjectNode.
|
|
13
|
+
*/
|
|
14
|
+
import type { PlanNode } from '../../nodes/plan-node.js';
|
|
15
|
+
import type { OptContext } from '../../framework/context.js';
|
|
16
|
+
export declare function ruleProjectionPruning(node: PlanNode, _context: OptContext): PlanNode | null;
|
|
17
|
+
//# sourceMappingURL=rule-projection-pruning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-projection-pruning.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/retrieve/rule-projection-pruning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAkB,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAoB7D,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAqE3F"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule: Projection Pruning
|
|
3
|
+
*
|
|
4
|
+
* When an outer ProjectNode references only a subset of an inner ProjectNode's
|
|
5
|
+
* output attributes, the inner projections that are not referenced can be removed.
|
|
6
|
+
*
|
|
7
|
+
* This commonly arises after view expansion:
|
|
8
|
+
* Project(outer: name) → Project(view: id, name, email, category, value) → Scan
|
|
9
|
+
* becomes:
|
|
10
|
+
* Project(outer: name) → Project(view: name) → Scan
|
|
11
|
+
*
|
|
12
|
+
* The rule only fires on ProjectNode whose source is also a ProjectNode.
|
|
13
|
+
*/
|
|
14
|
+
import { createLogger } from '../../../common/logger.js';
|
|
15
|
+
import { ProjectNode } from '../../nodes/project-node.js';
|
|
16
|
+
import { ColumnReferenceNode } from '../../nodes/reference.js';
|
|
17
|
+
const log = createLogger('optimizer:rule:projection-pruning');
|
|
18
|
+
/**
|
|
19
|
+
* Collect all attribute IDs referenced by ColumnReferenceNode leaves
|
|
20
|
+
* within a scalar expression tree.
|
|
21
|
+
*/
|
|
22
|
+
function collectReferencedAttributeIds(node, out) {
|
|
23
|
+
if (node instanceof ColumnReferenceNode) {
|
|
24
|
+
out.add(node.attributeId);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
for (const child of node.getChildren()) {
|
|
28
|
+
collectReferencedAttributeIds(child, out);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function ruleProjectionPruning(node, _context) {
|
|
32
|
+
if (!(node instanceof ProjectNode))
|
|
33
|
+
return null;
|
|
34
|
+
const outer = node;
|
|
35
|
+
if (!(outer.source instanceof ProjectNode))
|
|
36
|
+
return null;
|
|
37
|
+
const inner = outer.source;
|
|
38
|
+
// Collect attribute IDs the outer project's expressions reference
|
|
39
|
+
const referencedIds = new Set();
|
|
40
|
+
for (const proj of outer.projections) {
|
|
41
|
+
collectReferencedAttributeIds(proj.node, referencedIds);
|
|
42
|
+
}
|
|
43
|
+
// Determine which inner projections are referenced
|
|
44
|
+
const innerAttrs = inner.getAttributes();
|
|
45
|
+
const keptIndices = [];
|
|
46
|
+
for (let i = 0; i < inner.projections.length; i++) {
|
|
47
|
+
if (referencedIds.has(innerAttrs[i].id)) {
|
|
48
|
+
keptIndices.push(i);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Nothing to prune
|
|
52
|
+
if (keptIndices.length === inner.projections.length)
|
|
53
|
+
return null;
|
|
54
|
+
// Don't prune to zero projections — keep at least one
|
|
55
|
+
if (keptIndices.length === 0)
|
|
56
|
+
return null;
|
|
57
|
+
log('Pruning inner project from %d to %d projections', inner.projections.length, keptIndices.length);
|
|
58
|
+
// Build pruned inner projections preserving attribute IDs
|
|
59
|
+
const keptProjections = keptIndices.map(i => ({
|
|
60
|
+
node: inner.projections[i].node,
|
|
61
|
+
alias: inner.projections[i].alias,
|
|
62
|
+
attributeId: innerAttrs[i].id,
|
|
63
|
+
}));
|
|
64
|
+
const keptAttributes = keptIndices.map(i => innerAttrs[i]);
|
|
65
|
+
const prunedInner = new ProjectNode(inner.scope, inner.source, keptProjections, undefined, keptAttributes, inner.preserveInputColumns);
|
|
66
|
+
// Rebuild outer project with new source
|
|
67
|
+
const outerAttrs = outer.getAttributes();
|
|
68
|
+
const newOuterProjections = outer.projections.map((proj, i) => ({
|
|
69
|
+
node: proj.node,
|
|
70
|
+
alias: proj.alias,
|
|
71
|
+
attributeId: outerAttrs[i].id,
|
|
72
|
+
}));
|
|
73
|
+
return new ProjectNode(outer.scope, prunedInner, newOuterProjections, undefined, outerAttrs, outer.preserveInputColumns);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=rule-projection-pruning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-projection-pruning.js","sourceRoot":"","sources":["../../../../../src/planner/rules/retrieve/rule-projection-pruning.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { StreamAggregateNode } from '../../planner/nodes/stream-aggregate.js';
|
|
2
2
|
import type { Instruction } from '../types.js';
|
|
3
3
|
import type { EmissionContext } from '../emission-context.js';
|
|
4
|
+
import type { PlanNode } from '../../planner/nodes/plan-node.js';
|
|
5
|
+
import { AggValue } from '../../func/registration.js';
|
|
4
6
|
export declare const ctxLog: import("debug").Debugger;
|
|
7
|
+
/** Clone an aggregate initial value so each group gets an independent accumulator. */
|
|
8
|
+
export declare function cloneInitialValue(initialValue: unknown): AggValue;
|
|
9
|
+
/**
|
|
10
|
+
* Find the source relation node that column references should use as their context key.
|
|
11
|
+
* This traverses up the tree to find the original table scan or similar node.
|
|
12
|
+
*/
|
|
13
|
+
export declare function findSourceRelation(node: PlanNode): PlanNode;
|
|
5
14
|
export declare function emitStreamAggregate(plan: StreamAggregateNode, ctx: EmissionContext): Instruction;
|
|
6
15
|
//# sourceMappingURL=aggregate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/aggregate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,KAAK,EAAE,WAAW,EAAkC,MAAM,aAAa,CAAC;AAG/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/aggregate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,KAAK,EAAE,WAAW,EAAkC,MAAM,aAAa,CAAC;AAG/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9D,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,kCAAkC,CAAC;AAWhF,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,eAAO,MAAM,MAAM,0BAAkC,CAAC;AAEtD,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,CAUjE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAgB3D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,eAAe,GAAG,WAAW,CAmhBhG"}
|
|
@@ -12,7 +12,7 @@ import { StatusCode } from '../../common/types.js';
|
|
|
12
12
|
import { buildRowDescriptor } from '../../util/row-descriptor.js';
|
|
13
13
|
export const ctxLog = createLogger('runtime:context');
|
|
14
14
|
/** Clone an aggregate initial value so each group gets an independent accumulator. */
|
|
15
|
-
function cloneInitialValue(initialValue) {
|
|
15
|
+
export function cloneInitialValue(initialValue) {
|
|
16
16
|
if (typeof initialValue === 'function') {
|
|
17
17
|
return initialValue();
|
|
18
18
|
}
|
|
@@ -30,7 +30,7 @@ function cloneInitialValue(initialValue) {
|
|
|
30
30
|
* Find the source relation node that column references should use as their context key.
|
|
31
31
|
* This traverses up the tree to find the original table scan or similar node.
|
|
32
32
|
*/
|
|
33
|
-
function findSourceRelation(node) {
|
|
33
|
+
export function findSourceRelation(node) {
|
|
34
34
|
// Keep going up until we find a values node
|
|
35
35
|
let current = node;
|
|
36
36
|
while (current) {
|