@malloydata/malloy 0.0.22-dev230119001546 → 0.0.22-dev230119193053
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/lang/ast/ast-expr.d.ts +1 -2
- package/dist/lang/ast/ast-expr.js +4 -6
- package/dist/lang/ast/ast-main.d.ts +256 -2
- package/dist/lang/ast/ast-main.js +830 -16
- package/dist/lang/ast/ast-time-expr.d.ts +1 -2
- package/dist/lang/space-field.d.ts +1 -106
- package/dist/lang/space-field.js +5 -234
- package/dist/lang/test/field-symbols.spec.js +21 -23
- package/dist/lang/test/parse.spec.js +3 -4
- package/package.json +1 -1
- package/dist/lang/field-space.d.ts +0 -159
- package/dist/lang/field-space.js +0 -641
|
@@ -24,7 +24,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.TurtleHeadedPipe = exports.ExistingQuery = exports.Index = exports.Turtles = exports.Limit = exports.Ordering = exports.OrderBy = exports.WildcardFieldReference = exports.RenameField = exports.PrimaryKey = exports.Document = exports.QOPDesc = exports.Aggregate = exports.GroupBy = exports.FieldListEdit = exports.ProjectStatement = exports.isFieldCollectionMember = exports.FieldReferences = exports.FieldReference = exports.FieldName = exports.Renames = exports.Dimensions = exports.Measures = exports.DeclareFields = exports.Filter = exports.FilterElement = exports.ExploreDesc = exports.isExploreProperty = exports.isQueryProperty = exports.Joins = exports.ExpressionJoin = exports.KeyJoin = exports.Join = exports.QuerySource = exports.SQLSource = exports.NamedSource = exports.ModelEntryReference = exports.IsValueBlock = exports.TableSource = exports.RefinedExplore = exports.DefineSourceList = exports.DefineExplore = exports.isDocStatement = exports.RunList = exports.Mallobj = exports.isExploreField = exports.Unimplemented = exports.ListOf = exports.MalloyElement = exports.ErrorFactory = void 0;
|
|
27
|
-
exports.Range = exports.ExprTime = exports.ExprDuration = exports.TypeMistmatch = exports.ExprGranularTime = exports.ExprCompare = exports.BinaryBoolean = exports.applyBinary = exports.FieldDeclaration = exports.ConstantSubExpression = exports.ExpressionDef = exports.SampleProperty = exports.SQLStatement = exports.SQLString = exports.ConstantParameter = exports.HasParameter = exports.ImportStatement = exports.JSONStructDef = exports.JSONElement = exports.Top = exports.AnonymousQuery = exports.DefineQuery = exports.DefineQueryList = exports.isQueryElement = exports.Nests = exports.isNestedQuery = exports.NestDefinition = exports.NestRefinement = exports.NestReference = exports.TurtleDecl = exports.FullQuery = void 0;
|
|
27
|
+
exports.RenameSpaceField = exports.QueryFieldAST = exports.ExpressionFieldFromAst = exports.AbstractParameter = exports.SpaceSeed = exports.DefinedParameter = exports.SpaceParam = exports.ColumnSpaceField = exports.QueryFieldStruct = exports.QueryField = exports.StructSpaceField = exports.SpaceField = exports.SpaceEntry = exports.ProjectFieldSpace = exports.ReduceFieldSpace = exports.ResultSpace = exports.DynamicSpace = exports.StaticSpace = exports.DefSpace = exports.Range = exports.ExprTime = exports.ExprDuration = exports.TypeMistmatch = exports.ExprGranularTime = exports.ExprCompare = exports.BinaryBoolean = exports.applyBinary = exports.FieldDeclaration = exports.ConstantSubExpression = exports.ExpressionDef = exports.SampleProperty = exports.SQLStatement = exports.SQLString = exports.ConstantParameter = exports.HasParameter = exports.ImportStatement = exports.JSONStructDef = exports.JSONElement = exports.Top = exports.AnonymousQuery = exports.DefineQuery = exports.DefineQueryList = exports.isQueryElement = exports.Nests = exports.isNestedQuery = exports.NestDefinition = exports.NestRefinement = exports.NestReference = exports.TurtleDecl = exports.FullQuery = void 0;
|
|
28
|
+
exports.IndexFieldSpace = exports.WildSpaceField = exports.ReferenceField = exports.QuerySpace = exports.JoinSpaceField = void 0;
|
|
28
29
|
/*
|
|
29
30
|
* Copyright 2023 Google LLC
|
|
30
31
|
*
|
|
@@ -49,15 +50,15 @@ exports.Range = exports.ExprTime = exports.ExprDuration = exports.TypeMistmatch
|
|
|
49
50
|
*/
|
|
50
51
|
const lodash_1 = require("lodash");
|
|
51
52
|
const model = __importStar(require("../../model/malloy_types"));
|
|
53
|
+
const dialect_map_1 = require("../../dialect/dialect_map");
|
|
52
54
|
const malloy_types_1 = require("../../model/malloy_types");
|
|
53
55
|
const malloy_query_1 = require("../../model/malloy_query");
|
|
54
|
-
const field_space_1 = require("../field-space");
|
|
55
56
|
const ast_types_1 = require("./ast-types");
|
|
56
|
-
const space_field_1 = require("../space-field");
|
|
57
57
|
const sql_block_1 = require("../../model/sql_block");
|
|
58
58
|
const util_1 = require("util");
|
|
59
59
|
const time_utils_1 = require("./time-utils");
|
|
60
60
|
const apply_expr_1 = require("./apply-expr");
|
|
61
|
+
const field_utils_1 = require("../field-utils");
|
|
61
62
|
/*
|
|
62
63
|
** For times when there is a code generation error but your function needs
|
|
63
64
|
** to return some kind of object to type properly, the ErrorFactory is
|
|
@@ -541,7 +542,7 @@ class RefinedExplore extends Mallobj {
|
|
|
541
542
|
if (primaryKey) {
|
|
542
543
|
from.primaryKey = primaryKey.field.name;
|
|
543
544
|
}
|
|
544
|
-
const fs =
|
|
545
|
+
const fs = DynamicSpace.filteredFrom(from, fieldListEdit);
|
|
545
546
|
fs.addField(...fields);
|
|
546
547
|
if (pList) {
|
|
547
548
|
fs.addParameters(pList);
|
|
@@ -1115,7 +1116,7 @@ class ReduceExecutor {
|
|
|
1115
1116
|
this.inputFS = this.resultFS.exprSpace;
|
|
1116
1117
|
}
|
|
1117
1118
|
getResultSpace(fs) {
|
|
1118
|
-
return new
|
|
1119
|
+
return new ReduceFieldSpace(fs);
|
|
1119
1120
|
}
|
|
1120
1121
|
execute(qp) {
|
|
1121
1122
|
if (qp instanceof GroupBy ||
|
|
@@ -1219,7 +1220,7 @@ class ReduceExecutor {
|
|
|
1219
1220
|
}
|
|
1220
1221
|
class ProjectExecutor extends ReduceExecutor {
|
|
1221
1222
|
getResultSpace(fs) {
|
|
1222
|
-
return new
|
|
1223
|
+
return new ProjectFieldSpace(fs);
|
|
1223
1224
|
}
|
|
1224
1225
|
execute(qp) {
|
|
1225
1226
|
if (qp instanceof ProjectStatement) {
|
|
@@ -1253,7 +1254,7 @@ class ProjectExecutor extends ReduceExecutor {
|
|
|
1253
1254
|
class IndexExecutor {
|
|
1254
1255
|
constructor(inputFS) {
|
|
1255
1256
|
this.filters = [];
|
|
1256
|
-
this.resultFS = new
|
|
1257
|
+
this.resultFS = new IndexFieldSpace(inputFS);
|
|
1257
1258
|
this.inputFS = this.resultFS.exprSpace;
|
|
1258
1259
|
}
|
|
1259
1260
|
execute(qp) {
|
|
@@ -1394,7 +1395,7 @@ class QOPDesc extends ListOf {
|
|
|
1394
1395
|
const segment = qex.finalize(this.refineThis);
|
|
1395
1396
|
return {
|
|
1396
1397
|
segment,
|
|
1397
|
-
outputSpace: () => new
|
|
1398
|
+
outputSpace: () => new DynamicSpace(opOutputStruct(this, inputFS.structDef(), segment)),
|
|
1398
1399
|
};
|
|
1399
1400
|
}
|
|
1400
1401
|
}
|
|
@@ -1692,10 +1693,10 @@ class ExistingQuery extends PipelineDesc {
|
|
|
1692
1693
|
const queryHead = new QueryHeadStruct(seedQuery.structRef);
|
|
1693
1694
|
this.has({ queryHead });
|
|
1694
1695
|
const exploreStruct = queryHead.structDef();
|
|
1695
|
-
const exploreFS = new
|
|
1696
|
+
const exploreFS = new DynamicSpace(exploreStruct);
|
|
1696
1697
|
const sourcePipe = this.refinePipeline(exploreFS, seedQuery);
|
|
1697
1698
|
const walkStruct = this.getOutputStruct(exploreStruct, sourcePipe.pipeline);
|
|
1698
|
-
const appended = this.appendOps(sourcePipe.pipeline, new
|
|
1699
|
+
const appended = this.appendOps(sourcePipe.pipeline, new DynamicSpace(walkStruct));
|
|
1699
1700
|
const destPipe = { ...sourcePipe, pipeline: appended.opList };
|
|
1700
1701
|
const query = {
|
|
1701
1702
|
type: "query",
|
|
@@ -1736,7 +1737,7 @@ class FullQuery extends TurtleHeadedPipe {
|
|
|
1736
1737
|
const structDef = model.refIsStructDef(structRef)
|
|
1737
1738
|
? structRef
|
|
1738
1739
|
: this.explore.structDef();
|
|
1739
|
-
let pipeFs = new
|
|
1740
|
+
let pipeFs = new DynamicSpace(structDef);
|
|
1740
1741
|
if (ErrorFactory.isErrorStructDef(structDef)) {
|
|
1741
1742
|
return {
|
|
1742
1743
|
outputStruct: structDef,
|
|
@@ -1764,7 +1765,7 @@ class FullQuery extends TurtleHeadedPipe {
|
|
|
1764
1765
|
destQuery.pipeHead = { name };
|
|
1765
1766
|
}
|
|
1766
1767
|
const pipeStruct = this.getOutputStruct(structDef, refined);
|
|
1767
|
-
pipeFs = new
|
|
1768
|
+
pipeFs = new DynamicSpace(pipeStruct);
|
|
1768
1769
|
}
|
|
1769
1770
|
const appended = this.appendOps(destQuery.pipeline, pipeFs);
|
|
1770
1771
|
destQuery.pipeline = appended.opList;
|
|
@@ -1789,7 +1790,7 @@ class TurtleDecl extends TurtleHeadedPipe {
|
|
|
1789
1790
|
this.log(headEnt.error);
|
|
1790
1791
|
reportWrongType = false;
|
|
1791
1792
|
}
|
|
1792
|
-
else if (headEnt.found instanceof
|
|
1793
|
+
else if (headEnt.found instanceof QueryField) {
|
|
1793
1794
|
const headDef = headEnt.found.getQueryFieldDef(fs);
|
|
1794
1795
|
if (isTurtle(headDef)) {
|
|
1795
1796
|
const newPipe = this.refinePipeline(fs, headDef);
|
|
@@ -1810,7 +1811,7 @@ class TurtleDecl extends TurtleHeadedPipe {
|
|
|
1810
1811
|
for (const existingSeg of modelPipe.pipeline) {
|
|
1811
1812
|
endStruct = opOutputStruct(this, endStruct, existingSeg);
|
|
1812
1813
|
}
|
|
1813
|
-
appendInput = new
|
|
1814
|
+
appendInput = new DynamicSpace(endStruct);
|
|
1814
1815
|
}
|
|
1815
1816
|
const appended = this.appendOps(modelPipe.pipeline, appendInput);
|
|
1816
1817
|
modelPipe.pipeline = appended.opList;
|
|
@@ -2325,7 +2326,7 @@ class FieldDeclaration extends MalloyElement {
|
|
|
2325
2326
|
* a refactor of QueryFieldSpace might someday be the place where this should
|
|
2326
2327
|
* happen.
|
|
2327
2328
|
*/
|
|
2328
|
-
return this.queryFieldDef(new
|
|
2329
|
+
return this.queryFieldDef(new DefSpace(fs, this), exprName);
|
|
2329
2330
|
}
|
|
2330
2331
|
queryFieldDef(exprFS, exprName) {
|
|
2331
2332
|
let exprValue;
|
|
@@ -2362,7 +2363,7 @@ class FieldDeclaration extends MalloyElement {
|
|
|
2362
2363
|
}
|
|
2363
2364
|
return template;
|
|
2364
2365
|
}
|
|
2365
|
-
const circularDef = exprFS instanceof
|
|
2366
|
+
const circularDef = exprFS instanceof DefSpace && exprFS.foundCircle;
|
|
2366
2367
|
if (!circularDef) {
|
|
2367
2368
|
if (exprValue.dataType == "unknown") {
|
|
2368
2369
|
this.log(`Cannot define '${exprName}', value has unknown type`);
|
|
@@ -2855,4 +2856,817 @@ class Range extends ExpressionDef {
|
|
|
2855
2856
|
}
|
|
2856
2857
|
}
|
|
2857
2858
|
exports.Range = Range;
|
|
2859
|
+
/**
|
|
2860
|
+
* Used to detect references to fields in the statement which defines them
|
|
2861
|
+
*/
|
|
2862
|
+
class DefSpace {
|
|
2863
|
+
constructor(realFS, circular) {
|
|
2864
|
+
this.realFS = realFS;
|
|
2865
|
+
this.circular = circular;
|
|
2866
|
+
this.type = "fieldSpace";
|
|
2867
|
+
this.foundCircle = false;
|
|
2868
|
+
}
|
|
2869
|
+
structDef() {
|
|
2870
|
+
return this.realFS.structDef();
|
|
2871
|
+
}
|
|
2872
|
+
emptyStructDef() {
|
|
2873
|
+
return this.realFS.emptyStructDef();
|
|
2874
|
+
}
|
|
2875
|
+
lookup(symbol) {
|
|
2876
|
+
if (symbol[0] && symbol[0].refString === this.circular.defineName) {
|
|
2877
|
+
this.foundCircle = true;
|
|
2878
|
+
return {
|
|
2879
|
+
error: `Circular reference to '${this.circular.defineName}' in definition`,
|
|
2880
|
+
found: undefined,
|
|
2881
|
+
};
|
|
2882
|
+
}
|
|
2883
|
+
return this.realFS.lookup(symbol);
|
|
2884
|
+
}
|
|
2885
|
+
dialectObj() {
|
|
2886
|
+
return this.realFS.dialectObj();
|
|
2887
|
+
}
|
|
2888
|
+
whenComplete(step) {
|
|
2889
|
+
this.realFS.whenComplete(step);
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
exports.DefSpace = DefSpace;
|
|
2893
|
+
class StaticSpace {
|
|
2894
|
+
constructor(sourceStructDef) {
|
|
2895
|
+
this.type = "fieldSpace";
|
|
2896
|
+
this.fromStruct = sourceStructDef;
|
|
2897
|
+
}
|
|
2898
|
+
whenComplete(step) {
|
|
2899
|
+
step();
|
|
2900
|
+
}
|
|
2901
|
+
dialectObj() {
|
|
2902
|
+
try {
|
|
2903
|
+
return (0, dialect_map_1.getDialect)(this.fromStruct.dialect);
|
|
2904
|
+
}
|
|
2905
|
+
catch {
|
|
2906
|
+
return undefined;
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
fromFieldDef(from) {
|
|
2910
|
+
if (from.type === "struct") {
|
|
2911
|
+
return new StructSpaceField(from);
|
|
2912
|
+
}
|
|
2913
|
+
else if (model.isTurtleDef(from)) {
|
|
2914
|
+
return new QueryFieldStruct(this, from);
|
|
2915
|
+
}
|
|
2916
|
+
// TODO field has a filter and needs to be a filteredalias
|
|
2917
|
+
return new ColumnSpaceField(from);
|
|
2918
|
+
}
|
|
2919
|
+
get map() {
|
|
2920
|
+
if (this.memoMap === undefined) {
|
|
2921
|
+
this.memoMap = {};
|
|
2922
|
+
for (const f of this.fromStruct.fields) {
|
|
2923
|
+
const name = f.as || f.name;
|
|
2924
|
+
this.memoMap[name] = this.fromFieldDef(f);
|
|
2925
|
+
}
|
|
2926
|
+
if (this.fromStruct.parameters) {
|
|
2927
|
+
for (const [paramName, paramDef] of Object.entries(this.fromStruct.parameters)) {
|
|
2928
|
+
if (this.memoMap[paramName]) {
|
|
2929
|
+
throw new Error(`In struct '${this.fromStruct.as || this.fromStruct.name}': ` +
|
|
2930
|
+
` : Field and parameter name conflict '${paramName}`);
|
|
2931
|
+
}
|
|
2932
|
+
this.memoMap[paramName] = new DefinedParameter(paramDef);
|
|
2933
|
+
}
|
|
2934
|
+
}
|
|
2935
|
+
}
|
|
2936
|
+
return this.memoMap;
|
|
2937
|
+
}
|
|
2938
|
+
dropEntries() {
|
|
2939
|
+
this.memoMap = {};
|
|
2940
|
+
}
|
|
2941
|
+
dropEntry(name) {
|
|
2942
|
+
delete this.map[name];
|
|
2943
|
+
}
|
|
2944
|
+
entry(name) {
|
|
2945
|
+
return this.map[name];
|
|
2946
|
+
}
|
|
2947
|
+
setEntry(name, value) {
|
|
2948
|
+
this.map[name] = value;
|
|
2949
|
+
}
|
|
2950
|
+
entries() {
|
|
2951
|
+
return Object.entries(this.map);
|
|
2952
|
+
}
|
|
2953
|
+
structDef() {
|
|
2954
|
+
return this.fromStruct;
|
|
2955
|
+
}
|
|
2956
|
+
emptyStructDef() {
|
|
2957
|
+
return { ...this.fromStruct, fields: [] };
|
|
2958
|
+
}
|
|
2959
|
+
lookup(path) {
|
|
2960
|
+
const head = path[0];
|
|
2961
|
+
const rest = path.slice(1);
|
|
2962
|
+
const found = this.entry(head.refString);
|
|
2963
|
+
if (!found) {
|
|
2964
|
+
return { error: `'${head}' is not defined`, found };
|
|
2965
|
+
}
|
|
2966
|
+
if (found instanceof SpaceField) {
|
|
2967
|
+
/*
|
|
2968
|
+
* TODO cache defs, post the addReference call to whenComplete
|
|
2969
|
+
*
|
|
2970
|
+
* In the cleanup phase of query space construction, it may check
|
|
2971
|
+
* the output space for ungrouping variables. However if an
|
|
2972
|
+
* ungrouping variable is a measure, the field expression value
|
|
2973
|
+
* needed to get the definition needs to be computed in the
|
|
2974
|
+
* input space of the query. There is a test which failed which
|
|
2975
|
+
* caused this code to be here, but this is really a bandaid.
|
|
2976
|
+
*
|
|
2977
|
+
* Some re-work of how to get the definition of a SpaceField
|
|
2978
|
+
* no matter what it is contained in needs to be thought out.
|
|
2979
|
+
*
|
|
2980
|
+
* ... or this check would look at the finalized output of
|
|
2981
|
+
* the namespace and not re-compile ...
|
|
2982
|
+
*/
|
|
2983
|
+
const definition = found.fieldDef();
|
|
2984
|
+
if (definition) {
|
|
2985
|
+
head.addReference({
|
|
2986
|
+
type: found instanceof StructSpaceField
|
|
2987
|
+
? "joinReference"
|
|
2988
|
+
: "fieldReference",
|
|
2989
|
+
definition,
|
|
2990
|
+
location: head.location,
|
|
2991
|
+
text: head.refString,
|
|
2992
|
+
});
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
if (rest.length) {
|
|
2996
|
+
if (found instanceof StructSpaceField) {
|
|
2997
|
+
return found.fieldSpace.lookup(rest);
|
|
2998
|
+
}
|
|
2999
|
+
return {
|
|
3000
|
+
error: `'${head}' cannot contain a '${rest[0]}'`,
|
|
3001
|
+
found: undefined,
|
|
3002
|
+
};
|
|
3003
|
+
}
|
|
3004
|
+
return { found, error: undefined };
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
exports.StaticSpace = StaticSpace;
|
|
3008
|
+
/**
|
|
3009
|
+
* A FieldSpace which may undergo modification
|
|
3010
|
+
*/
|
|
3011
|
+
class DynamicSpace extends StaticSpace {
|
|
3012
|
+
constructor(extending) {
|
|
3013
|
+
const source = new SpaceSeed(extending);
|
|
3014
|
+
super((0, lodash_1.cloneDeep)(source.structDef));
|
|
3015
|
+
this.completions = [];
|
|
3016
|
+
this.complete = false;
|
|
3017
|
+
this.final = undefined;
|
|
3018
|
+
this.source = source;
|
|
3019
|
+
}
|
|
3020
|
+
/**
|
|
3021
|
+
* Factory for DynamicSpace when there are accept/except edits
|
|
3022
|
+
* @param from A structdef which seeds this space
|
|
3023
|
+
* @param choose A accept/except edit of the "from" fields
|
|
3024
|
+
*/
|
|
3025
|
+
static filteredFrom(from, choose) {
|
|
3026
|
+
const edited = new DynamicSpace(from);
|
|
3027
|
+
if (choose) {
|
|
3028
|
+
const names = choose.refs.list;
|
|
3029
|
+
const oldMap = edited.entries();
|
|
3030
|
+
edited.dropEntries();
|
|
3031
|
+
for (const [symbol, value] of oldMap) {
|
|
3032
|
+
const included = !!names.find((f) => f.refString === symbol);
|
|
3033
|
+
const accepting = choose.edit === "accept";
|
|
3034
|
+
if (included === accepting) {
|
|
3035
|
+
edited.setEntry(symbol, value);
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
return edited;
|
|
3040
|
+
}
|
|
3041
|
+
whenComplete(finalizeStep) {
|
|
3042
|
+
if (this.complete) {
|
|
3043
|
+
finalizeStep();
|
|
3044
|
+
}
|
|
3045
|
+
else {
|
|
3046
|
+
this.completions.push(finalizeStep);
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
isComplete() {
|
|
3050
|
+
this.complete = true;
|
|
3051
|
+
for (const step of this.completions) {
|
|
3052
|
+
step();
|
|
3053
|
+
}
|
|
3054
|
+
this.completions = [];
|
|
3055
|
+
}
|
|
3056
|
+
setEntry(name, value) {
|
|
3057
|
+
if (this.final) {
|
|
3058
|
+
throw new Error("Space already final");
|
|
3059
|
+
}
|
|
3060
|
+
super.setEntry(name, value);
|
|
3061
|
+
}
|
|
3062
|
+
addParameters(params) {
|
|
3063
|
+
for (const oneP of params) {
|
|
3064
|
+
this.setEntry(oneP.name, new AbstractParameter(oneP));
|
|
3065
|
+
}
|
|
3066
|
+
return this;
|
|
3067
|
+
}
|
|
3068
|
+
newEntry(name, astEl, entry) {
|
|
3069
|
+
if (this.entry(name)) {
|
|
3070
|
+
astEl.log(`Cannot redefine '${name}'`);
|
|
3071
|
+
return;
|
|
3072
|
+
}
|
|
3073
|
+
this.setEntry(name, entry);
|
|
3074
|
+
}
|
|
3075
|
+
addField(...defs) {
|
|
3076
|
+
for (const def of defs) {
|
|
3077
|
+
// TODO express the "three fields kinds" in a typesafe way
|
|
3078
|
+
// one of three kinds of fields are legal in an explore: expressions ...
|
|
3079
|
+
const elseLog = def.log;
|
|
3080
|
+
const elseType = def.elementType;
|
|
3081
|
+
if (def instanceof FieldDeclaration) {
|
|
3082
|
+
const exprField = new ExpressionFieldFromAst(this, def);
|
|
3083
|
+
this.newEntry(exprField.name, def, exprField);
|
|
3084
|
+
// querry (turtle) fields
|
|
3085
|
+
}
|
|
3086
|
+
else if (def instanceof TurtleDecl) {
|
|
3087
|
+
const name = def.name;
|
|
3088
|
+
this.newEntry(name, def, new QueryFieldAST(this, def, name));
|
|
3089
|
+
}
|
|
3090
|
+
else if (def instanceof RenameField) {
|
|
3091
|
+
if (def.oldName.refString === def.newName) {
|
|
3092
|
+
def.log("Can't rename field to itself");
|
|
3093
|
+
continue;
|
|
3094
|
+
}
|
|
3095
|
+
const oldValue = def.oldName.getField(this);
|
|
3096
|
+
if (oldValue.found) {
|
|
3097
|
+
if (oldValue.found instanceof SpaceField) {
|
|
3098
|
+
this.setEntry(def.newName, new RenameSpaceField(oldValue.found, def.newName, def.location));
|
|
3099
|
+
this.dropEntry(def.oldName.refString);
|
|
3100
|
+
}
|
|
3101
|
+
else {
|
|
3102
|
+
def.log(`'${def.oldName}' cannot be renamed`);
|
|
3103
|
+
}
|
|
3104
|
+
}
|
|
3105
|
+
else {
|
|
3106
|
+
def.log(`Can't rename '${def.oldName}', no such field`);
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
3109
|
+
else if (def instanceof Join) {
|
|
3110
|
+
this.newEntry(def.name.refString, def, new JoinSpaceField(this, def));
|
|
3111
|
+
}
|
|
3112
|
+
else {
|
|
3113
|
+
elseLog(`Internal error: Expected expression, query, or rename, got '${elseType}'`);
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
addFieldDef(fd) {
|
|
3118
|
+
this.setEntry((0, field_utils_1.nameOf)(fd), this.fromFieldDef(fd));
|
|
3119
|
+
}
|
|
3120
|
+
structDef() {
|
|
3121
|
+
const parameters = this.fromStruct.parameters || {};
|
|
3122
|
+
if (this.final === undefined) {
|
|
3123
|
+
this.final = {
|
|
3124
|
+
...this.fromStruct,
|
|
3125
|
+
fields: [],
|
|
3126
|
+
};
|
|
3127
|
+
// Need to process the entities in specific order
|
|
3128
|
+
const fields = [];
|
|
3129
|
+
const joins = [];
|
|
3130
|
+
const turtles = [];
|
|
3131
|
+
const fixupJoins = [];
|
|
3132
|
+
for (const [name, spaceEntry] of this.entries()) {
|
|
3133
|
+
if (spaceEntry instanceof StructSpaceField) {
|
|
3134
|
+
joins.push([name, spaceEntry]);
|
|
3135
|
+
}
|
|
3136
|
+
else if (spaceEntry instanceof QueryField) {
|
|
3137
|
+
turtles.push([name, spaceEntry]);
|
|
3138
|
+
}
|
|
3139
|
+
else if (spaceEntry instanceof SpaceField) {
|
|
3140
|
+
fields.push([name, spaceEntry]);
|
|
3141
|
+
}
|
|
3142
|
+
else if (spaceEntry instanceof SpaceParam) {
|
|
3143
|
+
parameters[name] = spaceEntry.parameter();
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
const reorderFields = [...fields, ...joins, ...turtles];
|
|
3147
|
+
for (const [fieldName, field] of reorderFields) {
|
|
3148
|
+
if (field instanceof JoinSpaceField) {
|
|
3149
|
+
const joinStruct = field.join.structDef();
|
|
3150
|
+
if (!ErrorFactory.isErrorStructDef(joinStruct)) {
|
|
3151
|
+
this.final.fields.push(joinStruct);
|
|
3152
|
+
fixupJoins.push([field.join, joinStruct]);
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
else {
|
|
3156
|
+
const fieldDef = field.fieldDef();
|
|
3157
|
+
if (fieldDef) {
|
|
3158
|
+
this.final.fields.push(fieldDef);
|
|
3159
|
+
}
|
|
3160
|
+
else {
|
|
3161
|
+
throw new Error(`'${fieldName}' doesn't have a FieldDef`);
|
|
3162
|
+
}
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3165
|
+
if (Object.entries(parameters).length > 0) {
|
|
3166
|
+
this.final.parameters = parameters;
|
|
3167
|
+
}
|
|
3168
|
+
// If we have join expressions, we need to now go back and fill them in
|
|
3169
|
+
for (const [join, missingOn] of fixupJoins) {
|
|
3170
|
+
join.fixupJoinOn(this, missingOn);
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
this.isComplete();
|
|
3174
|
+
return this.final;
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
exports.DynamicSpace = DynamicSpace;
|
|
3178
|
+
class ResultSpace extends DynamicSpace {
|
|
3179
|
+
constructor(queryInputSpace) {
|
|
3180
|
+
super(queryInputSpace.emptyStructDef());
|
|
3181
|
+
this.queryInputSpace = queryInputSpace;
|
|
3182
|
+
this.exprSpace = new QuerySpace(queryInputSpace, this);
|
|
3183
|
+
}
|
|
3184
|
+
log(s) {
|
|
3185
|
+
if (this.astEl) {
|
|
3186
|
+
this.astEl.log(s);
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
addMembers(members) {
|
|
3190
|
+
for (const member of members) {
|
|
3191
|
+
if (member instanceof FieldReference) {
|
|
3192
|
+
this.addReference(member);
|
|
3193
|
+
}
|
|
3194
|
+
else if (member instanceof WildcardFieldReference) {
|
|
3195
|
+
this.addWild(member);
|
|
3196
|
+
}
|
|
3197
|
+
else {
|
|
3198
|
+
this.addField(member);
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
addReference(ref) {
|
|
3203
|
+
const refName = ref.outputName;
|
|
3204
|
+
if (this.entry(refName)) {
|
|
3205
|
+
ref.log(`Output already has a field named '${refName}'`);
|
|
3206
|
+
}
|
|
3207
|
+
else {
|
|
3208
|
+
this.setEntry(refName, new ReferenceField(ref));
|
|
3209
|
+
}
|
|
3210
|
+
}
|
|
3211
|
+
addWild(wild) {
|
|
3212
|
+
this.setEntry(wild.refString, new WildSpaceField(wild.refString));
|
|
3213
|
+
}
|
|
3214
|
+
/**
|
|
3215
|
+
* Check for the definition of an ungrouping reference in the result space,
|
|
3216
|
+
* or in the case of an exclude reference, if this query is nested
|
|
3217
|
+
* in another query, in the result space of a query that this query
|
|
3218
|
+
* is nested inside of.
|
|
3219
|
+
*/
|
|
3220
|
+
checkUngroup(fn, isExclude) {
|
|
3221
|
+
if (!this.entry(fn.refString)) {
|
|
3222
|
+
if (isExclude && this.exprSpace.nestParent) {
|
|
3223
|
+
const parent = this.exprSpace.nestParent;
|
|
3224
|
+
parent.whenComplete(() => {
|
|
3225
|
+
parent.result.checkUngroup(fn, isExclude);
|
|
3226
|
+
});
|
|
3227
|
+
}
|
|
3228
|
+
else {
|
|
3229
|
+
const uName = isExclude ? "exclude()" : "all()";
|
|
3230
|
+
fn.log(`${uName} '${fn.refString}' is missing from query output`);
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
}
|
|
3234
|
+
addQueryItems(...qiList) {
|
|
3235
|
+
for (const qi of qiList) {
|
|
3236
|
+
if (qi instanceof FieldReference || qi instanceof NestReference) {
|
|
3237
|
+
this.addReference(qi);
|
|
3238
|
+
}
|
|
3239
|
+
else if (qi instanceof FieldDeclaration) {
|
|
3240
|
+
this.addField(qi);
|
|
3241
|
+
}
|
|
3242
|
+
else if (isNestedQuery(qi)) {
|
|
3243
|
+
const qf = new QueryFieldAST(this, qi, qi.name);
|
|
3244
|
+
qf.nestParent = this.exprSpace;
|
|
3245
|
+
this.setEntry(qi.name, qf);
|
|
3246
|
+
}
|
|
3247
|
+
else {
|
|
3248
|
+
// Compiler will error if we don't handle all cases
|
|
3249
|
+
const _itemNotHandled = qi;
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
canContain(_qd) {
|
|
3254
|
+
return true;
|
|
3255
|
+
}
|
|
3256
|
+
queryFieldDefs() {
|
|
3257
|
+
const fields = [];
|
|
3258
|
+
for (const [name, field] of this.entries()) {
|
|
3259
|
+
if (field instanceof SpaceField) {
|
|
3260
|
+
const fieldQueryDef = field.getQueryFieldDef(this.exprSpace);
|
|
3261
|
+
if (fieldQueryDef) {
|
|
3262
|
+
if (this.canContain(fieldQueryDef)) {
|
|
3263
|
+
fields.push(fieldQueryDef);
|
|
3264
|
+
}
|
|
3265
|
+
else {
|
|
3266
|
+
this.log(`'${name}' not legal in ${this.segmentType}`);
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
else {
|
|
3270
|
+
throw new Error(`'${name}' does not have a QueryFieldDef`);
|
|
3271
|
+
}
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
this.isComplete();
|
|
3275
|
+
return fields;
|
|
3276
|
+
}
|
|
3277
|
+
getQuerySegment(rf) {
|
|
3278
|
+
const p = this.getPipeSegment(rf);
|
|
3279
|
+
if (model.isQuerySegment(p)) {
|
|
3280
|
+
return p;
|
|
3281
|
+
}
|
|
3282
|
+
throw new Error("TODO NOT POSSIBLE");
|
|
3283
|
+
}
|
|
3284
|
+
getPipeSegment(refineFrom) {
|
|
3285
|
+
if (this.segmentType == "index") {
|
|
3286
|
+
// TODO ... should make this go away
|
|
3287
|
+
throw new Error("INDEX FIELD PIPE SEGMENT MIS HANDLED");
|
|
3288
|
+
}
|
|
3289
|
+
if (refineFrom === null || refineFrom === void 0 ? void 0 : refineFrom.extendSource) {
|
|
3290
|
+
for (const xField of refineFrom.extendSource) {
|
|
3291
|
+
this.exprSpace.addFieldDef(xField);
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
const segment = {
|
|
3295
|
+
type: this.segmentType,
|
|
3296
|
+
fields: this.queryFieldDefs(),
|
|
3297
|
+
};
|
|
3298
|
+
segment.fields = (0, field_utils_1.mergeFields)(refineFrom === null || refineFrom === void 0 ? void 0 : refineFrom.fields, segment.fields);
|
|
3299
|
+
if (refineFrom === null || refineFrom === void 0 ? void 0 : refineFrom.extendSource) {
|
|
3300
|
+
segment.extendSource = refineFrom.extendSource;
|
|
3301
|
+
}
|
|
3302
|
+
if (this.exprSpace.extendList.length > 0) {
|
|
3303
|
+
const newExtends = [];
|
|
3304
|
+
const extendedStruct = this.exprSpace.structDef();
|
|
3305
|
+
for (const extendName of this.exprSpace.extendList) {
|
|
3306
|
+
const extendEnt = extendedStruct.fields.find((f) => (0, field_utils_1.nameOf)(f) == extendName);
|
|
3307
|
+
if (extendEnt) {
|
|
3308
|
+
newExtends.push(extendEnt);
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
segment.extendSource = (0, field_utils_1.mergeFields)(segment.extendSource, newExtends);
|
|
3312
|
+
}
|
|
3313
|
+
this.isComplete();
|
|
3314
|
+
return segment;
|
|
3315
|
+
}
|
|
3316
|
+
}
|
|
3317
|
+
exports.ResultSpace = ResultSpace;
|
|
3318
|
+
/**
|
|
3319
|
+
* Reduce and project queries use a "QuerySpace"
|
|
3320
|
+
*/
|
|
3321
|
+
class ReduceFieldSpace extends ResultSpace {
|
|
3322
|
+
constructor() {
|
|
3323
|
+
super(...arguments);
|
|
3324
|
+
this.segmentType = "reduce";
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
exports.ReduceFieldSpace = ReduceFieldSpace;
|
|
3328
|
+
class ProjectFieldSpace extends ResultSpace {
|
|
3329
|
+
constructor() {
|
|
3330
|
+
super(...arguments);
|
|
3331
|
+
this.segmentType = "project";
|
|
3332
|
+
}
|
|
3333
|
+
canContain(qd) {
|
|
3334
|
+
if (typeof qd !== "string") {
|
|
3335
|
+
if (model.isFilteredAliasedName(qd)) {
|
|
3336
|
+
return true;
|
|
3337
|
+
}
|
|
3338
|
+
if (qd.type === "turtle") {
|
|
3339
|
+
this.log("Cannot nest queries in project");
|
|
3340
|
+
return false;
|
|
3341
|
+
}
|
|
3342
|
+
if (model.expressionIsAggregate(qd.expressionType)) {
|
|
3343
|
+
this.log("Cannot add aggregate measures to project");
|
|
3344
|
+
return false;
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
return true;
|
|
3348
|
+
}
|
|
3349
|
+
}
|
|
3350
|
+
exports.ProjectFieldSpace = ProjectFieldSpace;
|
|
3351
|
+
class SpaceEntry {
|
|
3352
|
+
}
|
|
3353
|
+
exports.SpaceEntry = SpaceEntry;
|
|
3354
|
+
class SpaceField extends SpaceEntry {
|
|
3355
|
+
constructor() {
|
|
3356
|
+
super(...arguments);
|
|
3357
|
+
this.refType = "field";
|
|
3358
|
+
}
|
|
3359
|
+
fieldTypeFromFieldDef(def) {
|
|
3360
|
+
const ref = { type: def.type };
|
|
3361
|
+
if (model.isFieldTypeDef(def) && def.expressionType) {
|
|
3362
|
+
ref.expressionType = def.expressionType;
|
|
3363
|
+
}
|
|
3364
|
+
return ref;
|
|
3365
|
+
}
|
|
3366
|
+
getQueryFieldDef(_fs) {
|
|
3367
|
+
return undefined;
|
|
3368
|
+
}
|
|
3369
|
+
fieldDef() {
|
|
3370
|
+
return undefined;
|
|
3371
|
+
}
|
|
3372
|
+
}
|
|
3373
|
+
exports.SpaceField = SpaceField;
|
|
3374
|
+
class StructSpaceField extends SpaceField {
|
|
3375
|
+
constructor(sourceDef) {
|
|
3376
|
+
super();
|
|
3377
|
+
this.sourceDef = sourceDef;
|
|
3378
|
+
}
|
|
3379
|
+
get fieldSpace() {
|
|
3380
|
+
if (!this.space) {
|
|
3381
|
+
this.space = new StaticSpace(this.sourceDef);
|
|
3382
|
+
}
|
|
3383
|
+
return this.space;
|
|
3384
|
+
}
|
|
3385
|
+
fieldDef() {
|
|
3386
|
+
return this.sourceDef;
|
|
3387
|
+
}
|
|
3388
|
+
type() {
|
|
3389
|
+
return { type: "struct" };
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
exports.StructSpaceField = StructSpaceField;
|
|
3393
|
+
class QueryField extends SpaceField {
|
|
3394
|
+
constructor(inSpace) {
|
|
3395
|
+
super();
|
|
3396
|
+
this.inSpace = inSpace;
|
|
3397
|
+
}
|
|
3398
|
+
type() {
|
|
3399
|
+
return { type: "turtle" };
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
exports.QueryField = QueryField;
|
|
3403
|
+
class QueryFieldStruct extends QueryField {
|
|
3404
|
+
constructor(fs, turtleDef) {
|
|
3405
|
+
super(fs);
|
|
3406
|
+
this.turtleDef = turtleDef;
|
|
3407
|
+
}
|
|
3408
|
+
rename(name) {
|
|
3409
|
+
this.turtleDef = {
|
|
3410
|
+
...this.turtleDef,
|
|
3411
|
+
as: name,
|
|
3412
|
+
};
|
|
3413
|
+
}
|
|
3414
|
+
fieldDef() {
|
|
3415
|
+
return this.turtleDef;
|
|
3416
|
+
}
|
|
3417
|
+
getQueryFieldDef(_fs) {
|
|
3418
|
+
return this.fieldDef();
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
exports.QueryFieldStruct = QueryFieldStruct;
|
|
3422
|
+
class ColumnSpaceField extends SpaceField {
|
|
3423
|
+
constructor(def) {
|
|
3424
|
+
super();
|
|
3425
|
+
this.def = def;
|
|
3426
|
+
}
|
|
3427
|
+
fieldDef() {
|
|
3428
|
+
return this.def;
|
|
3429
|
+
}
|
|
3430
|
+
type() {
|
|
3431
|
+
return this.fieldTypeFromFieldDef(this.def);
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
exports.ColumnSpaceField = ColumnSpaceField;
|
|
3435
|
+
class SpaceParam extends SpaceEntry {
|
|
3436
|
+
constructor() {
|
|
3437
|
+
super(...arguments);
|
|
3438
|
+
this.refType = "parameter";
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
exports.SpaceParam = SpaceParam;
|
|
3442
|
+
class DefinedParameter extends SpaceParam {
|
|
3443
|
+
constructor(paramDef) {
|
|
3444
|
+
super();
|
|
3445
|
+
this.paramDef = paramDef;
|
|
3446
|
+
}
|
|
3447
|
+
parameter() {
|
|
3448
|
+
return this.paramDef;
|
|
3449
|
+
}
|
|
3450
|
+
type() {
|
|
3451
|
+
return { type: this.paramDef.type };
|
|
3452
|
+
}
|
|
3453
|
+
}
|
|
3454
|
+
exports.DefinedParameter = DefinedParameter;
|
|
3455
|
+
/**
|
|
3456
|
+
* Based on how things are constructed, the starting field space
|
|
3457
|
+
* can either be another field space or an existing structdef.
|
|
3458
|
+
* Using a SpaceSeed allows a class to accept either one
|
|
3459
|
+
* and use either version at some future time.
|
|
3460
|
+
*/
|
|
3461
|
+
class SpaceSeed {
|
|
3462
|
+
constructor(sourceSpec) {
|
|
3463
|
+
this.sourceSpec = sourceSpec;
|
|
3464
|
+
this.spaceSpec = sourceSpec;
|
|
3465
|
+
}
|
|
3466
|
+
get structDef() {
|
|
3467
|
+
if (isFieldSpace(this.spaceSpec)) {
|
|
3468
|
+
if (!this.asStruct) {
|
|
3469
|
+
this.asStruct = this.spaceSpec.structDef();
|
|
3470
|
+
}
|
|
3471
|
+
return this.asStruct;
|
|
3472
|
+
}
|
|
3473
|
+
return this.spaceSpec;
|
|
3474
|
+
}
|
|
3475
|
+
get fieldSpace() {
|
|
3476
|
+
if (isFieldSpace(this.spaceSpec)) {
|
|
3477
|
+
return this.spaceSpec;
|
|
3478
|
+
}
|
|
3479
|
+
if (!this.asFS) {
|
|
3480
|
+
this.asFS = new StaticSpace(this.spaceSpec);
|
|
3481
|
+
}
|
|
3482
|
+
return this.asFS;
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
exports.SpaceSeed = SpaceSeed;
|
|
3486
|
+
function isFieldSpace(x) {
|
|
3487
|
+
return x.type == "fieldSpace";
|
|
3488
|
+
}
|
|
3489
|
+
class AbstractParameter extends SpaceParam {
|
|
3490
|
+
constructor(astParam) {
|
|
3491
|
+
super();
|
|
3492
|
+
this.astParam = astParam;
|
|
3493
|
+
}
|
|
3494
|
+
parameter() {
|
|
3495
|
+
return this.astParam.parameter();
|
|
3496
|
+
}
|
|
3497
|
+
type() {
|
|
3498
|
+
const type = this.astParam.type || "unknown";
|
|
3499
|
+
return { type };
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
exports.AbstractParameter = AbstractParameter;
|
|
3503
|
+
class ExpressionFieldFromAst extends SpaceField {
|
|
3504
|
+
constructor(space, exprDef) {
|
|
3505
|
+
super();
|
|
3506
|
+
this.space = space;
|
|
3507
|
+
this.exprDef = exprDef;
|
|
3508
|
+
this.fieldName = exprDef.defineName;
|
|
3509
|
+
}
|
|
3510
|
+
get name() {
|
|
3511
|
+
return this.fieldName;
|
|
3512
|
+
}
|
|
3513
|
+
fieldDef() {
|
|
3514
|
+
const def = this.exprDef.fieldDef(this.space, this.name);
|
|
3515
|
+
this.defType = this.fieldTypeFromFieldDef(def);
|
|
3516
|
+
return def;
|
|
3517
|
+
}
|
|
3518
|
+
getQueryFieldDef(fs) {
|
|
3519
|
+
const def = this.exprDef.queryFieldDef(fs, this.name);
|
|
3520
|
+
this.defType = this.fieldTypeFromFieldDef(def);
|
|
3521
|
+
return def;
|
|
3522
|
+
}
|
|
3523
|
+
type() {
|
|
3524
|
+
if (this.defType) {
|
|
3525
|
+
return this.defType;
|
|
3526
|
+
}
|
|
3527
|
+
return this.fieldTypeFromFieldDef(this.fieldDef());
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
exports.ExpressionFieldFromAst = ExpressionFieldFromAst;
|
|
3531
|
+
class QueryFieldAST extends QueryField {
|
|
3532
|
+
constructor(fs, turtle, name) {
|
|
3533
|
+
super(fs);
|
|
3534
|
+
this.turtle = turtle;
|
|
3535
|
+
this.name = name;
|
|
3536
|
+
}
|
|
3537
|
+
getQueryFieldDef(fs) {
|
|
3538
|
+
const def = this.turtle.getFieldDef(fs, this.nestParent);
|
|
3539
|
+
if (this.renameAs) {
|
|
3540
|
+
def.as = this.renameAs;
|
|
3541
|
+
}
|
|
3542
|
+
return def;
|
|
3543
|
+
}
|
|
3544
|
+
fieldDef() {
|
|
3545
|
+
const def = this.turtle.getFieldDef(this.inSpace, this.nestParent);
|
|
3546
|
+
if (this.renameAs) {
|
|
3547
|
+
def.as = this.renameAs;
|
|
3548
|
+
}
|
|
3549
|
+
return def;
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
exports.QueryFieldAST = QueryFieldAST;
|
|
3553
|
+
class RenameSpaceField extends SpaceField {
|
|
3554
|
+
constructor(otherField, newName, location) {
|
|
3555
|
+
super();
|
|
3556
|
+
this.otherField = otherField;
|
|
3557
|
+
this.newName = newName;
|
|
3558
|
+
this.location = location;
|
|
3559
|
+
}
|
|
3560
|
+
fieldDef() {
|
|
3561
|
+
const renamedFieldRaw = this.otherField.fieldDef();
|
|
3562
|
+
if (renamedFieldRaw === undefined) {
|
|
3563
|
+
return undefined;
|
|
3564
|
+
}
|
|
3565
|
+
return {
|
|
3566
|
+
...renamedFieldRaw,
|
|
3567
|
+
as: this.newName,
|
|
3568
|
+
location: this.location,
|
|
3569
|
+
};
|
|
3570
|
+
}
|
|
3571
|
+
type() {
|
|
3572
|
+
return this.otherField.type();
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
exports.RenameSpaceField = RenameSpaceField;
|
|
3576
|
+
class JoinSpaceField extends StructSpaceField {
|
|
3577
|
+
constructor(intoFS, join) {
|
|
3578
|
+
super(join.structDef());
|
|
3579
|
+
this.intoFS = intoFS;
|
|
3580
|
+
this.join = join;
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
exports.JoinSpaceField = JoinSpaceField;
|
|
3584
|
+
/**
|
|
3585
|
+
* Unlike a source, which is a refinement of a namespace, a query
|
|
3586
|
+
* is creating a new unrelated namespace. The query starts with a
|
|
3587
|
+
* source, which it might modify. This set of fields used to resolve
|
|
3588
|
+
* expressions in the query is called the "input space". There is a
|
|
3589
|
+
* specialized QuerySpace for each type of query operation.
|
|
3590
|
+
*
|
|
3591
|
+
* The query output is managed by an instance of ResultSpace.
|
|
3592
|
+
*/
|
|
3593
|
+
class QuerySpace extends DynamicSpace {
|
|
3594
|
+
constructor(input, result) {
|
|
3595
|
+
const inputSpace = new SpaceSeed(input);
|
|
3596
|
+
super(inputSpace.structDef);
|
|
3597
|
+
this.result = result;
|
|
3598
|
+
this.extendList = [];
|
|
3599
|
+
}
|
|
3600
|
+
extendSource(extendField) {
|
|
3601
|
+
this.addField(extendField);
|
|
3602
|
+
if (extendField instanceof Join) {
|
|
3603
|
+
this.extendList.push(extendField.name.refString);
|
|
3604
|
+
}
|
|
3605
|
+
else {
|
|
3606
|
+
this.extendList.push(extendField.defineName);
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
exports.QuerySpace = QuerySpace;
|
|
3611
|
+
class ReferenceField extends SpaceField {
|
|
3612
|
+
constructor(fieldRef) {
|
|
3613
|
+
super();
|
|
3614
|
+
this.fieldRef = fieldRef;
|
|
3615
|
+
}
|
|
3616
|
+
getQueryFieldDef(fs) {
|
|
3617
|
+
// Lookup string and generate error if it isn't defined.
|
|
3618
|
+
const check = this.fieldRef.getField(fs);
|
|
3619
|
+
if (check.error) {
|
|
3620
|
+
this.fieldRef.log(check.error);
|
|
3621
|
+
}
|
|
3622
|
+
return this.fieldRef.refString;
|
|
3623
|
+
}
|
|
3624
|
+
type() {
|
|
3625
|
+
return { type: "unknown" };
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
exports.ReferenceField = ReferenceField;
|
|
3629
|
+
class WildSpaceField extends SpaceField {
|
|
3630
|
+
constructor(wildText) {
|
|
3631
|
+
super();
|
|
3632
|
+
this.wildText = wildText;
|
|
3633
|
+
}
|
|
3634
|
+
type() {
|
|
3635
|
+
throw new Error("should never ask a wild field for its type");
|
|
3636
|
+
}
|
|
3637
|
+
getQueryFieldDef(_fs) {
|
|
3638
|
+
return this.wildText;
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
exports.WildSpaceField = WildSpaceField;
|
|
3642
|
+
class IndexFieldSpace extends ResultSpace {
|
|
3643
|
+
constructor() {
|
|
3644
|
+
super(...arguments);
|
|
3645
|
+
this.segmentType = "index";
|
|
3646
|
+
this.fieldList = new Set();
|
|
3647
|
+
}
|
|
3648
|
+
addReference(ref) {
|
|
3649
|
+
if (ref.getField(this.exprSpace).found) {
|
|
3650
|
+
this.fieldList.add(ref.refString);
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
addWild(wild) {
|
|
3654
|
+
this.fieldList.add(wild.refString);
|
|
3655
|
+
}
|
|
3656
|
+
getPipeSegment(refineIndex) {
|
|
3657
|
+
if (refineIndex && refineIndex.fields) {
|
|
3658
|
+
for (const exists of refineIndex.fields) {
|
|
3659
|
+
if (typeof exists == "string") {
|
|
3660
|
+
this.fieldList.add(exists);
|
|
3661
|
+
}
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
3664
|
+
this.isComplete();
|
|
3665
|
+
return {
|
|
3666
|
+
type: "index",
|
|
3667
|
+
fields: Array.from(this.fieldList.values()),
|
|
3668
|
+
};
|
|
3669
|
+
}
|
|
3670
|
+
}
|
|
3671
|
+
exports.IndexFieldSpace = IndexFieldSpace;
|
|
2858
3672
|
//# sourceMappingURL=ast-main.js.map
|