@malloydata/malloy 0.0.177-dev240828173040 → 0.0.177-dev240829030921
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/dialect/dialect.d.ts +23 -13
- package/dist/dialect/dialect.js +33 -27
- package/dist/dialect/duckdb/duckdb.d.ts +7 -11
- package/dist/dialect/duckdb/duckdb.js +34 -100
- package/dist/dialect/duckdb/functions/greatest_and_least.js +5 -12
- package/dist/dialect/functions/concat.js +1 -1
- package/dist/dialect/functions/greatest_and_least.js +1 -1
- package/dist/dialect/functions/simple_numeric_functions.js +1 -1
- package/dist/dialect/functions/sql.js +5 -15
- package/dist/dialect/functions/string_agg.js +2 -2
- package/dist/dialect/functions/trim_functions.js +2 -2
- package/dist/dialect/functions/util.d.ts +6 -9
- package/dist/dialect/functions/util.js +29 -38
- package/dist/dialect/index.d.ts +1 -1
- package/dist/dialect/index.js +1 -2
- package/dist/dialect/pg_impl.d.ts +15 -0
- package/dist/dialect/pg_impl.js +91 -0
- package/dist/dialect/postgres/functions/greatest_and_least.js +1 -3
- package/dist/dialect/postgres/functions/string_agg.js +2 -2
- package/dist/dialect/postgres/postgres.d.ts +7 -11
- package/dist/dialect/postgres/postgres.js +29 -92
- package/dist/dialect/snowflake/functions/string_agg.js +2 -2
- package/dist/dialect/snowflake/snowflake.d.ts +9 -9
- package/dist/dialect/snowflake/snowflake.js +41 -48
- package/dist/dialect/standardsql/functions/string_agg.js +4 -4
- package/dist/dialect/standardsql/standardsql.d.ts +9 -9
- package/dist/dialect/standardsql/standardsql.js +56 -51
- package/dist/dialect/trino/functions/concat.js +1 -1
- package/dist/dialect/trino/functions/string_agg.js +2 -2
- package/dist/dialect/trino/trino.d.ts +11 -12
- package/dist/dialect/trino/trino.js +59 -83
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -4
- package/dist/lang/ast/ast-utils.d.ts +1 -1
- package/dist/lang/ast/ast-utils.js +2 -2
- package/dist/lang/ast/expressions/apply.js +1 -2
- package/dist/lang/ast/expressions/binary-boolean.d.ts +2 -1
- package/dist/lang/ast/expressions/binary-boolean.js +6 -3
- package/dist/lang/ast/expressions/binary-numeric.d.ts +2 -1
- package/dist/lang/ast/expressions/boolean.js +1 -1
- package/dist/lang/ast/expressions/constant-expression.d.ts +3 -3
- package/dist/lang/ast/expressions/constant-expression.js +0 -23
- package/dist/lang/ast/expressions/expr-aggregate-function.js +24 -34
- package/dist/lang/ast/expressions/expr-alternation-tree.d.ts +6 -3
- package/dist/lang/ast/expressions/expr-alternation-tree.js +10 -5
- package/dist/lang/ast/expressions/expr-cast.js +1 -2
- package/dist/lang/ast/expressions/expr-coalesce.js +4 -1
- package/dist/lang/ast/expressions/expr-compare.d.ts +3 -3
- package/dist/lang/ast/expressions/expr-count-distinct.js +1 -1
- package/dist/lang/ast/expressions/expr-count.js +3 -3
- package/dist/lang/ast/expressions/expr-func.js +15 -18
- package/dist/lang/ast/expressions/expr-granular-time.js +8 -10
- package/dist/lang/ast/expressions/expr-id-reference.js +2 -2
- package/dist/lang/ast/expressions/expr-minus.js +5 -4
- package/dist/lang/ast/expressions/expr-not.js +1 -1
- package/dist/lang/ast/expressions/expr-now.js +1 -6
- package/dist/lang/ast/expressions/expr-null.js +1 -1
- package/dist/lang/ast/expressions/expr-number.js +1 -1
- package/dist/lang/ast/expressions/expr-parens.js +1 -1
- package/dist/lang/ast/expressions/expr-props.js +4 -7
- package/dist/lang/ast/expressions/expr-regex.js +1 -3
- package/dist/lang/ast/expressions/expr-string.js +1 -7
- package/dist/lang/ast/expressions/expr-time-extract.js +12 -16
- package/dist/lang/ast/expressions/expr-time.d.ts +2 -2
- package/dist/lang/ast/expressions/expr-time.js +4 -6
- package/dist/lang/ast/expressions/expr-ungroup.js +2 -2
- package/dist/lang/ast/expressions/for-range.d.ts +2 -1
- package/dist/lang/ast/expressions/function-ordering.js +5 -5
- package/dist/lang/ast/expressions/partial-compare.d.ts +3 -3
- package/dist/lang/ast/expressions/pick-when.js +24 -8
- package/dist/lang/ast/expressions/range.d.ts +2 -1
- package/dist/lang/ast/expressions/range.js +4 -2
- package/dist/lang/ast/expressions/time-literal.d.ts +4 -3
- package/dist/lang/ast/expressions/time-literal.js +5 -10
- package/dist/lang/ast/expressions/top-by.js +1 -2
- package/dist/lang/ast/expressions/utils.d.ts +3 -12
- package/dist/lang/ast/expressions/utils.js +8 -56
- package/dist/lang/ast/field-space/reference-field.js +1 -1
- package/dist/lang/ast/index.d.ts +1 -1
- package/dist/lang/ast/index.js +1 -1
- package/dist/lang/ast/query-builders/index-builder.d.ts +2 -2
- package/dist/lang/ast/query-builders/reduce-builder.d.ts +2 -2
- package/dist/lang/ast/query-items/field-declaration.js +1 -5
- package/dist/lang/ast/query-properties/filters.d.ts +3 -3
- package/dist/lang/ast/query-properties/filters.js +6 -5
- package/dist/lang/ast/query-properties/top.js +1 -2
- package/dist/lang/ast/source-elements/refined-source.js +1 -1
- package/dist/lang/ast/source-properties/joins.js +11 -10
- package/dist/lang/ast/time-utils.d.ts +5 -7
- package/dist/lang/ast/time-utils.js +17 -57
- package/dist/lang/ast/types/binary_operators.d.ts +9 -0
- package/dist/lang/ast/types/binary_operators.js +28 -0
- package/dist/lang/ast/types/expr-result.d.ts +3 -3
- package/dist/lang/ast/types/expression-def.d.ts +4 -3
- package/dist/lang/ast/types/expression-def.js +43 -50
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +0 -11
- package/dist/lang/lib/Malloy/MalloyParser.js +803 -858
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +0 -13
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +0 -8
- package/dist/lang/malloy-to-ast.d.ts +0 -1
- package/dist/lang/malloy-to-ast.js +0 -4
- package/dist/lang/test/expressions.spec.js +42 -86
- package/dist/lang/test/field-symbols.spec.js +8 -6
- package/dist/lang/test/literals.spec.js +6 -6
- package/dist/lang/test/model_serialization.spec.js +5 -5
- package/dist/lang/test/test-translator.js +9 -7
- package/dist/malloy.d.ts +3 -3
- package/dist/malloy.js +1 -1
- package/dist/model/index.d.ts +1 -1
- package/dist/model/index.js +2 -1
- package/dist/model/malloy_query.d.ts +24 -19
- package/dist/model/malloy_query.js +272 -244
- package/dist/model/malloy_types.d.ts +224 -205
- package/dist/model/malloy_types.js +19 -98
- package/dist/model/utils.d.ts +10 -3
- package/dist/model/utils.js +84 -219
- package/package.json +1 -1
- package/dist/lang/ast/types/comparison.d.ts +0 -11
- package/dist/lang/ast/types/comparison.js +0 -41
- package/dist/lang/ast/types/equality.d.ts +0 -7
- package/dist/lang/ast/types/equality.js +0 -37
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.ExprTime = void 0;
|
|
26
26
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
|
-
const utils_1 = require("./utils");
|
|
28
27
|
const expression_def_1 = require("../types/expression-def");
|
|
29
28
|
class ExprTime extends expression_def_1.ExpressionDef {
|
|
30
29
|
constructor(timeType, value, expressionType = 'scalar') {
|
|
@@ -34,7 +33,7 @@ class ExprTime extends expression_def_1.ExpressionDef {
|
|
|
34
33
|
this.translationValue = {
|
|
35
34
|
dataType: timeType,
|
|
36
35
|
expressionType,
|
|
37
|
-
value
|
|
36
|
+
value,
|
|
38
37
|
evalSpace: 'constant',
|
|
39
38
|
};
|
|
40
39
|
}
|
|
@@ -45,16 +44,15 @@ class ExprTime extends expression_def_1.ExpressionDef {
|
|
|
45
44
|
let value = expr.value;
|
|
46
45
|
if (timeType !== expr.dataType) {
|
|
47
46
|
const toTs = {
|
|
48
|
-
|
|
49
|
-
function: 'cast',
|
|
47
|
+
node: 'cast',
|
|
50
48
|
safe: false,
|
|
51
49
|
dstType: timeType,
|
|
52
|
-
|
|
50
|
+
e: expr.value,
|
|
53
51
|
};
|
|
54
52
|
if ((0, malloy_types_1.isTimeFieldType)(expr.dataType)) {
|
|
55
53
|
toTs.srcType = expr.dataType;
|
|
56
54
|
}
|
|
57
|
-
value =
|
|
55
|
+
value = toTs;
|
|
58
56
|
}
|
|
59
57
|
return new ExprTime(timeType, value, expr.expressionType);
|
|
60
58
|
}
|
|
@@ -51,7 +51,7 @@ class ExprUngroup extends expression_def_1.ExpressionDef {
|
|
|
51
51
|
return (0, ast_utils_1.errorFor)('doubly-ungrouped aggregate');
|
|
52
52
|
}
|
|
53
53
|
const ungroup = {
|
|
54
|
-
|
|
54
|
+
node: this.control,
|
|
55
55
|
e: exprVal.value,
|
|
56
56
|
};
|
|
57
57
|
if (this.typeCheck(this.expr, { ...exprVal, expressionType: 'scalar' })) {
|
|
@@ -87,7 +87,7 @@ class ExprUngroup extends expression_def_1.ExpressionDef {
|
|
|
87
87
|
return {
|
|
88
88
|
dataType: this.returns(exprVal),
|
|
89
89
|
expressionType: 'ungrouped_aggregate',
|
|
90
|
-
value:
|
|
90
|
+
value: ungroup,
|
|
91
91
|
evalSpace: 'output',
|
|
92
92
|
};
|
|
93
93
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BinaryMalloyOperator } from '../types/binary_operators';
|
|
1
2
|
import { ExprValue } from '../types/expr-value';
|
|
2
3
|
import { ExpressionDef } from '../types/expression-def';
|
|
3
4
|
import { FieldSpace } from '../types/field-space';
|
|
@@ -9,7 +10,7 @@ export declare class ForRange extends ExpressionDef {
|
|
|
9
10
|
elementType: string;
|
|
10
11
|
legalChildTypes: import("../../../model").TypeDesc[];
|
|
11
12
|
constructor(from: ExpressionDef, duration: ExpressionDef, timeframe: Timeframe);
|
|
12
|
-
apply(fs: FieldSpace, op:
|
|
13
|
+
apply(fs: FieldSpace, op: BinaryMalloyOperator, expr: ExpressionDef): ExprValue;
|
|
13
14
|
requestExpression(_fs: FieldSpace): undefined;
|
|
14
15
|
getExpression(_fs: FieldSpace): ExprValue;
|
|
15
16
|
}
|
|
@@ -38,7 +38,7 @@ class FunctionOrderBy extends malloy_element_1.MalloyElement {
|
|
|
38
38
|
getAnalyticOrderBy(fs) {
|
|
39
39
|
if (!this.field) {
|
|
40
40
|
this.log('analytic `order_by` must specify an aggregate expression or output field reference');
|
|
41
|
-
return { e:
|
|
41
|
+
return { node: 'functionOrderBy', e: { node: 'error' }, dir: this.dir };
|
|
42
42
|
}
|
|
43
43
|
const expr = this.field.getExpression(fs);
|
|
44
44
|
if ((0, malloy_types_1.expressionIsAggregate)(expr.expressionType)) {
|
|
@@ -53,7 +53,7 @@ class FunctionOrderBy extends malloy_element_1.MalloyElement {
|
|
|
53
53
|
else {
|
|
54
54
|
this.field.log('analytic `order_by` must be scalar or aggregate');
|
|
55
55
|
}
|
|
56
|
-
return { e: expr.value, dir: this.dir };
|
|
56
|
+
return { node: 'functionOrderBy', e: expr.value, dir: this.dir };
|
|
57
57
|
}
|
|
58
58
|
getAggregateOrderBy(fs, allowExpression) {
|
|
59
59
|
if (this.field) {
|
|
@@ -64,15 +64,15 @@ class FunctionOrderBy extends malloy_element_1.MalloyElement {
|
|
|
64
64
|
if (!allowExpression) {
|
|
65
65
|
this.field.log('`order_by` must be only `asc` or `desc` with no expression');
|
|
66
66
|
}
|
|
67
|
-
return { e: expr.value, dir: this.dir };
|
|
67
|
+
return { node: 'functionOrderBy', e: expr.value, dir: this.dir };
|
|
68
68
|
}
|
|
69
69
|
else {
|
|
70
70
|
if (this.dir === undefined) {
|
|
71
71
|
// This error should technically never happen because it can't parse this way
|
|
72
72
|
this.log('field or order direction must be specified');
|
|
73
|
-
return {
|
|
73
|
+
return { node: 'functionDefaultOrderBy', dir: 'asc' };
|
|
74
74
|
}
|
|
75
|
-
return {
|
|
75
|
+
return { node: 'functionDefaultOrderBy', dir: this.dir };
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CompareMalloyOperator } from '../types/binary_operators';
|
|
2
2
|
import { ExprValue } from '../types/expr-value';
|
|
3
3
|
import { ExpressionDef } from '../types/expression-def';
|
|
4
4
|
import { FieldSpace } from '../types/field-space';
|
|
5
5
|
export declare class PartialCompare extends ExpressionDef {
|
|
6
|
-
readonly op:
|
|
6
|
+
readonly op: CompareMalloyOperator;
|
|
7
7
|
readonly right: ExpressionDef;
|
|
8
8
|
elementType: string;
|
|
9
|
-
constructor(op:
|
|
9
|
+
constructor(op: CompareMalloyOperator, right: ExpressionDef);
|
|
10
10
|
granular(): boolean;
|
|
11
11
|
apply(fs: FieldSpace, op: string, expr: ExpressionDef): ExprValue;
|
|
12
12
|
requestExpression(_fs: FieldSpace): ExprValue | undefined;
|
|
@@ -28,7 +28,6 @@ const ast_utils_1 = require("../ast-utils");
|
|
|
28
28
|
const fragtype_utils_1 = require("../fragtype-utils");
|
|
29
29
|
const expression_def_1 = require("../types/expression-def");
|
|
30
30
|
const malloy_element_1 = require("../types/malloy-element");
|
|
31
|
-
const utils_1 = require("./utils");
|
|
32
31
|
function typeCoalesce(ev1, ev2) {
|
|
33
32
|
return ev1 === undefined ||
|
|
34
33
|
ev1.dataType === 'null' ||
|
|
@@ -63,7 +62,14 @@ class Pick extends expression_def_1.ExpressionDef {
|
|
|
63
62
|
return this.getExpression(fs);
|
|
64
63
|
}
|
|
65
64
|
apply(fs, op, expr) {
|
|
66
|
-
const caseValue =
|
|
65
|
+
const caseValue = {
|
|
66
|
+
node: 'pick',
|
|
67
|
+
kids: {
|
|
68
|
+
pickWhen: [],
|
|
69
|
+
pickThen: [],
|
|
70
|
+
pickElse: { node: 'error', message: 'pick statement not complete' },
|
|
71
|
+
},
|
|
72
|
+
};
|
|
67
73
|
let returnType;
|
|
68
74
|
let anyExpressionType = 'scalar';
|
|
69
75
|
let anyEvalSpace = 'constant';
|
|
@@ -80,7 +86,8 @@ class Pick extends expression_def_1.ExpressionDef {
|
|
|
80
86
|
return (0, ast_utils_1.errorFor)('pick when type');
|
|
81
87
|
}
|
|
82
88
|
returnType = typeCoalesce(returnType, thenExpr);
|
|
83
|
-
caseValue.push(
|
|
89
|
+
caseValue.kids.pickWhen.push(whenExpr.value);
|
|
90
|
+
caseValue.kids.pickThen.push(thenExpr.value);
|
|
84
91
|
}
|
|
85
92
|
const elsePart = this.elsePick || expr;
|
|
86
93
|
const elseVal = elsePart.getExpression(fs);
|
|
@@ -90,14 +97,23 @@ class Pick extends expression_def_1.ExpressionDef {
|
|
|
90
97
|
this.log(`${errSrc} type '${fragtype_utils_1.FT.inspect(elseVal)}', expected '${returnType.dataType}'[pick-values-must-match]`);
|
|
91
98
|
return (0, ast_utils_1.errorFor)('pick else type');
|
|
92
99
|
}
|
|
100
|
+
caseValue.kids.pickElse = elseVal.value;
|
|
93
101
|
return {
|
|
94
102
|
dataType: returnType.dataType,
|
|
95
103
|
expressionType: (0, malloy_types_1.maxExpressionType)(anyExpressionType, elseVal.expressionType),
|
|
96
104
|
evalSpace: (0, malloy_types_1.mergeEvalSpaces)(anyEvalSpace, elseVal.evalSpace),
|
|
97
|
-
value:
|
|
105
|
+
value: caseValue,
|
|
98
106
|
};
|
|
99
107
|
}
|
|
100
108
|
getExpression(fs) {
|
|
109
|
+
const pick = {
|
|
110
|
+
node: 'pick',
|
|
111
|
+
kids: {
|
|
112
|
+
pickWhen: [],
|
|
113
|
+
pickThen: [],
|
|
114
|
+
pickElse: { node: 'error', message: 'pick statement not complete' },
|
|
115
|
+
},
|
|
116
|
+
};
|
|
101
117
|
if (this.elsePick === undefined) {
|
|
102
118
|
this.log("pick incomplete, missing 'else'");
|
|
103
119
|
return (0, ast_utils_1.errorFor)('no value for partial pick');
|
|
@@ -119,7 +135,6 @@ class Pick extends expression_def_1.ExpressionDef {
|
|
|
119
135
|
});
|
|
120
136
|
}
|
|
121
137
|
let returnType;
|
|
122
|
-
const caseValue = ['CASE'];
|
|
123
138
|
let anyExpressionType = 'scalar';
|
|
124
139
|
let anyEvalSpace = 'constant';
|
|
125
140
|
for (const aChoice of choiceValues) {
|
|
@@ -135,7 +150,8 @@ class Pick extends expression_def_1.ExpressionDef {
|
|
|
135
150
|
returnType = typeCoalesce(returnType, aChoice.pick);
|
|
136
151
|
anyExpressionType = (0, malloy_types_1.maxExpressionType)(anyExpressionType, (0, malloy_types_1.maxExpressionType)(aChoice.pick.expressionType, aChoice.when.expressionType));
|
|
137
152
|
anyEvalSpace = (0, malloy_types_1.mergeEvalSpaces)(anyEvalSpace, aChoice.pick.evalSpace, aChoice.when.evalSpace);
|
|
138
|
-
|
|
153
|
+
pick.kids.pickWhen.push(aChoice.when.value);
|
|
154
|
+
pick.kids.pickThen.push(aChoice.pick.value);
|
|
139
155
|
}
|
|
140
156
|
const defVal = this.elsePick.getExpression(fs);
|
|
141
157
|
anyExpressionType = (0, malloy_types_1.maxExpressionType)(anyExpressionType, defVal.expressionType);
|
|
@@ -145,11 +161,11 @@ class Pick extends expression_def_1.ExpressionDef {
|
|
|
145
161
|
this.elsePick.log(`else type '${fragtype_utils_1.FT.inspect(defVal)}', expected '${returnType.dataType}'[pick-values-must-match]`);
|
|
146
162
|
return (0, ast_utils_1.errorFor)('pick value type mismatch');
|
|
147
163
|
}
|
|
148
|
-
|
|
164
|
+
pick.kids.pickElse = defVal.value;
|
|
149
165
|
return {
|
|
150
166
|
dataType: returnType.dataType,
|
|
151
167
|
expressionType: anyExpressionType,
|
|
152
|
-
value:
|
|
168
|
+
value: pick,
|
|
153
169
|
evalSpace: anyEvalSpace,
|
|
154
170
|
};
|
|
155
171
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BinaryMalloyOperator } from '../types/binary_operators';
|
|
1
2
|
import { ExprValue } from '../types/expr-value';
|
|
2
3
|
import { ExpressionDef } from '../types/expression-def';
|
|
3
4
|
import { FieldSpace } from '../types/field-space';
|
|
@@ -6,7 +7,7 @@ export declare class Range extends ExpressionDef {
|
|
|
6
7
|
readonly last: ExpressionDef;
|
|
7
8
|
elementType: string;
|
|
8
9
|
constructor(first: ExpressionDef, last: ExpressionDef);
|
|
9
|
-
apply(fs: FieldSpace, op:
|
|
10
|
+
apply(fs: FieldSpace, op: BinaryMalloyOperator, expr: ExpressionDef): ExprValue;
|
|
10
11
|
requestExpression(_fs: FieldSpace): undefined;
|
|
11
12
|
getExpression(_fs: FieldSpace): ExprValue;
|
|
12
13
|
}
|
|
@@ -26,7 +26,6 @@ exports.Range = void 0;
|
|
|
26
26
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
27
|
const ast_utils_1 = require("../ast-utils");
|
|
28
28
|
const expression_def_1 = require("../types/expression-def");
|
|
29
|
-
const utils_1 = require("./utils");
|
|
30
29
|
class Range extends expression_def_1.ExpressionDef {
|
|
31
30
|
constructor(first, last) {
|
|
32
31
|
super({ first: first, last: last });
|
|
@@ -47,7 +46,10 @@ class Range extends expression_def_1.ExpressionDef {
|
|
|
47
46
|
dataType: 'boolean',
|
|
48
47
|
expressionType: (0, malloy_types_1.maxExpressionType)(fromValue.expressionType, toValue.expressionType),
|
|
49
48
|
evalSpace: (0, malloy_types_1.mergeEvalSpaces)(fromValue.evalSpace, toValue.evalSpace),
|
|
50
|
-
value:
|
|
49
|
+
value: {
|
|
50
|
+
node: op2,
|
|
51
|
+
kids: { left: fromValue.value, right: toValue.value },
|
|
52
|
+
},
|
|
51
53
|
};
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { TimeFieldType, TimestampUnit,
|
|
1
|
+
import { TimeFieldType, TimestampUnit, TimeLiteralNode } from '../../../model/malloy_types';
|
|
2
2
|
import { ExprValue } from '../types/expr-value';
|
|
3
3
|
import { FieldSpace } from '../types/field-space';
|
|
4
4
|
import { ExpressionDef } from '../types/expression-def';
|
|
5
5
|
import { TimeResult } from '../types/time-result';
|
|
6
|
+
import { BinaryMalloyOperator } from '../types/binary_operators';
|
|
6
7
|
export declare class TimeFormatError extends Error {
|
|
7
8
|
}
|
|
8
9
|
interface TimeText {
|
|
@@ -19,7 +20,7 @@ declare abstract class TimeLiteral extends ExpressionDef {
|
|
|
19
20
|
nextLit?: string;
|
|
20
21
|
timeZone?: string;
|
|
21
22
|
constructor(tm: TimeText, units: TimestampUnit | undefined, timeType: TimeFieldType);
|
|
22
|
-
protected makeLiteral(val: string, typ: TimeFieldType):
|
|
23
|
+
protected makeLiteral(val: string, typ: TimeFieldType): TimeLiteralNode;
|
|
23
24
|
protected makeValue(val: string, dataType: TimeFieldType): TimeResult;
|
|
24
25
|
getExpression(_fs: FieldSpace): ExprValue;
|
|
25
26
|
getNext(): ExprValue | undefined;
|
|
@@ -38,7 +39,7 @@ declare class GranularLiteral extends TimeLiteral {
|
|
|
38
39
|
readonly nextLit: string;
|
|
39
40
|
elementType: string;
|
|
40
41
|
constructor(tm: TimeText, units: TimestampUnit | undefined, timeType: TimeFieldType, nextLit: string);
|
|
41
|
-
apply(fs: FieldSpace, op:
|
|
42
|
+
apply(fs: FieldSpace, op: BinaryMalloyOperator, left: ExpressionDef): ExprValue;
|
|
42
43
|
}
|
|
43
44
|
export declare class LiteralHour extends GranularLiteral {
|
|
44
45
|
elementType: string;
|
|
@@ -70,10 +70,9 @@ class TimeLiteral extends expression_def_1.ExpressionDef {
|
|
|
70
70
|
}
|
|
71
71
|
makeLiteral(val, typ) {
|
|
72
72
|
const timeFrag = {
|
|
73
|
-
|
|
74
|
-
function: 'timeLiteral',
|
|
73
|
+
node: 'timeLiteral',
|
|
75
74
|
literal: val,
|
|
76
|
-
|
|
75
|
+
dataType: typ,
|
|
77
76
|
};
|
|
78
77
|
if (this.timeZone) {
|
|
79
78
|
timeFrag.timezone = this.timeZone;
|
|
@@ -83,7 +82,7 @@ class TimeLiteral extends expression_def_1.ExpressionDef {
|
|
|
83
82
|
makeValue(val, dataType) {
|
|
84
83
|
const timeFrag = this.makeLiteral(val, dataType);
|
|
85
84
|
const expressionType = 'scalar';
|
|
86
|
-
const value =
|
|
85
|
+
const value = timeFrag;
|
|
87
86
|
if (this.units) {
|
|
88
87
|
return {
|
|
89
88
|
dataType,
|
|
@@ -214,16 +213,12 @@ class DateBasedLiteral extends GranularLiteral {
|
|
|
214
213
|
}
|
|
215
214
|
getExpression(_fs) {
|
|
216
215
|
const dateValue = this.makeValue(this.literalPart, 'date');
|
|
217
|
-
const timestamp =
|
|
218
|
-
this.makeLiteral(`${this.literalPart} 00:00:00`, 'timestamp'),
|
|
219
|
-
];
|
|
216
|
+
const timestamp = this.makeLiteral(`${this.literalPart} 00:00:00`, 'timestamp');
|
|
220
217
|
return { ...dateValue, morphic: { timestamp }, evalSpace: 'literal' };
|
|
221
218
|
}
|
|
222
219
|
getNext() {
|
|
223
220
|
const dateValue = this.makeValue(this.nextLit, 'date');
|
|
224
|
-
const timestamp =
|
|
225
|
-
this.makeLiteral(`${this.nextLit} 00:00:00`, 'timestamp'),
|
|
226
|
-
];
|
|
221
|
+
const timestamp = this.makeLiteral(`${this.nextLit} 00:00:00`, 'timestamp');
|
|
227
222
|
return { ...dateValue, morphic: { timestamp } };
|
|
228
223
|
}
|
|
229
224
|
}
|
|
@@ -26,7 +26,6 @@ exports.TopBy = void 0;
|
|
|
26
26
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
27
|
const expression_def_1 = require("../types/expression-def");
|
|
28
28
|
const malloy_element_1 = require("../types/malloy-element");
|
|
29
|
-
const utils_1 = require("./utils");
|
|
30
29
|
class TopBy extends malloy_element_1.MalloyElement {
|
|
31
30
|
constructor(by) {
|
|
32
31
|
super();
|
|
@@ -42,7 +41,7 @@ class TopBy extends malloy_element_1.MalloyElement {
|
|
|
42
41
|
if (!(0, malloy_types_1.expressionIsAggregate)(byExpr.expressionType)) {
|
|
43
42
|
this.log('top by expression must be an aggregate');
|
|
44
43
|
}
|
|
45
|
-
return { by: 'expression', e:
|
|
44
|
+
return { by: 'expression', e: byExpr.value };
|
|
46
45
|
}
|
|
47
46
|
return { by: 'name', name: this.by };
|
|
48
47
|
}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
import { Expr
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
* Compose a binary expression. Tries to write them safely and concisely
|
|
5
|
-
* @param left
|
|
6
|
-
* @param op
|
|
7
|
-
* @param right
|
|
8
|
-
* @return Fragment list of the composed expression
|
|
9
|
-
*/
|
|
10
|
-
export declare function compose(left: Fragment[], op: string, right: Fragment[]): Fragment[];
|
|
11
|
-
export declare function compressExpr(expr: Expr): Expr;
|
|
12
|
-
export declare function nullsafeNot(expr: Expr, op?: Equality): Expr;
|
|
1
|
+
import { Expr } from '../../../model/malloy_types';
|
|
2
|
+
import { EqualityMalloyOperator } from '../types/binary_operators';
|
|
3
|
+
export declare function nullsafeNot(expr: Expr, op?: EqualityMalloyOperator): Expr;
|
|
@@ -22,64 +22,16 @@
|
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.nullsafeNot =
|
|
26
|
-
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
|
-
/**
|
|
28
|
-
* If the passed expresion is not a single term, wrap it in parens
|
|
29
|
-
* @param f expression fragment
|
|
30
|
-
*/
|
|
31
|
-
function term(f) {
|
|
32
|
-
if (f.length > 1) {
|
|
33
|
-
return ['(', ...f, ')'];
|
|
34
|
-
}
|
|
35
|
-
if (f.length === 0) {
|
|
36
|
-
// Trying to compose a binary expresion with an entity that has no value
|
|
37
|
-
// this should at least cause the generated SQL to error, but likely
|
|
38
|
-
// there has already been a semantic error reported.
|
|
39
|
-
return ['__MISSING_VALUE__'];
|
|
40
|
-
}
|
|
41
|
-
return f;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Compose a binary expression. Tries to write them safely and concisely
|
|
45
|
-
* @param left
|
|
46
|
-
* @param op
|
|
47
|
-
* @param right
|
|
48
|
-
* @return Fragment list of the composed expression
|
|
49
|
-
*/
|
|
50
|
-
function compose(left, op, right) {
|
|
51
|
-
const opAlpha = op.match(/^[A-Za-z]/);
|
|
52
|
-
const leftSpace = left.length === 1 && opAlpha ? ' ' : '';
|
|
53
|
-
const rightSpace = right.length === 1 && opAlpha ? ' ' : '';
|
|
54
|
-
const newOp = leftSpace + op + rightSpace;
|
|
55
|
-
return [...term(left), newOp, ...term(right)];
|
|
56
|
-
}
|
|
57
|
-
exports.compose = compose;
|
|
58
|
-
function compressExpr(expr) {
|
|
59
|
-
// compress all adjacent strings
|
|
60
|
-
const compressValue = [];
|
|
61
|
-
let buildString;
|
|
62
|
-
for (const fragment of expr.flat()) {
|
|
63
|
-
if (typeof fragment === 'string') {
|
|
64
|
-
buildString = buildString ? buildString + fragment : fragment;
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
if (buildString) {
|
|
68
|
-
compressValue.push(buildString);
|
|
69
|
-
buildString = undefined;
|
|
70
|
-
}
|
|
71
|
-
compressValue.push(fragment);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (buildString) {
|
|
75
|
-
compressValue.push(buildString);
|
|
76
|
-
}
|
|
77
|
-
return compressValue;
|
|
78
|
-
}
|
|
79
|
-
exports.compressExpr = compressExpr;
|
|
25
|
+
exports.nullsafeNot = void 0;
|
|
80
26
|
function nullsafeNot(expr, op) {
|
|
81
27
|
if (op === undefined || op === '!=' || op === '!~') {
|
|
82
|
-
return
|
|
28
|
+
return {
|
|
29
|
+
node: 'not',
|
|
30
|
+
e: {
|
|
31
|
+
node: 'coalesce',
|
|
32
|
+
kids: { left: expr, right: { node: 'false' } },
|
|
33
|
+
},
|
|
34
|
+
};
|
|
83
35
|
}
|
|
84
36
|
return expr;
|
|
85
37
|
}
|
|
@@ -53,7 +53,7 @@ class ReferenceField extends space_field_1.SpaceField {
|
|
|
53
53
|
? {
|
|
54
54
|
type: check.found.typeDesc().dataType,
|
|
55
55
|
name: path[0],
|
|
56
|
-
e:
|
|
56
|
+
e: { node: 'parameter', path },
|
|
57
57
|
}
|
|
58
58
|
: { type: 'fieldref', path };
|
|
59
59
|
this.queryFieldDef = queryFieldDef;
|
package/dist/lang/ast/index.d.ts
CHANGED
|
@@ -96,7 +96,7 @@ export * from './source-elements/sql-source';
|
|
|
96
96
|
export * from './source-elements/table-source';
|
|
97
97
|
export * from './sql-elements/sql-string';
|
|
98
98
|
export * from './types/annotation-elements';
|
|
99
|
-
export * from './types/
|
|
99
|
+
export * from './types/binary_operators';
|
|
100
100
|
export * from './types/source-desc';
|
|
101
101
|
export * from './types/source-property';
|
|
102
102
|
export * from './types/expression-def';
|
package/dist/lang/ast/index.js
CHANGED
|
@@ -134,7 +134,7 @@ __exportStar(require("./source-elements/sql-source"), exports);
|
|
|
134
134
|
__exportStar(require("./source-elements/table-source"), exports);
|
|
135
135
|
__exportStar(require("./sql-elements/sql-string"), exports);
|
|
136
136
|
__exportStar(require("./types/annotation-elements"), exports);
|
|
137
|
-
__exportStar(require("./types/
|
|
137
|
+
__exportStar(require("./types/binary_operators"), exports);
|
|
138
138
|
__exportStar(require("./types/source-desc"), exports);
|
|
139
139
|
__exportStar(require("./types/source-property"), exports);
|
|
140
140
|
__exportStar(require("./types/expression-def"), exports);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FilterCondition, PipeSegment, Sampling } from '../../../model/malloy_types';
|
|
2
2
|
import { FieldName, FieldSpace } from '../types/field-space';
|
|
3
3
|
import { Limit } from '../query-properties/limit';
|
|
4
4
|
import { IndexFieldSpace } from '../field-space/index-field-space';
|
|
@@ -8,7 +8,7 @@ import { QueryInputSpace } from '../field-space/query-input-space';
|
|
|
8
8
|
import { QueryOperationSpace } from '../field-space/query-spaces';
|
|
9
9
|
import { MalloyElement } from '../types/malloy-element';
|
|
10
10
|
export declare class IndexBuilder implements QueryBuilder {
|
|
11
|
-
filters:
|
|
11
|
+
filters: FilterCondition[];
|
|
12
12
|
limit?: Limit;
|
|
13
13
|
indexOn?: FieldName;
|
|
14
14
|
sample?: Sampling;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FilterCondition, PipeSegment, QuerySegment } from '../../../model/malloy_types';
|
|
2
2
|
import { FieldSpace } from '../types/field-space';
|
|
3
3
|
import { Ordering } from '../query-properties/ordering';
|
|
4
4
|
import { Top } from '../query-properties/top';
|
|
@@ -13,7 +13,7 @@ export declare abstract class QuerySegmentBuilder implements QueryBuilder {
|
|
|
13
13
|
abstract inputFS: QueryInputSpace;
|
|
14
14
|
abstract resultFS: QueryOperationSpace;
|
|
15
15
|
abstract readonly type: 'grouping' | 'project';
|
|
16
|
-
filters:
|
|
16
|
+
filters: FilterCondition[];
|
|
17
17
|
execute(qp: QueryProperty): void;
|
|
18
18
|
abstract finalize(fromSeg: PipeSegment | undefined): PipeSegment;
|
|
19
19
|
refineFrom(from: PipeSegment | undefined, to: QuerySegment): void;
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.FieldDefinitionValue = exports.DefSpace = exports.DimensionFieldDeclaration = exports.MeasureFieldDeclaration = exports.DeclareFieldDeclaration = exports.ProjectFieldDeclaration = exports.GroupByFieldDeclaration = exports.AggregateFieldDeclaration = exports.CalculateFieldDeclaration = exports.AtomicFieldDeclaration = void 0;
|
|
26
26
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
|
-
const utils_1 = require("../expressions/utils");
|
|
28
27
|
const fragtype_utils_1 = require("../fragtype-utils");
|
|
29
28
|
const granular_result_1 = require("../types/granular-result");
|
|
30
29
|
const malloy_element_1 = require("../types/malloy-element");
|
|
@@ -74,7 +73,6 @@ class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
|
|
|
74
73
|
type: 'error',
|
|
75
74
|
};
|
|
76
75
|
}
|
|
77
|
-
const compressValue = (0, utils_1.compressExpr)(exprValue.value);
|
|
78
76
|
let retType = exprValue.dataType;
|
|
79
77
|
if (retType === 'null') {
|
|
80
78
|
this.expr.log('null value defaults to type number, use "null::TYPE" to specify correct type', 'warn');
|
|
@@ -86,9 +84,7 @@ class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
|
|
|
86
84
|
type: retType,
|
|
87
85
|
location: this.location,
|
|
88
86
|
};
|
|
89
|
-
|
|
90
|
-
template.e = compressValue;
|
|
91
|
-
}
|
|
87
|
+
template.e = exprValue.value;
|
|
92
88
|
if (exprValue.expressionType) {
|
|
93
89
|
template.expressionType = exprValue.expressionType;
|
|
94
90
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FilterCondition } from '../../../model/malloy_types';
|
|
2
2
|
import { ExpressionDef } from '../types/expression-def';
|
|
3
3
|
import { FieldSpace } from '../types/field-space';
|
|
4
4
|
import { ListOf, MalloyElement } from '../types/malloy-element';
|
|
@@ -8,7 +8,7 @@ export declare class FilterElement extends MalloyElement {
|
|
|
8
8
|
readonly exprSrc: string;
|
|
9
9
|
elementType: string;
|
|
10
10
|
constructor(expr: ExpressionDef, exprSrc: string);
|
|
11
|
-
|
|
11
|
+
filterCondition(fs: FieldSpace): FilterCondition;
|
|
12
12
|
}
|
|
13
13
|
export declare class Filter extends ListOf<FilterElement> implements QueryPropertyInterface {
|
|
14
14
|
elementType: string;
|
|
@@ -16,5 +16,5 @@ export declare class Filter extends ListOf<FilterElement> implements QueryProper
|
|
|
16
16
|
forceQueryClass: undefined;
|
|
17
17
|
queryRefinementStage: LegalRefinementStage;
|
|
18
18
|
set having(isHaving: boolean);
|
|
19
|
-
getFilterList(fs: FieldSpace):
|
|
19
|
+
getFilterList(fs: FieldSpace): FilterCondition[];
|
|
20
20
|
}
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.Filter = exports.FilterElement = void 0;
|
|
26
26
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
|
-
const utils_1 = require("../expressions/utils");
|
|
28
27
|
const malloy_element_1 = require("../types/malloy-element");
|
|
29
28
|
const query_property_interface_1 = require("../types/query-property-interface");
|
|
30
29
|
class FilterElement extends malloy_element_1.MalloyElement {
|
|
@@ -34,19 +33,21 @@ class FilterElement extends malloy_element_1.MalloyElement {
|
|
|
34
33
|
this.exprSrc = exprSrc;
|
|
35
34
|
this.elementType = 'filterElement';
|
|
36
35
|
}
|
|
37
|
-
|
|
36
|
+
filterCondition(fs) {
|
|
38
37
|
const exprVal = this.expr.getExpression(fs);
|
|
39
38
|
if (exprVal.dataType !== 'boolean') {
|
|
40
39
|
this.expr.log('Filter expression must have boolean value');
|
|
41
40
|
return {
|
|
41
|
+
node: 'filterCondition',
|
|
42
42
|
code: this.exprSrc,
|
|
43
|
-
|
|
43
|
+
e: { node: 'false' },
|
|
44
44
|
expressionType: 'scalar',
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
const exprCond = {
|
|
48
|
+
node: 'filterCondition',
|
|
48
49
|
code: this.exprSrc,
|
|
49
|
-
|
|
50
|
+
e: exprVal.value,
|
|
50
51
|
expressionType: exprVal.expressionType,
|
|
51
52
|
};
|
|
52
53
|
return exprCond;
|
|
@@ -70,7 +71,7 @@ class Filter extends malloy_element_1.ListOf {
|
|
|
70
71
|
getFilterList(fs) {
|
|
71
72
|
const checked = [];
|
|
72
73
|
for (const oneElement of this.list) {
|
|
73
|
-
const fExpr = oneElement.
|
|
74
|
+
const fExpr = oneElement.filterCondition(fs);
|
|
74
75
|
// mtoy todo is having we never set then queryRefinementStage might be wrong
|
|
75
76
|
// ... calculations and aggregations must go last
|
|
76
77
|
// Aggregates are ALSO checked at SQL generation time, but checking
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.Top = void 0;
|
|
26
26
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
|
-
const utils_1 = require("../expressions/utils");
|
|
28
27
|
const field_space_1 = require("../types/field-space");
|
|
29
28
|
const malloy_element_1 = require("../types/malloy-element");
|
|
30
29
|
const query_property_interface_1 = require("../types/query-property-interface");
|
|
@@ -67,7 +66,7 @@ class Top extends malloy_element_1.MalloyElement {
|
|
|
67
66
|
if (byExpr.evalSpace === 'output') {
|
|
68
67
|
this.by.log('top by expression must be an output expression');
|
|
69
68
|
}
|
|
70
|
-
return { by: 'expression', e:
|
|
69
|
+
return { by: 'expression', e: byExpr.value };
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
return undefined;
|
|
@@ -119,7 +119,7 @@ class RefinedSource extends source_1.Source {
|
|
|
119
119
|
let moreFilters = false;
|
|
120
120
|
for (const filter of filters) {
|
|
121
121
|
for (const el of filter.list) {
|
|
122
|
-
const fc = el.
|
|
122
|
+
const fc = el.filterCondition(fs);
|
|
123
123
|
if ((0, malloy_types_1.expressionIsCalculation)(fc.expressionType)) {
|
|
124
124
|
el.log("Can't use aggregate computations in top level filters");
|
|
125
125
|
}
|