sof-mssql 2.1.0 → 2.3.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/dist/fhirpath/visitor.d.ts +78 -0
- package/dist/fhirpath/visitor.d.ts.map +1 -1
- package/dist/fhirpath/visitor.js +208 -11
- package/dist/fhirpath/visitor.js.map +1 -1
- package/dist/parser.d.ts +1 -1
- package/dist/parser.js +1 -1
- package/dist/queryGenerator/index.d.ts +0 -4
- package/dist/queryGenerator/index.d.ts.map +1 -1
- package/dist/queryGenerator/index.js +1 -9
- package/dist/queryGenerator/index.js.map +1 -1
- package/dist/queryGenerator/treeWalker/aliasGenerator.d.ts +26 -0
- package/dist/queryGenerator/treeWalker/aliasGenerator.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/aliasGenerator.js +31 -0
- package/dist/queryGenerator/treeWalker/aliasGenerator.js.map +1 -0
- package/dist/queryGenerator/treeWalker/classify.d.ts +19 -0
- package/dist/queryGenerator/treeWalker/classify.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/classify.js +36 -0
- package/dist/queryGenerator/treeWalker/classify.js.map +1 -0
- package/dist/queryGenerator/treeWalker/compile.d.ts +29 -0
- package/dist/queryGenerator/treeWalker/compile.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/compile.js +97 -0
- package/dist/queryGenerator/treeWalker/compile.js.map +1 -0
- package/dist/queryGenerator/treeWalker/cteTemplates.d.ts +58 -0
- package/dist/queryGenerator/treeWalker/cteTemplates.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/cteTemplates.js +131 -0
- package/dist/queryGenerator/treeWalker/cteTemplates.js.map +1 -0
- package/dist/queryGenerator/treeWalker/index.d.ts +6 -0
- package/dist/queryGenerator/treeWalker/index.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/index.js +9 -0
- package/dist/queryGenerator/treeWalker/index.js.map +1 -0
- package/dist/queryGenerator/treeWalker/mergeSiblings.d.ts +28 -0
- package/dist/queryGenerator/treeWalker/mergeSiblings.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/mergeSiblings.js +54 -0
- package/dist/queryGenerator/treeWalker/mergeSiblings.js.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/columnsOnly.d.ts +40 -0
- package/dist/queryGenerator/treeWalker/operators/columnsOnly.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/columnsOnly.js +56 -0
- package/dist/queryGenerator/treeWalker/operators/columnsOnly.js.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/forEach.d.ts +47 -0
- package/dist/queryGenerator/treeWalker/operators/forEach.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/forEach.js +150 -0
- package/dist/queryGenerator/treeWalker/operators/forEach.js.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/group.d.ts +35 -0
- package/dist/queryGenerator/treeWalker/operators/group.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/group.js +56 -0
- package/dist/queryGenerator/treeWalker/operators/group.js.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/repeat.d.ts +47 -0
- package/dist/queryGenerator/treeWalker/operators/repeat.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/repeat.js +122 -0
- package/dist/queryGenerator/treeWalker/operators/repeat.js.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/unionAll.d.ts +54 -0
- package/dist/queryGenerator/treeWalker/operators/unionAll.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/unionAll.js +121 -0
- package/dist/queryGenerator/treeWalker/operators/unionAll.js.map +1 -0
- package/dist/queryGenerator/treeWalker/render.d.ts +34 -0
- package/dist/queryGenerator/treeWalker/render.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/render.js +41 -0
- package/dist/queryGenerator/treeWalker/render.js.map +1 -0
- package/dist/queryGenerator/treeWalker/types.d.ts +64 -0
- package/dist/queryGenerator/treeWalker/types.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/types.js +14 -0
- package/dist/queryGenerator/treeWalker/types.js.map +1 -0
- package/dist/queryGenerator/treeWalker/walker.d.ts +36 -0
- package/dist/queryGenerator/treeWalker/walker.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/walker.js +58 -0
- package/dist/queryGenerator/treeWalker/walker.js.map +1 -0
- package/dist/queryGenerator.d.ts +8 -94
- package/dist/queryGenerator.d.ts.map +1 -1
- package/dist/queryGenerator.js +16 -268
- package/dist/queryGenerator.js.map +1 -1
- package/dist/tests/utils/database.d.ts +2 -0
- package/dist/tests/utils/database.d.ts.map +1 -1
- package/dist/tests/utils/database.js +10 -1
- package/dist/tests/utils/database.js.map +1 -1
- package/dist/tests/utils/generator.d.ts +2 -0
- package/dist/tests/utils/generator.d.ts.map +1 -1
- package/dist/tests/utils/generator.js +24 -0
- package/dist/tests/utils/generator.js.map +1 -1
- package/dist/tests/utils/reporter.d.ts +1 -1
- package/dist/tests/utils/reporter.d.ts.map +1 -1
- package/dist/tests/utils/reporter.js +5 -4
- package/dist/tests/utils/reporter.js.map +1 -1
- package/dist/tests/utils/types.d.ts +1 -1
- package/dist/tests/utils/types.js +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +2 -1
- package/dist/queryGenerator/ForEachProcessor.d.ts +0 -127
- package/dist/queryGenerator/ForEachProcessor.d.ts.map +0 -1
- package/dist/queryGenerator/ForEachProcessor.js +0 -351
- package/dist/queryGenerator/ForEachProcessor.js.map +0 -1
- package/dist/queryGenerator/RepeatProcessor.d.ts +0 -177
- package/dist/queryGenerator/RepeatProcessor.d.ts.map +0 -1
- package/dist/queryGenerator/RepeatProcessor.js +0 -336
- package/dist/queryGenerator/RepeatProcessor.js.map +0 -1
- package/dist/queryGenerator/SelectClauseBuilder.d.ts +0 -108
- package/dist/queryGenerator/SelectClauseBuilder.d.ts.map +0 -1
- package/dist/queryGenerator/SelectClauseBuilder.js +0 -346
- package/dist/queryGenerator/SelectClauseBuilder.js.map +0 -1
- package/dist/queryGenerator/SelectCombinationExpander.d.ts +0 -42
- package/dist/queryGenerator/SelectCombinationExpander.d.ts.map +0 -1
- package/dist/queryGenerator/SelectCombinationExpander.js +0 -95
- package/dist/queryGenerator/SelectCombinationExpander.js.map +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walker for UnionAll nodes.
|
|
3
|
+
*
|
|
4
|
+
* Emits a local derived table with one SELECT per branch, joined by
|
|
5
|
+
* `UNION ALL`, wrapped as `CROSS APPLY (...) AS ua_<n>`. CTEs from any
|
|
6
|
+
* branch (e.g. enclosed Repeats) bubble up to the top-level WITH clause.
|
|
7
|
+
*
|
|
8
|
+
* Branches must produce the same column names and types (SoF spec
|
|
9
|
+
* requirement). The walker aligns them positionally — branch[0]'s names
|
|
10
|
+
* become the outer projection.
|
|
11
|
+
*
|
|
12
|
+
* If the same node also has `column[]` or `select[]` alongside `unionAll`,
|
|
13
|
+
* those are emitted as outer siblings (they live in the SELECT list at the
|
|
14
|
+
* same level as the ua_<n> projection, evaluated in the parent scope).
|
|
15
|
+
*/
|
|
16
|
+
import type { ViewDefinitionSelect } from "../../../types.js";
|
|
17
|
+
import type { ColumnExpressionGenerator } from "../../ColumnExpressionGenerator.js";
|
|
18
|
+
import type { Context, Fragment } from "../types.js";
|
|
19
|
+
export interface UnionAllDeps {
|
|
20
|
+
columnGenerator: ColumnExpressionGenerator;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Walker for UnionAll nodes.
|
|
24
|
+
*
|
|
25
|
+
* Walks each branch of `node.unionAll` in the current context and assembles
|
|
26
|
+
* them into a `CROSS APPLY (...) AS ua_<n>` derived table where each branch
|
|
27
|
+
* contributes a `SELECT … FROM (SELECT 1 AS _) AS _seed …` statement joined
|
|
28
|
+
* by `UNION ALL`. Branch columns are aligned positionally to branch[0]'s
|
|
29
|
+
* names, satisfying the SoF spec requirement that all branches produce the
|
|
30
|
+
* same column names and types.
|
|
31
|
+
*
|
|
32
|
+
* CTEs from any branch (e.g. produced by enclosed Repeat nodes) bubble up
|
|
33
|
+
* into the returned Fragment's `ctes` list so they appear in the top-level
|
|
34
|
+
* `WITH` clause.
|
|
35
|
+
*
|
|
36
|
+
* If the same node also carries `column[]` or `select[]` alongside
|
|
37
|
+
* `unionAll`, those are emitted as outer siblings in the enclosing SELECT
|
|
38
|
+
* scope and merged with the union fragment via `mergeSiblings`.
|
|
39
|
+
*
|
|
40
|
+
* @param node - The UnionAll select node; `node.unionAll` must be a non-empty
|
|
41
|
+
* array of branch select nodes.
|
|
42
|
+
* @param ctx - The current walker context, passed unchanged to every branch
|
|
43
|
+
* and to any sibling column/select processing.
|
|
44
|
+
* @param walk - The recursive walk function used to visit each branch and any
|
|
45
|
+
* outer sibling select nodes.
|
|
46
|
+
* @param deps - Dependencies containing the `ColumnExpressionGenerator` used
|
|
47
|
+
* to project any outer sibling `column[]` entries.
|
|
48
|
+
* @returns A Fragment whose `fromExtensions` contains the `CROSS APPLY`
|
|
49
|
+
* derived-table clause, `ctes` aggregates all branch CTEs, and `columns`
|
|
50
|
+
* contains the outer projection (plus any sibling columns).
|
|
51
|
+
* @throws {Error} When `node.unionAll` is empty.
|
|
52
|
+
*/
|
|
53
|
+
export declare function walkUnionAll(node: ViewDefinitionSelect, ctx: Context, walk: (n: ViewDefinitionSelect, c: Context) => Fragment, deps: UnionAllDeps): Fragment;
|
|
54
|
+
//# sourceMappingURL=unionAll.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unionAll.d.ts","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/unionAll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAGpF,OAAO,KAAK,EACV,OAAO,EAEP,QAAQ,EAET,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,yBAAyB,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,OAAO,KAAK,QAAQ,EACvD,IAAI,EAAE,YAAY,GACjB,QAAQ,CAWV"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Walker for UnionAll nodes.
|
|
4
|
+
*
|
|
5
|
+
* Emits a local derived table with one SELECT per branch, joined by
|
|
6
|
+
* `UNION ALL`, wrapped as `CROSS APPLY (...) AS ua_<n>`. CTEs from any
|
|
7
|
+
* branch (e.g. enclosed Repeats) bubble up to the top-level WITH clause.
|
|
8
|
+
*
|
|
9
|
+
* Branches must produce the same column names and types (SoF spec
|
|
10
|
+
* requirement). The walker aligns them positionally — branch[0]'s names
|
|
11
|
+
* become the outer projection.
|
|
12
|
+
*
|
|
13
|
+
* If the same node also has `column[]` or `select[]` alongside `unionAll`,
|
|
14
|
+
* those are emitted as outer siblings (they live in the SELECT list at the
|
|
15
|
+
* same level as the ua_<n> projection, evaluated in the parent scope).
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.walkUnionAll = walkUnionAll;
|
|
19
|
+
const aliasGenerator_js_1 = require("../aliasGenerator.js");
|
|
20
|
+
const mergeSiblings_js_1 = require("../mergeSiblings.js");
|
|
21
|
+
const columnsOnly_js_1 = require("./columnsOnly.js");
|
|
22
|
+
/**
|
|
23
|
+
* Walker for UnionAll nodes.
|
|
24
|
+
*
|
|
25
|
+
* Walks each branch of `node.unionAll` in the current context and assembles
|
|
26
|
+
* them into a `CROSS APPLY (...) AS ua_<n>` derived table where each branch
|
|
27
|
+
* contributes a `SELECT … FROM (SELECT 1 AS _) AS _seed …` statement joined
|
|
28
|
+
* by `UNION ALL`. Branch columns are aligned positionally to branch[0]'s
|
|
29
|
+
* names, satisfying the SoF spec requirement that all branches produce the
|
|
30
|
+
* same column names and types.
|
|
31
|
+
*
|
|
32
|
+
* CTEs from any branch (e.g. produced by enclosed Repeat nodes) bubble up
|
|
33
|
+
* into the returned Fragment's `ctes` list so they appear in the top-level
|
|
34
|
+
* `WITH` clause.
|
|
35
|
+
*
|
|
36
|
+
* If the same node also carries `column[]` or `select[]` alongside
|
|
37
|
+
* `unionAll`, those are emitted as outer siblings in the enclosing SELECT
|
|
38
|
+
* scope and merged with the union fragment via `mergeSiblings`.
|
|
39
|
+
*
|
|
40
|
+
* @param node - The UnionAll select node; `node.unionAll` must be a non-empty
|
|
41
|
+
* array of branch select nodes.
|
|
42
|
+
* @param ctx - The current walker context, passed unchanged to every branch
|
|
43
|
+
* and to any sibling column/select processing.
|
|
44
|
+
* @param walk - The recursive walk function used to visit each branch and any
|
|
45
|
+
* outer sibling select nodes.
|
|
46
|
+
* @param deps - Dependencies containing the `ColumnExpressionGenerator` used
|
|
47
|
+
* to project any outer sibling `column[]` entries.
|
|
48
|
+
* @returns A Fragment whose `fromExtensions` contains the `CROSS APPLY`
|
|
49
|
+
* derived-table clause, `ctes` aggregates all branch CTEs, and `columns`
|
|
50
|
+
* contains the outer projection (plus any sibling columns).
|
|
51
|
+
* @throws {Error} When `node.unionAll` is empty.
|
|
52
|
+
*/
|
|
53
|
+
function walkUnionAll(node, ctx, walk, deps) {
|
|
54
|
+
const branches = node.unionAll ?? [];
|
|
55
|
+
if (branches.length === 0)
|
|
56
|
+
throw new Error("walkUnionAll: empty unionAll");
|
|
57
|
+
const branchFragments = branches.map((b) => walk(b, ctx));
|
|
58
|
+
const uaFragment = buildUnionAllFragment(branchFragments, ctx);
|
|
59
|
+
const outerSiblings = collectOuterSiblings(node, ctx, walk, deps);
|
|
60
|
+
return outerSiblings.length === 0
|
|
61
|
+
? uaFragment
|
|
62
|
+
: (0, mergeSiblings_js_1.mergeSiblings)([...outerSiblings, uaFragment], ctx);
|
|
63
|
+
}
|
|
64
|
+
function buildUnionAllFragment(branchFragments, ctx) {
|
|
65
|
+
const uaAlias = (0, aliasGenerator_js_1.freshAlias)(ctx, "ua");
|
|
66
|
+
const allCtes = branchFragments.flatMap((f) => f.ctes);
|
|
67
|
+
const referenceColumns = branchFragments[0].columns;
|
|
68
|
+
const branchSqls = branchFragments.map((f) => renderBranchSelect(f, referenceColumns));
|
|
69
|
+
const unionDerivedTable = `(\n ${branchSqls.join("\n UNION ALL\n ")}\n) AS ${uaAlias}`;
|
|
70
|
+
const uaColumns = referenceColumns.map((c) => ({
|
|
71
|
+
name: c.name,
|
|
72
|
+
sqlExpr: `${uaAlias}.[${c.name}]`,
|
|
73
|
+
}));
|
|
74
|
+
return {
|
|
75
|
+
ctes: allCtes,
|
|
76
|
+
fromExtensions: `\nCROSS APPLY ${unionDerivedTable}`,
|
|
77
|
+
columns: uaColumns,
|
|
78
|
+
partitionKeys: ctx.partitionKeys,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function collectOuterSiblings(node, ctx, walk, deps) {
|
|
82
|
+
const out = [];
|
|
83
|
+
if (node.column && node.column.length > 0) {
|
|
84
|
+
out.push({
|
|
85
|
+
ctes: [],
|
|
86
|
+
fromExtensions: "",
|
|
87
|
+
columns: (0, columnsOnly_js_1.projectColumns)(node.column, ctx, deps.columnGenerator),
|
|
88
|
+
partitionKeys: ctx.partitionKeys,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (node.select) {
|
|
92
|
+
for (const child of node.select)
|
|
93
|
+
out.push(walk(child, ctx));
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Renders one branch's SELECT inside the unionAll derived table.
|
|
99
|
+
*
|
|
100
|
+
* The seed `(SELECT 1 AS _) AS _seed` ensures the branch always has a
|
|
101
|
+
* FROM clause to attach its CROSS/OUTER APPLY chain to, and keeps the SQL
|
|
102
|
+
* uniform whether the branch has operators or not. No unique suffix is
|
|
103
|
+
* needed because each SELECT in a UNION ALL has its own independent FROM
|
|
104
|
+
* scope — `_seed` in one branch cannot collide with `_seed` in another.
|
|
105
|
+
*
|
|
106
|
+
* Columns are re-aliased to branch[0]'s names so the outer projection by
|
|
107
|
+
* name works for every branch row.
|
|
108
|
+
*/
|
|
109
|
+
function renderBranchSelect(fragment, referenceColumns) {
|
|
110
|
+
const projection = referenceColumns
|
|
111
|
+
.map((ref, i) => {
|
|
112
|
+
const branchCol = fragment.columns[i];
|
|
113
|
+
if (!branchCol) {
|
|
114
|
+
throw new Error(`unionAll branch is missing column at index ${i} (expected '${ref.name}')`);
|
|
115
|
+
}
|
|
116
|
+
return `${branchCol.sqlExpr} AS [${ref.name}]`;
|
|
117
|
+
})
|
|
118
|
+
.join(", ");
|
|
119
|
+
return `SELECT ${projection} FROM (SELECT 1 AS _) AS _seed${fragment.fromExtensions}`;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=unionAll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unionAll.js","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/unionAll.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders a root Fragment into the final T-SQL statement:
|
|
3
|
+
*
|
|
4
|
+
* WITH <ctes> SELECT <cols> FROM <root> <fromExtensions> WHERE <pred>
|
|
5
|
+
*/
|
|
6
|
+
import type { TranspilerContext } from "../../fhirpath/transpiler.js";
|
|
7
|
+
import type { ViewDefinition } from "../../types.js";
|
|
8
|
+
import type { WhereClauseBuilder } from "../WhereClauseBuilder.js";
|
|
9
|
+
import type { Fragment } from "./types.js";
|
|
10
|
+
export interface RenderOptions {
|
|
11
|
+
resourceAlias: string;
|
|
12
|
+
schemaName: string;
|
|
13
|
+
tableName: string;
|
|
14
|
+
testId?: string;
|
|
15
|
+
whereClauseBuilder: WhereClauseBuilder;
|
|
16
|
+
transpilerCtx: TranspilerContext;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Renders a root Fragment into the final T-SQL statement.
|
|
20
|
+
*
|
|
21
|
+
* Assembles the optional `WITH <ctes>` preamble, the `SELECT <cols>` list,
|
|
22
|
+
* the `FROM <table>` clause, any `fromExtensions` (APPLY / JOIN chains), and
|
|
23
|
+
* the optional `WHERE` predicate built by `WhereClauseBuilder`.
|
|
24
|
+
*
|
|
25
|
+
* @param fragment - The root Fragment produced by walking the select tree.
|
|
26
|
+
* @param viewDef - The ViewDefinition supplying the resource type, WHERE
|
|
27
|
+
* predicates, and other metadata needed to construct the WHERE clause.
|
|
28
|
+
* @param options - Render options including table/schema names, resource alias,
|
|
29
|
+
* optional test-isolation ID, the where-clause builder, and the transpiler
|
|
30
|
+
* context.
|
|
31
|
+
* @returns The complete T-SQL query string ready for execution.
|
|
32
|
+
*/
|
|
33
|
+
export declare function renderRoot(fragment: Fragment, viewDef: ViewDefinition, options: RenderOptions): string;
|
|
34
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/render.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,aAAa,EAAE,iBAAiB,CAAC;CAClC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,aAAa,GACrB,MAAM,CA6BR"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Renders a root Fragment into the final T-SQL statement:
|
|
4
|
+
*
|
|
5
|
+
* WITH <ctes> SELECT <cols> FROM <root> <fromExtensions> WHERE <pred>
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.renderRoot = renderRoot;
|
|
9
|
+
/**
|
|
10
|
+
* Renders a root Fragment into the final T-SQL statement.
|
|
11
|
+
*
|
|
12
|
+
* Assembles the optional `WITH <ctes>` preamble, the `SELECT <cols>` list,
|
|
13
|
+
* the `FROM <table>` clause, any `fromExtensions` (APPLY / JOIN chains), and
|
|
14
|
+
* the optional `WHERE` predicate built by `WhereClauseBuilder`.
|
|
15
|
+
*
|
|
16
|
+
* @param fragment - The root Fragment produced by walking the select tree.
|
|
17
|
+
* @param viewDef - The ViewDefinition supplying the resource type, WHERE
|
|
18
|
+
* predicates, and other metadata needed to construct the WHERE clause.
|
|
19
|
+
* @param options - Render options including table/schema names, resource alias,
|
|
20
|
+
* optional test-isolation ID, the where-clause builder, and the transpiler
|
|
21
|
+
* context.
|
|
22
|
+
* @returns The complete T-SQL query string ready for execution.
|
|
23
|
+
*/
|
|
24
|
+
function renderRoot(fragment, viewDef, options) {
|
|
25
|
+
const { resourceAlias, schemaName, tableName } = options;
|
|
26
|
+
const tableRef = `[${schemaName}].[${tableName}]`;
|
|
27
|
+
const cteSection = fragment.ctes.length > 0
|
|
28
|
+
? `WITH\n${fragment.ctes.map((c) => `${c.alias} AS (\n${c.body}\n)`).join(",\n")}\n`
|
|
29
|
+
: "";
|
|
30
|
+
const selectList = fragment.columns
|
|
31
|
+
.map((c) => `${c.sqlExpr} AS [${c.name}]`)
|
|
32
|
+
.join(",\n ");
|
|
33
|
+
const fromClause = `FROM ${tableRef} AS [${resourceAlias}]`;
|
|
34
|
+
const whereClause = options.whereClauseBuilder.buildWhereClause(viewDef.resource, resourceAlias, options.testId, viewDef.where, options.transpilerCtx);
|
|
35
|
+
let body = `SELECT\n ${selectList}\n${fromClause}${fragment.fromExtensions}`;
|
|
36
|
+
if (whereClause !== null) {
|
|
37
|
+
body += `\n${whereClause}`;
|
|
38
|
+
}
|
|
39
|
+
return `${cteSection}${body}`;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/render.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AA+BH,gCAiCC;AAhDD;;;;;;;;;;;;;;GAcG;AACH,SAAgB,UAAU,CACxB,QAAkB,EAClB,OAAuB,EACvB,OAAsB;IAEtB,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACzD,MAAM,QAAQ,GAAG,IAAI,UAAU,MAAM,SAAS,GAAG,CAAC;IAElD,MAAM,UAAU,GACd,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QACtB,CAAC,CAAC,SAAS,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;QACpF,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,IAAI,GAAG,CAAC;SACzC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEjB,MAAM,UAAU,GAAG,QAAQ,QAAQ,QAAQ,aAAa,GAAG,CAAC;IAE5D,MAAM,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC,gBAAgB,CAC7D,OAAO,CAAC,QAAQ,EAChB,aAAa,EACb,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,aAAa,CACtB,CAAC;IAEF,IAAI,IAAI,GAAG,aAAa,UAAU,KAAK,UAAU,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC9E,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,GAAG,UAAU,GAAG,IAAI,EAAE,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for the tree-walker query generator.
|
|
3
|
+
*
|
|
4
|
+
* Each select-tree node produces a Fragment; sibling fragments are merged
|
|
5
|
+
* via partition-key joins. Context threads through descent, accumulating
|
|
6
|
+
* the current JSON source, partition keys, and APPLY chain.
|
|
7
|
+
*/
|
|
8
|
+
import type { TranspilerContext } from "../../fhirpath/transpiler.js";
|
|
9
|
+
export declare const SQL_INT = "INT";
|
|
10
|
+
export declare const SQL_NVARCHAR_4000 = "NVARCHAR(4000)";
|
|
11
|
+
export declare const SQL_NVARCHAR_MAX = "NVARCHAR(MAX)";
|
|
12
|
+
export type NodeKind = "ColumnsOnly" | "Group" | "ForEach" | "ForEachOrNull" | "Repeat" | "UnionAll";
|
|
13
|
+
export interface PartitionKey {
|
|
14
|
+
/** Logical name, e.g. "id", "fe_0_key", "repeat_2_path". */
|
|
15
|
+
name: string;
|
|
16
|
+
/** SQL expression that yields it in the *defining* scope. */
|
|
17
|
+
sqlExpr: string;
|
|
18
|
+
/** Type used when projecting it through a CTE column list. */
|
|
19
|
+
sqlType: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ProjectedColumn {
|
|
22
|
+
/** Bracketed identifier as it appears in the final SELECT list. */
|
|
23
|
+
name: string;
|
|
24
|
+
sqlExpr: string;
|
|
25
|
+
}
|
|
26
|
+
export interface CteDefinition {
|
|
27
|
+
alias: string;
|
|
28
|
+
/** Full SQL body without the "alias AS (...)" wrapper. */
|
|
29
|
+
body: string;
|
|
30
|
+
}
|
|
31
|
+
export interface Context {
|
|
32
|
+
resourceAlias: string;
|
|
33
|
+
/** Current JSON source expression, e.g. "r.json", "forEach_0.value". */
|
|
34
|
+
source: string;
|
|
35
|
+
/** Ordered, monotonically appended as the walker descends. */
|
|
36
|
+
partitionKeys: PartitionKey[];
|
|
37
|
+
/**
|
|
38
|
+
* CROSS/OUTER APPLY chain accumulated above this point, needed so any
|
|
39
|
+
* enclosed Repeat CTE anchor can reach `ctx.source`. Each element starts
|
|
40
|
+
* with "\n".
|
|
41
|
+
*/
|
|
42
|
+
ancestorApplies: string;
|
|
43
|
+
/** Shared mutable counter for unique CTE/alias names across the whole compile. */
|
|
44
|
+
cteCounter: {
|
|
45
|
+
value: number;
|
|
46
|
+
};
|
|
47
|
+
/** Pass-through context for the FHIRPath transpiler. */
|
|
48
|
+
transpilerCtx: TranspilerContext;
|
|
49
|
+
}
|
|
50
|
+
export interface Fragment {
|
|
51
|
+
ctes: CteDefinition[];
|
|
52
|
+
/**
|
|
53
|
+
* Ordered sequence of FROM-clause extensions: a mix of CROSS/OUTER APPLY
|
|
54
|
+
* and INNER/LEFT/FULL OUTER JOIN clauses, each prefixed by "\n". Order is
|
|
55
|
+
* preserved so that aliases are always introduced before they are
|
|
56
|
+
* referenced (e.g. an INNER JOIN to a Repeat CTE precedes any CROSS APPLY
|
|
57
|
+
* that reads from the CTE's `item_json`).
|
|
58
|
+
*/
|
|
59
|
+
fromExtensions: string;
|
|
60
|
+
columns: ProjectedColumn[];
|
|
61
|
+
/** Keys exposed by this fragment for use by sibling joins. */
|
|
62
|
+
partitionKeys: PartitionKey[];
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,eAAO,MAAM,OAAO,QAAQ,CAAC;AAC7B,eAAO,MAAM,iBAAiB,mBAAmB,CAAC;AAClD,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,OAAO,GACP,SAAS,GACT,eAAe,GACf,QAAQ,GACR,UAAU,CAAC;AAEf,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,kFAAkF;IAClF,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,wDAAwD;IACxD,aAAa,EAAE,iBAAiB,CAAC;CAClC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,8DAA8D;IAC9D,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Core types for the tree-walker query generator.
|
|
4
|
+
*
|
|
5
|
+
* Each select-tree node produces a Fragment; sibling fragments are merged
|
|
6
|
+
* via partition-key joins. Context threads through descent, accumulating
|
|
7
|
+
* the current JSON source, partition keys, and APPLY chain.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SQL_NVARCHAR_MAX = exports.SQL_NVARCHAR_4000 = exports.SQL_INT = void 0;
|
|
11
|
+
exports.SQL_INT = "INT";
|
|
12
|
+
exports.SQL_NVARCHAR_4000 = "NVARCHAR(4000)";
|
|
13
|
+
exports.SQL_NVARCHAR_MAX = "NVARCHAR(MAX)";
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAIU,QAAA,OAAO,GAAG,KAAK,CAAC;AAChB,QAAA,iBAAiB,GAAG,gBAAgB,CAAC;AACrC,QAAA,gBAAgB,GAAG,eAAe,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursive dispatch — visits a select-tree node and produces a Fragment.
|
|
3
|
+
*
|
|
4
|
+
* Each node kind has its own walker; this module just dispatches via
|
|
5
|
+
* classifyNode. Operators not yet implemented throw a clear error.
|
|
6
|
+
*/
|
|
7
|
+
import type { ViewDefinitionSelect } from "../../types.js";
|
|
8
|
+
import type { ColumnExpressionGenerator } from "../ColumnExpressionGenerator.js";
|
|
9
|
+
import type { PathParser } from "../PathParser.js";
|
|
10
|
+
import type { Context, Fragment } from "./types.js";
|
|
11
|
+
export interface WalkerDeps {
|
|
12
|
+
columnGenerator: ColumnExpressionGenerator;
|
|
13
|
+
pathParser: PathParser;
|
|
14
|
+
schemaName: string;
|
|
15
|
+
tableName: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates the recursive walk function used to traverse the select tree.
|
|
19
|
+
*
|
|
20
|
+
* The returned `walk` function classifies each `ViewDefinitionSelect` node via
|
|
21
|
+
* `classifyNode` and dispatches to the appropriate operator walker
|
|
22
|
+
* (`walkColumnsOnly`, `walkGroup`, `walkForEach`, `walkRepeat`, or
|
|
23
|
+
* `walkUnionAll`). The same `walk` reference is threaded into every operator
|
|
24
|
+
* so they can recurse into child nodes without circular imports.
|
|
25
|
+
*
|
|
26
|
+
* @param deps - External service dependencies shared across all operator
|
|
27
|
+
* walkers: a `ColumnExpressionGenerator`, a `PathParser`, and the target
|
|
28
|
+
* schema/table names used by the Repeat CTE builder.
|
|
29
|
+
* @returns A `walk` function that accepts a node and a `Context` and returns
|
|
30
|
+
* the corresponding `Fragment`.
|
|
31
|
+
* @throws {Error} When a node's kind is not handled (should not occur given
|
|
32
|
+
* the exhaustive `classifyNode` discriminants, but TypeScript exhaustiveness
|
|
33
|
+
* checking requires the switch to be complete).
|
|
34
|
+
*/
|
|
35
|
+
export declare function makeWalker(deps: WalkerDeps): (node: ViewDefinitionSelect, ctx: Context) => Fragment;
|
|
36
|
+
//# sourceMappingURL=walker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walker.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/walker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAOnD,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,yBAAyB,CAAC;IAC3C,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,GACf,CAAC,IAAI,EAAE,oBAAoB,EAAE,GAAG,EAAE,OAAO,KAAK,QAAQ,CAuBxD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Recursive dispatch — visits a select-tree node and produces a Fragment.
|
|
4
|
+
*
|
|
5
|
+
* Each node kind has its own walker; this module just dispatches via
|
|
6
|
+
* classifyNode. Operators not yet implemented throw a clear error.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.makeWalker = makeWalker;
|
|
10
|
+
const classify_js_1 = require("./classify.js");
|
|
11
|
+
const columnsOnly_js_1 = require("./operators/columnsOnly.js");
|
|
12
|
+
const forEach_js_1 = require("./operators/forEach.js");
|
|
13
|
+
const group_js_1 = require("./operators/group.js");
|
|
14
|
+
const repeat_js_1 = require("./operators/repeat.js");
|
|
15
|
+
const unionAll_js_1 = require("./operators/unionAll.js");
|
|
16
|
+
/**
|
|
17
|
+
* Creates the recursive walk function used to traverse the select tree.
|
|
18
|
+
*
|
|
19
|
+
* The returned `walk` function classifies each `ViewDefinitionSelect` node via
|
|
20
|
+
* `classifyNode` and dispatches to the appropriate operator walker
|
|
21
|
+
* (`walkColumnsOnly`, `walkGroup`, `walkForEach`, `walkRepeat`, or
|
|
22
|
+
* `walkUnionAll`). The same `walk` reference is threaded into every operator
|
|
23
|
+
* so they can recurse into child nodes without circular imports.
|
|
24
|
+
*
|
|
25
|
+
* @param deps - External service dependencies shared across all operator
|
|
26
|
+
* walkers: a `ColumnExpressionGenerator`, a `PathParser`, and the target
|
|
27
|
+
* schema/table names used by the Repeat CTE builder.
|
|
28
|
+
* @returns A `walk` function that accepts a node and a `Context` and returns
|
|
29
|
+
* the corresponding `Fragment`.
|
|
30
|
+
* @throws {Error} When a node's kind is not handled (should not occur given
|
|
31
|
+
* the exhaustive `classifyNode` discriminants, but TypeScript exhaustiveness
|
|
32
|
+
* checking requires the switch to be complete).
|
|
33
|
+
*/
|
|
34
|
+
function makeWalker(deps) {
|
|
35
|
+
function walk(node, ctx) {
|
|
36
|
+
const kind = (0, classify_js_1.classifyNode)(node);
|
|
37
|
+
switch (kind) {
|
|
38
|
+
case "ColumnsOnly":
|
|
39
|
+
return (0, columnsOnly_js_1.walkColumnsOnly)(node, ctx, deps.columnGenerator);
|
|
40
|
+
case "Group":
|
|
41
|
+
return (0, group_js_1.walkGroup)(node, ctx, walk, deps.columnGenerator);
|
|
42
|
+
case "ForEach":
|
|
43
|
+
case "ForEachOrNull":
|
|
44
|
+
return (0, forEach_js_1.walkForEach)(node, ctx, walk, { pathParser: deps.pathParser });
|
|
45
|
+
case "Repeat":
|
|
46
|
+
return (0, repeat_js_1.walkRepeat)(node, ctx, walk, {
|
|
47
|
+
schemaName: deps.schemaName,
|
|
48
|
+
tableName: deps.tableName,
|
|
49
|
+
});
|
|
50
|
+
case "UnionAll":
|
|
51
|
+
return (0, unionAll_js_1.walkUnionAll)(node, ctx, walk, {
|
|
52
|
+
columnGenerator: deps.columnGenerator,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return walk;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walker.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/walker.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAsCH,gCAyBC;AA1DD,+CAA6C;AAC7C,+DAA6D;AAC7D,uDAAqD;AACrD,mDAAiD;AACjD,qDAAmD;AACnD,yDAAuD;AAUvD;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,UAAU,CACxB,IAAgB;IAEhB,SAAS,IAAI,CAAC,IAA0B,EAAE,GAAY;QACpD,MAAM,IAAI,GAAG,IAAA,0BAAY,EAAC,IAAI,CAAC,CAAC;QAChC,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,aAAa;gBAChB,OAAO,IAAA,gCAAe,EAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YAC1D,KAAK,OAAO;gBACV,OAAO,IAAA,oBAAS,EAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YAC1D,KAAK,SAAS,CAAC;YACf,KAAK,eAAe;gBAClB,OAAO,IAAA,wBAAW,EAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YACvE,KAAK,QAAQ;gBACX,OAAO,IAAA,sBAAU,EAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE;oBACjC,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;iBAC1B,CAAC,CAAC;YACL,KAAK,UAAU;gBACb,OAAO,IAAA,0BAAY,EAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE;oBACnC,eAAe,EAAE,IAAI,CAAC,eAAe;iBACtC,CAAC,CAAC;QACP,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/queryGenerator.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* T-SQL query generator for ViewDefinition structures.
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Public façade over the tree-walker query compiler. Builds the base
|
|
5
|
+
* transpiler context (resource alias, constants, optional test id) and
|
|
6
|
+
* delegates SQL generation to `compileViewDefinition`.
|
|
4
7
|
*/
|
|
5
8
|
import { TranspilationResult, ViewDefinition } from "./types.js";
|
|
6
9
|
export interface QueryGeneratorOptions {
|
|
@@ -10,112 +13,23 @@ export interface QueryGeneratorOptions {
|
|
|
10
13
|
resourceJsonColumn?: string;
|
|
11
14
|
}
|
|
12
15
|
/**
|
|
13
|
-
*
|
|
16
|
+
* Compiles a SQL on FHIR `ViewDefinition` to a T-SQL query.
|
|
14
17
|
*/
|
|
15
18
|
export declare class QueryGenerator {
|
|
16
19
|
private readonly options;
|
|
17
|
-
private readonly pathParser;
|
|
18
|
-
private readonly combinationExpander;
|
|
19
|
-
private readonly forEachProcessor;
|
|
20
|
-
private readonly repeatProcessor;
|
|
21
|
-
private readonly selectClauseBuilder;
|
|
22
|
-
private readonly whereClauseBuilder;
|
|
23
|
-
private readonly columnGenerator;
|
|
24
20
|
constructor(options?: QueryGeneratorOptions);
|
|
25
21
|
/**
|
|
26
22
|
* Generate a T-SQL query from a ViewDefinition.
|
|
27
23
|
*/
|
|
28
24
|
generateQuery(viewDef: ViewDefinition, testId?: string): TranspilationResult;
|
|
29
25
|
/**
|
|
30
|
-
*
|
|
31
|
-
*/
|
|
32
|
-
private generateAllSelectStatements;
|
|
33
|
-
/**
|
|
34
|
-
* Generate a complete SQL statement for a specific combination.
|
|
35
|
-
*
|
|
36
|
-
* Routes to the appropriate statement generator based on the directives
|
|
37
|
-
* present in the combination:
|
|
38
|
-
* - Repeat statements use recursive CTEs.
|
|
39
|
-
* - ForEach statements use CROSS APPLY.
|
|
40
|
-
* - Simple statements have neither.
|
|
41
|
-
*
|
|
42
|
-
* @param combination - The select combination to generate.
|
|
43
|
-
* @param viewDef - The ViewDefinition being processed.
|
|
44
|
-
* @param context - The transpiler context.
|
|
45
|
-
* @param isMultiUnion - If true, CTEs are returned separately for consolidation.
|
|
46
|
-
* @param cteCounter - Shared counter for unique CTE aliases across combinations.
|
|
47
|
-
* @returns The statement and any CTE definitions (empty if not repeat or single statement).
|
|
48
|
-
*/
|
|
49
|
-
private generateStatementForCombination;
|
|
50
|
-
/**
|
|
51
|
-
* Generate a simple SELECT statement without forEach.
|
|
52
|
-
*/
|
|
53
|
-
private generateSimpleStatement;
|
|
54
|
-
/**
|
|
55
|
-
* Generate a SELECT statement with forEach using CROSS APPLY.
|
|
56
|
-
*/
|
|
57
|
-
private generateForEachStatement;
|
|
58
|
-
/**
|
|
59
|
-
* Generate a SELECT statement with repeat using recursive CTEs.
|
|
60
|
-
*
|
|
61
|
-
* The repeat directive generates a recursive CTE that traverses a tree
|
|
62
|
-
* structure by following one or more paths at each level. The CTE is then
|
|
63
|
-
* joined to the main query using INNER JOIN.
|
|
64
|
-
*
|
|
65
|
-
* If the combination also contains forEach, the forEach is processed after
|
|
66
|
-
* the repeat CTE, using the repeat context as its source.
|
|
67
|
-
*
|
|
68
|
-
* @param combination - The select combination being processed.
|
|
69
|
-
* @param viewDef - The ViewDefinition.
|
|
70
|
-
* @param context - The transpiler context.
|
|
71
|
-
* @param isMultiUnion - If true, return CTE definitions separately for consolidation.
|
|
72
|
-
* @param cteCounter - Shared counter for unique CTE aliases across combinations.
|
|
73
|
-
* @returns Statement and CTE definitions.
|
|
74
|
-
*/
|
|
75
|
-
private generateRepeatStatement;
|
|
76
|
-
/**
|
|
77
|
-
* Build select clause and forEach apply clauses for repeat statements.
|
|
78
|
-
*/
|
|
79
|
-
private buildRepeatSelectAndForEach;
|
|
80
|
-
/**
|
|
81
|
-
* Assemble the final repeat statement from its components.
|
|
82
|
-
*/
|
|
83
|
-
private assembleRepeatStatement;
|
|
84
|
-
/**
|
|
85
|
-
* Update forEach source expressions to use repeat CTE instead of resource JSON.
|
|
86
|
-
*
|
|
87
|
-
* When forEach is nested inside repeat, the forEach should iterate over
|
|
88
|
-
* arrays within the repeat context (e.g., repeat_0.item_json) rather than
|
|
89
|
-
* the root resource JSON.
|
|
90
|
-
*/
|
|
91
|
-
private updateForEachSourcesForRepeat;
|
|
92
|
-
/**
|
|
93
|
-
* Find the repeat select that contains a given forEach select.
|
|
94
|
-
*/
|
|
95
|
-
private findContainingRepeat;
|
|
96
|
-
/**
|
|
97
|
-
* Check if a forEach select is nested within a repeat select.
|
|
98
|
-
*/
|
|
99
|
-
private isForEachNestedInRepeat;
|
|
100
|
-
/**
|
|
101
|
-
* Recursively check if a select is nested within a list of selects.
|
|
102
|
-
*/
|
|
103
|
-
private isSelectNestedIn;
|
|
104
|
-
/**
|
|
105
|
-
* Generate the FROM clause.
|
|
106
|
-
*/
|
|
107
|
-
private generateFromClause;
|
|
108
|
-
/**
|
|
109
|
-
* Create the base transpiler context.
|
|
26
|
+
* Create the base transpiler context with resource alias and constants.
|
|
110
27
|
*/
|
|
111
28
|
private createBaseContext;
|
|
112
29
|
/**
|
|
113
|
-
* Extract the value from a ViewDefinitionConstant.
|
|
30
|
+
* Extract the value from a ViewDefinitionConstant. Throws if zero or more
|
|
31
|
+
* than one `value[x]` element is set.
|
|
114
32
|
*/
|
|
115
33
|
private getConstantValue;
|
|
116
|
-
/**
|
|
117
|
-
* Collect all column definitions from select elements.
|
|
118
|
-
*/
|
|
119
|
-
private collectAllColumns;
|
|
120
34
|
}
|
|
121
35
|
//# sourceMappingURL=queryGenerator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryGenerator.d.ts","sourceRoot":"","sources":["../src/queryGenerator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"queryGenerator.d.ts","sourceRoot":"","sources":["../src/queryGenerator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EACL,mBAAmB,EACnB,cAAc,EAEf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;gBAE9C,OAAO,GAAE,qBAA0B;IAU/C;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,mBAAmB;IAc5E;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;CA6CzB"}
|