@malloydata/malloy 0.0.22-dev230126015148 → 0.0.22-dev230202171033
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-main.d.ts +18 -815
- package/dist/lang/ast/ast-main.js +106 -3241
- package/dist/lang/ast/ast-utils.d.ts +10 -0
- package/dist/lang/ast/ast-utils.js +42 -0
- package/dist/lang/ast/elements/define-explore.d.ts +17 -0
- package/dist/lang/ast/elements/define-explore.js +79 -0
- package/dist/lang/ast/elements/define-query.d.ts +14 -0
- package/dist/lang/ast/elements/define-query.js +56 -0
- package/dist/lang/ast/elements/mallobj.d.ts +12 -0
- package/dist/lang/ast/elements/mallobj.js +53 -0
- package/dist/lang/ast/elements/pipeline-desc.d.ts +28 -0
- package/dist/lang/ast/elements/pipeline-desc.js +102 -0
- package/dist/lang/ast/elements/refined-explore.d.ts +15 -0
- package/dist/lang/ast/elements/refined-explore.js +121 -0
- package/dist/lang/ast/error-factory.d.ts +9 -0
- package/dist/lang/ast/error-factory.js +61 -0
- package/dist/lang/ast/executors/index-executor.d.ts +18 -0
- package/dist/lang/ast/executors/index-executor.js +96 -0
- package/dist/lang/ast/executors/project-executor.d.ts +10 -0
- package/dist/lang/ast/executors/project-executor.js +68 -0
- package/dist/lang/ast/executors/reduce-executor.d.ts +20 -0
- package/dist/lang/ast/executors/reduce-executor.js +149 -0
- package/dist/lang/ast/explore-properties/field-list-edit.d.ts +8 -0
- package/dist/lang/ast/explore-properties/field-list-edit.js +36 -0
- package/dist/lang/ast/explore-properties/primary-key.d.ts +7 -0
- package/dist/lang/ast/{apply-expr.js → explore-properties/primary-key.js} +9 -8
- package/dist/lang/ast/explore-properties/renames.d.ts +11 -0
- package/dist/lang/ast/explore-properties/renames.js +43 -0
- package/dist/lang/ast/explore-properties/turtles.d.ts +5 -0
- package/dist/lang/ast/explore-properties/turtles.js +33 -0
- package/dist/lang/ast/expressions/apply.d.ts +8 -0
- package/dist/lang/ast/expressions/apply.js +37 -0
- package/dist/lang/ast/expressions/binary-boolean.d.ts +12 -0
- package/dist/lang/ast/expressions/binary-boolean.js +54 -0
- package/dist/lang/ast/expressions/binary-numeric.d.ts +11 -0
- package/dist/lang/ast/expressions/binary-numeric.js +42 -0
- package/dist/lang/ast/expressions/boolean.d.ts +8 -0
- package/dist/lang/ast/expressions/boolean.js +39 -0
- package/dist/lang/ast/expressions/constant-sub-expression.d.ts +16 -0
- package/dist/lang/ast/expressions/constant-sub-expression.js +98 -0
- package/dist/lang/ast/expressions/expr-add-sub.d.ts +4 -0
- package/dist/lang/ast/expressions/expr-add-sub.js +34 -0
- package/dist/lang/ast/expressions/expr-aggregate-function.d.ts +15 -0
- package/dist/lang/ast/expressions/expr-aggregate-function.js +99 -0
- package/dist/lang/ast/expressions/expr-alternation-tree.d.ts +11 -0
- package/dist/lang/ast/expressions/expr-alternation-tree.js +54 -0
- package/dist/lang/ast/expressions/expr-asymmetric.d.ts +10 -0
- package/dist/lang/ast/expressions/expr-asymmetric.js +27 -0
- package/dist/lang/ast/expressions/expr-avg.d.ts +6 -0
- package/dist/lang/ast/expressions/expr-avg.js +34 -0
- package/dist/lang/ast/expressions/expr-case.d.ts +11 -0
- package/dist/lang/ast/expressions/expr-case.js +84 -0
- package/dist/lang/ast/expressions/expr-cast.d.ts +13 -0
- package/dist/lang/ast/expressions/expr-cast.js +29 -0
- package/dist/lang/ast/expressions/expr-compare.d.ts +10 -0
- package/dist/lang/ast/expressions/expr-compare.js +48 -0
- package/dist/lang/ast/expressions/expr-count-distinct.d.ts +6 -0
- package/dist/lang/ast/expressions/expr-count-distinct.js +35 -0
- package/dist/lang/ast/expressions/expr-count.d.ts +11 -0
- package/dist/lang/ast/expressions/expr-count.js +57 -0
- package/dist/lang/ast/expressions/expr-filter.d.ts +12 -0
- package/dist/lang/ast/expressions/expr-filter.js +69 -0
- package/dist/lang/ast/expressions/expr-func.d.ts +10 -0
- package/dist/lang/ast/expressions/expr-func.js +63 -0
- package/dist/lang/ast/expressions/expr-granular-time.d.ts +24 -0
- package/dist/lang/ast/expressions/expr-granular-time.js +117 -0
- package/dist/lang/ast/expressions/expr-id-reference.d.ts +12 -0
- package/dist/lang/ast/expressions/expr-id-reference.js +76 -0
- package/dist/lang/ast/expressions/expr-logical-op.d.ts +9 -0
- package/dist/lang/ast/expressions/expr-logical-op.js +36 -0
- package/dist/lang/ast/expressions/expr-max.d.ts +9 -0
- package/dist/lang/ast/expressions/expr-max.js +16 -0
- package/dist/lang/ast/expressions/expr-min.d.ts +9 -0
- package/dist/lang/ast/expressions/expr-min.js +16 -0
- package/dist/lang/ast/expressions/expr-minus.d.ts +9 -0
- package/dist/lang/ast/expressions/expr-minus.js +48 -0
- package/dist/lang/ast/expressions/expr-mul-div.d.ts +4 -0
- package/dist/lang/ast/expressions/expr-mul-div.js +34 -0
- package/dist/lang/ast/expressions/expr-not.d.ts +10 -0
- package/dist/lang/ast/expressions/expr-not.js +49 -0
- package/dist/lang/ast/expressions/expr-now.d.ts +7 -0
- package/dist/lang/ast/expressions/expr-now.js +46 -0
- package/dist/lang/ast/expressions/expr-null.d.ts +6 -0
- package/dist/lang/ast/expressions/expr-null.js +41 -0
- package/dist/lang/ast/expressions/expr-number.d.ts +10 -0
- package/dist/lang/ast/expressions/expr-number.js +42 -0
- package/dist/lang/ast/expressions/expr-parens.d.ts +10 -0
- package/dist/lang/ast/expressions/expr-parens.js +42 -0
- package/dist/lang/ast/expressions/expr-regex.d.ts +8 -0
- package/dist/lang/ast/expressions/expr-regex.js +42 -0
- package/dist/lang/ast/expressions/expr-string.d.ts +9 -0
- package/dist/lang/ast/expressions/expr-string.js +50 -0
- package/dist/lang/ast/expressions/expr-sum.d.ts +6 -0
- package/dist/lang/ast/expressions/expr-sum.js +12 -0
- package/dist/lang/ast/expressions/expr-time-extract.d.ts +13 -0
- package/dist/lang/ast/expressions/expr-time-extract.js +117 -0
- package/dist/lang/ast/expressions/expr-time.d.ts +11 -0
- package/dist/lang/ast/expressions/expr-time.js +62 -0
- package/dist/lang/ast/expressions/expr-ungroup.d.ts +14 -0
- package/dist/lang/ast/expressions/expr-ungroup.js +83 -0
- package/dist/lang/ast/expressions/for-range.d.ts +19 -0
- package/dist/lang/ast/expressions/for-range.js +101 -0
- package/dist/lang/ast/expressions/granular-literal.d.ts +20 -0
- package/dist/lang/ast/expressions/granular-literal.js +148 -0
- package/dist/lang/ast/expressions/partial-compare.d.ts +14 -0
- package/dist/lang/ast/expressions/partial-compare.js +50 -0
- package/dist/lang/ast/expressions/pick-when.d.ts +19 -0
- package/dist/lang/ast/expressions/pick-when.js +156 -0
- package/dist/lang/ast/expressions/range.d.ts +12 -0
- package/dist/lang/ast/expressions/range.js +80 -0
- package/dist/lang/ast/expressions/time-frame.d.ts +7 -0
- package/dist/lang/ast/expressions/time-frame.js +40 -0
- package/dist/lang/ast/expressions/top-by.d.ts +10 -0
- package/dist/lang/ast/expressions/top-by.js +51 -0
- package/dist/lang/ast/expressions/unary.d.ts +5 -0
- package/dist/lang/ast/expressions/unary.js +34 -0
- package/dist/lang/ast/expressions/utils.d.ts +15 -0
- package/dist/lang/ast/expressions/utils.js +106 -0
- package/dist/lang/ast/expressions/when-clause.d.ts +10 -0
- package/dist/lang/ast/expressions/when-clause.js +17 -0
- package/dist/lang/ast/fragtype-utils.d.ts +39 -0
- package/dist/lang/ast/fragtype-utils.js +100 -0
- package/dist/lang/ast/import-elements/import-statement.d.ts +9 -0
- package/dist/lang/ast/import-elements/import-statement.js +78 -0
- package/dist/lang/ast/index.d.ts +94 -3
- package/dist/lang/ast/index.js +94 -3
- package/dist/lang/ast/json-elements/json-element.d.ts +6 -0
- package/dist/lang/ast/json-elements/json-element.js +41 -0
- package/dist/lang/ast/json-elements/json-struct-def.d.ts +10 -0
- package/dist/lang/ast/json-elements/json-struct-def.js +48 -0
- package/dist/lang/ast/nesting/nest-reference.d.ts +7 -0
- package/dist/lang/ast/nesting/nest-reference.js +35 -0
- package/dist/lang/ast/parameters/constant-parameter.d.ts +8 -0
- package/dist/lang/ast/parameters/constant-parameter.js +54 -0
- package/dist/lang/ast/parameters/has-parameter.d.ts +19 -0
- package/dist/lang/ast/parameters/has-parameter.js +64 -0
- package/dist/lang/ast/query-elements/anonymous-query.d.ts +9 -0
- package/dist/lang/ast/query-elements/anonymous-query.js +41 -0
- package/dist/lang/ast/query-elements/existing-query.d.ts +11 -0
- package/dist/lang/ast/query-elements/existing-query.js +79 -0
- package/dist/lang/ast/query-elements/full-query.d.ts +10 -0
- package/dist/lang/ast/query-elements/full-query.js +85 -0
- package/dist/lang/ast/query-elements/query-head-struct.d.ts +9 -0
- package/dist/lang/ast/query-elements/query-head-struct.js +48 -0
- package/dist/lang/ast/query-items/field-declaration.d.ts +31 -0
- package/dist/lang/ast/query-items/field-declaration.js +137 -0
- package/dist/lang/ast/query-items/field-references.d.ts +25 -0
- package/dist/lang/ast/query-items/field-references.js +80 -0
- package/dist/lang/ast/query-properties/aggregate.d.ts +5 -0
- package/dist/lang/ast/query-properties/aggregate.js +39 -0
- package/dist/lang/ast/query-properties/declare-fields.d.ts +5 -0
- package/dist/lang/ast/query-properties/declare-fields.js +33 -0
- package/dist/lang/ast/query-properties/dimmensions.d.ts +5 -0
- package/dist/lang/ast/query-properties/dimmensions.js +36 -0
- package/dist/lang/ast/query-properties/filters.d.ts +18 -0
- package/dist/lang/ast/query-properties/filters.js +89 -0
- package/dist/lang/ast/query-properties/group-by.d.ts +5 -0
- package/dist/lang/ast/query-properties/group-by.js +39 -0
- package/dist/lang/ast/query-properties/indexing.d.ts +10 -0
- package/dist/lang/ast/query-properties/indexing.js +39 -0
- package/dist/lang/ast/query-properties/joins.d.ts +36 -0
- package/dist/lang/ast/query-properties/joins.js +143 -0
- package/dist/lang/ast/query-properties/limit.d.ts +6 -0
- package/dist/lang/ast/query-properties/limit.js +35 -0
- package/dist/lang/ast/query-properties/measures.d.ts +5 -0
- package/dist/lang/ast/query-properties/measures.js +36 -0
- package/dist/lang/ast/query-properties/nests.d.ts +5 -0
- package/dist/lang/ast/query-properties/nests.js +33 -0
- package/dist/lang/ast/query-properties/ordering.d.ts +15 -0
- package/dist/lang/ast/query-properties/ordering.js +66 -0
- package/dist/lang/ast/query-properties/project-statement.d.ts +5 -0
- package/dist/lang/ast/query-properties/project-statement.js +33 -0
- package/dist/lang/ast/query-properties/qop-desc.d.ts +17 -0
- package/dist/lang/ast/query-properties/qop-desc.js +123 -0
- package/dist/lang/ast/query-properties/sampling.d.ts +8 -0
- package/dist/lang/ast/query-properties/sampling.js +38 -0
- package/dist/lang/ast/query-properties/top.d.ts +13 -0
- package/dist/lang/ast/query-properties/top.js +60 -0
- package/dist/lang/ast/result-spaces/index-field-space.d.ts +10 -0
- package/dist/lang/ast/result-spaces/index-field-space.js +57 -0
- package/dist/lang/ast/result-spaces/project-field-space.d.ts +6 -0
- package/dist/lang/ast/result-spaces/project-field-space.js +51 -0
- package/dist/lang/ast/result-spaces/reduce-field-space.d.ts +7 -0
- package/dist/lang/ast/result-spaces/reduce-field-space.js +37 -0
- package/dist/lang/ast/sources/named-source.d.ts +19 -0
- package/dist/lang/ast/sources/named-source.js +147 -0
- package/dist/lang/ast/sources/query-source.d.ts +9 -0
- package/dist/lang/ast/sources/query-source.js +41 -0
- package/dist/lang/ast/sources/sql-source.d.ts +7 -0
- package/dist/lang/ast/sources/sql-source.js +54 -0
- package/dist/lang/ast/sources/table-source.d.ts +8 -0
- package/dist/lang/ast/sources/table-source.js +60 -0
- package/dist/lang/ast/space-fields/column-space-field.d.ts +9 -0
- package/dist/lang/ast/space-fields/column-space-field.js +40 -0
- package/dist/lang/ast/space-fields/join-space-field.d.ts +8 -0
- package/dist/lang/ast/space-fields/join-space-field.js +35 -0
- package/dist/lang/ast/space-fields/query-field-struct.d.ts +10 -0
- package/dist/lang/ast/space-fields/query-field-struct.js +46 -0
- package/dist/lang/ast/space-fields/query-space-field.d.ts +11 -0
- package/dist/lang/ast/space-fields/query-space-field.js +37 -0
- package/dist/lang/ast/space-fields/reference-field.d.ts +11 -0
- package/dist/lang/ast/space-fields/reference-field.js +45 -0
- package/dist/lang/ast/space-fields/rename-space-field.d.ts +11 -0
- package/dist/lang/ast/space-fields/rename-space-field.js +50 -0
- package/dist/lang/ast/space-fields/wild-space-field.d.ts +10 -0
- package/dist/lang/ast/space-fields/wild-space-field.js +40 -0
- package/dist/lang/ast/space-parameters/abstract-parameter.d.ts +10 -0
- package/dist/lang/ast/space-parameters/abstract-parameter.js +41 -0
- package/dist/lang/ast/space-parameters/defined-parameter.d.ts +9 -0
- package/dist/lang/ast/space-parameters/defined-parameter.js +40 -0
- package/dist/lang/ast/space-seed.d.ts +17 -0
- package/dist/lang/ast/space-seed.js +59 -0
- package/dist/lang/ast/sql-elements/sql-statement.d.ts +19 -0
- package/dist/lang/ast/sql-elements/sql-statement.js +80 -0
- package/dist/lang/ast/sql-elements/sql-string.d.ts +12 -0
- package/dist/lang/ast/sql-elements/sql-string.js +60 -0
- package/dist/lang/ast/static-space.d.ts +33 -0
- package/dist/lang/ast/static-space.js +167 -0
- package/dist/lang/ast/struct-utils.d.ts +4 -0
- package/dist/lang/ast/struct-utils.js +48 -0
- package/dist/lang/ast/time-utils.d.ts +5 -2
- package/dist/lang/ast/time-utils.js +37 -1
- package/dist/lang/ast/types/comparison.d.ts +11 -0
- package/dist/lang/ast/types/comparison.js +41 -0
- package/dist/lang/ast/types/compart-types.d.ts +10 -0
- package/dist/lang/ast/types/compart-types.js +37 -0
- package/dist/lang/ast/types/document-compile-result.d.ts +8 -0
- package/dist/lang/ast/types/document-compile-result.js +25 -0
- package/dist/lang/ast/types/equality.d.ts +7 -0
- package/dist/lang/ast/types/equality.js +37 -0
- package/dist/lang/ast/types/executor.d.ts +9 -0
- package/dist/lang/ast/types/executor.js +25 -0
- package/dist/lang/ast/types/explore-desc.d.ts +5 -0
- package/dist/lang/ast/types/explore-desc.js +33 -0
- package/dist/lang/ast/types/explore-field.d.ts +5 -0
- package/dist/lang/ast/types/explore-field.js +32 -0
- package/dist/lang/ast/types/explore-property.d.ts +10 -0
- package/dist/lang/ast/types/explore-property.js +43 -0
- package/dist/lang/ast/types/expr-result.d.ts +5 -0
- package/dist/lang/ast/types/expr-result.js +25 -0
- package/dist/lang/ast/types/expr-value.d.ts +3 -0
- package/dist/lang/ast/types/expr-value.js +25 -0
- package/dist/lang/ast/types/expression-def.d.ts +69 -0
- package/dist/lang/ast/types/expression-def.js +346 -0
- package/dist/lang/ast/types/expression-value-type.d.ts +2 -0
- package/dist/lang/ast/types/expression-value-type.js +25 -0
- package/dist/lang/ast/types/field-collection-member.d.ts +5 -0
- package/dist/lang/ast/types/field-collection-member.js +34 -0
- package/dist/lang/ast/types/field-decl.d.ts +7 -0
- package/dist/lang/ast/types/field-decl.js +37 -0
- package/dist/lang/ast/types/field-map.d.ts +2 -0
- package/dist/lang/ast/types/field-map.js +25 -0
- package/dist/lang/ast/types/field-space.d.ts +26 -0
- package/dist/lang/ast/types/field-space.js +48 -0
- package/dist/lang/ast/types/field-type.d.ts +6 -0
- package/dist/lang/ast/types/field-type.js +25 -0
- package/dist/lang/ast/types/field-value-type.d.ts +3 -0
- package/dist/lang/ast/types/field-value-type.js +25 -0
- package/dist/lang/ast/types/frag-type.d.ts +6 -0
- package/dist/lang/ast/types/frag-type.js +25 -0
- package/dist/lang/ast/types/granular-result.d.ts +7 -0
- package/dist/lang/ast/types/granular-result.js +11 -0
- package/dist/lang/ast/types/lookup-result.d.ts +10 -0
- package/dist/lang/ast/types/lookup-result.js +25 -0
- package/dist/lang/ast/types/malloy-element.d.ts +105 -0
- package/dist/lang/ast/types/malloy-element.js +398 -0
- package/dist/lang/ast/types/model-entry.d.ts +6 -0
- package/dist/lang/ast/types/model-entry.js +25 -0
- package/dist/lang/ast/types/name-space.d.ts +5 -0
- package/dist/lang/ast/types/name-space.js +25 -0
- package/dist/lang/ast/types/nested-query.d.ts +3 -0
- package/dist/lang/ast/types/nested-query.js +25 -0
- package/dist/lang/ast/types/op-desc.d.ts +6 -0
- package/dist/lang/ast/types/op-desc.js +25 -0
- package/dist/lang/ast/types/query-comp.d.ts +5 -0
- package/dist/lang/ast/types/query-comp.js +25 -0
- package/dist/lang/ast/types/query-element.d.ts +5 -0
- package/dist/lang/ast/types/query-element.js +32 -0
- package/dist/lang/ast/types/query-item.d.ts +5 -0
- package/dist/lang/ast/types/query-item.js +25 -0
- package/dist/lang/ast/types/query-property.d.ts +17 -0
- package/dist/lang/ast/types/query-property.js +55 -0
- package/dist/lang/ast/types/space-entry.d.ts +5 -0
- package/dist/lang/ast/types/space-entry.js +29 -0
- package/dist/lang/ast/types/space-field.d.ts +10 -0
- package/dist/lang/ast/types/space-field.js +48 -0
- package/dist/lang/ast/types/space-param.d.ts +6 -0
- package/dist/lang/ast/types/space-param.js +34 -0
- package/dist/lang/ast/types/stage-field-type.d.ts +1 -0
- package/dist/lang/ast/types/stage-field-type.js +25 -0
- package/dist/lang/ast/types/time-result.d.ts +6 -0
- package/dist/lang/ast/types/time-result.js +25 -0
- package/dist/lang/ast/types/turtle-headed-pipe.d.ts +7 -0
- package/dist/lang/ast/types/turtle-headed-pipe.js +37 -0
- package/dist/lang/space-field.d.ts +4 -1
- package/dist/lang/space-field.js +4 -3
- package/dist/lang/test/field-symbols.spec.js +25 -21
- package/dist/lang/test/parse.spec.js +4 -3
- package/dist/lang/test/test-translator.d.ts +3 -1
- package/package.json +1 -1
- package/dist/lang/ast/apply-expr.d.ts +0 -3
- package/dist/lang/ast/ast-expr.d.ts +0 -206
- package/dist/lang/ast/ast-expr.js +0 -781
- package/dist/lang/ast/ast-time-expr.d.ts +0 -69
- package/dist/lang/ast/ast-time-expr.js +0 -389
- package/dist/lang/ast/ast-types.d.ts +0 -83
- package/dist/lang/ast/ast-types.js +0 -225
|
@@ -23,9 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.
|
|
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;
|
|
26
|
+
exports.QuerySpace = exports.QueryFieldAST = exports.ExpressionFieldFromAst = exports.ResultSpace = exports.DynamicSpace = exports.isNestedQuery = exports.NestDefinition = exports.NestRefinement = exports.TurtleDecl = void 0;
|
|
29
27
|
/*
|
|
30
28
|
* Copyright 2023 Google LLC
|
|
31
29
|
*
|
|
@@ -50,2967 +48,111 @@ exports.IndexFieldSpace = exports.WildSpaceField = exports.ReferenceField = expo
|
|
|
50
48
|
*/
|
|
51
49
|
const lodash_1 = require("lodash");
|
|
52
50
|
const model = __importStar(require("../../model/malloy_types"));
|
|
53
|
-
const dialect_map_1 = require("../../dialect/dialect_map");
|
|
54
|
-
const malloy_types_1 = require("../../model/malloy_types");
|
|
55
|
-
const malloy_query_1 = require("../../model/malloy_query");
|
|
56
|
-
const ast_types_1 = require("./ast-types");
|
|
57
|
-
const sql_block_1 = require("../../model/sql_block");
|
|
58
|
-
const util_1 = require("util");
|
|
59
|
-
const time_utils_1 = require("./time-utils");
|
|
60
|
-
const apply_expr_1 = require("./apply-expr");
|
|
61
51
|
const field_utils_1 = require("../field-utils");
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return s.name.includes(theErrorStruct.name);
|
|
84
|
-
}
|
|
85
|
-
static get query() {
|
|
86
|
-
return {
|
|
87
|
-
structRef: ErrorFactory.structDef,
|
|
88
|
-
pipeline: [],
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
static get reduceSegment() {
|
|
92
|
-
return { type: "reduce", fields: [] };
|
|
93
|
-
}
|
|
94
|
-
static get projectSegment() {
|
|
95
|
-
return { type: "project", fields: [] };
|
|
96
|
-
}
|
|
97
|
-
static get indexSegment() {
|
|
98
|
-
return { type: "index", fields: [] };
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
exports.ErrorFactory = ErrorFactory;
|
|
102
|
-
function opOutputStruct(logTo, inputStruct, opDesc) {
|
|
103
|
-
const badModel = ErrorFactory.isErrorStructDef(inputStruct);
|
|
104
|
-
// Don't call into the model code with a broken model
|
|
105
|
-
if (!badModel) {
|
|
106
|
-
try {
|
|
107
|
-
return malloy_query_1.Segment.nextStructDef(inputStruct, opDesc);
|
|
108
|
-
}
|
|
109
|
-
catch (e) {
|
|
110
|
-
logTo.log(`INTERNAL ERROR model/Segment.nextStructDef: ${e.message}\n` +
|
|
111
|
-
`QUERY: ${(0, util_1.inspect)(opDesc, { breakLength: 72, depth: Infinity })}`);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return { ...ErrorFactory.structDef, dialect: inputStruct.dialect };
|
|
115
|
-
}
|
|
116
|
-
class MalloyElement {
|
|
117
|
-
/**
|
|
118
|
-
* @param kids All children passed to the constructor are not optional
|
|
119
|
-
*/
|
|
120
|
-
constructor(kids) {
|
|
121
|
-
this.children = {};
|
|
122
|
-
this.parent = null;
|
|
123
|
-
this.logged = new Set();
|
|
124
|
-
if (kids) {
|
|
125
|
-
this.has(kids);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Record all elements as children of this element, and mark this
|
|
130
|
-
* element as their parent.
|
|
131
|
-
* @param kids Some of these might be undefined, in which case they are ignored
|
|
132
|
-
*/
|
|
133
|
-
has(kids) {
|
|
134
|
-
for (const kidName in kids) {
|
|
135
|
-
const kidValue = kids[kidName];
|
|
136
|
-
if (kidValue !== undefined) {
|
|
137
|
-
this.children[kidName] = kidValue;
|
|
138
|
-
if (kidValue instanceof MalloyElement) {
|
|
139
|
-
kidValue.parent = this;
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
for (const oneKid of kidValue) {
|
|
143
|
-
oneKid.parent = this;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
get location() {
|
|
150
|
-
if (this.codeLocation) {
|
|
151
|
-
return this.codeLocation;
|
|
152
|
-
}
|
|
153
|
-
if (this.parent) {
|
|
154
|
-
return this.parent.location;
|
|
155
|
-
}
|
|
156
|
-
return {
|
|
157
|
-
url: this.sourceURL,
|
|
158
|
-
range: {
|
|
159
|
-
start: { line: 0, character: 0 },
|
|
160
|
-
end: { line: 0, character: 0 },
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
set location(loc) {
|
|
165
|
-
this.codeLocation = loc;
|
|
166
|
-
}
|
|
167
|
-
namespace() {
|
|
168
|
-
if (this instanceof Document) {
|
|
169
|
-
return this;
|
|
170
|
-
}
|
|
171
|
-
else if (this.parent) {
|
|
172
|
-
return this.parent.namespace();
|
|
173
|
-
}
|
|
174
|
-
throw new Error("INTERNAL ERROR: Translation without document scope");
|
|
175
|
-
}
|
|
176
|
-
modelEntry(reference) {
|
|
177
|
-
var _a;
|
|
178
|
-
const key = reference instanceof ModelEntryReference ? reference.name : reference;
|
|
179
|
-
const result = (_a = this.namespace()) === null || _a === void 0 ? void 0 : _a.getEntry(key);
|
|
180
|
-
if (reference instanceof ModelEntryReference) {
|
|
181
|
-
if ((result === null || result === void 0 ? void 0 : result.entry.type) === "query") {
|
|
182
|
-
this.addReference({
|
|
183
|
-
type: "queryReference",
|
|
184
|
-
text: key,
|
|
185
|
-
definition: result.entry,
|
|
186
|
-
location: reference.location,
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
else if ((result === null || result === void 0 ? void 0 : result.entry.type) === "struct") {
|
|
190
|
-
if (model.isSQLBlock(result.entry)) {
|
|
191
|
-
this.addReference({
|
|
192
|
-
type: "sqlBlockReference",
|
|
193
|
-
text: key,
|
|
194
|
-
definition: result.entry,
|
|
195
|
-
location: reference.location,
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
this.addReference({
|
|
200
|
-
type: "exploreReference",
|
|
201
|
-
text: key,
|
|
202
|
-
definition: result.entry,
|
|
203
|
-
location: reference.location,
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return result;
|
|
209
|
-
}
|
|
210
|
-
translator() {
|
|
211
|
-
if (this.xlate) {
|
|
212
|
-
return this.xlate;
|
|
213
|
-
}
|
|
214
|
-
if (this.parent) {
|
|
215
|
-
return this.parent.translator();
|
|
216
|
-
}
|
|
217
|
-
return undefined;
|
|
218
|
-
}
|
|
219
|
-
setTranslator(x) {
|
|
220
|
-
this.xlate = x;
|
|
221
|
-
}
|
|
222
|
-
addReference(reference) {
|
|
223
|
-
var _a;
|
|
224
|
-
(_a = this.translator()) === null || _a === void 0 ? void 0 : _a.addReference(reference);
|
|
225
|
-
}
|
|
226
|
-
get sourceURL() {
|
|
227
|
-
const trans = this.translator();
|
|
228
|
-
return (trans === null || trans === void 0 ? void 0 : trans.sourceURL) || "(missing)";
|
|
229
|
-
}
|
|
230
|
-
errorsExist() {
|
|
231
|
-
var _a;
|
|
232
|
-
const logger = (_a = this.translator()) === null || _a === void 0 ? void 0 : _a.root.logger;
|
|
233
|
-
if (logger) {
|
|
234
|
-
return logger.hasErrors();
|
|
235
|
-
}
|
|
236
|
-
return true;
|
|
237
|
-
}
|
|
238
|
-
log(message) {
|
|
239
|
-
if (this.codeLocation) {
|
|
240
|
-
/*
|
|
241
|
-
* If this element has a location, then don't report the same
|
|
242
|
-
* error message at the same location more than once
|
|
243
|
-
*/
|
|
244
|
-
if (this.logged.has(message)) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
this.logged.add(message);
|
|
248
|
-
}
|
|
249
|
-
const trans = this.translator();
|
|
250
|
-
const msg = { at: this.location, message };
|
|
251
|
-
const logTo = trans === null || trans === void 0 ? void 0 : trans.root.logger;
|
|
252
|
-
if (logTo) {
|
|
253
|
-
logTo.log(msg);
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
throw new Error(`Translation error (without error reporter):\n${JSON.stringify(msg, null, 2)}`);
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Mostly for debugging / testing. A string-y version of this object which
|
|
260
|
-
* is used to ask "are these two AST segments equal". Formatted so that
|
|
261
|
-
* errors would be human readable.
|
|
262
|
-
* @param indent only used for recursion
|
|
263
|
-
*/
|
|
264
|
-
toString() {
|
|
265
|
-
return this.stringify("", 0);
|
|
266
|
-
}
|
|
267
|
-
stringify(prefix, indent) {
|
|
268
|
-
const left = " ".repeat(indent);
|
|
269
|
-
let asString = `${left}${prefix}<${this.elementType}>${this.varInfo()}`;
|
|
270
|
-
for (const kidLabel of Object.keys(this.children)) {
|
|
271
|
-
const kiddle = this.children[kidLabel];
|
|
272
|
-
if (kiddle instanceof MalloyElement) {
|
|
273
|
-
asString += "\n" + kiddle.stringify(`${kidLabel}: `, indent + 2);
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
asString += `\n${left} ${kidLabel}: [`;
|
|
277
|
-
if (kiddle.length > 0) {
|
|
278
|
-
asString +=
|
|
279
|
-
"\n" +
|
|
280
|
-
kiddle.map((k) => k.stringify("", indent + 4)).join("\n") +
|
|
281
|
-
`\n${left} `;
|
|
282
|
-
}
|
|
283
|
-
asString += "]";
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return asString;
|
|
287
|
-
}
|
|
288
|
-
walk(callBack) {
|
|
289
|
-
callBack(this);
|
|
290
|
-
for (const kidLabel of Object.keys(this.children)) {
|
|
291
|
-
const kiddle = this.children[kidLabel];
|
|
292
|
-
if (kiddle instanceof MalloyElement) {
|
|
293
|
-
kiddle.walk(callBack);
|
|
294
|
-
}
|
|
295
|
-
else {
|
|
296
|
-
for (const k of kiddle) {
|
|
297
|
-
k.walk(callBack);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
varInfo() {
|
|
303
|
-
let extra = "";
|
|
304
|
-
for (const [key, value] of Object.entries(this)) {
|
|
305
|
-
if (key !== "elementType") {
|
|
306
|
-
if (typeof value == "boolean") {
|
|
307
|
-
extra += value ? ` ${key}` : ` !${key}`;
|
|
308
|
-
}
|
|
309
|
-
else if (typeof value === "string" || typeof value === "number") {
|
|
310
|
-
extra += ` ${key}=${value}`;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return extra;
|
|
315
|
-
}
|
|
316
|
-
internalError(msg) {
|
|
317
|
-
this.log(`INTERNAL ERROR IN TRANSLATION: ${msg}`);
|
|
318
|
-
return new Error(msg);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
exports.MalloyElement = MalloyElement;
|
|
322
|
-
class ListOf extends MalloyElement {
|
|
323
|
-
constructor(listDesc, elements) {
|
|
324
|
-
super();
|
|
325
|
-
this.elementType = "genericElementList";
|
|
326
|
-
this.elements = elements;
|
|
327
|
-
if (this.elementType === "genericElementList") {
|
|
328
|
-
this.elementType = listDesc;
|
|
329
|
-
}
|
|
330
|
-
this.newContents();
|
|
331
|
-
}
|
|
332
|
-
newContents() {
|
|
333
|
-
this.has({ [this.elementType]: this.elements });
|
|
334
|
-
}
|
|
335
|
-
get list() {
|
|
336
|
-
return this.elements;
|
|
337
|
-
}
|
|
338
|
-
empty() {
|
|
339
|
-
return this.elements.length === 0;
|
|
340
|
-
}
|
|
341
|
-
notEmpty() {
|
|
342
|
-
return this.elements.length > 0;
|
|
343
|
-
}
|
|
344
|
-
push(...el) {
|
|
345
|
-
this.elements.push(...el);
|
|
346
|
-
this.newContents();
|
|
347
|
-
return this.elements;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
exports.ListOf = ListOf;
|
|
351
|
-
class Unimplemented extends MalloyElement {
|
|
352
|
-
constructor() {
|
|
353
|
-
super(...arguments);
|
|
354
|
-
this.elementType = "unimplemented";
|
|
355
|
-
this.reported = false;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
exports.Unimplemented = Unimplemented;
|
|
359
|
-
function getStructFieldDef(s, fn) {
|
|
360
|
-
return s.fields.find((fld) => (fld.as || fld.name) === fn);
|
|
361
|
-
}
|
|
362
|
-
function isFieldDecl(f) {
|
|
363
|
-
return (f instanceof FieldDeclaration ||
|
|
364
|
-
f instanceof Join ||
|
|
365
|
-
f instanceof TurtleDecl ||
|
|
366
|
-
f instanceof Turtles);
|
|
367
|
-
}
|
|
368
|
-
function isExploreField(f) {
|
|
369
|
-
return isFieldDecl(f) || f instanceof RenameField;
|
|
370
|
-
}
|
|
371
|
-
exports.isExploreField = isExploreField;
|
|
372
|
-
/**
|
|
373
|
-
* A "Mallobj" is a thing which you can run queries against, it has been called
|
|
374
|
-
* an "exploreable", or a "space".
|
|
375
|
-
*/
|
|
376
|
-
class Mallobj extends MalloyElement {
|
|
377
|
-
structRef() {
|
|
378
|
-
return this.structDef();
|
|
379
|
-
}
|
|
380
|
-
withParameters(pList) {
|
|
381
|
-
const before = this.structDef();
|
|
382
|
-
// TODO name collisions are flagged where?
|
|
383
|
-
if (pList) {
|
|
384
|
-
const parameters = { ...(before.parameters || {}) };
|
|
385
|
-
for (const hasP of pList) {
|
|
386
|
-
const pVal = hasP.parameter();
|
|
387
|
-
parameters[pVal.name] = pVal;
|
|
388
|
-
}
|
|
389
|
-
return {
|
|
390
|
-
...before,
|
|
391
|
-
parameters,
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
return before;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
exports.Mallobj = Mallobj;
|
|
398
|
-
class QueryHeadStruct extends Mallobj {
|
|
399
|
-
constructor(fromRef) {
|
|
400
|
-
super();
|
|
401
|
-
this.fromRef = fromRef;
|
|
402
|
-
this.elementType = "internalOnlyQueryHead";
|
|
403
|
-
}
|
|
404
|
-
structRef() {
|
|
405
|
-
return this.fromRef;
|
|
406
|
-
}
|
|
407
|
-
structDef() {
|
|
408
|
-
if (model.refIsStructDef(this.fromRef)) {
|
|
409
|
-
return this.fromRef;
|
|
410
|
-
}
|
|
411
|
-
const ns = new NamedSource(this.fromRef);
|
|
412
|
-
this.has({ exploreReference: ns });
|
|
413
|
-
return ns.structDef();
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
class RunList extends ListOf {
|
|
417
|
-
constructor() {
|
|
418
|
-
super(...arguments);
|
|
419
|
-
this.execCursor = 0;
|
|
420
|
-
}
|
|
421
|
-
executeList(doc) {
|
|
422
|
-
while (this.execCursor < this.elements.length) {
|
|
423
|
-
if (doc.errorsExist()) {
|
|
424
|
-
// This stops cascading errors
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
const el = this.elements[this.execCursor];
|
|
428
|
-
if (isDocStatement(el)) {
|
|
429
|
-
const resp = el.execute(doc);
|
|
430
|
-
if (resp) {
|
|
431
|
-
return resp;
|
|
432
|
-
}
|
|
433
|
-
this.execCursor += 1;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
return undefined;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
exports.RunList = RunList;
|
|
440
|
-
function isDocStatement(e) {
|
|
441
|
-
return e.execute !== undefined;
|
|
442
|
-
}
|
|
443
|
-
exports.isDocStatement = isDocStatement;
|
|
444
|
-
class DefineExplore extends MalloyElement {
|
|
445
|
-
constructor(name, mallobj, exported, params) {
|
|
446
|
-
super({ explore: mallobj });
|
|
447
|
-
this.name = name;
|
|
448
|
-
this.mallobj = mallobj;
|
|
449
|
-
this.exported = exported;
|
|
450
|
-
this.elementType = "defineExplore";
|
|
451
|
-
if (params) {
|
|
452
|
-
this.parameters = [];
|
|
453
|
-
for (const el of params) {
|
|
454
|
-
if (el instanceof HasParameter) {
|
|
455
|
-
this.parameters.push(el);
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
458
|
-
this.log(`Unexpected element type in define statement: ${el.elementType}`);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
this.has({ parameters: this.parameters });
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
execute(doc) {
|
|
465
|
-
if (doc.modelEntry(this.name)) {
|
|
466
|
-
this.log(`Cannot redefine '${this.name}'`);
|
|
467
|
-
}
|
|
468
|
-
else {
|
|
469
|
-
const structDef = this.mallobj.withParameters(this.parameters);
|
|
470
|
-
if (ErrorFactory.isErrorStructDef(structDef)) {
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
doc.setEntry(this.name, {
|
|
474
|
-
entry: {
|
|
475
|
-
...structDef,
|
|
476
|
-
as: this.name,
|
|
477
|
-
location: this.location,
|
|
478
|
-
},
|
|
479
|
-
exported: this.exported,
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
exports.DefineExplore = DefineExplore;
|
|
485
|
-
class DefineSourceList extends RunList {
|
|
486
|
-
constructor(sourceList) {
|
|
487
|
-
super("defineSources", sourceList);
|
|
488
|
-
}
|
|
489
|
-
execute(doc) {
|
|
490
|
-
return this.executeList(doc);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
exports.DefineSourceList = DefineSourceList;
|
|
494
|
-
/**
|
|
495
|
-
* A Mallobj made from a source and a set of refinements
|
|
496
|
-
*/
|
|
497
|
-
class RefinedExplore extends Mallobj {
|
|
498
|
-
constructor(source, refinement) {
|
|
499
|
-
super({ source, refinement });
|
|
500
|
-
this.source = source;
|
|
501
|
-
this.refinement = refinement;
|
|
502
|
-
this.elementType = "refinedExplore";
|
|
503
|
-
}
|
|
504
|
-
structDef() {
|
|
505
|
-
return this.withParameters([]);
|
|
506
|
-
}
|
|
507
|
-
withParameters(pList) {
|
|
508
|
-
let primaryKey;
|
|
509
|
-
let fieldListEdit;
|
|
510
|
-
const fields = [];
|
|
511
|
-
const filters = [];
|
|
512
|
-
for (const el of this.refinement.list) {
|
|
513
|
-
const errTo = el;
|
|
514
|
-
if (el instanceof PrimaryKey) {
|
|
515
|
-
if (primaryKey) {
|
|
516
|
-
primaryKey.log("Primary key already defined");
|
|
517
|
-
el.log("Primary key redefined");
|
|
518
|
-
}
|
|
519
|
-
primaryKey = el;
|
|
520
|
-
}
|
|
521
|
-
else if (el instanceof FieldListEdit) {
|
|
522
|
-
if (fieldListEdit) {
|
|
523
|
-
fieldListEdit.log("Too many accept/except statements");
|
|
524
|
-
el.log("Too many accept/except statements");
|
|
525
|
-
}
|
|
526
|
-
fieldListEdit = el;
|
|
527
|
-
}
|
|
528
|
-
else if (el instanceof DeclareFields ||
|
|
529
|
-
el instanceof Joins ||
|
|
530
|
-
el instanceof Turtles ||
|
|
531
|
-
el instanceof Renames) {
|
|
532
|
-
fields.push(...el.list);
|
|
533
|
-
}
|
|
534
|
-
else if (el instanceof Filter) {
|
|
535
|
-
filters.push(el);
|
|
536
|
-
}
|
|
537
|
-
else {
|
|
538
|
-
errTo.log(`Unexpected explore property: '${errTo.elementType}'`);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
const from = (0, lodash_1.cloneDeep)(this.source.structDef());
|
|
542
|
-
if (primaryKey) {
|
|
543
|
-
from.primaryKey = primaryKey.field.name;
|
|
544
|
-
}
|
|
545
|
-
const fs = DynamicSpace.filteredFrom(from, fieldListEdit);
|
|
546
|
-
fs.addField(...fields);
|
|
547
|
-
if (pList) {
|
|
548
|
-
fs.addParameters(pList);
|
|
549
|
-
}
|
|
550
|
-
if (primaryKey) {
|
|
551
|
-
const keyDef = primaryKey.field.getField(fs);
|
|
552
|
-
if (keyDef.error) {
|
|
553
|
-
primaryKey.log(keyDef.error);
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
const retStruct = fs.structDef();
|
|
557
|
-
const filterList = retStruct.filterList || [];
|
|
558
|
-
let moreFilters = false;
|
|
559
|
-
for (const filter of filters) {
|
|
560
|
-
for (const el of filter.list) {
|
|
561
|
-
const fc = el.filterExpression(fs);
|
|
562
|
-
if (model.expressionIsCalculation(fc.expressionType)) {
|
|
563
|
-
el.log("Can't use aggregate computations in top level filters");
|
|
564
|
-
}
|
|
565
|
-
else {
|
|
566
|
-
filterList.push(fc);
|
|
567
|
-
moreFilters = true;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
if (moreFilters) {
|
|
572
|
-
return { ...retStruct, filterList };
|
|
573
|
-
}
|
|
574
|
-
return retStruct;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
exports.RefinedExplore = RefinedExplore;
|
|
578
|
-
class TableSource extends Mallobj {
|
|
579
|
-
constructor(name) {
|
|
580
|
-
super();
|
|
581
|
-
this.name = name;
|
|
582
|
-
this.elementType = "tableSource";
|
|
583
|
-
}
|
|
584
|
-
structDef() {
|
|
585
|
-
var _a;
|
|
586
|
-
const tableDefEntry = (_a = this.translator()) === null || _a === void 0 ? void 0 : _a.root.schemaZone.getEntry(this.name);
|
|
587
|
-
let msg = `Schema read failure for table '${this.name}'`;
|
|
588
|
-
if (tableDefEntry) {
|
|
589
|
-
if (tableDefEntry.status == "present") {
|
|
590
|
-
tableDefEntry.value.location = this.location;
|
|
591
|
-
tableDefEntry.value.fields.forEach((field) => (field.location = this.location));
|
|
592
|
-
return {
|
|
593
|
-
...tableDefEntry.value,
|
|
594
|
-
fields: tableDefEntry.value.fields.map((field) => ({
|
|
595
|
-
...field,
|
|
596
|
-
location: this.location,
|
|
597
|
-
})),
|
|
598
|
-
location: this.location,
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
if (tableDefEntry.status == "error") {
|
|
602
|
-
msg = tableDefEntry.message;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
this.log(msg);
|
|
606
|
-
return ErrorFactory.structDef;
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
exports.TableSource = TableSource;
|
|
610
|
-
class IsValueBlock extends MalloyElement {
|
|
611
|
-
constructor(isMap) {
|
|
612
|
-
super();
|
|
613
|
-
this.isMap = isMap;
|
|
614
|
-
this.elementType = "isValueBlock";
|
|
615
|
-
this.has(isMap);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
exports.IsValueBlock = IsValueBlock;
|
|
619
|
-
class ModelEntryReference extends MalloyElement {
|
|
620
|
-
constructor(name) {
|
|
621
|
-
super();
|
|
622
|
-
this.name = name;
|
|
623
|
-
this.elementType = "modelEntryReference";
|
|
624
|
-
}
|
|
625
|
-
get refString() {
|
|
626
|
-
return this.name;
|
|
627
|
-
}
|
|
628
|
-
toString() {
|
|
629
|
-
return this.refString;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
exports.ModelEntryReference = ModelEntryReference;
|
|
633
|
-
class NamedSource extends Mallobj {
|
|
634
|
-
constructor(ref, paramValues = {}) {
|
|
635
|
-
super();
|
|
636
|
-
this.ref = ref;
|
|
637
|
-
this.elementType = "namedSource";
|
|
638
|
-
if (paramValues && Object.keys(paramValues).length > 0) {
|
|
639
|
-
this.isBlock = new IsValueBlock(paramValues);
|
|
640
|
-
this.has({ parameterValues: this.isBlock });
|
|
641
|
-
}
|
|
642
|
-
if (ref instanceof ModelEntryReference) {
|
|
643
|
-
this.has({ ref });
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
get refName() {
|
|
647
|
-
return this.ref instanceof ModelEntryReference ? this.ref.name : this.ref;
|
|
648
|
-
}
|
|
649
|
-
structRef() {
|
|
650
|
-
if (this.isBlock) {
|
|
651
|
-
return this.structDef();
|
|
652
|
-
}
|
|
653
|
-
const modelEnt = this.modelEntry(this.ref);
|
|
654
|
-
if (modelEnt && !modelEnt.exported) {
|
|
655
|
-
// If we are not exporting the referenced structdef, don't
|
|
656
|
-
// use the reference
|
|
657
|
-
return this.structDef();
|
|
658
|
-
}
|
|
659
|
-
return this.refName;
|
|
660
|
-
}
|
|
661
|
-
modelStruct() {
|
|
662
|
-
const modelEnt = this.modelEntry(this.ref);
|
|
663
|
-
const entry = modelEnt === null || modelEnt === void 0 ? void 0 : modelEnt.entry;
|
|
664
|
-
if (!entry) {
|
|
665
|
-
const undefMsg = `Undefined source '${this.refName}'`;
|
|
666
|
-
(this.ref instanceof ModelEntryReference ? this.ref : this).log(undefMsg);
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
if (entry.type === "query") {
|
|
670
|
-
this.log(`Must use 'from()' for query source '${this.refName}`);
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
else if (modelEnt.sqlType) {
|
|
674
|
-
this.log(`Must use 'from_sql()' for sql source '${this.refName}`);
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
return { ...entry };
|
|
678
|
-
}
|
|
679
|
-
structDef() {
|
|
680
|
-
/*
|
|
681
|
-
Can't really generate the callback list until after all the
|
|
682
|
-
things before me are translated, and that kinda screws up
|
|
683
|
-
the translation process, so that might be a better place
|
|
684
|
-
to start the next step, because how that gets done might
|
|
685
|
-
make any code I write which ignores the translation problem
|
|
686
|
-
kind of meaningless.
|
|
687
|
-
|
|
688
|
-
Maybe the output of a translation is something which describes
|
|
689
|
-
all the missing data, and then there is a "link" step where you
|
|
690
|
-
can do other translations and link them into a partial translation
|
|
691
|
-
which might result in a full translation.
|
|
692
|
-
*/
|
|
693
|
-
var _a;
|
|
694
|
-
const ret = this.modelStruct();
|
|
695
|
-
if (!ret) {
|
|
696
|
-
const notFound = ErrorFactory.structDef;
|
|
697
|
-
const err = `${this.refName}-undefined`;
|
|
698
|
-
notFound.name = notFound.name + err;
|
|
699
|
-
notFound.dialect = notFound.dialect + err;
|
|
700
|
-
return notFound;
|
|
701
|
-
}
|
|
702
|
-
const declared = { ...ret.parameters } || {};
|
|
703
|
-
const makeWith = ((_a = this.isBlock) === null || _a === void 0 ? void 0 : _a.isMap) || {};
|
|
704
|
-
for (const [pName, pExpr] of Object.entries(makeWith)) {
|
|
705
|
-
const decl = declared[pName];
|
|
706
|
-
// const pVal = pExpr.constantValue();
|
|
707
|
-
if (!decl) {
|
|
708
|
-
this.log(`Value given for undeclared parameter '${pName}`);
|
|
709
|
-
}
|
|
710
|
-
else {
|
|
711
|
-
if (model.isValueParameter(decl)) {
|
|
712
|
-
if (decl.constant) {
|
|
713
|
-
pExpr.log(`Cannot override constant parameter ${pName}`);
|
|
714
|
-
}
|
|
715
|
-
else {
|
|
716
|
-
const pVal = pExpr.constantValue();
|
|
717
|
-
let value = pVal.value;
|
|
718
|
-
if (pVal.dataType !== decl.type) {
|
|
719
|
-
value = (0, time_utils_1.castTo)(decl.type, pVal.value, true);
|
|
720
|
-
}
|
|
721
|
-
decl.value = value;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
else {
|
|
725
|
-
// TODO type checking here -- except I am still not sure what
|
|
726
|
-
// datatype half conditions have ..
|
|
727
|
-
decl.condition = pExpr.constantCondition(decl.type).value;
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
for (const checkDef in ret.parameters) {
|
|
732
|
-
if (!model.paramHasValue(declared[checkDef])) {
|
|
733
|
-
this.log(`Value not provided for required parameter ${checkDef}`);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
return ret;
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
exports.NamedSource = NamedSource;
|
|
740
|
-
class SQLSource extends NamedSource {
|
|
741
|
-
constructor() {
|
|
742
|
-
super(...arguments);
|
|
743
|
-
this.elementType = "sqlSource";
|
|
744
|
-
}
|
|
745
|
-
structRef() {
|
|
746
|
-
return this.structDef();
|
|
747
|
-
}
|
|
748
|
-
modelStruct() {
|
|
749
|
-
const modelEnt = this.modelEntry(this.ref);
|
|
750
|
-
const entry = modelEnt === null || modelEnt === void 0 ? void 0 : modelEnt.entry;
|
|
751
|
-
if (!entry) {
|
|
752
|
-
this.log(`Undefined from_sql source '${this.refName}'`);
|
|
753
|
-
return;
|
|
754
|
-
}
|
|
755
|
-
if (entry.type === "query") {
|
|
756
|
-
this.log(`Cannot use 'from_sql()' to explore query '${this.refName}'`);
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
else if (!modelEnt.sqlType) {
|
|
760
|
-
this.log(`Cannot use 'from_sql()' to explore '${this.refName}'`);
|
|
761
|
-
return;
|
|
762
|
-
}
|
|
763
|
-
return entry;
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
exports.SQLSource = SQLSource;
|
|
767
|
-
class QuerySource extends Mallobj {
|
|
768
|
-
constructor(query) {
|
|
769
|
-
super({ query });
|
|
770
|
-
this.query = query;
|
|
771
|
-
this.elementType = "querySource";
|
|
772
|
-
}
|
|
773
|
-
structDef() {
|
|
774
|
-
const comp = this.query.queryComp();
|
|
775
|
-
const queryStruct = comp.outputStruct;
|
|
776
|
-
queryStruct.structSource = { type: "query", query: comp.query };
|
|
777
|
-
return queryStruct;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
exports.QuerySource = QuerySource;
|
|
781
|
-
class Join extends MalloyElement {
|
|
782
|
-
}
|
|
783
|
-
exports.Join = Join;
|
|
784
|
-
class KeyJoin extends Join {
|
|
785
|
-
constructor(name, source, keyExpr) {
|
|
786
|
-
super({ name, source, keyExpr });
|
|
787
|
-
this.name = name;
|
|
788
|
-
this.source = source;
|
|
789
|
-
this.keyExpr = keyExpr;
|
|
790
|
-
this.elementType = "joinOnKey";
|
|
791
|
-
}
|
|
792
|
-
structDef() {
|
|
793
|
-
const sourceDef = this.source.structDef();
|
|
794
|
-
const joinStruct = {
|
|
795
|
-
...sourceDef,
|
|
796
|
-
structRelationship: {
|
|
797
|
-
type: "one",
|
|
798
|
-
onExpression: ["('join fixup'='not done yet')"],
|
|
799
|
-
},
|
|
800
|
-
location: this.location,
|
|
801
|
-
};
|
|
802
|
-
if (sourceDef.structSource.type === "query") {
|
|
803
|
-
// the name from query does not need to be preserved
|
|
804
|
-
joinStruct.name = this.name.refString;
|
|
805
|
-
}
|
|
806
|
-
else {
|
|
807
|
-
joinStruct.as = this.name.refString;
|
|
808
|
-
}
|
|
809
|
-
return joinStruct;
|
|
810
|
-
}
|
|
811
|
-
fixupJoinOn(outer, inStruct) {
|
|
812
|
-
const exprX = this.keyExpr.getExpression(outer);
|
|
813
|
-
if (inStruct.primaryKey) {
|
|
814
|
-
const pkey = inStruct.fields.find((f) => (f.as || f.name) === inStruct.primaryKey);
|
|
815
|
-
if (pkey) {
|
|
816
|
-
if (pkey.type === exprX.dataType) {
|
|
817
|
-
inStruct.structRelationship = {
|
|
818
|
-
type: "one",
|
|
819
|
-
onExpression: [
|
|
820
|
-
{ type: "field", path: `${this.name}.${inStruct.primaryKey}` },
|
|
821
|
-
"=",
|
|
822
|
-
...exprX.value,
|
|
823
|
-
],
|
|
824
|
-
};
|
|
825
|
-
return;
|
|
826
|
-
}
|
|
827
|
-
else {
|
|
828
|
-
this.log(`join_one: with type mismatch with primary key: ${exprX.dataType}/${pkey.type}`);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
else {
|
|
832
|
-
this.log(`join_one: Primary key '${pkey}' not found in source`);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
else {
|
|
836
|
-
this.log(`join_one: Cannot use with unless source has a primary key`);
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
exports.KeyJoin = KeyJoin;
|
|
841
|
-
class ExpressionJoin extends Join {
|
|
842
|
-
constructor(name, source) {
|
|
843
|
-
super({ name, source });
|
|
844
|
-
this.name = name;
|
|
845
|
-
this.source = source;
|
|
846
|
-
this.elementType = "joinOnExpr";
|
|
847
|
-
this.joinType = "one";
|
|
848
|
-
}
|
|
849
|
-
set joinOn(joinExpr) {
|
|
850
|
-
this.expr = joinExpr;
|
|
851
|
-
this.has({ on: joinExpr });
|
|
852
|
-
}
|
|
853
|
-
get joinOn() {
|
|
854
|
-
return this.expr;
|
|
855
|
-
}
|
|
856
|
-
fixupJoinOn(outer, inStruct) {
|
|
857
|
-
if (this.expr == undefined) {
|
|
858
|
-
return;
|
|
859
|
-
}
|
|
860
|
-
const exprX = this.expr.getExpression(outer);
|
|
861
|
-
if (exprX.dataType !== "boolean") {
|
|
862
|
-
this.log("join conditions must be boolean expressions");
|
|
863
|
-
return;
|
|
864
|
-
}
|
|
865
|
-
const joinRel = inStruct.structRelationship;
|
|
866
|
-
if (model.isJoinOn(joinRel)) {
|
|
867
|
-
joinRel.onExpression = (0, ast_types_1.compressExpr)(exprX.value);
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
structDef() {
|
|
871
|
-
const sourceDef = this.source.structDef();
|
|
872
|
-
const joinStruct = {
|
|
873
|
-
...sourceDef,
|
|
874
|
-
structRelationship: { type: this.joinType },
|
|
875
|
-
location: this.location,
|
|
876
|
-
};
|
|
877
|
-
if (sourceDef.structSource.type === "query") {
|
|
878
|
-
// the name from query does not need to be preserved
|
|
879
|
-
joinStruct.name = this.name.refString;
|
|
880
|
-
delete joinStruct.as;
|
|
881
|
-
}
|
|
882
|
-
else {
|
|
883
|
-
joinStruct.as = this.name.refString;
|
|
884
|
-
}
|
|
885
|
-
return joinStruct;
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
exports.ExpressionJoin = ExpressionJoin;
|
|
889
|
-
class Joins extends ListOf {
|
|
890
|
-
constructor(joins) {
|
|
891
|
-
super("joinList", joins);
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
exports.Joins = Joins;
|
|
895
|
-
function isQueryProperty(q) {
|
|
896
|
-
return (q instanceof Ordering ||
|
|
897
|
-
q instanceof Top ||
|
|
898
|
-
q instanceof Limit ||
|
|
899
|
-
q instanceof Filter ||
|
|
900
|
-
q instanceof Index ||
|
|
901
|
-
q instanceof SampleProperty ||
|
|
902
|
-
q instanceof Joins ||
|
|
903
|
-
q instanceof DeclareFields ||
|
|
904
|
-
q instanceof ProjectStatement ||
|
|
905
|
-
q instanceof Aggregate ||
|
|
906
|
-
q instanceof Nests ||
|
|
907
|
-
isNestedQuery(q) ||
|
|
908
|
-
q instanceof GroupBy);
|
|
909
|
-
}
|
|
910
|
-
exports.isQueryProperty = isQueryProperty;
|
|
911
|
-
function isExploreProperty(p) {
|
|
912
|
-
return (p instanceof Filter ||
|
|
913
|
-
p instanceof Joins ||
|
|
914
|
-
p instanceof DeclareFields ||
|
|
915
|
-
p instanceof FieldListEdit ||
|
|
916
|
-
p instanceof Renames ||
|
|
917
|
-
p instanceof PrimaryKey ||
|
|
918
|
-
p instanceof Turtles);
|
|
919
|
-
}
|
|
920
|
-
exports.isExploreProperty = isExploreProperty;
|
|
921
|
-
class ExploreDesc extends ListOf {
|
|
922
|
-
constructor(props) {
|
|
923
|
-
super("exploreDesc", props);
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
exports.ExploreDesc = ExploreDesc;
|
|
927
|
-
class FilterElement extends MalloyElement {
|
|
928
|
-
constructor(expr, exprSrc) {
|
|
929
|
-
super({ expr });
|
|
930
|
-
this.expr = expr;
|
|
931
|
-
this.exprSrc = exprSrc;
|
|
932
|
-
this.elementType = "filterElement";
|
|
933
|
-
}
|
|
934
|
-
filterExpression(fs) {
|
|
935
|
-
const exprVal = this.expr.getExpression(fs);
|
|
936
|
-
if (exprVal.dataType !== "boolean") {
|
|
937
|
-
this.expr.log("Filter expression must have boolean value");
|
|
938
|
-
return {
|
|
939
|
-
code: this.exprSrc,
|
|
940
|
-
expression: ["_FILTER_MUST_RETURN_BOOLEAN_"],
|
|
941
|
-
expressionType: "scalar",
|
|
942
|
-
};
|
|
943
|
-
}
|
|
944
|
-
const exprCond = {
|
|
945
|
-
code: this.exprSrc,
|
|
946
|
-
expression: (0, ast_types_1.compressExpr)(exprVal.value),
|
|
947
|
-
expressionType: exprVal.expressionType,
|
|
948
|
-
};
|
|
949
|
-
return exprCond;
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
exports.FilterElement = FilterElement;
|
|
953
|
-
class Filter extends ListOf {
|
|
954
|
-
constructor(elements = []) {
|
|
955
|
-
super("filterElements", elements);
|
|
956
|
-
this.elementType = "filter";
|
|
957
|
-
}
|
|
958
|
-
set having(isHaving) {
|
|
959
|
-
this.elementType = isHaving ? "having" : "where";
|
|
960
|
-
}
|
|
961
|
-
getFilterList(fs) {
|
|
962
|
-
const checked = [];
|
|
963
|
-
for (const oneElement of this.list) {
|
|
964
|
-
const fExpr = oneElement.filterExpression(fs);
|
|
965
|
-
// Aggregates are ALSO checked at SQL generation time, but checking
|
|
966
|
-
// here allows better reflection of errors back to user.
|
|
967
|
-
if (this.havingClause !== undefined) {
|
|
968
|
-
if (this.havingClause) {
|
|
969
|
-
if (model.expressionIsCalculation(fExpr.expressionType)) {
|
|
970
|
-
oneElement.log("Aggregate or Analytical expression expected in HAVING filter");
|
|
971
|
-
continue;
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
else {
|
|
975
|
-
if (fExpr.expressionType !== "scalar") {
|
|
976
|
-
oneElement.log("Aggregate or Analytical expressions not allowed in WHERE");
|
|
977
|
-
continue;
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
checked.push(fExpr);
|
|
982
|
-
}
|
|
983
|
-
return checked;
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
exports.Filter = Filter;
|
|
987
|
-
class DeclareFields extends ListOf {
|
|
988
|
-
constructor(fields, fieldType = "declare") {
|
|
989
|
-
super(fieldType, fields);
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
exports.DeclareFields = DeclareFields;
|
|
993
|
-
class Measures extends DeclareFields {
|
|
994
|
-
constructor(measures) {
|
|
995
|
-
super(measures, "measure");
|
|
996
|
-
for (const dim of measures) {
|
|
997
|
-
dim.isMeasure = true;
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
exports.Measures = Measures;
|
|
1002
|
-
class Dimensions extends DeclareFields {
|
|
1003
|
-
constructor(dimensions) {
|
|
1004
|
-
super(dimensions, "dimension");
|
|
1005
|
-
for (const dim of dimensions) {
|
|
1006
|
-
dim.isMeasure = false;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
exports.Dimensions = Dimensions;
|
|
1011
|
-
class Renames extends ListOf {
|
|
1012
|
-
constructor(renames) {
|
|
1013
|
-
super("renameField", renames);
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
exports.Renames = Renames;
|
|
1017
|
-
class FieldName extends MalloyElement {
|
|
1018
|
-
constructor(name) {
|
|
1019
|
-
super();
|
|
1020
|
-
this.name = name;
|
|
1021
|
-
this.elementType = "fieldName";
|
|
1022
|
-
}
|
|
1023
|
-
get refString() {
|
|
1024
|
-
return this.name;
|
|
1025
|
-
}
|
|
1026
|
-
toString() {
|
|
1027
|
-
return this.refString;
|
|
1028
|
-
}
|
|
1029
|
-
getField(fs) {
|
|
1030
|
-
return fs.lookup([this]);
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
exports.FieldName = FieldName;
|
|
1034
|
-
class FieldReference extends ListOf {
|
|
1035
|
-
constructor(names) {
|
|
1036
|
-
super("fieldReference", names);
|
|
1037
|
-
this.elementType = "fieldReference";
|
|
1038
|
-
}
|
|
1039
|
-
get refString() {
|
|
1040
|
-
return this.list.map((n) => n.refString).join(".");
|
|
1041
|
-
}
|
|
1042
|
-
get outputName() {
|
|
1043
|
-
const last = this.list[this.list.length - 1];
|
|
1044
|
-
return last.refString;
|
|
1045
|
-
}
|
|
1046
|
-
get sourceString() {
|
|
1047
|
-
if (this.list.length > 1) {
|
|
1048
|
-
return this.list
|
|
1049
|
-
.slice(0, -1)
|
|
1050
|
-
.map((n) => n.refString)
|
|
1051
|
-
.join(".");
|
|
1052
|
-
}
|
|
1053
|
-
return undefined;
|
|
1054
|
-
}
|
|
1055
|
-
get nameString() {
|
|
1056
|
-
return this.list[this.list.length - 1].refString;
|
|
1057
|
-
}
|
|
1058
|
-
getField(fs) {
|
|
1059
|
-
return fs.lookup(this.list);
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
exports.FieldReference = FieldReference;
|
|
1063
|
-
class FieldReferences extends ListOf {
|
|
1064
|
-
constructor(members) {
|
|
1065
|
-
super("fieldReferenceList", members);
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
exports.FieldReferences = FieldReferences;
|
|
1069
|
-
function isFieldCollectionMember(el) {
|
|
1070
|
-
return (el instanceof FieldReference ||
|
|
1071
|
-
el instanceof WildcardFieldReference ||
|
|
1072
|
-
el instanceof FieldDeclaration);
|
|
1073
|
-
}
|
|
1074
|
-
exports.isFieldCollectionMember = isFieldCollectionMember;
|
|
1075
|
-
class ProjectStatement extends ListOf {
|
|
1076
|
-
constructor(members) {
|
|
1077
|
-
super("fieldCollection", members);
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
exports.ProjectStatement = ProjectStatement;
|
|
1081
|
-
class FieldListEdit extends MalloyElement {
|
|
1082
|
-
constructor(edit, refs) {
|
|
1083
|
-
super({ refs });
|
|
1084
|
-
this.edit = edit;
|
|
1085
|
-
this.refs = refs;
|
|
1086
|
-
this.elementType = "fieldListEdit";
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
exports.FieldListEdit = FieldListEdit;
|
|
1090
|
-
class GroupBy extends ListOf {
|
|
1091
|
-
constructor(members) {
|
|
1092
|
-
super("groupBy", members);
|
|
1093
|
-
for (const el of members) {
|
|
1094
|
-
if (el instanceof FieldDeclaration) {
|
|
1095
|
-
el.isMeasure = false;
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
exports.GroupBy = GroupBy;
|
|
1101
|
-
class Aggregate extends ListOf {
|
|
1102
|
-
constructor(members) {
|
|
1103
|
-
super("aggregate", members);
|
|
1104
|
-
for (const el of members) {
|
|
1105
|
-
if (el instanceof FieldDeclaration) {
|
|
1106
|
-
el.isMeasure = true;
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
exports.Aggregate = Aggregate;
|
|
1112
|
-
class ReduceExecutor {
|
|
1113
|
-
constructor(baseFS) {
|
|
1114
|
-
this.filters = [];
|
|
1115
|
-
this.resultFS = this.getResultSpace(baseFS);
|
|
1116
|
-
this.inputFS = this.resultFS.exprSpace;
|
|
1117
|
-
}
|
|
1118
|
-
getResultSpace(fs) {
|
|
1119
|
-
return new ReduceFieldSpace(fs);
|
|
1120
|
-
}
|
|
1121
|
-
execute(qp) {
|
|
1122
|
-
if (qp instanceof GroupBy ||
|
|
1123
|
-
qp instanceof Aggregate ||
|
|
1124
|
-
qp instanceof Nests) {
|
|
1125
|
-
this.resultFS.addQueryItems(...qp.list);
|
|
1126
|
-
}
|
|
1127
|
-
else if (isNestedQuery(qp)) {
|
|
1128
|
-
this.resultFS.addQueryItems(qp);
|
|
1129
|
-
}
|
|
1130
|
-
else if (qp instanceof Filter) {
|
|
1131
|
-
this.filters.push(...qp.getFilterList(this.inputFS));
|
|
1132
|
-
}
|
|
1133
|
-
else if (qp instanceof Top) {
|
|
1134
|
-
if (this.limit) {
|
|
1135
|
-
qp.log("Query operation already limited");
|
|
1136
|
-
}
|
|
1137
|
-
else {
|
|
1138
|
-
this.limit = qp.limit;
|
|
1139
|
-
}
|
|
1140
|
-
if (qp.by) {
|
|
1141
|
-
if (this.order) {
|
|
1142
|
-
qp.log("Query operation is already sorted");
|
|
1143
|
-
}
|
|
1144
|
-
else {
|
|
1145
|
-
this.order = qp;
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
|
-
else if (qp instanceof Limit) {
|
|
1150
|
-
if (this.limit) {
|
|
1151
|
-
qp.log("Query operation already limited");
|
|
1152
|
-
}
|
|
1153
|
-
else {
|
|
1154
|
-
this.limit = qp.limit;
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
else if (qp instanceof Ordering) {
|
|
1158
|
-
if (this.order) {
|
|
1159
|
-
qp.log("Query operation already sorted");
|
|
1160
|
-
}
|
|
1161
|
-
else {
|
|
1162
|
-
this.order = qp;
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
else if (qp instanceof Joins || qp instanceof DeclareFields) {
|
|
1166
|
-
for (const qel of qp.list) {
|
|
1167
|
-
this.inputFS.extendSource(qel);
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
refineFrom(from, to) {
|
|
1172
|
-
if (from && from.type !== "index") {
|
|
1173
|
-
if (!this.order) {
|
|
1174
|
-
if (from.orderBy) {
|
|
1175
|
-
to.orderBy = from.orderBy;
|
|
1176
|
-
}
|
|
1177
|
-
else if (from.by) {
|
|
1178
|
-
to.by = from.by;
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
if (!this.limit && from.limit) {
|
|
1182
|
-
to.limit = from.limit;
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
if (this.limit) {
|
|
1186
|
-
to.limit = this.limit;
|
|
1187
|
-
}
|
|
1188
|
-
if (this.order instanceof Top) {
|
|
1189
|
-
const topBy = this.order.getBy(this.inputFS);
|
|
1190
|
-
if (topBy) {
|
|
1191
|
-
to.by = topBy;
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
if (this.order instanceof Ordering) {
|
|
1195
|
-
to.orderBy = this.order.getOrderBy(this.inputFS);
|
|
1196
|
-
}
|
|
1197
|
-
const oldFilters = (from === null || from === void 0 ? void 0 : from.filterList) || [];
|
|
1198
|
-
if (this.filters.length > 0 && !oldFilters) {
|
|
1199
|
-
to.filterList = this.filters;
|
|
1200
|
-
}
|
|
1201
|
-
else if (oldFilters) {
|
|
1202
|
-
to.filterList = [...oldFilters, ...this.filters];
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
finalize(fromSeg) {
|
|
1206
|
-
let from;
|
|
1207
|
-
if (fromSeg) {
|
|
1208
|
-
if (model.isReduceSegment(fromSeg)) {
|
|
1209
|
-
from = fromSeg;
|
|
1210
|
-
}
|
|
1211
|
-
else {
|
|
1212
|
-
this.inputFS.result.log(`Can't refine reduce with ${fromSeg.type}`);
|
|
1213
|
-
return ErrorFactory.reduceSegment;
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
const reduceSegment = this.resultFS.getQuerySegment(from);
|
|
1217
|
-
this.refineFrom(from, reduceSegment);
|
|
1218
|
-
return reduceSegment;
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
class ProjectExecutor extends ReduceExecutor {
|
|
1222
|
-
getResultSpace(fs) {
|
|
1223
|
-
return new ProjectFieldSpace(fs);
|
|
1224
|
-
}
|
|
1225
|
-
execute(qp) {
|
|
1226
|
-
if (qp instanceof ProjectStatement) {
|
|
1227
|
-
this.resultFS.addMembers(qp.list);
|
|
1228
|
-
}
|
|
1229
|
-
else if ((qp instanceof Filter && qp.elementType === "having") ||
|
|
1230
|
-
qp instanceof Measures ||
|
|
1231
|
-
qp instanceof GroupBy) {
|
|
1232
|
-
qp.log("Illegal statement in a project query operation");
|
|
1233
|
-
}
|
|
1234
|
-
else {
|
|
1235
|
-
super.execute(qp);
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
finalize(fromSeg) {
|
|
1239
|
-
let from;
|
|
1240
|
-
if (fromSeg) {
|
|
1241
|
-
if (model.isProjectSegment(fromSeg)) {
|
|
1242
|
-
from = fromSeg;
|
|
1243
|
-
}
|
|
1244
|
-
else {
|
|
1245
|
-
this.resultFS.log(`Can't refine project with ${fromSeg.type}`);
|
|
1246
|
-
return ErrorFactory.projectSegment;
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
const projectSegment = this.resultFS.getQuerySegment(from);
|
|
1250
|
-
this.refineFrom(from, projectSegment);
|
|
1251
|
-
return projectSegment;
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
class IndexExecutor {
|
|
1255
|
-
constructor(inputFS) {
|
|
1256
|
-
this.filters = [];
|
|
1257
|
-
this.resultFS = new IndexFieldSpace(inputFS);
|
|
1258
|
-
this.inputFS = this.resultFS.exprSpace;
|
|
1259
|
-
}
|
|
1260
|
-
execute(qp) {
|
|
1261
|
-
if (qp instanceof Filter) {
|
|
1262
|
-
this.filters.push(...qp.getFilterList(this.inputFS));
|
|
1263
|
-
}
|
|
1264
|
-
else if (qp instanceof Limit) {
|
|
1265
|
-
if (this.limit) {
|
|
1266
|
-
this.limit.log("Ignored, too many limit: statements");
|
|
1267
|
-
}
|
|
1268
|
-
this.limit = qp;
|
|
1269
|
-
}
|
|
1270
|
-
else if (qp instanceof Index) {
|
|
1271
|
-
this.resultFS.addMembers(qp.fields.list);
|
|
1272
|
-
if (qp.weightBy) {
|
|
1273
|
-
if (this.indexOn) {
|
|
1274
|
-
this.indexOn.log("Ignoring previous BY");
|
|
1275
|
-
}
|
|
1276
|
-
this.indexOn = qp.weightBy;
|
|
1277
|
-
}
|
|
1278
|
-
}
|
|
1279
|
-
else if (qp instanceof SampleProperty) {
|
|
1280
|
-
this.sample = qp.sampling();
|
|
1281
|
-
}
|
|
1282
|
-
else {
|
|
1283
|
-
qp.log("Not legal in an index query operation");
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
finalize(from) {
|
|
1287
|
-
if (from && from.type !== "index") {
|
|
1288
|
-
this.resultFS.log(`Can't refine index with ${from.type}`);
|
|
1289
|
-
return ErrorFactory.indexSegment;
|
|
1290
|
-
}
|
|
1291
|
-
const indexSegment = this.resultFS.getPipeSegment(from);
|
|
1292
|
-
const oldFilters = (from === null || from === void 0 ? void 0 : from.filterList) || [];
|
|
1293
|
-
if (this.filters.length > 0 && !oldFilters) {
|
|
1294
|
-
indexSegment.filterList = this.filters;
|
|
1295
|
-
}
|
|
1296
|
-
else if (oldFilters) {
|
|
1297
|
-
indexSegment.filterList = [...oldFilters, ...this.filters];
|
|
1298
|
-
}
|
|
1299
|
-
if (from === null || from === void 0 ? void 0 : from.limit) {
|
|
1300
|
-
indexSegment.limit = from.limit;
|
|
1301
|
-
}
|
|
1302
|
-
if (this.limit) {
|
|
1303
|
-
indexSegment.limit = this.limit.limit;
|
|
1304
|
-
}
|
|
1305
|
-
if (this.indexOn) {
|
|
1306
|
-
indexSegment.weightMeasure = this.indexOn.refString;
|
|
1307
|
-
}
|
|
1308
|
-
if (from === null || from === void 0 ? void 0 : from.sample) {
|
|
1309
|
-
indexSegment.sample = from.sample;
|
|
1310
|
-
}
|
|
1311
|
-
if (this.sample) {
|
|
1312
|
-
indexSegment.sample = this.sample;
|
|
1313
|
-
}
|
|
1314
|
-
return indexSegment;
|
|
1315
|
-
}
|
|
1316
|
-
}
|
|
1317
|
-
class QOPDesc extends ListOf {
|
|
1318
|
-
constructor(props) {
|
|
1319
|
-
super("queryOperator", props);
|
|
1320
|
-
this.opType = "grouping";
|
|
1321
|
-
}
|
|
1322
|
-
computeType() {
|
|
1323
|
-
let firstGuess;
|
|
1324
|
-
if (this.refineThis) {
|
|
1325
|
-
if (this.refineThis.type == "reduce") {
|
|
1326
|
-
firstGuess = "grouping";
|
|
1327
|
-
}
|
|
1328
|
-
else {
|
|
1329
|
-
firstGuess = this.refineThis.type;
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
let anyGrouping = false;
|
|
1333
|
-
for (const el of this.list) {
|
|
1334
|
-
if (el instanceof Index) {
|
|
1335
|
-
firstGuess || (firstGuess = "index");
|
|
1336
|
-
if (firstGuess !== "index") {
|
|
1337
|
-
el.log(`index: not legal in ${firstGuess} query`);
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
else if (el instanceof Nests ||
|
|
1341
|
-
isNestedQuery(el) ||
|
|
1342
|
-
el instanceof GroupBy) {
|
|
1343
|
-
firstGuess || (firstGuess = "grouping");
|
|
1344
|
-
anyGrouping = true;
|
|
1345
|
-
if (firstGuess === "project" || firstGuess === "index") {
|
|
1346
|
-
el.log(`group_by: not legal in ${firstGuess} query`);
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
else if (el instanceof Aggregate) {
|
|
1350
|
-
firstGuess || (firstGuess = "aggregate");
|
|
1351
|
-
if (firstGuess === "project" || firstGuess === "index") {
|
|
1352
|
-
el.log(`aggregate: not legal in ${firstGuess} query`);
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
else if (el instanceof ProjectStatement) {
|
|
1356
|
-
firstGuess || (firstGuess = "project");
|
|
1357
|
-
if (firstGuess !== "project") {
|
|
1358
|
-
el.log(`project: not legal in ${firstGuess} query`);
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
if (firstGuess === "aggregate" && anyGrouping) {
|
|
1363
|
-
firstGuess = "grouping";
|
|
1364
|
-
}
|
|
1365
|
-
if (!firstGuess) {
|
|
1366
|
-
this.log("Can't determine query type (group_by/aggregate/nest,project,index)");
|
|
1367
|
-
}
|
|
1368
|
-
const guessType = firstGuess || "grouping";
|
|
1369
|
-
this.opType = guessType;
|
|
1370
|
-
return guessType;
|
|
1371
|
-
}
|
|
1372
|
-
refineFrom(existing) {
|
|
1373
|
-
this.refineThis = existing;
|
|
1374
|
-
}
|
|
1375
|
-
getExecutor(baseFS) {
|
|
1376
|
-
switch (this.computeType()) {
|
|
1377
|
-
case "aggregate":
|
|
1378
|
-
case "grouping":
|
|
1379
|
-
return new ReduceExecutor(baseFS);
|
|
1380
|
-
case "project":
|
|
1381
|
-
return new ProjectExecutor(baseFS);
|
|
1382
|
-
case "index":
|
|
1383
|
-
return new IndexExecutor(baseFS);
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
getOp(inputFS, forPipeline) {
|
|
1387
|
-
const qex = this.getExecutor(inputFS);
|
|
1388
|
-
if (forPipeline === null || forPipeline === void 0 ? void 0 : forPipeline.nestedInQuerySpace) {
|
|
1389
|
-
qex.inputFS.nestParent = forPipeline.nestedInQuerySpace;
|
|
1390
|
-
}
|
|
1391
|
-
qex.resultFS.astEl = this;
|
|
1392
|
-
for (const qp of this.list) {
|
|
1393
|
-
qex.execute(qp);
|
|
1394
|
-
}
|
|
1395
|
-
const segment = qex.finalize(this.refineThis);
|
|
1396
|
-
return {
|
|
1397
|
-
segment,
|
|
1398
|
-
outputSpace: () => new DynamicSpace(opOutputStruct(this, inputFS.structDef(), segment)),
|
|
1399
|
-
};
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
exports.QOPDesc = QOPDesc;
|
|
1403
|
-
/**
|
|
1404
|
-
* The Document class is a little weird because we might need to bounce back
|
|
1405
|
-
* to the requestor, which might be on the other side of a wire, to get
|
|
1406
|
-
* back some schema information. The intended translation of a Document
|
|
1407
|
-
* is to call initModelDef(), and then to call modelDataRequest() until it
|
|
1408
|
-
* returns undefined. At any time you can call modelDef to get the model
|
|
1409
|
-
* as it exists so far, but the translation is not complete until
|
|
1410
|
-
* modelDataRequest() returns undefined;
|
|
1411
|
-
*
|
|
1412
|
-
* TODO probably modelRequest should be the method and you call it
|
|
1413
|
-
* until it returns a model with no additional data needed ...
|
|
1414
|
-
* that can be tomorrow
|
|
1415
|
-
*/
|
|
1416
|
-
class Document extends MalloyElement {
|
|
1417
|
-
constructor(statements) {
|
|
1418
|
-
super();
|
|
1419
|
-
this.elementType = "document";
|
|
1420
|
-
this.documentModel = {};
|
|
1421
|
-
this.queryList = [];
|
|
1422
|
-
this.sqlBlocks = [];
|
|
1423
|
-
this.didInitModel = false;
|
|
1424
|
-
this.statements = new RunList("topLevelStatements", statements);
|
|
1425
|
-
this.has({ statements });
|
|
1426
|
-
}
|
|
1427
|
-
initModelDef(extendingModelDef) {
|
|
1428
|
-
if (this.didInitModel) {
|
|
1429
|
-
return;
|
|
1430
|
-
}
|
|
1431
|
-
this.documentModel = {};
|
|
1432
|
-
this.queryList = [];
|
|
1433
|
-
this.sqlBlocks = [];
|
|
1434
|
-
if (extendingModelDef) {
|
|
1435
|
-
for (const inName in extendingModelDef.contents) {
|
|
1436
|
-
const struct = extendingModelDef.contents[inName];
|
|
1437
|
-
if (struct.type == "struct") {
|
|
1438
|
-
const exported = extendingModelDef.exports.includes(inName);
|
|
1439
|
-
this.setEntry(inName, { entry: struct, exported });
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
}
|
|
1443
|
-
this.didInitModel = true;
|
|
1444
|
-
}
|
|
1445
|
-
compile() {
|
|
1446
|
-
const needs = this.statements.executeList(this);
|
|
1447
|
-
const ret = {
|
|
1448
|
-
modelDef: this.modelDef(),
|
|
1449
|
-
queryList: this.queryList,
|
|
1450
|
-
sqlBlocks: this.sqlBlocks,
|
|
1451
|
-
needs,
|
|
1452
|
-
};
|
|
1453
|
-
return ret;
|
|
1454
|
-
}
|
|
1455
|
-
modelDef() {
|
|
1456
|
-
const def = { name: "", exports: [], contents: {} };
|
|
1457
|
-
for (const entry in this.documentModel) {
|
|
1458
|
-
const entryDef = this.documentModel[entry].entry;
|
|
1459
|
-
if (entryDef.type === "struct" || entryDef.type === "query") {
|
|
1460
|
-
if (this.documentModel[entry].exported) {
|
|
1461
|
-
def.exports.push(entry);
|
|
1462
|
-
}
|
|
1463
|
-
def.contents[entry] = (0, lodash_1.cloneDeep)(entryDef);
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
return def;
|
|
1467
|
-
}
|
|
1468
|
-
defineSQL(sql, name) {
|
|
1469
|
-
const ret = { ...sql, as: `$${this.sqlBlocks.length}` };
|
|
1470
|
-
if (name) {
|
|
1471
|
-
if (this.getEntry(name)) {
|
|
1472
|
-
return false;
|
|
1473
|
-
}
|
|
1474
|
-
ret.as = name;
|
|
1475
|
-
this.setEntry(name, { entry: ret, sqlType: true });
|
|
1476
|
-
}
|
|
1477
|
-
this.sqlBlocks.push(ret);
|
|
1478
|
-
return true;
|
|
1479
|
-
}
|
|
1480
|
-
getEntry(str) {
|
|
1481
|
-
return this.documentModel[str];
|
|
1482
|
-
}
|
|
1483
|
-
setEntry(str, ent) {
|
|
1484
|
-
this.documentModel[str] = ent;
|
|
1485
|
-
}
|
|
1486
|
-
}
|
|
1487
|
-
exports.Document = Document;
|
|
1488
|
-
class PrimaryKey extends MalloyElement {
|
|
1489
|
-
constructor(field) {
|
|
1490
|
-
super({ field });
|
|
1491
|
-
this.field = field;
|
|
1492
|
-
this.elementType = "primary key";
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
exports.PrimaryKey = PrimaryKey;
|
|
1496
|
-
class RenameField extends MalloyElement {
|
|
1497
|
-
constructor(newName, oldName) {
|
|
1498
|
-
super();
|
|
1499
|
-
this.newName = newName;
|
|
1500
|
-
this.oldName = oldName;
|
|
1501
|
-
this.elementType = "renameField";
|
|
1502
|
-
this.has({ oldName });
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
|
-
exports.RenameField = RenameField;
|
|
1506
|
-
class WildcardFieldReference extends MalloyElement {
|
|
1507
|
-
constructor(joinPath, star) {
|
|
1508
|
-
super();
|
|
1509
|
-
this.joinPath = joinPath;
|
|
1510
|
-
this.star = star;
|
|
1511
|
-
this.elementType = "wildcardFieldReference";
|
|
1512
|
-
this.has({ joinPath });
|
|
1513
|
-
}
|
|
1514
|
-
getFieldDef() {
|
|
1515
|
-
throw this.internalError("fielddef request from wildcard reference");
|
|
1516
|
-
}
|
|
1517
|
-
get refString() {
|
|
1518
|
-
return this.joinPath
|
|
1519
|
-
? `${this.joinPath.refString}.${this.star}`
|
|
1520
|
-
: this.star;
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
exports.WildcardFieldReference = WildcardFieldReference;
|
|
1524
|
-
class OrderBy extends MalloyElement {
|
|
1525
|
-
constructor(field, dir) {
|
|
1526
|
-
super();
|
|
1527
|
-
this.field = field;
|
|
1528
|
-
this.dir = dir;
|
|
1529
|
-
this.elementType = "orderBy";
|
|
1530
|
-
if (field instanceof FieldName) {
|
|
1531
|
-
this.has({ field });
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
get modelField() {
|
|
1535
|
-
return typeof this.field === "number" ? this.field : this.field.refString;
|
|
1536
|
-
}
|
|
1537
|
-
getOrderBy(_fs) {
|
|
1538
|
-
// TODO jump-to-definition `fs` cannot currently `lookup` fields in the output space
|
|
1539
|
-
// if (this.field instanceof FieldName) {
|
|
1540
|
-
// const entry = this.field.getField(_fs);
|
|
1541
|
-
// if (entry.error) {
|
|
1542
|
-
// this.field.log(entry.error);
|
|
1543
|
-
// }
|
|
1544
|
-
// }
|
|
1545
|
-
const orderElement = { field: this.modelField };
|
|
1546
|
-
if (this.dir) {
|
|
1547
|
-
orderElement.dir = this.dir;
|
|
1548
|
-
}
|
|
1549
|
-
return orderElement;
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
exports.OrderBy = OrderBy;
|
|
1553
|
-
class Ordering extends ListOf {
|
|
1554
|
-
constructor(list) {
|
|
1555
|
-
super("ordering", list);
|
|
1556
|
-
}
|
|
1557
|
-
getOrderBy(fs) {
|
|
1558
|
-
return this.list.map((el) => el.getOrderBy(fs));
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
exports.Ordering = Ordering;
|
|
1562
|
-
class Limit extends MalloyElement {
|
|
1563
|
-
constructor(limit) {
|
|
1564
|
-
super();
|
|
1565
|
-
this.limit = limit;
|
|
1566
|
-
this.elementType = "limit";
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
exports.Limit = Limit;
|
|
1570
|
-
class Turtles extends ListOf {
|
|
1571
|
-
constructor(turtles) {
|
|
1572
|
-
super("turtleDeclarationList", turtles);
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
exports.Turtles = Turtles;
|
|
1576
|
-
class Index extends MalloyElement {
|
|
1577
|
-
constructor(fields) {
|
|
1578
|
-
super({ fields });
|
|
1579
|
-
this.fields = fields;
|
|
1580
|
-
this.elementType = "index";
|
|
1581
|
-
}
|
|
1582
|
-
useWeight(fn) {
|
|
1583
|
-
this.has({ weightBy: fn });
|
|
1584
|
-
this.weightBy = fn;
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
exports.Index = Index;
|
|
1588
|
-
function isTurtle(fd) {
|
|
1589
|
-
const ret = fd && typeof fd !== "string" && fd.type === "turtle";
|
|
1590
|
-
return !!ret;
|
|
1591
|
-
}
|
|
1592
|
-
/**
|
|
1593
|
-
* Generic abstract for all pipelines, the first segment might be a reference
|
|
1594
|
-
* to an existing pipeline (query or turtle), and if there is a refinement it
|
|
1595
|
-
* is refers to the first segment of the composed pipeline.
|
|
1596
|
-
*/
|
|
1597
|
-
class PipelineDesc extends MalloyElement {
|
|
1598
|
-
constructor() {
|
|
1599
|
-
super(...arguments);
|
|
1600
|
-
this.elementType = "pipelineDesc";
|
|
1601
|
-
this.qops = [];
|
|
1602
|
-
}
|
|
1603
|
-
refineHead(refinement) {
|
|
1604
|
-
this.headRefinement = refinement;
|
|
1605
|
-
this.has({ headRefinement: refinement });
|
|
1606
|
-
}
|
|
1607
|
-
addSegments(...segDesc) {
|
|
1608
|
-
this.qops.push(...segDesc);
|
|
1609
|
-
this.has({ segments: this.qops });
|
|
1610
|
-
}
|
|
1611
|
-
appendOps(modelPipe, existingEndSpace) {
|
|
1612
|
-
let nextFS = existingEndSpace;
|
|
1613
|
-
let returnPipe;
|
|
1614
|
-
for (const qop of this.qops) {
|
|
1615
|
-
const qopIsNested = modelPipe.length == 0;
|
|
1616
|
-
const next = qop.getOp(nextFS, qopIsNested ? this : null);
|
|
1617
|
-
if (returnPipe == undefined) {
|
|
1618
|
-
returnPipe = [...modelPipe];
|
|
1619
|
-
}
|
|
1620
|
-
returnPipe.push(next.segment);
|
|
1621
|
-
nextFS = next.outputSpace();
|
|
1622
|
-
}
|
|
1623
|
-
return {
|
|
1624
|
-
opList: returnPipe || modelPipe,
|
|
1625
|
-
structDef: nextFS.structDef(),
|
|
1626
|
-
};
|
|
1627
|
-
}
|
|
1628
|
-
refinePipeline(fs, modelPipe) {
|
|
1629
|
-
if (!this.headRefinement) {
|
|
1630
|
-
return modelPipe;
|
|
1631
|
-
}
|
|
1632
|
-
const pipeline = [];
|
|
1633
|
-
if (modelPipe.pipeHead) {
|
|
1634
|
-
const { pipeline: turtlePipe } = this.expandTurtle(modelPipe.pipeHead.name, fs.structDef());
|
|
1635
|
-
pipeline.push(...turtlePipe);
|
|
1636
|
-
}
|
|
1637
|
-
pipeline.push(...modelPipe.pipeline);
|
|
1638
|
-
const firstSeg = pipeline[0];
|
|
1639
|
-
if (firstSeg) {
|
|
1640
|
-
this.headRefinement.refineFrom(firstSeg);
|
|
1641
|
-
}
|
|
1642
|
-
pipeline[0] = this.headRefinement.getOp(fs, this).segment;
|
|
1643
|
-
return { pipeline };
|
|
1644
|
-
}
|
|
1645
|
-
expandTurtle(turtleName, fromStruct) {
|
|
1646
|
-
const turtle = getStructFieldDef(fromStruct, turtleName);
|
|
1647
|
-
if (!turtle) {
|
|
1648
|
-
this.log(`Query '${turtleName}' is not defined in source`);
|
|
1649
|
-
}
|
|
1650
|
-
else if (turtle.type !== "turtle") {
|
|
1651
|
-
this.log(`'${turtleName}' is not a query`);
|
|
1652
|
-
}
|
|
1653
|
-
else {
|
|
1654
|
-
return { pipeline: turtle.pipeline, location: turtle.location };
|
|
1655
|
-
}
|
|
1656
|
-
return { pipeline: [], location: undefined };
|
|
1657
|
-
}
|
|
1658
|
-
getOutputStruct(walkStruct, pipeline) {
|
|
1659
|
-
for (const modelQop of pipeline) {
|
|
1660
|
-
walkStruct = opOutputStruct(this, walkStruct, modelQop);
|
|
1661
|
-
}
|
|
1662
|
-
return walkStruct;
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
class ExistingQuery extends PipelineDesc {
|
|
1666
|
-
set head(head) {
|
|
1667
|
-
this._head = head;
|
|
1668
|
-
this.has({ head });
|
|
1669
|
-
}
|
|
1670
|
-
get head() {
|
|
1671
|
-
return this._head;
|
|
1672
|
-
}
|
|
1673
|
-
queryComp() {
|
|
1674
|
-
if (!this.head) {
|
|
1675
|
-
throw this.internalError("can't make query from nameless query");
|
|
1676
|
-
}
|
|
1677
|
-
const queryEntry = this.modelEntry(this.head);
|
|
1678
|
-
const seedQuery = queryEntry === null || queryEntry === void 0 ? void 0 : queryEntry.entry;
|
|
1679
|
-
const oops = function () {
|
|
1680
|
-
return {
|
|
1681
|
-
outputStruct: ErrorFactory.structDef,
|
|
1682
|
-
query: ErrorFactory.query,
|
|
1683
|
-
};
|
|
1684
|
-
};
|
|
1685
|
-
if (!seedQuery) {
|
|
1686
|
-
this.log(`Reference to undefined query '${this.head}'`);
|
|
1687
|
-
return oops();
|
|
1688
|
-
}
|
|
1689
|
-
if (seedQuery.type !== "query") {
|
|
1690
|
-
this.log(`Illegal reference to '${this.head}', query expected`);
|
|
1691
|
-
return oops();
|
|
1692
|
-
}
|
|
1693
|
-
const queryHead = new QueryHeadStruct(seedQuery.structRef);
|
|
1694
|
-
this.has({ queryHead });
|
|
1695
|
-
const exploreStruct = queryHead.structDef();
|
|
1696
|
-
const exploreFS = new DynamicSpace(exploreStruct);
|
|
1697
|
-
const sourcePipe = this.refinePipeline(exploreFS, seedQuery);
|
|
1698
|
-
const walkStruct = this.getOutputStruct(exploreStruct, sourcePipe.pipeline);
|
|
1699
|
-
const appended = this.appendOps(sourcePipe.pipeline, new DynamicSpace(walkStruct));
|
|
1700
|
-
const destPipe = { ...sourcePipe, pipeline: appended.opList };
|
|
1701
|
-
const query = {
|
|
1702
|
-
type: "query",
|
|
1703
|
-
...destPipe,
|
|
1704
|
-
structRef: queryHead.structRef(),
|
|
1705
|
-
location: this.location,
|
|
1706
|
-
};
|
|
1707
|
-
return { outputStruct: appended.structDef, query };
|
|
1708
|
-
}
|
|
1709
|
-
query() {
|
|
1710
|
-
return this.queryComp().query;
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
exports.ExistingQuery = ExistingQuery;
|
|
1714
|
-
class TurtleHeadedPipe extends PipelineDesc {
|
|
1715
|
-
set turtleName(turtleName) {
|
|
1716
|
-
this._turtleName = turtleName;
|
|
1717
|
-
this.has({ turtleName });
|
|
1718
|
-
}
|
|
1719
|
-
get turtleName() {
|
|
1720
|
-
return this._turtleName;
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
|
-
exports.TurtleHeadedPipe = TurtleHeadedPipe;
|
|
1724
|
-
class FullQuery extends TurtleHeadedPipe {
|
|
1725
|
-
constructor(explore) {
|
|
1726
|
-
super({ explore });
|
|
1727
|
-
this.explore = explore;
|
|
1728
|
-
}
|
|
1729
|
-
queryComp() {
|
|
1730
|
-
const structRef = this.explore.structRef();
|
|
1731
|
-
const destQuery = {
|
|
1732
|
-
type: "query",
|
|
1733
|
-
structRef,
|
|
1734
|
-
pipeline: [],
|
|
1735
|
-
location: this.location,
|
|
1736
|
-
};
|
|
1737
|
-
const structDef = model.refIsStructDef(structRef)
|
|
1738
|
-
? structRef
|
|
1739
|
-
: this.explore.structDef();
|
|
1740
|
-
let pipeFs = new DynamicSpace(structDef);
|
|
1741
|
-
if (ErrorFactory.isErrorStructDef(structDef)) {
|
|
1742
|
-
return {
|
|
1743
|
-
outputStruct: structDef,
|
|
1744
|
-
query: {
|
|
1745
|
-
structRef: structRef,
|
|
1746
|
-
pipeline: [],
|
|
1747
|
-
},
|
|
1748
|
-
};
|
|
1749
|
-
}
|
|
1750
|
-
if (this.turtleName) {
|
|
1751
|
-
const { error } = this.turtleName.getField(pipeFs);
|
|
1752
|
-
if (error)
|
|
1753
|
-
this.log(error);
|
|
1754
|
-
const name = this.turtleName.refString;
|
|
1755
|
-
const { pipeline, location } = this.expandTurtle(name, structDef);
|
|
1756
|
-
destQuery.location = location;
|
|
1757
|
-
const refined = this.refinePipeline(pipeFs, { pipeline }).pipeline;
|
|
1758
|
-
if (this.headRefinement) {
|
|
1759
|
-
// TODO there is an issue with losing the name of the turtle
|
|
1760
|
-
// which we need to fix, possibly adding a "name:" field to a segment
|
|
1761
|
-
// TODO there was mention of promoting filters to the query
|
|
1762
|
-
destQuery.pipeline = refined;
|
|
1763
|
-
}
|
|
1764
|
-
else {
|
|
1765
|
-
destQuery.pipeHead = { name };
|
|
1766
|
-
}
|
|
1767
|
-
const pipeStruct = this.getOutputStruct(structDef, refined);
|
|
1768
|
-
pipeFs = new DynamicSpace(pipeStruct);
|
|
1769
|
-
}
|
|
1770
|
-
const appended = this.appendOps(destQuery.pipeline, pipeFs);
|
|
1771
|
-
destQuery.pipeline = appended.opList;
|
|
1772
|
-
return { outputStruct: appended.structDef, query: destQuery };
|
|
1773
|
-
}
|
|
1774
|
-
query() {
|
|
1775
|
-
return this.queryComp().query;
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
exports.FullQuery = FullQuery;
|
|
1779
|
-
class TurtleDecl extends TurtleHeadedPipe {
|
|
1780
|
-
constructor(name) {
|
|
1781
|
-
super();
|
|
1782
|
-
this.name = name;
|
|
1783
|
-
}
|
|
1784
|
-
getPipeline(fs) {
|
|
1785
|
-
const modelPipe = { pipeline: [] };
|
|
1786
|
-
if (this.turtleName) {
|
|
1787
|
-
const headEnt = this.turtleName.getField(fs);
|
|
1788
|
-
let reportWrongType = true;
|
|
1789
|
-
if (headEnt.error) {
|
|
1790
|
-
this.log(headEnt.error);
|
|
1791
|
-
reportWrongType = false;
|
|
1792
|
-
}
|
|
1793
|
-
else if (headEnt.found instanceof QueryField) {
|
|
1794
|
-
const headDef = headEnt.found.getQueryFieldDef(fs);
|
|
1795
|
-
if (isTurtle(headDef)) {
|
|
1796
|
-
const newPipe = this.refinePipeline(fs, headDef);
|
|
1797
|
-
modelPipe.pipeline = [...newPipe.pipeline];
|
|
1798
|
-
reportWrongType = false;
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
|
-
if (reportWrongType) {
|
|
1802
|
-
this.log(`Expected '${this.turtleName}' to be a query`);
|
|
1803
|
-
}
|
|
1804
|
-
}
|
|
1805
|
-
else if (this.headRefinement) {
|
|
1806
|
-
throw this.internalError("Can't refine the head of a turtle in its definition");
|
|
1807
|
-
}
|
|
1808
|
-
let appendInput = fs;
|
|
1809
|
-
if (modelPipe.pipeline.length > 0) {
|
|
1810
|
-
let endStruct = appendInput.structDef();
|
|
1811
|
-
for (const existingSeg of modelPipe.pipeline) {
|
|
1812
|
-
endStruct = opOutputStruct(this, endStruct, existingSeg);
|
|
1813
|
-
}
|
|
1814
|
-
appendInput = new DynamicSpace(endStruct);
|
|
1815
|
-
}
|
|
1816
|
-
const appended = this.appendOps(modelPipe.pipeline, appendInput);
|
|
1817
|
-
modelPipe.pipeline = appended.opList;
|
|
1818
|
-
return modelPipe;
|
|
1819
|
-
}
|
|
1820
|
-
getFieldDef(fs, nestParent) {
|
|
1821
|
-
if (nestParent) {
|
|
1822
|
-
this.nestedInQuerySpace = nestParent;
|
|
1823
|
-
}
|
|
1824
|
-
const pipe = this.getPipeline(fs);
|
|
1825
|
-
return {
|
|
1826
|
-
type: "turtle",
|
|
1827
|
-
name: this.name,
|
|
1828
|
-
...pipe,
|
|
1829
|
-
location: this.location,
|
|
1830
|
-
};
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
exports.TurtleDecl = TurtleDecl;
|
|
1834
|
-
class NestReference extends FieldReference {
|
|
1835
|
-
constructor(name) {
|
|
1836
|
-
super([name]);
|
|
1837
|
-
this.name = name;
|
|
1838
|
-
this.elementType = "nestReference";
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
exports.NestReference = NestReference;
|
|
1842
|
-
class NestRefinement extends TurtleDecl {
|
|
1843
|
-
constructor(turtleName) {
|
|
1844
|
-
super(turtleName.refString);
|
|
1845
|
-
this.elementType = "nestRefinement";
|
|
1846
|
-
this.turtleName = turtleName;
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
exports.NestRefinement = NestRefinement;
|
|
1850
|
-
class NestDefinition extends TurtleDecl {
|
|
1851
|
-
constructor(name) {
|
|
1852
|
-
super(name);
|
|
1853
|
-
this.elementType = "nestDefinition";
|
|
1854
|
-
}
|
|
1855
|
-
}
|
|
1856
|
-
exports.NestDefinition = NestDefinition;
|
|
1857
|
-
function isNestedQuery(me) {
|
|
1858
|
-
return (me instanceof NestRefinement ||
|
|
1859
|
-
me instanceof NestReference ||
|
|
1860
|
-
me instanceof NestDefinition);
|
|
1861
|
-
}
|
|
1862
|
-
exports.isNestedQuery = isNestedQuery;
|
|
1863
|
-
class Nests extends ListOf {
|
|
1864
|
-
constructor(nests) {
|
|
1865
|
-
super("nestedQueries", nests);
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
|
-
exports.Nests = Nests;
|
|
1869
|
-
function isQueryElement(e) {
|
|
1870
|
-
return e instanceof FullQuery || e instanceof ExistingQuery;
|
|
1871
|
-
}
|
|
1872
|
-
exports.isQueryElement = isQueryElement;
|
|
1873
|
-
class DefineQueryList extends RunList {
|
|
1874
|
-
constructor(queryList) {
|
|
1875
|
-
super("defineQueries", queryList);
|
|
1876
|
-
}
|
|
1877
|
-
execute(doc) {
|
|
1878
|
-
return this.executeList(doc);
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
exports.DefineQueryList = DefineQueryList;
|
|
1882
|
-
class DefineQuery extends MalloyElement {
|
|
1883
|
-
constructor(name, queryDetails) {
|
|
1884
|
-
super({ queryDetails });
|
|
1885
|
-
this.name = name;
|
|
1886
|
-
this.queryDetails = queryDetails;
|
|
1887
|
-
this.elementType = "defineQuery";
|
|
1888
|
-
}
|
|
1889
|
-
execute(doc) {
|
|
1890
|
-
const entry = {
|
|
1891
|
-
...this.queryDetails.query(),
|
|
1892
|
-
type: "query",
|
|
1893
|
-
name: this.name,
|
|
1894
|
-
location: this.location,
|
|
1895
|
-
};
|
|
1896
|
-
const exported = false;
|
|
1897
|
-
doc.setEntry(this.name, { entry, exported });
|
|
1898
|
-
return undefined;
|
|
1899
|
-
}
|
|
1900
|
-
}
|
|
1901
|
-
exports.DefineQuery = DefineQuery;
|
|
1902
|
-
class AnonymousQuery extends MalloyElement {
|
|
1903
|
-
constructor(theQuery) {
|
|
1904
|
-
super();
|
|
1905
|
-
this.theQuery = theQuery;
|
|
1906
|
-
this.elementType = "anonymousQuery";
|
|
1907
|
-
this.has({ query: theQuery });
|
|
1908
|
-
}
|
|
1909
|
-
execute(doc) {
|
|
1910
|
-
const modelQuery = this.theQuery.query();
|
|
1911
|
-
doc.queryList.push(modelQuery);
|
|
1912
|
-
return undefined;
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
|
-
exports.AnonymousQuery = AnonymousQuery;
|
|
1916
|
-
class Top extends MalloyElement {
|
|
1917
|
-
constructor(limit, by) {
|
|
1918
|
-
super();
|
|
1919
|
-
this.limit = limit;
|
|
1920
|
-
this.by = by;
|
|
1921
|
-
this.elementType = "top";
|
|
1922
|
-
this.has({ by });
|
|
1923
|
-
}
|
|
1924
|
-
getBy(fs) {
|
|
1925
|
-
if (this.by) {
|
|
1926
|
-
if (this.by instanceof FieldName) {
|
|
1927
|
-
// TODO jump-to-definition `fs` cannot currently `lookup` fields in the output space
|
|
1928
|
-
// const entry = this.by.getField(fs);
|
|
1929
|
-
// if (entry.error) {
|
|
1930
|
-
// this.by.log(entry.error);
|
|
1931
|
-
// }
|
|
1932
|
-
return { by: "name", name: this.by.refString };
|
|
1933
|
-
}
|
|
1934
|
-
else {
|
|
1935
|
-
const byExpr = this.by.getExpression(fs);
|
|
1936
|
-
if (model.expressionIsAggregate(byExpr.expressionType)) {
|
|
1937
|
-
this.log("top by expression must be an aggregate");
|
|
1938
|
-
}
|
|
1939
|
-
return { by: "expression", e: (0, ast_types_1.compressExpr)(byExpr.value) };
|
|
1940
|
-
}
|
|
1941
|
-
}
|
|
1942
|
-
return undefined;
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
exports.Top = Top;
|
|
1946
|
-
class JSONElement extends MalloyElement {
|
|
1947
|
-
constructor(jsonSrc) {
|
|
1948
|
-
super();
|
|
1949
|
-
this.elementType = "jsonElement";
|
|
1950
|
-
try {
|
|
1951
|
-
this.value = JSON.parse(jsonSrc);
|
|
1952
|
-
}
|
|
1953
|
-
catch (SyntaxError) {
|
|
1954
|
-
this.log("JSON syntax error");
|
|
1955
|
-
this.value = undefined;
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
|
-
}
|
|
1959
|
-
exports.JSONElement = JSONElement;
|
|
1960
|
-
class JSONStructDef extends Mallobj {
|
|
1961
|
-
constructor(struct) {
|
|
1962
|
-
super();
|
|
1963
|
-
this.struct = struct;
|
|
1964
|
-
this.elementType = "jsonStructDef";
|
|
1965
|
-
}
|
|
1966
|
-
static fromJSON(jsonObj) {
|
|
1967
|
-
const obj = jsonObj.value;
|
|
1968
|
-
if (obj &&
|
|
1969
|
-
obj.type === "struct" &&
|
|
1970
|
-
obj.structRelationship &&
|
|
1971
|
-
obj.structSource) {
|
|
1972
|
-
return new JSONStructDef(obj);
|
|
1973
|
-
}
|
|
1974
|
-
return undefined;
|
|
1975
|
-
}
|
|
1976
|
-
structDef() {
|
|
1977
|
-
return this.struct;
|
|
1978
|
-
}
|
|
1979
|
-
}
|
|
1980
|
-
exports.JSONStructDef = JSONStructDef;
|
|
1981
|
-
class ImportStatement extends MalloyElement {
|
|
1982
|
-
/*
|
|
1983
|
-
* At the time of writng this comment, it is guaranteed that if an AST
|
|
1984
|
-
* node for an import statement is created, the translator has already
|
|
1985
|
-
* succesfully fetched the URL referred to in the statement.
|
|
1986
|
-
*
|
|
1987
|
-
* Error checking code in here is future proofing against a day when
|
|
1988
|
-
* there are other ways to contruct an AST.
|
|
1989
|
-
*/
|
|
1990
|
-
constructor(url, baseURL) {
|
|
1991
|
-
super();
|
|
1992
|
-
this.url = url;
|
|
1993
|
-
this.elementType = "import statement";
|
|
1994
|
-
try {
|
|
1995
|
-
this.fullURL = decodeURI(new URL(url, baseURL).toString());
|
|
1996
|
-
}
|
|
1997
|
-
catch (e) {
|
|
1998
|
-
this.log("Invalid URI in import statement");
|
|
1999
|
-
}
|
|
2000
|
-
}
|
|
2001
|
-
execute(doc) {
|
|
2002
|
-
const trans = this.translator();
|
|
2003
|
-
if (!trans) {
|
|
2004
|
-
this.log("Cannot import without translation context");
|
|
2005
|
-
}
|
|
2006
|
-
else if (this.fullURL) {
|
|
2007
|
-
const src = trans.root.importZone.getEntry(this.fullURL);
|
|
2008
|
-
if (src.status === "present") {
|
|
2009
|
-
const childNeeds = trans.childRequest(this.fullURL);
|
|
2010
|
-
if (childNeeds) {
|
|
2011
|
-
return childNeeds;
|
|
2012
|
-
}
|
|
2013
|
-
const importStructs = trans.getChildExports(this.fullURL);
|
|
2014
|
-
for (const importing in importStructs) {
|
|
2015
|
-
doc.setEntry(importing, {
|
|
2016
|
-
entry: importStructs[importing],
|
|
2017
|
-
exported: false,
|
|
2018
|
-
});
|
|
2019
|
-
}
|
|
2020
|
-
}
|
|
2021
|
-
else if (src.status === "error") {
|
|
2022
|
-
this.log(`import failed: '${src.message}'`);
|
|
2023
|
-
}
|
|
2024
|
-
else {
|
|
2025
|
-
this.log(`import failed with status: '${src.status}'`);
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
return undefined;
|
|
2029
|
-
}
|
|
2030
|
-
}
|
|
2031
|
-
exports.ImportStatement = ImportStatement;
|
|
2032
|
-
class HasParameter extends MalloyElement {
|
|
2033
|
-
constructor(init) {
|
|
2034
|
-
super();
|
|
2035
|
-
this.elementType = "hasParameter";
|
|
2036
|
-
this.name = init.name;
|
|
2037
|
-
this.isCondition = init.isCondition;
|
|
2038
|
-
if (init.type && model.isAtomicFieldType(init.type)) {
|
|
2039
|
-
this.type = init.type;
|
|
2040
|
-
}
|
|
2041
|
-
if (init.default) {
|
|
2042
|
-
this.default = init.default;
|
|
2043
|
-
this.has({ default: this.default });
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
parameter() {
|
|
2047
|
-
var _a, _b;
|
|
2048
|
-
const name = this.name;
|
|
2049
|
-
const type = this.type || "string";
|
|
2050
|
-
if (this.isCondition) {
|
|
2051
|
-
const cCond = ((_a = this.default) === null || _a === void 0 ? void 0 : _a.constantCondition(type).value) || null;
|
|
2052
|
-
return {
|
|
2053
|
-
type,
|
|
2054
|
-
name,
|
|
2055
|
-
condition: cCond,
|
|
2056
|
-
};
|
|
2057
|
-
}
|
|
2058
|
-
const cVal = ((_b = this.default) === null || _b === void 0 ? void 0 : _b.constantValue().value) || null;
|
|
2059
|
-
return {
|
|
2060
|
-
value: cVal,
|
|
2061
|
-
type,
|
|
2062
|
-
name: this.name,
|
|
2063
|
-
constant: false,
|
|
2064
|
-
};
|
|
2065
|
-
}
|
|
2066
|
-
}
|
|
2067
|
-
exports.HasParameter = HasParameter;
|
|
2068
|
-
class ConstantParameter extends HasParameter {
|
|
2069
|
-
constructor(name, value) {
|
|
2070
|
-
super({ name, isCondition: false });
|
|
2071
|
-
this.value = value;
|
|
2072
|
-
this.has({ value });
|
|
2073
|
-
}
|
|
2074
|
-
parameter() {
|
|
2075
|
-
const cVal = this.value.constantValue();
|
|
2076
|
-
if (!model.isAtomicFieldType(cVal.dataType)) {
|
|
2077
|
-
this.log(`Unexpected expression type '${cVal.dataType}'`);
|
|
2078
|
-
return {
|
|
2079
|
-
value: ["XXX-type-mismatch-error-XXX"],
|
|
2080
|
-
type: "string",
|
|
2081
|
-
name: this.name,
|
|
2082
|
-
constant: true,
|
|
2083
|
-
};
|
|
2084
|
-
}
|
|
2085
|
-
return {
|
|
2086
|
-
value: cVal.value,
|
|
2087
|
-
type: cVal.dataType,
|
|
2088
|
-
name: this.name,
|
|
2089
|
-
constant: true,
|
|
2090
|
-
};
|
|
2091
|
-
}
|
|
2092
|
-
}
|
|
2093
|
-
exports.ConstantParameter = ConstantParameter;
|
|
2094
|
-
class SQLString extends MalloyElement {
|
|
2095
|
-
constructor() {
|
|
2096
|
-
super(...arguments);
|
|
2097
|
-
this.elementType = "sqlString";
|
|
2098
|
-
this.elements = [];
|
|
2099
|
-
this.containsQueries = false;
|
|
2100
|
-
}
|
|
2101
|
-
push(el) {
|
|
2102
|
-
if (typeof el == "string") {
|
|
2103
|
-
if (el.length > 0) {
|
|
2104
|
-
this.elements.push(el);
|
|
2105
|
-
}
|
|
2106
|
-
}
|
|
2107
|
-
else if (isQueryElement(el)) {
|
|
2108
|
-
this.elements.push(el);
|
|
2109
|
-
this.containsQueries = true;
|
|
2110
|
-
el.parent = this;
|
|
2111
|
-
}
|
|
2112
|
-
else {
|
|
2113
|
-
el.log("This element is not legal inside an SQL string");
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
sqlPhrases() {
|
|
2117
|
-
return this.elements.map((el) => {
|
|
2118
|
-
if (typeof el == "string") {
|
|
2119
|
-
return { sql: el };
|
|
2120
|
-
}
|
|
2121
|
-
return el.query();
|
|
2122
|
-
});
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
|
-
exports.SQLString = SQLString;
|
|
2126
|
-
class SQLStatement extends MalloyElement {
|
|
2127
|
-
constructor(select) {
|
|
2128
|
-
super();
|
|
2129
|
-
this.select = select;
|
|
2130
|
-
this.elementType = "sqlStatement";
|
|
2131
|
-
this.has({ select });
|
|
2132
|
-
}
|
|
2133
|
-
sqlBlock() {
|
|
2134
|
-
if (!this.requestBlock) {
|
|
2135
|
-
this.requestBlock = (0, sql_block_1.makeSQLBlock)(this.select.sqlPhrases(), this.connection);
|
|
2136
|
-
}
|
|
2137
|
-
return this.requestBlock;
|
|
2138
|
-
}
|
|
2139
|
-
/**
|
|
2140
|
-
* This is the one statement which pauses execution. First time through
|
|
2141
|
-
* it will generate a schema request, next time through it will either
|
|
2142
|
-
* record the error or record the schema.
|
|
2143
|
-
*/
|
|
2144
|
-
execute(doc) {
|
|
2145
|
-
var _a;
|
|
2146
|
-
const sqlDefEntry = (_a = this.translator()) === null || _a === void 0 ? void 0 : _a.root.sqlQueryZone;
|
|
2147
|
-
if (!sqlDefEntry) {
|
|
2148
|
-
this.log("Cant't look up schema for sql block");
|
|
2149
|
-
return;
|
|
2150
|
-
}
|
|
2151
|
-
const sql = this.sqlBlock();
|
|
2152
|
-
sqlDefEntry.reference(sql.name, this.location);
|
|
2153
|
-
const lookup = sqlDefEntry.getEntry(sql.name);
|
|
2154
|
-
if (lookup.status == "error") {
|
|
2155
|
-
const msgLines = lookup.message.split(/\r?\n/);
|
|
2156
|
-
this.select.log("Invalid SQL, " + msgLines.join("\n "));
|
|
2157
|
-
return undefined;
|
|
2158
|
-
}
|
|
2159
|
-
if (lookup.status == "present") {
|
|
2160
|
-
const location = this.select.location;
|
|
2161
|
-
const locStruct = {
|
|
2162
|
-
...lookup.value,
|
|
2163
|
-
fields: lookup.value.fields.map((f) => ({ ...f, location })),
|
|
2164
|
-
location: this.location,
|
|
2165
|
-
};
|
|
2166
|
-
if (this.is && !doc.defineSQL(locStruct, this.is)) {
|
|
2167
|
-
this.log(`'${this.is}' already defined`);
|
|
2168
|
-
}
|
|
2169
|
-
return undefined;
|
|
2170
|
-
}
|
|
2171
|
-
return {
|
|
2172
|
-
compileSQL: sql,
|
|
2173
|
-
partialModel: this.select.containsQueries ? doc.modelDef() : undefined,
|
|
2174
|
-
};
|
|
2175
|
-
}
|
|
2176
|
-
}
|
|
2177
|
-
exports.SQLStatement = SQLStatement;
|
|
2178
|
-
class SampleProperty extends MalloyElement {
|
|
2179
|
-
constructor(sample) {
|
|
2180
|
-
super();
|
|
2181
|
-
this.sample = sample;
|
|
2182
|
-
this.elementType = "sampleProperty";
|
|
2183
|
-
}
|
|
2184
|
-
sampling() {
|
|
2185
|
-
return this.sample;
|
|
2186
|
-
}
|
|
2187
|
-
}
|
|
2188
|
-
exports.SampleProperty = SampleProperty;
|
|
2189
|
-
/**
|
|
2190
|
-
* Root node for any element in an expression. These essentially
|
|
2191
|
-
* create a sub-tree in the larger AST. Expression nodes know
|
|
2192
|
-
* how to write themselves as SQL (or rather, generate the
|
|
2193
|
-
* template for SQL required by the query writer)
|
|
2194
|
-
*/
|
|
2195
|
-
class ExpressionDef extends MalloyElement {
|
|
2196
|
-
constructor() {
|
|
2197
|
-
super(...arguments);
|
|
2198
|
-
this.legalChildTypes = ast_types_1.FT.anyAtomicT;
|
|
2199
|
-
}
|
|
2200
|
-
granular() {
|
|
2201
|
-
return false;
|
|
2202
|
-
}
|
|
2203
|
-
/**
|
|
2204
|
-
* Some operators want to give the right hand value a chance to
|
|
2205
|
-
* rewrite itself. This requests a translation for a rewrite,
|
|
2206
|
-
* or returns undefined if that request should be denied.
|
|
2207
|
-
* @param fs FieldSpace
|
|
2208
|
-
* @returns Translated expression or undefined
|
|
2209
|
-
*/
|
|
2210
|
-
requestExpression(fs) {
|
|
2211
|
-
return this.getExpression(fs);
|
|
2212
|
-
}
|
|
2213
|
-
defaultFieldName() {
|
|
2214
|
-
return undefined;
|
|
2215
|
-
}
|
|
2216
|
-
/**
|
|
2217
|
-
* Check an expression for type compatibility
|
|
2218
|
-
* @param _eNode currently unused, will be used to get error location
|
|
2219
|
-
* @param eVal ...list of expressions that must match legalChildTypes
|
|
2220
|
-
*/
|
|
2221
|
-
typeCheck(eNode, eVal) {
|
|
2222
|
-
if (!ast_types_1.FT.in(eVal, this.legalChildTypes)) {
|
|
2223
|
-
eNode.log(`'${this.elementType}' Can't use type ${ast_types_1.FT.inspect(eVal)}`);
|
|
2224
|
-
return false;
|
|
2225
|
-
}
|
|
2226
|
-
return true;
|
|
2227
|
-
}
|
|
2228
|
-
/**
|
|
2229
|
-
* This is the operation which makes partial comparison and value trees work
|
|
2230
|
-
* The default implemention merely constructs LEFT OP RIGHT, but specialized
|
|
2231
|
-
* nodes like alternation trees or or partial comparison can control how
|
|
2232
|
-
* the appplication gets generated
|
|
2233
|
-
* @param fs The symbol table
|
|
2234
|
-
* @param op The operator being applied
|
|
2235
|
-
* @param expr The "other" (besdies 'this') value
|
|
2236
|
-
* @returns The translated expression
|
|
2237
|
-
*/
|
|
2238
|
-
apply(fs, op, left) {
|
|
2239
|
-
return applyBinary(fs, left, op, this);
|
|
2240
|
-
}
|
|
2241
|
-
}
|
|
2242
|
-
exports.ExpressionDef = ExpressionDef;
|
|
2243
|
-
class ConstantSubExpression extends ExpressionDef {
|
|
2244
|
-
constructor(expr) {
|
|
2245
|
-
super({ expr });
|
|
2246
|
-
this.expr = expr;
|
|
2247
|
-
this.elementType = "constantExpression";
|
|
2248
|
-
}
|
|
2249
|
-
getExpression(_fs) {
|
|
2250
|
-
return this.constantValue();
|
|
2251
|
-
}
|
|
2252
|
-
get constantFs() {
|
|
2253
|
-
if (!this.cfs) {
|
|
2254
|
-
this.cfs = new ConstantFieldSpace();
|
|
2255
|
-
}
|
|
2256
|
-
return this.cfs;
|
|
2257
|
-
}
|
|
2258
|
-
constantValue() {
|
|
2259
|
-
return this.expr.getExpression(this.constantFs);
|
|
2260
|
-
}
|
|
2261
|
-
constantCondition(type) {
|
|
2262
|
-
const compareAndContrast = new ExprCompare(new DollarReference(type), "=", this.expr);
|
|
2263
|
-
const application = compareAndContrast.getExpression(this.constantFs);
|
|
2264
|
-
return { ...application, value: (0, ast_types_1.compressExpr)(application.value) };
|
|
2265
|
-
}
|
|
2266
|
-
apply(fs, op, expr) {
|
|
2267
|
-
return this.expr.apply(fs, op, expr);
|
|
2268
|
-
}
|
|
2269
|
-
requestExpression(fs) {
|
|
2270
|
-
return this.expr.requestExpression(fs);
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
exports.ConstantSubExpression = ConstantSubExpression;
|
|
2274
|
-
class DollarReference extends ExpressionDef {
|
|
2275
|
-
constructor(refType) {
|
|
2276
|
-
super();
|
|
2277
|
-
this.refType = refType;
|
|
2278
|
-
this.elementType = "$";
|
|
2279
|
-
}
|
|
2280
|
-
getExpression(_fs) {
|
|
2281
|
-
return {
|
|
2282
|
-
dataType: this.refType,
|
|
2283
|
-
value: [{ type: "applyVal" }],
|
|
2284
|
-
expressionType: "scalar",
|
|
2285
|
-
};
|
|
2286
|
-
}
|
|
2287
|
-
}
|
|
2288
|
-
class ConstantFieldSpace {
|
|
2289
|
-
constructor() {
|
|
2290
|
-
this.type = "fieldSpace";
|
|
2291
|
-
}
|
|
2292
|
-
structDef() {
|
|
2293
|
-
throw new Error("ConstantFieldSpace cannot generate a structDef");
|
|
2294
|
-
}
|
|
2295
|
-
emptyStructDef() {
|
|
2296
|
-
throw new Error("ConstantFieldSpace cannot generate a structDef");
|
|
2297
|
-
}
|
|
2298
|
-
lookup(_name) {
|
|
2299
|
-
return {
|
|
2300
|
-
error: "Only constants allowed in parameter expressions",
|
|
2301
|
-
found: undefined,
|
|
2302
|
-
};
|
|
2303
|
-
}
|
|
2304
|
-
dialectObj() {
|
|
2305
|
-
return undefined;
|
|
2306
|
-
}
|
|
2307
|
-
whenComplete(step) {
|
|
2308
|
-
step();
|
|
2309
|
-
}
|
|
2310
|
-
}
|
|
2311
|
-
class FieldDeclaration extends MalloyElement {
|
|
2312
|
-
constructor(expr, defineName, exprSrc) {
|
|
2313
|
-
super({ expr });
|
|
2314
|
-
this.expr = expr;
|
|
2315
|
-
this.defineName = defineName;
|
|
2316
|
-
this.exprSrc = exprSrc;
|
|
2317
|
-
this.elementType = "fieldDeclaration";
|
|
2318
|
-
}
|
|
2319
|
-
fieldDef(fs, exprName) {
|
|
2320
|
-
/*
|
|
2321
|
-
* In an explore we cannot reference the thing we are defining, you need
|
|
2322
|
-
* to use rename. In a query, the output space is a new thing, and expressions
|
|
2323
|
-
* can reference the outer value in order to make a value with the new name,
|
|
2324
|
-
* and it feels wrong that this is HERE and not somehow in the QueryOperation.
|
|
2325
|
-
* For now, this stops the stack overflow, and passes all tests, but I think
|
|
2326
|
-
* a refactor of QueryFieldSpace might someday be the place where this should
|
|
2327
|
-
* happen.
|
|
2328
|
-
*/
|
|
2329
|
-
return this.queryFieldDef(new DefSpace(fs, this), exprName);
|
|
2330
|
-
}
|
|
2331
|
-
queryFieldDef(exprFS, exprName) {
|
|
2332
|
-
let exprValue;
|
|
2333
|
-
try {
|
|
2334
|
-
exprValue = this.expr.getExpression(exprFS);
|
|
2335
|
-
}
|
|
2336
|
-
catch (error) {
|
|
2337
|
-
this.log(`Cannot define '${exprName}', ${error.message}`);
|
|
2338
|
-
return {
|
|
2339
|
-
name: `error_defining_${exprName}`,
|
|
2340
|
-
type: "string",
|
|
2341
|
-
};
|
|
2342
|
-
}
|
|
2343
|
-
const compressValue = (0, ast_types_1.compressExpr)(exprValue.value);
|
|
2344
|
-
const retType = exprValue.dataType;
|
|
2345
|
-
if ((0, malloy_types_1.isAtomicFieldType)(retType)) {
|
|
2346
|
-
const template = {
|
|
2347
|
-
name: exprName,
|
|
2348
|
-
type: retType,
|
|
2349
|
-
location: this.location,
|
|
2350
|
-
};
|
|
2351
|
-
if (compressValue.length > 0) {
|
|
2352
|
-
template.e = compressValue;
|
|
2353
|
-
}
|
|
2354
|
-
if (exprValue.expressionType) {
|
|
2355
|
-
template.expressionType = exprValue.expressionType;
|
|
2356
|
-
}
|
|
2357
|
-
if (this.exprSrc) {
|
|
2358
|
-
template.code = this.exprSrc;
|
|
2359
|
-
}
|
|
2360
|
-
// TODO this should work for dates too
|
|
2361
|
-
if ((0, ast_types_1.isGranularResult)(exprValue) && template.type === "timestamp") {
|
|
2362
|
-
template.timeframe = exprValue.timeframe;
|
|
2363
|
-
}
|
|
2364
|
-
return template;
|
|
2365
|
-
}
|
|
2366
|
-
const circularDef = exprFS instanceof DefSpace && exprFS.foundCircle;
|
|
2367
|
-
if (!circularDef) {
|
|
2368
|
-
if (exprValue.dataType == "unknown") {
|
|
2369
|
-
this.log(`Cannot define '${exprName}', value has unknown type`);
|
|
2370
|
-
}
|
|
2371
|
-
else {
|
|
2372
|
-
const badType = ast_types_1.FT.inspect(exprValue);
|
|
2373
|
-
this.log(`Cannot define '${exprName}', unexpected type: ${badType}`);
|
|
2374
|
-
}
|
|
2375
|
-
}
|
|
2376
|
-
return {
|
|
2377
|
-
name: `error_defining_${exprName}`,
|
|
2378
|
-
type: "string",
|
|
2379
|
-
};
|
|
2380
|
-
}
|
|
2381
|
-
}
|
|
2382
|
-
exports.FieldDeclaration = FieldDeclaration;
|
|
2383
|
-
/**
|
|
2384
|
-
* All of the magic of malloy expressions eventually flows to here,
|
|
2385
|
-
* where an operator is applied to two values. Depending on the
|
|
2386
|
-
* operator and value types this may involve transformations of
|
|
2387
|
-
* the values or even the operator.
|
|
2388
|
-
* @param fs FieldSpace for the symbols
|
|
2389
|
-
* @param left Left value
|
|
2390
|
-
* @param op The operator
|
|
2391
|
-
* @param right Right Value
|
|
2392
|
-
* @returns ExprValue of the expression
|
|
2393
|
-
*/
|
|
2394
|
-
function applyBinary(fs, left, op, right) {
|
|
2395
|
-
if ((0, ast_types_1.isEquality)(op)) {
|
|
2396
|
-
return equality(fs, left, op, right);
|
|
2397
|
-
}
|
|
2398
|
-
if ((0, ast_types_1.isComparison)(op)) {
|
|
2399
|
-
return compare(fs, left, op, right);
|
|
2400
|
-
}
|
|
2401
|
-
if (oneOf(op, "+", "-")) {
|
|
2402
|
-
return delta(fs, left, op, right);
|
|
2403
|
-
}
|
|
2404
|
-
if (oneOf(op, "*", "%")) {
|
|
2405
|
-
return numeric(fs, left, op, right);
|
|
2406
|
-
}
|
|
2407
|
-
if (oneOf(op, "/")) {
|
|
2408
|
-
const num = left.getExpression(fs);
|
|
2409
|
-
const denom = right.getExpression(fs);
|
|
2410
|
-
if (num.dataType != "number") {
|
|
2411
|
-
left.log("Numerator for division must be a number");
|
|
2412
|
-
}
|
|
2413
|
-
else if (denom.dataType != "number") {
|
|
2414
|
-
right.log("Denominator for division must be a number");
|
|
2415
|
-
}
|
|
2416
|
-
else {
|
|
2417
|
-
const div = {
|
|
2418
|
-
type: "dialect",
|
|
2419
|
-
function: "div",
|
|
2420
|
-
numerator: num.value,
|
|
2421
|
-
denominator: denom.value,
|
|
2422
|
-
};
|
|
2423
|
-
return {
|
|
2424
|
-
dataType: "number",
|
|
2425
|
-
expressionType: (0, malloy_types_1.maxExpressionType)(num.expressionType, denom.expressionType),
|
|
2426
|
-
value: [div],
|
|
2427
|
-
};
|
|
2428
|
-
}
|
|
2429
|
-
return (0, ast_types_1.errorFor)("divide type mismatch");
|
|
2430
|
-
}
|
|
2431
|
-
left.log(`Canot use ${op} operator here`);
|
|
2432
|
-
return (0, ast_types_1.errorFor)("applybinary bad operator");
|
|
2433
|
-
}
|
|
2434
|
-
exports.applyBinary = applyBinary;
|
|
2435
|
-
class BinaryBoolean extends ExpressionDef {
|
|
2436
|
-
constructor(left, op, right) {
|
|
2437
|
-
super({ left, right });
|
|
2438
|
-
this.left = left;
|
|
2439
|
-
this.op = op;
|
|
2440
|
-
this.right = right;
|
|
2441
|
-
this.elementType = "abstract boolean binary";
|
|
2442
|
-
this.legalChildTypes = [ast_types_1.FT.boolT];
|
|
2443
|
-
}
|
|
2444
|
-
getExpression(fs) {
|
|
2445
|
-
const left = this.left.getExpression(fs);
|
|
2446
|
-
const right = this.right.getExpression(fs);
|
|
2447
|
-
if (this.typeCheck(this.left, left) && this.typeCheck(this.right, right)) {
|
|
2448
|
-
return {
|
|
2449
|
-
dataType: "boolean",
|
|
2450
|
-
expressionType: (0, malloy_types_1.maxExpressionType)(left.expressionType, right.expressionType),
|
|
2451
|
-
value: (0, ast_types_1.compose)(left.value, this.op, right.value),
|
|
2452
|
-
};
|
|
2453
|
-
}
|
|
2454
|
-
return (0, ast_types_1.errorFor)("logial required boolean");
|
|
2455
|
-
}
|
|
2456
|
-
}
|
|
2457
|
-
exports.BinaryBoolean = BinaryBoolean;
|
|
2458
|
-
class ExprCompare extends BinaryBoolean {
|
|
2459
|
-
constructor(left, op, right) {
|
|
2460
|
-
super(left, op, right);
|
|
2461
|
-
this.elementType = "a<=>b";
|
|
2462
|
-
this.legalChildTypes = compareTypes[op];
|
|
2463
|
-
}
|
|
2464
|
-
getExpression(fs) {
|
|
2465
|
-
if (!this.right.granular()) {
|
|
2466
|
-
const rhs = this.right.requestExpression(fs);
|
|
2467
|
-
if (rhs && (0, ast_types_1.isGranularResult)(rhs)) {
|
|
2468
|
-
const newRight = new ExprGranularTime(this.right, rhs.timeframe, false);
|
|
2469
|
-
return newRight.apply(fs, this.op, this.left);
|
|
2470
|
-
}
|
|
2471
|
-
}
|
|
2472
|
-
return this.right.apply(fs, this.op, this.left);
|
|
2473
|
-
}
|
|
2474
|
-
}
|
|
2475
|
-
exports.ExprCompare = ExprCompare;
|
|
2476
|
-
function equality(fs, left, op, right) {
|
|
2477
|
-
const lhs = left.getExpression(fs);
|
|
2478
|
-
const rhs = right.getExpression(fs);
|
|
2479
|
-
let value = timeCompare(lhs, op, rhs) || (0, ast_types_1.compose)(lhs.value, op, rhs.value);
|
|
2480
|
-
if (lhs.dataType != "unknown" && rhs.dataType != "unknown") {
|
|
2481
|
-
switch (op) {
|
|
2482
|
-
case "~":
|
|
2483
|
-
case "!~": {
|
|
2484
|
-
if (lhs.dataType === "string" && rhs.dataType === "string") {
|
|
2485
|
-
value = (0, ast_types_1.compose)(lhs.value, "LIKE", rhs.value);
|
|
2486
|
-
}
|
|
2487
|
-
else {
|
|
2488
|
-
const regexCmp = regexEqual(lhs, rhs);
|
|
2489
|
-
if (regexCmp === undefined) {
|
|
2490
|
-
throw new TypeMistmatch("Incompatible types for match('~') operator");
|
|
2491
|
-
}
|
|
2492
|
-
value = regexCmp;
|
|
2493
|
-
}
|
|
2494
|
-
value = (0, apply_expr_1.nullsafeNot)(value, op);
|
|
2495
|
-
break;
|
|
2496
|
-
}
|
|
2497
|
-
case "=":
|
|
2498
|
-
case "!=": {
|
|
2499
|
-
const nullCmp = nullCompare(lhs, op, rhs);
|
|
2500
|
-
if (nullCmp) {
|
|
2501
|
-
value = nullCmp;
|
|
2502
|
-
}
|
|
2503
|
-
else {
|
|
2504
|
-
value = (0, apply_expr_1.nullsafeNot)(regexEqual(lhs, rhs) || (0, ast_types_1.compose)(lhs.value, "=", rhs.value), op);
|
|
2505
|
-
}
|
|
2506
|
-
break;
|
|
2507
|
-
}
|
|
2508
|
-
}
|
|
2509
|
-
}
|
|
2510
|
-
return {
|
|
2511
|
-
dataType: "boolean",
|
|
2512
|
-
expressionType: (0, malloy_types_1.maxExpressionType)(lhs.expressionType, rhs.expressionType),
|
|
2513
|
-
value,
|
|
2514
|
-
};
|
|
2515
|
-
}
|
|
2516
|
-
function compare(fs, left, op, right) {
|
|
2517
|
-
const lhs = left.getExpression(fs);
|
|
2518
|
-
const rhs = right.getExpression(fs);
|
|
2519
|
-
const expressionType = (0, malloy_types_1.maxExpressionType)(lhs.expressionType, rhs.expressionType);
|
|
2520
|
-
const value = timeCompare(lhs, op, rhs) || (0, ast_types_1.compose)(lhs.value, op, rhs.value);
|
|
2521
|
-
return {
|
|
2522
|
-
dataType: "boolean",
|
|
2523
|
-
expressionType,
|
|
2524
|
-
value: value,
|
|
2525
|
-
};
|
|
2526
|
-
}
|
|
2527
|
-
function oneOf(op, ...operators) {
|
|
2528
|
-
return operators.includes(op);
|
|
2529
|
-
}
|
|
2530
|
-
function delta(fs, left, op, right) {
|
|
2531
|
-
const lhs = left.getExpression(fs);
|
|
2532
|
-
const rhs = right.getExpression(fs);
|
|
2533
|
-
if ((0, malloy_types_1.isTimeFieldType)(lhs.dataType)) {
|
|
2534
|
-
let duration = right;
|
|
2535
|
-
if (rhs.dataType !== "duration") {
|
|
2536
|
-
if ((0, ast_types_1.isGranularResult)(lhs)) {
|
|
2537
|
-
duration = new ExprDuration(right, lhs.timeframe);
|
|
2538
|
-
}
|
|
2539
|
-
else if (lhs.dataType === "date") {
|
|
2540
|
-
duration = new ExprDuration(right, "day");
|
|
2541
|
-
}
|
|
2542
|
-
else {
|
|
2543
|
-
left.log(`Can not offset time by '${rhs.dataType}'`);
|
|
2544
|
-
return (0, ast_types_1.errorFor)(`time plus ${rhs.dataType}`);
|
|
2545
|
-
}
|
|
2546
|
-
}
|
|
2547
|
-
return duration.apply(fs, op, left);
|
|
2548
|
-
}
|
|
2549
|
-
return numeric(fs, left, op, right);
|
|
2550
|
-
}
|
|
2551
|
-
function numeric(fs, left, op, right) {
|
|
2552
|
-
const lhs = left.getExpression(fs);
|
|
2553
|
-
const rhs = right.getExpression(fs);
|
|
2554
|
-
const expressionType = (0, malloy_types_1.maxExpressionType)(lhs.expressionType, rhs.expressionType);
|
|
2555
|
-
if (allAre("number", lhs, rhs)) {
|
|
2556
|
-
return {
|
|
2557
|
-
dataType: "number",
|
|
2558
|
-
expressionType,
|
|
2559
|
-
value: (0, ast_types_1.compose)(lhs.value, op, rhs.value),
|
|
2560
|
-
};
|
|
2561
|
-
}
|
|
2562
|
-
left.log(`Non numeric('${lhs.dataType},${rhs.dataType}') value with '${op}'`);
|
|
2563
|
-
return (0, ast_types_1.errorFor)("numbers required");
|
|
52
|
+
const error_factory_1 = require("./error-factory");
|
|
53
|
+
const renames_1 = require("./explore-properties/renames");
|
|
54
|
+
const field_declaration_1 = require("./query-items/field-declaration");
|
|
55
|
+
const field_references_1 = require("./query-items/field-references");
|
|
56
|
+
const nest_reference_1 = require("./nesting/nest-reference");
|
|
57
|
+
const joins_1 = require("./query-properties/joins");
|
|
58
|
+
const space_field_1 = require("./types/space-field");
|
|
59
|
+
const join_space_field_1 = require("./space-fields/join-space-field");
|
|
60
|
+
const query_space_field_1 = require("./space-fields/query-space-field");
|
|
61
|
+
const reference_field_1 = require("./space-fields/reference-field");
|
|
62
|
+
const rename_space_field_1 = require("./space-fields/rename-space-field");
|
|
63
|
+
const wild_space_field_1 = require("./space-fields/wild-space-field");
|
|
64
|
+
const space_param_1 = require("./types/space-param");
|
|
65
|
+
const abstract_parameter_1 = require("./space-parameters/abstract-parameter");
|
|
66
|
+
const space_seed_1 = require("./space-seed");
|
|
67
|
+
const static_space_1 = require("./static-space");
|
|
68
|
+
const struct_utils_1 = require("./struct-utils");
|
|
69
|
+
const turtle_headed_pipe_1 = require("./types/turtle-headed-pipe");
|
|
70
|
+
function isTurtle(fd) {
|
|
71
|
+
const ret = fd && typeof fd !== "string" && fd.type === "turtle";
|
|
72
|
+
return !!ret;
|
|
2564
73
|
}
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
"<=": [ast_types_1.FT.numberT, ast_types_1.FT.stringT, ast_types_1.FT.dateT, ast_types_1.FT.timestampT],
|
|
2570
|
-
"=": [ast_types_1.FT.numberT, ast_types_1.FT.stringT, ast_types_1.FT.dateT, ast_types_1.FT.timestampT],
|
|
2571
|
-
"!=": [ast_types_1.FT.numberT, ast_types_1.FT.stringT, ast_types_1.FT.dateT, ast_types_1.FT.timestampT],
|
|
2572
|
-
">=": [ast_types_1.FT.numberT, ast_types_1.FT.stringT, ast_types_1.FT.dateT, ast_types_1.FT.timestampT],
|
|
2573
|
-
">": [ast_types_1.FT.numberT, ast_types_1.FT.stringT, ast_types_1.FT.dateT, ast_types_1.FT.timestampT],
|
|
2574
|
-
};
|
|
2575
|
-
/**
|
|
2576
|
-
* GranularTime is a moment in time which ALSO has a "granularity"
|
|
2577
|
-
* commonly this are created by applying ".datePart" to an expression
|
|
2578
|
-
* 1) They have a value, which is the moment in time
|
|
2579
|
-
* 2) When used in a comparison, they act like a range, for the
|
|
2580
|
-
* duration of 1 unit of granularity
|
|
2581
|
-
*/
|
|
2582
|
-
class ExprGranularTime extends ExpressionDef {
|
|
2583
|
-
constructor(expr, units, truncate) {
|
|
2584
|
-
super({ expr });
|
|
2585
|
-
this.expr = expr;
|
|
2586
|
-
this.units = units;
|
|
2587
|
-
this.truncate = truncate;
|
|
2588
|
-
this.elementType = "granularTime";
|
|
2589
|
-
this.legalChildTypes = [ast_types_1.FT.timestampT, ast_types_1.FT.dateT];
|
|
2590
|
-
}
|
|
2591
|
-
granular() {
|
|
2592
|
-
return true;
|
|
74
|
+
class TurtleDecl extends turtle_headed_pipe_1.TurtleHeadedPipe {
|
|
75
|
+
constructor(name) {
|
|
76
|
+
super();
|
|
77
|
+
this.name = name;
|
|
2593
78
|
}
|
|
2594
|
-
|
|
2595
|
-
const
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
};
|
|
2603
|
-
if (this.truncate) {
|
|
2604
|
-
tsVal.value = [
|
|
2605
|
-
{
|
|
2606
|
-
type: "dialect",
|
|
2607
|
-
function: "trunc",
|
|
2608
|
-
expr: { value: exprVal.value, valueType: exprVal.dataType },
|
|
2609
|
-
units: timeframe,
|
|
2610
|
-
},
|
|
2611
|
-
];
|
|
79
|
+
getPipeline(fs) {
|
|
80
|
+
const modelPipe = { pipeline: [] };
|
|
81
|
+
if (this.turtleName) {
|
|
82
|
+
const headEnt = this.turtleName.getField(fs);
|
|
83
|
+
let reportWrongType = true;
|
|
84
|
+
if (headEnt.error) {
|
|
85
|
+
this.log(headEnt.error);
|
|
86
|
+
reportWrongType = false;
|
|
2612
87
|
}
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
const _valueType = left.getExpression(fs).dataType;
|
|
2621
|
-
const granularityType = (0, malloy_types_1.isDateUnit)(this.units) ? "date" : "timestamp";
|
|
2622
|
-
if (rangeType == "date" && granularityType == "date") {
|
|
2623
|
-
return this.dateRange(fs, op, left);
|
|
2624
|
-
}
|
|
2625
|
-
return this.timestampRange(fs, op, left);
|
|
2626
|
-
/*
|
|
2627
|
-
write tests for each of these cases ....
|
|
2628
|
-
|
|
2629
|
-
vt rt gt use
|
|
2630
|
-
dt dt dt dateRange
|
|
2631
|
-
dt dt ts == or timeStampRange
|
|
2632
|
-
dt ts dt timestampRange
|
|
2633
|
-
dt ts ts timeStampRange
|
|
2634
|
-
|
|
2635
|
-
ts ts ts timestampRange
|
|
2636
|
-
ts ts dt timestampRange
|
|
2637
|
-
ts dt ts timestampRange
|
|
2638
|
-
ts dt dt either
|
|
2639
|
-
|
|
2640
|
-
*/
|
|
2641
|
-
}
|
|
2642
|
-
timestampRange(fs, op, expr) {
|
|
2643
|
-
const begin = this.getExpression(fs);
|
|
2644
|
-
const beginTime = ExprTime.fromValue("timestamp", begin);
|
|
2645
|
-
const endTime = new ExprTime("timestamp", (0, time_utils_1.timeOffset)("timestamp", begin.value, "+", (0, malloy_types_1.mkExpr) `1`, this.units), begin.expressionType);
|
|
2646
|
-
const range = new Range(beginTime, endTime);
|
|
2647
|
-
return range.apply(fs, op, expr);
|
|
2648
|
-
}
|
|
2649
|
-
dateRange(fs, op, expr) {
|
|
2650
|
-
const begin = this.getExpression(fs);
|
|
2651
|
-
const beginTime = new ExprTime("date", begin.value, begin.expressionType);
|
|
2652
|
-
const endAt = (0, time_utils_1.timeOffset)("date", begin.value, "+", ["1"], this.units);
|
|
2653
|
-
const end = new ExprTime("date", endAt, begin.expressionType);
|
|
2654
|
-
const range = new Range(beginTime, end);
|
|
2655
|
-
return range.apply(fs, op, expr);
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
exports.ExprGranularTime = ExprGranularTime;
|
|
2659
|
-
function timeCompare(lhs, op, rhs) {
|
|
2660
|
-
if ((0, malloy_types_1.isTimeFieldType)(lhs.dataType) && (0, malloy_types_1.isTimeFieldType)(rhs.dataType)) {
|
|
2661
|
-
if (lhs.dataType !== rhs.dataType) {
|
|
2662
|
-
let lval = lhs.value;
|
|
2663
|
-
let rval = rhs.value;
|
|
2664
|
-
if (lhs.dataType === "timestamp") {
|
|
2665
|
-
lval = (0, time_utils_1.castTimestampToDate)(lval);
|
|
88
|
+
else if (headEnt.found instanceof query_space_field_1.QueryField) {
|
|
89
|
+
const headDef = headEnt.found.getQueryFieldDef(fs);
|
|
90
|
+
if (isTurtle(headDef)) {
|
|
91
|
+
const newPipe = this.refinePipeline(fs, headDef);
|
|
92
|
+
modelPipe.pipeline = [...newPipe.pipeline];
|
|
93
|
+
reportWrongType = false;
|
|
94
|
+
}
|
|
2666
95
|
}
|
|
2667
|
-
|
|
2668
|
-
|
|
96
|
+
if (reportWrongType) {
|
|
97
|
+
this.log(`Expected '${this.turtleName}' to be a query`);
|
|
2669
98
|
}
|
|
2670
|
-
return (0, ast_types_1.compose)(lval, op, rval);
|
|
2671
|
-
}
|
|
2672
|
-
}
|
|
2673
|
-
return undefined;
|
|
2674
|
-
}
|
|
2675
|
-
function regexEqual(left, right) {
|
|
2676
|
-
if (left.dataType === "string") {
|
|
2677
|
-
if (right.dataType === "regular expression") {
|
|
2678
|
-
return [
|
|
2679
|
-
{
|
|
2680
|
-
type: "dialect",
|
|
2681
|
-
function: "regexpMatch",
|
|
2682
|
-
expr: left.value,
|
|
2683
|
-
regexp: right.value[0].replace(/^r'/, "'"),
|
|
2684
|
-
},
|
|
2685
|
-
];
|
|
2686
|
-
}
|
|
2687
|
-
}
|
|
2688
|
-
else if (right.dataType === "string") {
|
|
2689
|
-
if (left.dataType === "regular expression") {
|
|
2690
|
-
return [
|
|
2691
|
-
{
|
|
2692
|
-
type: "dialect",
|
|
2693
|
-
function: "regexpMatch",
|
|
2694
|
-
expr: right.value,
|
|
2695
|
-
regexp: left.value[0].replace(/^r'/, "'"),
|
|
2696
|
-
},
|
|
2697
|
-
];
|
|
2698
|
-
}
|
|
2699
|
-
}
|
|
2700
|
-
return undefined;
|
|
2701
|
-
}
|
|
2702
|
-
class TypeMistmatch extends Error {
|
|
2703
|
-
}
|
|
2704
|
-
exports.TypeMistmatch = TypeMistmatch;
|
|
2705
|
-
function nullCompare(left, op, right) {
|
|
2706
|
-
const not = op === "!=" || op === "!~";
|
|
2707
|
-
if (left.dataType === "null" || right.dataType === "null") {
|
|
2708
|
-
const maybeNot = not ? " NOT" : "";
|
|
2709
|
-
if (left.dataType !== "null") {
|
|
2710
|
-
return [...left.value, ` IS${maybeNot} NULL`];
|
|
2711
99
|
}
|
|
2712
|
-
if (
|
|
2713
|
-
|
|
100
|
+
else if (this.headRefinement) {
|
|
101
|
+
throw this.internalError("Can't refine the head of a turtle in its definition");
|
|
2714
102
|
}
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
constructor(n, timeframe) {
|
|
2721
|
-
super({ n });
|
|
2722
|
-
this.n = n;
|
|
2723
|
-
this.timeframe = timeframe;
|
|
2724
|
-
this.elementType = "duration";
|
|
2725
|
-
this.legalChildTypes = [ast_types_1.FT.timestampT, ast_types_1.FT.dateT];
|
|
2726
|
-
}
|
|
2727
|
-
apply(fs, op, left) {
|
|
2728
|
-
const lhs = left.getExpression(fs);
|
|
2729
|
-
this.typeCheck(this, lhs);
|
|
2730
|
-
if ((0, malloy_types_1.isTimeFieldType)(lhs.dataType) && (op === "+" || op === "-")) {
|
|
2731
|
-
const num = this.n.getExpression(fs);
|
|
2732
|
-
if (!ast_types_1.FT.typeEq(num, ast_types_1.FT.numberT)) {
|
|
2733
|
-
this.log(`Duration units needs number not '${num.dataType}`);
|
|
2734
|
-
return (0, ast_types_1.errorFor)("illegal unit expression");
|
|
2735
|
-
}
|
|
2736
|
-
let resultGranularity;
|
|
2737
|
-
// Only allow the output of this to be granular if the
|
|
2738
|
-
// granularities match, this is still an area where
|
|
2739
|
-
// more thought is required.
|
|
2740
|
-
if ((0, ast_types_1.isGranularResult)(lhs) && lhs.timeframe == this.timeframe) {
|
|
2741
|
-
resultGranularity = lhs.timeframe;
|
|
2742
|
-
}
|
|
2743
|
-
if (lhs.dataType === "timestamp") {
|
|
2744
|
-
const result = (0, time_utils_1.timeOffset)("timestamp", lhs.value, op, num.value, this.timeframe);
|
|
2745
|
-
return (0, time_utils_1.timeResult)({
|
|
2746
|
-
dataType: "timestamp",
|
|
2747
|
-
expressionType: (0, malloy_types_1.maxExpressionType)(lhs.expressionType, num.expressionType),
|
|
2748
|
-
value: result,
|
|
2749
|
-
}, resultGranularity);
|
|
103
|
+
let appendInput = fs;
|
|
104
|
+
if (modelPipe.pipeline.length > 0) {
|
|
105
|
+
let endStruct = appendInput.structDef();
|
|
106
|
+
for (const existingSeg of modelPipe.pipeline) {
|
|
107
|
+
endStruct = (0, struct_utils_1.opOutputStruct)(this, endStruct, existingSeg);
|
|
2750
108
|
}
|
|
2751
|
-
|
|
2752
|
-
dataType: "date",
|
|
2753
|
-
expressionType: (0, malloy_types_1.maxExpressionType)(lhs.expressionType, num.expressionType),
|
|
2754
|
-
value: (0, time_utils_1.timeOffset)("date", lhs.value, op, num.value, this.timeframe),
|
|
2755
|
-
}, resultGranularity);
|
|
109
|
+
appendInput = new DynamicSpace(endStruct);
|
|
2756
110
|
}
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
return {
|
|
2761
|
-
dataType: "duration",
|
|
2762
|
-
expressionType: "scalar",
|
|
2763
|
-
value: ["__ERROR_DURATION_IS_NOT_A_VALUE__"],
|
|
2764
|
-
};
|
|
111
|
+
const appended = this.appendOps(modelPipe.pipeline, appendInput);
|
|
112
|
+
modelPipe.pipeline = appended.opList;
|
|
113
|
+
return modelPipe;
|
|
2765
114
|
}
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
for (const v of values) {
|
|
2770
|
-
if (v.dataType !== oneType) {
|
|
2771
|
-
return false;
|
|
115
|
+
getFieldDef(fs, nestParent) {
|
|
116
|
+
if (nestParent) {
|
|
117
|
+
this.nestedInQuerySpace = nestParent;
|
|
2772
118
|
}
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
this.elementType = "timestampOrDate";
|
|
2780
|
-
this.elementType = timeType;
|
|
2781
|
-
this.translationValue = {
|
|
2782
|
-
dataType: timeType,
|
|
2783
|
-
expressionType,
|
|
2784
|
-
value: typeof value === "string" ? [value] : value,
|
|
119
|
+
const pipe = this.getPipeline(fs);
|
|
120
|
+
return {
|
|
121
|
+
type: "turtle",
|
|
122
|
+
name: this.name,
|
|
123
|
+
...pipe,
|
|
124
|
+
location: this.location,
|
|
2785
125
|
};
|
|
2786
126
|
}
|
|
2787
|
-
getExpression(_fs) {
|
|
2788
|
-
return this.translationValue;
|
|
2789
|
-
}
|
|
2790
|
-
static fromValue(timeType, expr) {
|
|
2791
|
-
let value = expr.value;
|
|
2792
|
-
if (timeType != expr.dataType) {
|
|
2793
|
-
const toTs = {
|
|
2794
|
-
type: "dialect",
|
|
2795
|
-
function: "cast",
|
|
2796
|
-
safe: false,
|
|
2797
|
-
dstType: timeType,
|
|
2798
|
-
expr: expr.value,
|
|
2799
|
-
};
|
|
2800
|
-
if ((0, malloy_types_1.isTimeFieldType)(expr.dataType)) {
|
|
2801
|
-
toTs.srcType = expr.dataType;
|
|
2802
|
-
}
|
|
2803
|
-
value = (0, ast_types_1.compressExpr)([toTs]);
|
|
2804
|
-
}
|
|
2805
|
-
return new ExprTime(timeType, value, expr.expressionType);
|
|
2806
|
-
}
|
|
2807
127
|
}
|
|
2808
|
-
exports.
|
|
2809
|
-
class
|
|
2810
|
-
constructor(
|
|
2811
|
-
super(
|
|
2812
|
-
this.
|
|
2813
|
-
this.
|
|
2814
|
-
this.elementType = "range";
|
|
2815
|
-
}
|
|
2816
|
-
apply(fs, op, expr) {
|
|
2817
|
-
switch (op) {
|
|
2818
|
-
case "=":
|
|
2819
|
-
case "!=": {
|
|
2820
|
-
const op1 = op === "=" ? ">=" : "<";
|
|
2821
|
-
const op2 = op === "=" ? "and" : "or";
|
|
2822
|
-
const op3 = op === "=" ? "<" : ">=";
|
|
2823
|
-
const fromValue = this.first.apply(fs, op1, expr);
|
|
2824
|
-
const toValue = this.last.apply(fs, op3, expr);
|
|
2825
|
-
return {
|
|
2826
|
-
dataType: "boolean",
|
|
2827
|
-
expressionType: (0, malloy_types_1.maxExpressionType)(fromValue.expressionType, toValue.expressionType),
|
|
2828
|
-
value: (0, ast_types_1.compose)(fromValue.value, op2, toValue.value),
|
|
2829
|
-
};
|
|
2830
|
-
}
|
|
2831
|
-
/**
|
|
2832
|
-
* This is a little surprising, but is actually how you comapre a
|
|
2833
|
-
* value to a range ...
|
|
2834
|
-
*
|
|
2835
|
-
* val > begin to end val >= end
|
|
2836
|
-
* val >= begin to end val >= begin
|
|
2837
|
-
* val < begin to end val < begin
|
|
2838
|
-
* val <= begin to end val < end
|
|
2839
|
-
*/
|
|
2840
|
-
case ">":
|
|
2841
|
-
return this.last.apply(fs, ">=", expr);
|
|
2842
|
-
case ">=":
|
|
2843
|
-
return this.first.apply(fs, ">=", expr);
|
|
2844
|
-
case "<":
|
|
2845
|
-
return this.first.apply(fs, "<", expr);
|
|
2846
|
-
case "<=":
|
|
2847
|
-
return this.last.apply(fs, "<", expr);
|
|
2848
|
-
}
|
|
2849
|
-
throw new Error("mysterious error in range computation");
|
|
2850
|
-
}
|
|
2851
|
-
requestExpression(_fs) {
|
|
2852
|
-
return undefined;
|
|
2853
|
-
}
|
|
2854
|
-
getExpression(_fs) {
|
|
2855
|
-
return (0, ast_types_1.errorFor)("a range is not a value");
|
|
128
|
+
exports.TurtleDecl = TurtleDecl;
|
|
129
|
+
class NestRefinement extends TurtleDecl {
|
|
130
|
+
constructor(turtleName) {
|
|
131
|
+
super(turtleName.refString);
|
|
132
|
+
this.elementType = "nestRefinement";
|
|
133
|
+
this.turtleName = turtleName;
|
|
2856
134
|
}
|
|
2857
135
|
}
|
|
2858
|
-
exports.
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
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);
|
|
136
|
+
exports.NestRefinement = NestRefinement;
|
|
137
|
+
class NestDefinition extends TurtleDecl {
|
|
138
|
+
constructor(name) {
|
|
139
|
+
super(name);
|
|
140
|
+
this.elementType = "nestDefinition";
|
|
2890
141
|
}
|
|
2891
142
|
}
|
|
2892
|
-
exports.
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
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
|
-
}
|
|
143
|
+
exports.NestDefinition = NestDefinition;
|
|
144
|
+
function isNestedQuery(me) {
|
|
145
|
+
return (me instanceof NestRefinement ||
|
|
146
|
+
me instanceof nest_reference_1.NestReference ||
|
|
147
|
+
me instanceof NestDefinition);
|
|
3006
148
|
}
|
|
3007
|
-
exports.
|
|
149
|
+
exports.isNestedQuery = isNestedQuery;
|
|
3008
150
|
/**
|
|
3009
151
|
* A FieldSpace which may undergo modification
|
|
3010
152
|
*/
|
|
3011
|
-
class DynamicSpace extends StaticSpace {
|
|
153
|
+
class DynamicSpace extends static_space_1.StaticSpace {
|
|
3012
154
|
constructor(extending) {
|
|
3013
|
-
const source = new SpaceSeed(extending);
|
|
155
|
+
const source = new space_seed_1.SpaceSeed(extending);
|
|
3014
156
|
super((0, lodash_1.cloneDeep)(source.structDef));
|
|
3015
157
|
this.completions = [];
|
|
3016
158
|
this.complete = false;
|
|
@@ -3061,7 +203,7 @@ class DynamicSpace extends StaticSpace {
|
|
|
3061
203
|
}
|
|
3062
204
|
addParameters(params) {
|
|
3063
205
|
for (const oneP of params) {
|
|
3064
|
-
this.setEntry(oneP.name, new AbstractParameter(oneP));
|
|
206
|
+
this.setEntry(oneP.name, new abstract_parameter_1.AbstractParameter(oneP));
|
|
3065
207
|
}
|
|
3066
208
|
return this;
|
|
3067
209
|
}
|
|
@@ -3078,7 +220,7 @@ class DynamicSpace extends StaticSpace {
|
|
|
3078
220
|
// one of three kinds of fields are legal in an explore: expressions ...
|
|
3079
221
|
const elseLog = def.log;
|
|
3080
222
|
const elseType = def.elementType;
|
|
3081
|
-
if (def instanceof FieldDeclaration) {
|
|
223
|
+
if (def instanceof field_declaration_1.FieldDeclaration) {
|
|
3082
224
|
const exprField = new ExpressionFieldFromAst(this, def);
|
|
3083
225
|
this.newEntry(exprField.name, def, exprField);
|
|
3084
226
|
// querry (turtle) fields
|
|
@@ -3087,15 +229,15 @@ class DynamicSpace extends StaticSpace {
|
|
|
3087
229
|
const name = def.name;
|
|
3088
230
|
this.newEntry(name, def, new QueryFieldAST(this, def, name));
|
|
3089
231
|
}
|
|
3090
|
-
else if (def instanceof RenameField) {
|
|
232
|
+
else if (def instanceof renames_1.RenameField) {
|
|
3091
233
|
if (def.oldName.refString === def.newName) {
|
|
3092
234
|
def.log("Can't rename field to itself");
|
|
3093
235
|
continue;
|
|
3094
236
|
}
|
|
3095
237
|
const oldValue = def.oldName.getField(this);
|
|
3096
238
|
if (oldValue.found) {
|
|
3097
|
-
if (oldValue.found instanceof SpaceField) {
|
|
3098
|
-
this.setEntry(def.newName, new RenameSpaceField(oldValue.found, def.newName, def.location));
|
|
239
|
+
if (oldValue.found instanceof space_field_1.SpaceField) {
|
|
240
|
+
this.setEntry(def.newName, new rename_space_field_1.RenameSpaceField(oldValue.found, def.newName, def.location));
|
|
3099
241
|
this.dropEntry(def.oldName.refString);
|
|
3100
242
|
}
|
|
3101
243
|
else {
|
|
@@ -3106,8 +248,8 @@ class DynamicSpace extends StaticSpace {
|
|
|
3106
248
|
def.log(`Can't rename '${def.oldName}', no such field`);
|
|
3107
249
|
}
|
|
3108
250
|
}
|
|
3109
|
-
else if (def instanceof Join) {
|
|
3110
|
-
this.newEntry(def.name.refString, def, new JoinSpaceField(this, def));
|
|
251
|
+
else if (def instanceof joins_1.Join) {
|
|
252
|
+
this.newEntry(def.name.refString, def, new join_space_field_1.JoinSpaceField(this, def));
|
|
3111
253
|
}
|
|
3112
254
|
else {
|
|
3113
255
|
elseLog(`Internal error: Expected expression, query, or rename, got '${elseType}'`);
|
|
@@ -3130,24 +272,24 @@ class DynamicSpace extends StaticSpace {
|
|
|
3130
272
|
const turtles = [];
|
|
3131
273
|
const fixupJoins = [];
|
|
3132
274
|
for (const [name, spaceEntry] of this.entries()) {
|
|
3133
|
-
if (spaceEntry instanceof StructSpaceField) {
|
|
275
|
+
if (spaceEntry instanceof static_space_1.StructSpaceField) {
|
|
3134
276
|
joins.push([name, spaceEntry]);
|
|
3135
277
|
}
|
|
3136
|
-
else if (spaceEntry instanceof QueryField) {
|
|
278
|
+
else if (spaceEntry instanceof query_space_field_1.QueryField) {
|
|
3137
279
|
turtles.push([name, spaceEntry]);
|
|
3138
280
|
}
|
|
3139
|
-
else if (spaceEntry instanceof SpaceField) {
|
|
281
|
+
else if (spaceEntry instanceof space_field_1.SpaceField) {
|
|
3140
282
|
fields.push([name, spaceEntry]);
|
|
3141
283
|
}
|
|
3142
|
-
else if (spaceEntry instanceof SpaceParam) {
|
|
284
|
+
else if (spaceEntry instanceof space_param_1.SpaceParam) {
|
|
3143
285
|
parameters[name] = spaceEntry.parameter();
|
|
3144
286
|
}
|
|
3145
287
|
}
|
|
3146
288
|
const reorderFields = [...fields, ...joins, ...turtles];
|
|
3147
289
|
for (const [fieldName, field] of reorderFields) {
|
|
3148
|
-
if (field instanceof JoinSpaceField) {
|
|
290
|
+
if (field instanceof join_space_field_1.JoinSpaceField) {
|
|
3149
291
|
const joinStruct = field.join.structDef();
|
|
3150
|
-
if (!ErrorFactory.isErrorStructDef(joinStruct)) {
|
|
292
|
+
if (!error_factory_1.ErrorFactory.isErrorStructDef(joinStruct)) {
|
|
3151
293
|
this.final.fields.push(joinStruct);
|
|
3152
294
|
fixupJoins.push([field.join, joinStruct]);
|
|
3153
295
|
}
|
|
@@ -3188,10 +330,10 @@ class ResultSpace extends DynamicSpace {
|
|
|
3188
330
|
}
|
|
3189
331
|
addMembers(members) {
|
|
3190
332
|
for (const member of members) {
|
|
3191
|
-
if (member instanceof FieldReference) {
|
|
333
|
+
if (member instanceof field_references_1.FieldReference) {
|
|
3192
334
|
this.addReference(member);
|
|
3193
335
|
}
|
|
3194
|
-
else if (member instanceof WildcardFieldReference) {
|
|
336
|
+
else if (member instanceof field_references_1.WildcardFieldReference) {
|
|
3195
337
|
this.addWild(member);
|
|
3196
338
|
}
|
|
3197
339
|
else {
|
|
@@ -3205,11 +347,11 @@ class ResultSpace extends DynamicSpace {
|
|
|
3205
347
|
ref.log(`Output already has a field named '${refName}'`);
|
|
3206
348
|
}
|
|
3207
349
|
else {
|
|
3208
|
-
this.setEntry(refName, new ReferenceField(ref));
|
|
350
|
+
this.setEntry(refName, new reference_field_1.ReferenceField(ref));
|
|
3209
351
|
}
|
|
3210
352
|
}
|
|
3211
353
|
addWild(wild) {
|
|
3212
|
-
this.setEntry(wild.refString, new WildSpaceField(wild.refString));
|
|
354
|
+
this.setEntry(wild.refString, new wild_space_field_1.WildSpaceField(wild.refString));
|
|
3213
355
|
}
|
|
3214
356
|
/**
|
|
3215
357
|
* Check for the definition of an ungrouping reference in the result space,
|
|
@@ -3233,10 +375,10 @@ class ResultSpace extends DynamicSpace {
|
|
|
3233
375
|
}
|
|
3234
376
|
addQueryItems(...qiList) {
|
|
3235
377
|
for (const qi of qiList) {
|
|
3236
|
-
if (qi instanceof FieldReference || qi instanceof NestReference) {
|
|
378
|
+
if (qi instanceof field_references_1.FieldReference || qi instanceof nest_reference_1.NestReference) {
|
|
3237
379
|
this.addReference(qi);
|
|
3238
380
|
}
|
|
3239
|
-
else if (qi instanceof FieldDeclaration) {
|
|
381
|
+
else if (qi instanceof field_declaration_1.FieldDeclaration) {
|
|
3240
382
|
this.addField(qi);
|
|
3241
383
|
}
|
|
3242
384
|
else if (isNestedQuery(qi)) {
|
|
@@ -3256,7 +398,7 @@ class ResultSpace extends DynamicSpace {
|
|
|
3256
398
|
queryFieldDefs() {
|
|
3257
399
|
const fields = [];
|
|
3258
400
|
for (const [name, field] of this.entries()) {
|
|
3259
|
-
if (field instanceof SpaceField) {
|
|
401
|
+
if (field instanceof space_field_1.SpaceField) {
|
|
3260
402
|
const fieldQueryDef = field.getQueryFieldDef(this.exprSpace);
|
|
3261
403
|
if (fieldQueryDef) {
|
|
3262
404
|
if (this.canContain(fieldQueryDef)) {
|
|
@@ -3315,192 +457,7 @@ class ResultSpace extends DynamicSpace {
|
|
|
3315
457
|
}
|
|
3316
458
|
}
|
|
3317
459
|
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 {
|
|
460
|
+
class ExpressionFieldFromAst extends space_field_1.SpaceField {
|
|
3504
461
|
constructor(space, exprDef) {
|
|
3505
462
|
super();
|
|
3506
463
|
this.space = space;
|
|
@@ -3528,7 +485,7 @@ class ExpressionFieldFromAst extends SpaceField {
|
|
|
3528
485
|
}
|
|
3529
486
|
}
|
|
3530
487
|
exports.ExpressionFieldFromAst = ExpressionFieldFromAst;
|
|
3531
|
-
class QueryFieldAST extends QueryField {
|
|
488
|
+
class QueryFieldAST extends query_space_field_1.QueryField {
|
|
3532
489
|
constructor(fs, turtle, name) {
|
|
3533
490
|
super(fs);
|
|
3534
491
|
this.turtle = turtle;
|
|
@@ -3550,37 +507,6 @@ class QueryFieldAST extends QueryField {
|
|
|
3550
507
|
}
|
|
3551
508
|
}
|
|
3552
509
|
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
510
|
/**
|
|
3585
511
|
* Unlike a source, which is a refinement of a namespace, a query
|
|
3586
512
|
* is creating a new unrelated namespace. The query starts with a
|
|
@@ -3592,14 +518,14 @@ exports.JoinSpaceField = JoinSpaceField;
|
|
|
3592
518
|
*/
|
|
3593
519
|
class QuerySpace extends DynamicSpace {
|
|
3594
520
|
constructor(input, result) {
|
|
3595
|
-
const inputSpace = new SpaceSeed(input);
|
|
521
|
+
const inputSpace = new space_seed_1.SpaceSeed(input);
|
|
3596
522
|
super(inputSpace.structDef);
|
|
3597
523
|
this.result = result;
|
|
3598
524
|
this.extendList = [];
|
|
3599
525
|
}
|
|
3600
526
|
extendSource(extendField) {
|
|
3601
527
|
this.addField(extendField);
|
|
3602
|
-
if (extendField instanceof Join) {
|
|
528
|
+
if (extendField instanceof joins_1.Join) {
|
|
3603
529
|
this.extendList.push(extendField.name.refString);
|
|
3604
530
|
}
|
|
3605
531
|
else {
|
|
@@ -3608,65 +534,4 @@ class QuerySpace extends DynamicSpace {
|
|
|
3608
534
|
}
|
|
3609
535
|
}
|
|
3610
536
|
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;
|
|
3672
537
|
//# sourceMappingURL=ast-main.js.map
|