sof-mssql 2.1.0 → 2.2.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/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 +98 -0
- package/dist/queryGenerator/treeWalker/compile.js.map +1 -0
- package/dist/queryGenerator/treeWalker/cteTemplates.d.ts +50 -0
- package/dist/queryGenerator/treeWalker/cteTemplates.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/cteTemplates.js +95 -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 +45 -0
- package/dist/queryGenerator/treeWalker/operators/forEach.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/forEach.js +144 -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 +45 -0
- package/dist/queryGenerator/treeWalker/operators/repeat.d.ts.map +1 -0
- package/dist/queryGenerator/treeWalker/operators/repeat.js +110 -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 +66 -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/package.json +1 -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
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
* Query generator components for building T-SQL from ViewDefinitions.
|
|
3
3
|
*/
|
|
4
4
|
export { PathParser } from "./PathParser.js";
|
|
5
|
-
export { SelectCombination, SelectCombinationExpander, } from "./SelectCombinationExpander.js";
|
|
6
|
-
export { ForEachProcessor } from "./ForEachProcessor.js";
|
|
7
|
-
export { RepeatProcessor, RepeatContext } from "./RepeatProcessor.js";
|
|
8
|
-
export { SelectClauseBuilder } from "./SelectClauseBuilder.js";
|
|
9
5
|
export { WhereClauseBuilder } from "./WhereClauseBuilder.js";
|
|
10
6
|
export { ColumnExpressionGenerator } from "./ColumnExpressionGenerator.js";
|
|
11
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/queryGenerator/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/queryGenerator/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -3,17 +3,9 @@
|
|
|
3
3
|
* Query generator components for building T-SQL from ViewDefinitions.
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ColumnExpressionGenerator = exports.WhereClauseBuilder = exports.
|
|
6
|
+
exports.ColumnExpressionGenerator = exports.WhereClauseBuilder = exports.PathParser = void 0;
|
|
7
7
|
var PathParser_js_1 = require("./PathParser.js");
|
|
8
8
|
Object.defineProperty(exports, "PathParser", { enumerable: true, get: function () { return PathParser_js_1.PathParser; } });
|
|
9
|
-
var SelectCombinationExpander_js_1 = require("./SelectCombinationExpander.js");
|
|
10
|
-
Object.defineProperty(exports, "SelectCombinationExpander", { enumerable: true, get: function () { return SelectCombinationExpander_js_1.SelectCombinationExpander; } });
|
|
11
|
-
var ForEachProcessor_js_1 = require("./ForEachProcessor.js");
|
|
12
|
-
Object.defineProperty(exports, "ForEachProcessor", { enumerable: true, get: function () { return ForEachProcessor_js_1.ForEachProcessor; } });
|
|
13
|
-
var RepeatProcessor_js_1 = require("./RepeatProcessor.js");
|
|
14
|
-
Object.defineProperty(exports, "RepeatProcessor", { enumerable: true, get: function () { return RepeatProcessor_js_1.RepeatProcessor; } });
|
|
15
|
-
var SelectClauseBuilder_js_1 = require("./SelectClauseBuilder.js");
|
|
16
|
-
Object.defineProperty(exports, "SelectClauseBuilder", { enumerable: true, get: function () { return SelectClauseBuilder_js_1.SelectClauseBuilder; } });
|
|
17
9
|
var WhereClauseBuilder_js_1 = require("./WhereClauseBuilder.js");
|
|
18
10
|
Object.defineProperty(exports, "WhereClauseBuilder", { enumerable: true, get: function () { return WhereClauseBuilder_js_1.WhereClauseBuilder; } });
|
|
19
11
|
var ColumnExpressionGenerator_js_1 = require("./ColumnExpressionGenerator.js");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/queryGenerator/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,iDAA6C;AAApC,2GAAA,UAAU,OAAA;AACnB
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/queryGenerator/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,iDAA6C;AAApC,2GAAA,UAAU,OAAA;AACnB,iEAA6D;AAApD,2HAAA,kBAAkB,OAAA;AAC3B,+EAA2E;AAAlE,yIAAA,yBAAyB,OAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sole producer of all SQL aliases generated by the tree walker.
|
|
3
|
+
*
|
|
4
|
+
* Routing every alias through here guarantees uniqueness across the whole
|
|
5
|
+
* compile (the counter lives on Context.cteCounter and is shared by every
|
|
6
|
+
* recursive walk call).
|
|
7
|
+
*/
|
|
8
|
+
import type { Context } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Generates a globally unique SQL alias for the current compilation.
|
|
11
|
+
*
|
|
12
|
+
* Increments the shared `ctx.cteCounter` (a mutable reference threaded
|
|
13
|
+
* through every recursive walk call) and returns `"<prefix>_<n>"`. Because
|
|
14
|
+
* the counter is shared, aliases produced across different branches and depths
|
|
15
|
+
* of the tree are guaranteed to be distinct within a single
|
|
16
|
+
* `compileViewDefinition` call.
|
|
17
|
+
*
|
|
18
|
+
* @param ctx - The current walker context; its `cteCounter.value` is
|
|
19
|
+
* incremented as a side effect.
|
|
20
|
+
* @param prefix - A human-readable prefix that identifies the operator
|
|
21
|
+
* creating the alias (e.g. `"forEach"`, `"repeat"`, `"ua"`).
|
|
22
|
+
* @returns A string of the form `"<prefix>_<n>"` that is unique within the
|
|
23
|
+
* current compilation.
|
|
24
|
+
*/
|
|
25
|
+
export declare function freshAlias(ctx: Context, prefix: string): string;
|
|
26
|
+
//# sourceMappingURL=aliasGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aliasGenerator.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/aliasGenerator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAG/D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Sole producer of all SQL aliases generated by the tree walker.
|
|
4
|
+
*
|
|
5
|
+
* Routing every alias through here guarantees uniqueness across the whole
|
|
6
|
+
* compile (the counter lives on Context.cteCounter and is shared by every
|
|
7
|
+
* recursive walk call).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.freshAlias = freshAlias;
|
|
11
|
+
/**
|
|
12
|
+
* Generates a globally unique SQL alias for the current compilation.
|
|
13
|
+
*
|
|
14
|
+
* Increments the shared `ctx.cteCounter` (a mutable reference threaded
|
|
15
|
+
* through every recursive walk call) and returns `"<prefix>_<n>"`. Because
|
|
16
|
+
* the counter is shared, aliases produced across different branches and depths
|
|
17
|
+
* of the tree are guaranteed to be distinct within a single
|
|
18
|
+
* `compileViewDefinition` call.
|
|
19
|
+
*
|
|
20
|
+
* @param ctx - The current walker context; its `cteCounter.value` is
|
|
21
|
+
* incremented as a side effect.
|
|
22
|
+
* @param prefix - A human-readable prefix that identifies the operator
|
|
23
|
+
* creating the alias (e.g. `"forEach"`, `"repeat"`, `"ua"`).
|
|
24
|
+
* @returns A string of the form `"<prefix>_<n>"` that is unique within the
|
|
25
|
+
* current compilation.
|
|
26
|
+
*/
|
|
27
|
+
function freshAlias(ctx, prefix) {
|
|
28
|
+
const id = ctx.cteCounter.value++;
|
|
29
|
+
return `${prefix}_${id}`;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=aliasGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aliasGenerator.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/aliasGenerator.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAoBH,gCAGC;AAnBD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,UAAU,CAAC,GAAY,EAAE,MAAc;IACrD,MAAM,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAClC,OAAO,GAAG,MAAM,IAAI,EAAE,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classifies a ViewDefinition select node into one of the walker's NodeKinds.
|
|
3
|
+
*/
|
|
4
|
+
import type { ViewDefinitionSelect } from "../../types.js";
|
|
5
|
+
import type { NodeKind } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Classifies a ViewDefinition select node into one of the walker's NodeKinds.
|
|
8
|
+
*
|
|
9
|
+
* Operators are tested outer-to-inner: `forEachOrNull` first, then `forEach`,
|
|
10
|
+
* `repeat`, `unionAll`, `select` (Group), and finally `ColumnsOnly` as the
|
|
11
|
+
* base case. A node that carries multiple operator fields is classified as the
|
|
12
|
+
* outermost one; inner operators surface when the walker descends.
|
|
13
|
+
*
|
|
14
|
+
* @param node - The select node to classify.
|
|
15
|
+
* @returns The `NodeKind` string discriminant that determines which operator
|
|
16
|
+
* walker handles this node.
|
|
17
|
+
*/
|
|
18
|
+
export declare function classifyNode(node: ViewDefinitionSelect): NodeKind;
|
|
19
|
+
//# sourceMappingURL=classify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/classify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,oBAAoB,GAAG,QAAQ,CAWjE"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Classifies a ViewDefinition select node into one of the walker's NodeKinds.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.classifyNode = classifyNode;
|
|
7
|
+
/**
|
|
8
|
+
* Classifies a ViewDefinition select node into one of the walker's NodeKinds.
|
|
9
|
+
*
|
|
10
|
+
* Operators are tested outer-to-inner: `forEachOrNull` first, then `forEach`,
|
|
11
|
+
* `repeat`, `unionAll`, `select` (Group), and finally `ColumnsOnly` as the
|
|
12
|
+
* base case. A node that carries multiple operator fields is classified as the
|
|
13
|
+
* outermost one; inner operators surface when the walker descends.
|
|
14
|
+
*
|
|
15
|
+
* @param node - The select node to classify.
|
|
16
|
+
* @returns The `NodeKind` string discriminant that determines which operator
|
|
17
|
+
* walker handles this node.
|
|
18
|
+
*/
|
|
19
|
+
function classifyNode(node) {
|
|
20
|
+
// Operators are ordered outer-to-inner. A node with multiple operators
|
|
21
|
+
// (e.g. `{forEach, unionAll}`) is processed as the outer one; the inner
|
|
22
|
+
// operator surfaces when the walker descends into the node's
|
|
23
|
+
// `{column, select, unionAll}` sub-node.
|
|
24
|
+
if (node.forEachOrNull !== undefined)
|
|
25
|
+
return "ForEachOrNull";
|
|
26
|
+
if (node.forEach !== undefined)
|
|
27
|
+
return "ForEach";
|
|
28
|
+
if (node.repeat && node.repeat.length > 0)
|
|
29
|
+
return "Repeat";
|
|
30
|
+
if (node.unionAll && node.unionAll.length > 0)
|
|
31
|
+
return "UnionAll";
|
|
32
|
+
if (node.select && node.select.length > 0)
|
|
33
|
+
return "Group";
|
|
34
|
+
return "ColumnsOnly";
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=classify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/classify.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAiBH,oCAWC;AAvBD;;;;;;;;;;;GAWG;AACH,SAAgB,YAAY,CAAC,IAA0B;IACrD,uEAAuE;IACvE,wEAAwE;IACxE,6DAA6D;IAC7D,yCAAyC;IACzC,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAC7D,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACjD,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC3D,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IACjE,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1D,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public entry point for the tree-walker query generator.
|
|
3
|
+
*
|
|
4
|
+
* Wraps viewDef.select as a synthetic Group node, walks it, and renders
|
|
5
|
+
* the resulting Fragment as a single T-SQL statement.
|
|
6
|
+
*/
|
|
7
|
+
import { TranspilerContext } from "../../fhirpath/transpiler.js";
|
|
8
|
+
import type { TranspilationResult, ViewDefinition } from "../../types.js";
|
|
9
|
+
export interface CompileOptions {
|
|
10
|
+
tableName: string;
|
|
11
|
+
schemaName: string;
|
|
12
|
+
testId?: string;
|
|
13
|
+
transpilerCtx: TranspilerContext;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compiles a ViewDefinition into a T-SQL query string and column metadata.
|
|
17
|
+
*
|
|
18
|
+
* Wraps `viewDef.select` as a synthetic root Group node, walks the entire
|
|
19
|
+
* select tree to produce a Fragment, then renders that Fragment into a
|
|
20
|
+
* complete T-SQL statement (WITH … SELECT … FROM … WHERE).
|
|
21
|
+
*
|
|
22
|
+
* @param viewDef - The parsed ViewDefinition whose `select` tree is compiled.
|
|
23
|
+
* @param options - Compilation options including table/schema names, an
|
|
24
|
+
* optional test-isolation ID, and the FHIRPath transpiler context.
|
|
25
|
+
* @returns A `TranspilationResult` containing the generated SQL string and
|
|
26
|
+
* an ordered array of column metadata matching the view's output shape.
|
|
27
|
+
*/
|
|
28
|
+
export declare function compileViewDefinition(viewDef: ViewDefinition, options: CompileOptions): TranspilationResult;
|
|
29
|
+
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/compile.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAc,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EAEV,mBAAmB,EACnB,cAAc,EAEf,MAAM,gBAAgB,CAAC;AAYxB,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,iBAAiB,CAAC;CAClC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,cAAc,GACtB,mBAAmB,CAuBrB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Public entry point for the tree-walker query generator.
|
|
4
|
+
*
|
|
5
|
+
* Wraps viewDef.select as a synthetic Group node, walks it, and renders
|
|
6
|
+
* the resulting Fragment as a single T-SQL statement.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.compileViewDefinition = compileViewDefinition;
|
|
10
|
+
const transpiler_js_1 = require("../../fhirpath/transpiler.js");
|
|
11
|
+
const ColumnExpressionGenerator_js_1 = require("../ColumnExpressionGenerator.js");
|
|
12
|
+
const PathParser_js_1 = require("../PathParser.js");
|
|
13
|
+
const WhereClauseBuilder_js_1 = require("../WhereClauseBuilder.js");
|
|
14
|
+
const render_js_1 = require("./render.js");
|
|
15
|
+
const types_js_1 = require("./types.js");
|
|
16
|
+
const walker_js_1 = require("./walker.js");
|
|
17
|
+
const columnGenerator = new ColumnExpressionGenerator_js_1.ColumnExpressionGenerator();
|
|
18
|
+
const pathParser = new PathParser_js_1.PathParser();
|
|
19
|
+
const whereClauseBuilder = new WhereClauseBuilder_js_1.WhereClauseBuilder();
|
|
20
|
+
/**
|
|
21
|
+
* Compiles a ViewDefinition into a T-SQL query string and column metadata.
|
|
22
|
+
*
|
|
23
|
+
* Wraps `viewDef.select` as a synthetic root Group node, walks the entire
|
|
24
|
+
* select tree to produce a Fragment, then renders that Fragment into a
|
|
25
|
+
* complete T-SQL statement (WITH … SELECT … FROM … WHERE).
|
|
26
|
+
*
|
|
27
|
+
* @param viewDef - The parsed ViewDefinition whose `select` tree is compiled.
|
|
28
|
+
* @param options - Compilation options including table/schema names, an
|
|
29
|
+
* optional test-isolation ID, and the FHIRPath transpiler context.
|
|
30
|
+
* @returns A `TranspilationResult` containing the generated SQL string and
|
|
31
|
+
* an ordered array of column metadata matching the view's output shape.
|
|
32
|
+
*/
|
|
33
|
+
function compileViewDefinition(viewDef, options) {
|
|
34
|
+
const resourceAlias = options.transpilerCtx.resourceAlias;
|
|
35
|
+
const ctx = buildRootContext(resourceAlias, options.transpilerCtx);
|
|
36
|
+
const rootNode = { select: viewDef.select };
|
|
37
|
+
const walk = (0, walker_js_1.makeWalker)({
|
|
38
|
+
columnGenerator,
|
|
39
|
+
pathParser,
|
|
40
|
+
schemaName: options.schemaName,
|
|
41
|
+
tableName: options.tableName,
|
|
42
|
+
});
|
|
43
|
+
const fragment = walk(rootNode, ctx);
|
|
44
|
+
const sql = (0, render_js_1.renderRoot)(fragment, viewDef, {
|
|
45
|
+
resourceAlias,
|
|
46
|
+
schemaName: options.schemaName,
|
|
47
|
+
tableName: options.tableName,
|
|
48
|
+
testId: options.testId,
|
|
49
|
+
whereClauseBuilder,
|
|
50
|
+
transpilerCtx: options.transpilerCtx,
|
|
51
|
+
});
|
|
52
|
+
return { sql, columns: collectColumnMetadata(viewDef.select) };
|
|
53
|
+
}
|
|
54
|
+
function buildRootContext(resourceAlias, transpilerCtx) {
|
|
55
|
+
const idKey = {
|
|
56
|
+
name: "id",
|
|
57
|
+
sqlExpr: `[${resourceAlias}].[id]`,
|
|
58
|
+
sqlType: types_js_1.SQL_INT,
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
resourceAlias,
|
|
62
|
+
// Use unbracketed `r.json` for the JSON source: matches the FHIRPath
|
|
63
|
+
// transpiler's expectations (see visitor.ts handleJsonQueryMember which
|
|
64
|
+
// pattern-matches on the source string).
|
|
65
|
+
source: `${resourceAlias}.json`,
|
|
66
|
+
partitionKeys: [idKey],
|
|
67
|
+
ancestorApplies: "",
|
|
68
|
+
nullable: false,
|
|
69
|
+
cteCounter: { value: 0 },
|
|
70
|
+
transpilerCtx,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Walk the select tree and collect ColumnInfo metadata in lexical order.
|
|
75
|
+
* Mirrors the behaviour of QueryGenerator.collectAllColumns so the public
|
|
76
|
+
* TranspilationResult.columns shape is unchanged.
|
|
77
|
+
*/
|
|
78
|
+
function collectColumnMetadata(selects) {
|
|
79
|
+
const out = [];
|
|
80
|
+
for (const select of selects) {
|
|
81
|
+
if (select.column) {
|
|
82
|
+
for (const column of select.column) {
|
|
83
|
+
out.push({
|
|
84
|
+
name: column.name,
|
|
85
|
+
type: transpiler_js_1.Transpiler.inferSqlType(column.type, column.tag),
|
|
86
|
+
nullable: true,
|
|
87
|
+
description: column.description,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (select.select)
|
|
92
|
+
out.push(...collectColumnMetadata(select.select));
|
|
93
|
+
if (select.unionAll)
|
|
94
|
+
out.push(...collectColumnMetadata(select.unionAll));
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/compile.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAwCH,sDA0BC;AAhED,gEAA6E;AAO7E,kFAA4E;AAC5E,oDAA8C;AAC9C,oEAA8D;AAC9D,2CAAyC;AACzC,yCAAsE;AACtE,2CAAyC;AAEzC,MAAM,eAAe,GAAG,IAAI,wDAAyB,EAAE,CAAC;AACxD,MAAM,UAAU,GAAG,IAAI,0BAAU,EAAE,CAAC;AACpC,MAAM,kBAAkB,GAAG,IAAI,0CAAkB,EAAE,CAAC;AASpD;;;;;;;;;;;;GAYG;AACH,SAAgB,qBAAqB,CACnC,OAAuB,EACvB,OAAuB;IAEvB,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC;IAC1D,MAAM,GAAG,GAAG,gBAAgB,CAAC,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAEnE,MAAM,QAAQ,GAAyB,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;IAClE,MAAM,IAAI,GAAG,IAAA,sBAAU,EAAC;QACtB,eAAe;QACf,UAAU;QACV,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAErC,MAAM,GAAG,GAAG,IAAA,sBAAU,EAAC,QAAQ,EAAE,OAAO,EAAE;QACxC,aAAa;QACb,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,kBAAkB;QAClB,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;AACjE,CAAC;AAED,SAAS,gBAAgB,CACvB,aAAqB,EACrB,aAAgC;IAEhC,MAAM,KAAK,GAAiB;QAC1B,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,IAAI,aAAa,QAAQ;QAClC,OAAO,EAAE,kBAAO;KACjB,CAAC;IACF,OAAO;QACL,aAAa;QACb,qEAAqE;QACrE,wEAAwE;QACxE,yCAAyC;QACzC,MAAM,EAAE,GAAG,aAAa,OAAO;QAC/B,aAAa,EAAE,CAAC,KAAK,CAAC;QACtB,eAAe,EAAE,EAAE;QACnB,QAAQ,EAAE,KAAK;QACf,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;QACxB,aAAa;KACd,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,OAA+B;IAC5D,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnC,GAAG,CAAC,IAAI,CAAC;oBACP,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,IAAI,EAAE,0BAAU,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC;oBACtD,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,MAAM,CAAC,WAAW;iBAChC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACrE,IAAI,MAAM,CAAC,QAAQ;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,qBAAqB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL string templates for the recursive CTE produced by `repeat`.
|
|
3
|
+
*
|
|
4
|
+
* Builds the anchor + recursive members, propagating partition keys and
|
|
5
|
+
* baked scalar columns through both. Multi-segment paths chain CROSS APPLY
|
|
6
|
+
* OPENJSON per segment.
|
|
7
|
+
*
|
|
8
|
+
* Note: `__path` is built by string-concatenating each child's `[key]`.
|
|
9
|
+
* If a JSON object key contains a literal `.`, two distinct nodes could
|
|
10
|
+
* theoretically produce equal `__path` strings. FHIR JSON keys do not
|
|
11
|
+
* contain dots in practice; not a blocker.
|
|
12
|
+
*/
|
|
13
|
+
import type { CteDefinition, PartitionKey } from "./types.js";
|
|
14
|
+
export interface BuildRepeatCteArgs {
|
|
15
|
+
cteAlias: string;
|
|
16
|
+
/** FHIRPath strings — first is the anchor path; all are recursive paths. */
|
|
17
|
+
paths: string[];
|
|
18
|
+
/** JSON source expression for the anchor (e.g. "r.json", "forEach_0.value"). */
|
|
19
|
+
source: string;
|
|
20
|
+
/** "FROM <table> AS [r]" — the resource table reference for the anchor. */
|
|
21
|
+
fromClause: string;
|
|
22
|
+
/** CROSS/OUTER APPLY chain inherited from ancestors (each starts with "\n"). */
|
|
23
|
+
ancestorApplies: string;
|
|
24
|
+
/** Partition keys propagated through anchor and recursive members. */
|
|
25
|
+
partitionKeys: PartitionKey[];
|
|
26
|
+
/** Resource-level WHERE applied to the anchor (or null to omit). */
|
|
27
|
+
resourcePredicate: string | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Builds the SQL body of the recursive CTE used by the Repeat operator.
|
|
31
|
+
*
|
|
32
|
+
* Produces a `CteDefinition` whose body is an anchor SELECT followed by one
|
|
33
|
+
* `UNION ALL` recursive SELECT per path in `args.paths`. The anchor starts
|
|
34
|
+
* at the resource root and expands each array element via `OPENJSON`; each
|
|
35
|
+
* recursive member re-expands from the CTE's own `item_json` column,
|
|
36
|
+
* appending `.[key]` to the `__path` accumulator for stable per-element
|
|
37
|
+
* identity. Multi-segment paths (e.g. `"a.b.c"`) produce a chain of nested
|
|
38
|
+
* `CROSS APPLY OPENJSON` calls.
|
|
39
|
+
*
|
|
40
|
+
* @param args - Parameters controlling CTE generation: the CTE alias, the
|
|
41
|
+
* FHIRPath repeat paths, the JSON source expression for the anchor, the
|
|
42
|
+
* resource table FROM clause, any ancestor APPLY chain, the partition keys
|
|
43
|
+
* to propagate, and an optional resource-level WHERE predicate for the
|
|
44
|
+
* anchor.
|
|
45
|
+
* @returns A `CteDefinition` with `alias` set to `args.cteAlias` and `body`
|
|
46
|
+
* containing the full anchor + recursive SQL (without the outer
|
|
47
|
+
* `alias AS (...)` wrapper, which `renderRoot` adds).
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildRepeatCte(args: BuildRepeatCteArgs): CteDefinition;
|
|
50
|
+
//# sourceMappingURL=cteTemplates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cteTemplates.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/cteTemplates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,eAAe,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,oEAAoE;IACpE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,aAAa,CAOtE"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SQL string templates for the recursive CTE produced by `repeat`.
|
|
4
|
+
*
|
|
5
|
+
* Builds the anchor + recursive members, propagating partition keys and
|
|
6
|
+
* baked scalar columns through both. Multi-segment paths chain CROSS APPLY
|
|
7
|
+
* OPENJSON per segment.
|
|
8
|
+
*
|
|
9
|
+
* Note: `__path` is built by string-concatenating each child's `[key]`.
|
|
10
|
+
* If a JSON object key contains a literal `.`, two distinct nodes could
|
|
11
|
+
* theoretically produce equal `__path` strings. FHIR JSON keys do not
|
|
12
|
+
* contain dots in practice; not a blocker.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.buildRepeatCte = buildRepeatCte;
|
|
16
|
+
/**
|
|
17
|
+
* Builds the SQL body of the recursive CTE used by the Repeat operator.
|
|
18
|
+
*
|
|
19
|
+
* Produces a `CteDefinition` whose body is an anchor SELECT followed by one
|
|
20
|
+
* `UNION ALL` recursive SELECT per path in `args.paths`. The anchor starts
|
|
21
|
+
* at the resource root and expands each array element via `OPENJSON`; each
|
|
22
|
+
* recursive member re-expands from the CTE's own `item_json` column,
|
|
23
|
+
* appending `.[key]` to the `__path` accumulator for stable per-element
|
|
24
|
+
* identity. Multi-segment paths (e.g. `"a.b.c"`) produce a chain of nested
|
|
25
|
+
* `CROSS APPLY OPENJSON` calls.
|
|
26
|
+
*
|
|
27
|
+
* @param args - Parameters controlling CTE generation: the CTE alias, the
|
|
28
|
+
* FHIRPath repeat paths, the JSON source expression for the anchor, the
|
|
29
|
+
* resource table FROM clause, any ancestor APPLY chain, the partition keys
|
|
30
|
+
* to propagate, and an optional resource-level WHERE predicate for the
|
|
31
|
+
* anchor.
|
|
32
|
+
* @returns A `CteDefinition` with `alias` set to `args.cteAlias` and `body`
|
|
33
|
+
* containing the full anchor + recursive SQL (without the outer
|
|
34
|
+
* `alias AS (...)` wrapper, which `renderRoot` adds).
|
|
35
|
+
*/
|
|
36
|
+
function buildRepeatCte(args) {
|
|
37
|
+
const anchor = buildAnchorMember(args);
|
|
38
|
+
const recBlocks = args.paths.map((p, i) => buildRecursiveMember(args, p, i));
|
|
39
|
+
const body = `${anchor}
|
|
40
|
+
UNION ALL
|
|
41
|
+
${recBlocks.join("\n UNION ALL\n")}`;
|
|
42
|
+
return { alias: args.cteAlias, body };
|
|
43
|
+
}
|
|
44
|
+
function buildAnchorMember(args) {
|
|
45
|
+
const { paths, source, fromClause, ancestorApplies, partitionKeys, resourcePredicate, } = args;
|
|
46
|
+
const projLines = partitionKeys
|
|
47
|
+
.map((k) => `${k.sqlExpr} AS [${k.name}]`)
|
|
48
|
+
.join(",\n ");
|
|
49
|
+
const chain = buildOpenJsonChain(source, paths[0], "anchor");
|
|
50
|
+
const wherePart = resourcePredicate ? `\n ${resourcePredicate}` : "";
|
|
51
|
+
return ` SELECT
|
|
52
|
+
${projLines},
|
|
53
|
+
CAST(${chain.lastAlias}.[key] AS NVARCHAR(MAX)) AS __path,
|
|
54
|
+
${chain.lastAlias}.value AS item_json,
|
|
55
|
+
0 AS depth
|
|
56
|
+
${fromClause}${ancestorApplies}
|
|
57
|
+
${chain.applyClauses}${wherePart}`;
|
|
58
|
+
}
|
|
59
|
+
function buildRecursiveMember(args, path, index) {
|
|
60
|
+
const { cteAlias, partitionKeys } = args;
|
|
61
|
+
const head = partitionKeys.map((k) => `cte.[${k.name}]`).join(", ");
|
|
62
|
+
const chain = buildOpenJsonChain("cte.item_json", path, `child_${index}`);
|
|
63
|
+
return ` SELECT
|
|
64
|
+
${head},
|
|
65
|
+
cte.__path + '.' + CAST(${chain.lastAlias}.[key] AS NVARCHAR(4000)) AS __path,
|
|
66
|
+
${chain.lastAlias}.value AS item_json,
|
|
67
|
+
cte.depth + 1
|
|
68
|
+
FROM ${cteAlias} AS cte
|
|
69
|
+
${chain.applyClauses}`;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Builds the CROSS APPLY OPENJSON chain for a (possibly multi-segment) path.
|
|
73
|
+
* For "a.b.c" produces three chained APPLYs; the last alias is `finalAlias`.
|
|
74
|
+
*/
|
|
75
|
+
function buildOpenJsonChain(source, path, finalAlias) {
|
|
76
|
+
const segments = path.split(".");
|
|
77
|
+
if (segments.length === 1) {
|
|
78
|
+
return {
|
|
79
|
+
applyClauses: `CROSS APPLY OPENJSON(${source}, '$.${segments[0]}') AS ${finalAlias}`,
|
|
80
|
+
lastAlias: finalAlias,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
let chain = "";
|
|
84
|
+
let currentSource = source;
|
|
85
|
+
for (let i = 0; i < segments.length; i++) {
|
|
86
|
+
const isLast = i === segments.length - 1;
|
|
87
|
+
const alias = isLast ? finalAlias : `${finalAlias}_${i}`;
|
|
88
|
+
if (i > 0)
|
|
89
|
+
chain += "\n ";
|
|
90
|
+
chain += `CROSS APPLY OPENJSON(${currentSource}, '$.${segments[i]}') AS ${alias}`;
|
|
91
|
+
currentSource = `${alias}.value`;
|
|
92
|
+
}
|
|
93
|
+
return { applyClauses: chain, lastAlias: finalAlias };
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=cteTemplates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cteTemplates.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/cteTemplates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tree-walker query generator.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.compileViewDefinition = void 0;
|
|
7
|
+
var compile_js_1 = require("./compile.js");
|
|
8
|
+
Object.defineProperty(exports, "compileViewDefinition", { enumerable: true, get: function () { return compile_js_1.compileViewDefinition; } });
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,2CAAqD;AAA5C,mHAAA,qBAAqB,OAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges sibling fragments produced by walking children of a Group.
|
|
3
|
+
*
|
|
4
|
+
* Flattens CTE lists, concatenates `fromExtensions` strings and `columns`
|
|
5
|
+
* arrays in order, and passes `partitionKeys` through unchanged from `ctx`.
|
|
6
|
+
*/
|
|
7
|
+
import type { Context, Fragment } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Merges sibling Fragments produced by walking children of a Group node.
|
|
10
|
+
*
|
|
11
|
+
* Flattens each fragment's `ctes` list, concatenates `fromExtensions` strings
|
|
12
|
+
* (preserving order so aliases are introduced before they are referenced), and
|
|
13
|
+
* concatenates `columns` arrays in lexical order. `partitionKeys` are passed
|
|
14
|
+
* through unchanged from `ctx` — siblings share the same partition scope.
|
|
15
|
+
*
|
|
16
|
+
* Returns an empty Fragment (no CTEs, no extensions, no columns) when
|
|
17
|
+
* `fragments` is empty, and returns the sole fragment unchanged when only one
|
|
18
|
+
* is provided.
|
|
19
|
+
*
|
|
20
|
+
* @param fragments - Ordered array of sibling Fragments to merge.
|
|
21
|
+
* @param ctx - The context of the parent Group node, used to supply
|
|
22
|
+
* `partitionKeys` for the merged result and as the base for the empty-array
|
|
23
|
+
* case.
|
|
24
|
+
* @returns A single merged Fragment whose columns, CTEs, and FROM extensions
|
|
25
|
+
* are the ordered union of all input fragments.
|
|
26
|
+
*/
|
|
27
|
+
export declare function mergeSiblings(fragments: Fragment[], ctx: Context): Fragment;
|
|
28
|
+
//# sourceMappingURL=mergeSiblings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeSiblings.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/mergeSiblings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,QAAQ,CA0B3E"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Merges sibling fragments produced by walking children of a Group.
|
|
4
|
+
*
|
|
5
|
+
* Flattens CTE lists, concatenates `fromExtensions` strings and `columns`
|
|
6
|
+
* arrays in order, and passes `partitionKeys` through unchanged from `ctx`.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.mergeSiblings = mergeSiblings;
|
|
10
|
+
/**
|
|
11
|
+
* Merges sibling Fragments produced by walking children of a Group node.
|
|
12
|
+
*
|
|
13
|
+
* Flattens each fragment's `ctes` list, concatenates `fromExtensions` strings
|
|
14
|
+
* (preserving order so aliases are introduced before they are referenced), and
|
|
15
|
+
* concatenates `columns` arrays in lexical order. `partitionKeys` are passed
|
|
16
|
+
* through unchanged from `ctx` — siblings share the same partition scope.
|
|
17
|
+
*
|
|
18
|
+
* Returns an empty Fragment (no CTEs, no extensions, no columns) when
|
|
19
|
+
* `fragments` is empty, and returns the sole fragment unchanged when only one
|
|
20
|
+
* is provided.
|
|
21
|
+
*
|
|
22
|
+
* @param fragments - Ordered array of sibling Fragments to merge.
|
|
23
|
+
* @param ctx - The context of the parent Group node, used to supply
|
|
24
|
+
* `partitionKeys` for the merged result and as the base for the empty-array
|
|
25
|
+
* case.
|
|
26
|
+
* @returns A single merged Fragment whose columns, CTEs, and FROM extensions
|
|
27
|
+
* are the ordered union of all input fragments.
|
|
28
|
+
*/
|
|
29
|
+
function mergeSiblings(fragments, ctx) {
|
|
30
|
+
if (fragments.length === 0) {
|
|
31
|
+
return {
|
|
32
|
+
ctes: [],
|
|
33
|
+
fromExtensions: "",
|
|
34
|
+
columns: [],
|
|
35
|
+
partitionKeys: ctx.partitionKeys,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (fragments.length === 1)
|
|
39
|
+
return fragments[0];
|
|
40
|
+
const ctes = fragments.flatMap((f) => f.ctes);
|
|
41
|
+
const fromExtensions = fragments.map((f) => f.fromExtensions).join("");
|
|
42
|
+
const columns = fragments.flatMap((f) => f.columns);
|
|
43
|
+
// Row siblings + zero or more set siblings: each set fragment already carries
|
|
44
|
+
// its own INNER JOIN to its CTE, joined on the partition keys it inherited
|
|
45
|
+
// from `ctx`. The outer FROM stays as the resource table so row siblings can
|
|
46
|
+
// keep their references to `r` valid.
|
|
47
|
+
return {
|
|
48
|
+
ctes,
|
|
49
|
+
fromExtensions,
|
|
50
|
+
columns,
|
|
51
|
+
partitionKeys: ctx.partitionKeys,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=mergeSiblings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeSiblings.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/mergeSiblings.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAuBH,sCA0BC;AA7CD;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,aAAa,CAAC,SAAqB,EAAE,GAAY;IAC/D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,IAAI,EAAE,EAAE;YACR,cAAc,EAAE,EAAE;YAClB,OAAO,EAAE,EAAE;YACX,aAAa,EAAE,GAAG,CAAC,aAAa;SACjC,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvE,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAEpD,8EAA8E;IAC9E,2EAA2E;IAC3E,6EAA6E;IAC7E,sCAAsC;IACtC,OAAO;QACL,IAAI;QACJ,cAAc;QACd,OAAO;QACP,aAAa,EAAE,GAAG,CAAC,aAAa;KACjC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walker for ColumnsOnly nodes — emits the projected columns for the
|
|
3
|
+
* select.column[] array using the current transpiler context.
|
|
4
|
+
*/
|
|
5
|
+
import type { ViewDefinitionColumn, ViewDefinitionSelect } from "../../../types.js";
|
|
6
|
+
import type { ColumnExpressionGenerator } from "../../ColumnExpressionGenerator.js";
|
|
7
|
+
import type { Context, Fragment, ProjectedColumn } from "../types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Projects an array of ViewDefinition column descriptors into SQL expressions.
|
|
10
|
+
*
|
|
11
|
+
* Delegates expression generation to `ColumnExpressionGenerator`, which
|
|
12
|
+
* translates each column's FHIRPath expression into a T-SQL expression
|
|
13
|
+
* relative to the current transpiler context (iteration source, aliases, etc.).
|
|
14
|
+
*
|
|
15
|
+
* @param columns - The column descriptors from the ViewDefinition select node.
|
|
16
|
+
* @param ctx - The current walker context supplying the transpiler context
|
|
17
|
+
* used for FHIRPath-to-SQL translation.
|
|
18
|
+
* @param columnGenerator - The generator that converts each column descriptor
|
|
19
|
+
* into its SQL expression string.
|
|
20
|
+
* @returns An ordered array of `ProjectedColumn` objects, each pairing the
|
|
21
|
+
* column's logical name with its SQL expression.
|
|
22
|
+
*/
|
|
23
|
+
export declare function projectColumns(columns: ViewDefinitionColumn[], ctx: Context, columnGenerator: ColumnExpressionGenerator): ProjectedColumn[];
|
|
24
|
+
/**
|
|
25
|
+
* Walker for ColumnsOnly nodes — emits the projected columns for a leaf select node.
|
|
26
|
+
*
|
|
27
|
+
* Produces a Fragment with no CTEs, no FROM extensions, and columns derived
|
|
28
|
+
* from `node.column[]` via `projectColumns`. If `node.column` is absent or
|
|
29
|
+
* empty, the returned Fragment has an empty columns array.
|
|
30
|
+
*
|
|
31
|
+
* @param node - The leaf select node whose `column[]` array is projected.
|
|
32
|
+
* @param ctx - The current walker context supplying partition keys and the
|
|
33
|
+
* transpiler context for expression generation.
|
|
34
|
+
* @param columnGenerator - The generator that converts column descriptors into
|
|
35
|
+
* T-SQL expressions.
|
|
36
|
+
* @returns A Fragment carrying only projected columns; `ctes` and
|
|
37
|
+
* `fromExtensions` are always empty.
|
|
38
|
+
*/
|
|
39
|
+
export declare function walkColumnsOnly(node: ViewDefinitionSelect, ctx: Context, columnGenerator: ColumnExpressionGenerator): Fragment;
|
|
40
|
+
//# sourceMappingURL=columnsOnly.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columnsOnly.d.ts","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/columnsOnly.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,oBAAoB,EAAE,EAC/B,GAAG,EAAE,OAAO,EACZ,eAAe,EAAE,yBAAyB,GACzC,eAAe,EAAE,CAKnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,OAAO,EACZ,eAAe,EAAE,yBAAyB,GACzC,QAAQ,CAUV"}
|