@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.Joins = exports.ExpressionJoin = exports.KeyJoin = exports.Join = void 0;
|
|
26
26
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
|
-
const utils_1 = require("../expressions/utils");
|
|
28
27
|
const join_space_field_1 = require("../field-space/join-space-field");
|
|
29
28
|
const definition_list_1 = require("../types/definition-list");
|
|
30
29
|
const malloy_element_1 = require("../types/malloy-element");
|
|
@@ -66,7 +65,7 @@ class KeyJoin extends Join {
|
|
|
66
65
|
structRelationship: {
|
|
67
66
|
type: 'one',
|
|
68
67
|
matrixOperation: 'left',
|
|
69
|
-
onExpression:
|
|
68
|
+
onExpression: { node: 'error', message: "('join fixup'='not done yet')" },
|
|
70
69
|
},
|
|
71
70
|
location: this.location,
|
|
72
71
|
};
|
|
@@ -92,14 +91,16 @@ class KeyJoin extends Join {
|
|
|
92
91
|
inStruct.structRelationship = {
|
|
93
92
|
type: 'one',
|
|
94
93
|
matrixOperation: 'left',
|
|
95
|
-
onExpression:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
onExpression: {
|
|
95
|
+
node: '=',
|
|
96
|
+
kids: {
|
|
97
|
+
left: {
|
|
98
|
+
node: 'field',
|
|
99
|
+
path: [this.name.refString, inStruct.primaryKey],
|
|
100
|
+
},
|
|
101
|
+
right: exprX.value,
|
|
99
102
|
},
|
|
100
|
-
|
|
101
|
-
...exprX.value,
|
|
102
|
-
],
|
|
103
|
+
},
|
|
103
104
|
};
|
|
104
105
|
return;
|
|
105
106
|
}
|
|
@@ -144,7 +145,7 @@ class ExpressionJoin extends Join {
|
|
|
144
145
|
}
|
|
145
146
|
const joinRel = inStruct.structRelationship;
|
|
146
147
|
if ((0, malloy_types_1.isJoinOn)(joinRel)) {
|
|
147
|
-
joinRel.onExpression =
|
|
148
|
+
joinRel.onExpression = exprX.value;
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
structDef(parameterSpace) {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { Expr,
|
|
1
|
+
import { Expr, TimeFieldType, TimestampUnit, FieldValueType, CastType, TypecastExpr, TimeDeltaExpr } from '../../model/malloy_types';
|
|
2
2
|
import { TimeResult } from './types/time-result';
|
|
3
|
-
export declare function timeOffset(timeType: TimeFieldType, from: Expr, op: '+' | '-', n: Expr, timeframe: TimestampUnit):
|
|
3
|
+
export declare function timeOffset(timeType: TimeFieldType, from: Expr, op: '+' | '-', n: Expr, timeframe: TimestampUnit): TimeDeltaExpr;
|
|
4
4
|
export declare function castTo(castType: CastType | {
|
|
5
5
|
raw: string;
|
|
6
|
-
}, from: Expr, fromType: FieldValueType, safe?: boolean):
|
|
7
|
-
export declare function castTimestampToDate(from: Expr, safe?: boolean):
|
|
8
|
-
export declare function castDateToTimestamp(from: Expr, safe?: boolean):
|
|
6
|
+
}, from: Expr, fromType: FieldValueType, safe?: boolean): TypecastExpr;
|
|
7
|
+
export declare function castTimestampToDate(from: Expr, safe?: boolean): TypecastExpr;
|
|
8
|
+
export declare function castDateToTimestamp(from: Expr, safe?: boolean): TypecastExpr;
|
|
9
9
|
export declare function resolution(timeframe: string): TimeFieldType;
|
|
10
10
|
export declare function timeResult(t: TimeResult, tt: TimestampUnit | undefined): TimeResult;
|
|
11
|
-
export declare function timestampOffset(from: Fragment[], op: '+' | '-', n: Fragment[], timeframe: TimestampUnit, fromNotTimestamp?: boolean): Fragment[];
|
|
12
|
-
export declare function dateOffset(from: Fragment[], op: '+' | '-', n: Fragment[], timeframe: TimestampUnit): Fragment[];
|
|
@@ -22,58 +22,53 @@
|
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.
|
|
25
|
+
exports.timeResult = exports.resolution = exports.castDateToTimestamp = exports.castTimestampToDate = exports.castTo = exports.timeOffset = void 0;
|
|
26
26
|
const malloy_types_1 = require("../../model/malloy_types");
|
|
27
|
-
const utils_1 = require("./expressions/utils");
|
|
28
27
|
function timeOffset(timeType, from, op, n, timeframe) {
|
|
29
|
-
return
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
base: { valueType: timeType, value: from },
|
|
34
|
-
op,
|
|
28
|
+
return {
|
|
29
|
+
node: 'delta',
|
|
30
|
+
kids: {
|
|
31
|
+
base: { ...from, dataType: timeType },
|
|
35
32
|
delta: n,
|
|
36
|
-
units: timeframe,
|
|
37
33
|
},
|
|
38
|
-
|
|
34
|
+
op,
|
|
35
|
+
units: timeframe,
|
|
36
|
+
};
|
|
39
37
|
}
|
|
40
38
|
exports.timeOffset = timeOffset;
|
|
41
39
|
function castTo(castType, from, fromType, safe = false) {
|
|
42
40
|
const cast = {
|
|
43
|
-
|
|
44
|
-
function: 'cast',
|
|
41
|
+
node: 'cast',
|
|
45
42
|
dstType: castType,
|
|
46
|
-
|
|
43
|
+
e: from,
|
|
47
44
|
safe,
|
|
48
45
|
};
|
|
49
46
|
if ((0, malloy_types_1.isAtomicFieldType)(fromType)) {
|
|
50
47
|
cast.srcType = fromType;
|
|
51
48
|
}
|
|
52
|
-
return
|
|
49
|
+
return cast;
|
|
53
50
|
}
|
|
54
51
|
exports.castTo = castTo;
|
|
55
52
|
function castTimestampToDate(from, safe = false) {
|
|
56
53
|
const cast = {
|
|
57
|
-
|
|
58
|
-
function: 'cast',
|
|
54
|
+
node: 'cast',
|
|
59
55
|
dstType: 'date',
|
|
60
56
|
srcType: 'timestamp',
|
|
61
|
-
|
|
57
|
+
e: from,
|
|
62
58
|
safe,
|
|
63
59
|
};
|
|
64
|
-
return
|
|
60
|
+
return cast;
|
|
65
61
|
}
|
|
66
62
|
exports.castTimestampToDate = castTimestampToDate;
|
|
67
63
|
function castDateToTimestamp(from, safe = false) {
|
|
68
64
|
const cast = {
|
|
69
|
-
|
|
70
|
-
function: 'cast',
|
|
65
|
+
node: 'cast',
|
|
71
66
|
dstType: 'timestamp',
|
|
72
67
|
srcType: 'date',
|
|
73
|
-
|
|
68
|
+
e: from,
|
|
74
69
|
safe,
|
|
75
70
|
};
|
|
76
|
-
return
|
|
71
|
+
return cast;
|
|
77
72
|
}
|
|
78
73
|
exports.castDateToTimestamp = castDateToTimestamp;
|
|
79
74
|
function resolution(timeframe) {
|
|
@@ -95,39 +90,4 @@ function timeResult(t, tt) {
|
|
|
95
90
|
return t;
|
|
96
91
|
}
|
|
97
92
|
exports.timeResult = timeResult;
|
|
98
|
-
function timestampOffset(from, op, n, timeframe, fromNotTimestamp = false) {
|
|
99
|
-
const useDatetime = ['week', 'month', 'quarter', 'year'].includes(timeframe);
|
|
100
|
-
const add = op === '+' ? '_ADD' : '_SUB';
|
|
101
|
-
const units = timeframe.toUpperCase();
|
|
102
|
-
if (useDatetime) {
|
|
103
|
-
return [
|
|
104
|
-
`TIMESTAMP(DATETIME${add}(DATETIME(`,
|
|
105
|
-
...from,
|
|
106
|
-
'),INTERVAL ',
|
|
107
|
-
...n,
|
|
108
|
-
` ${units}))`,
|
|
109
|
-
];
|
|
110
|
-
}
|
|
111
|
-
const typeFrom = fromNotTimestamp ? ['TIMESTAMP(', ...from, ')'] : from;
|
|
112
|
-
return (0, utils_1.compressExpr)([
|
|
113
|
-
`TIMESTAMP${add}(`,
|
|
114
|
-
...typeFrom,
|
|
115
|
-
',INTERVAL ',
|
|
116
|
-
...n,
|
|
117
|
-
` ${units})`,
|
|
118
|
-
]);
|
|
119
|
-
}
|
|
120
|
-
exports.timestampOffset = timestampOffset;
|
|
121
|
-
function dateOffset(from, op, n, timeframe) {
|
|
122
|
-
const add = op === '+' ? '_ADD' : '_SUB';
|
|
123
|
-
const units = timeframe.toUpperCase();
|
|
124
|
-
return (0, utils_1.compressExpr)([
|
|
125
|
-
`DATE${add}(`,
|
|
126
|
-
...from,
|
|
127
|
-
',INTERVAL ',
|
|
128
|
-
...n,
|
|
129
|
-
` ${units})`,
|
|
130
|
-
]);
|
|
131
|
-
}
|
|
132
|
-
exports.dateOffset = dateOffset;
|
|
133
93
|
//# sourceMappingURL=time-utils.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BinaryOperator } from '../../../model';
|
|
2
|
+
export type LogicalMalloyOperator = 'and' | 'or';
|
|
3
|
+
export type ArithmeticMalloyOperator = '+' | '-' | '*' | '/' | '%';
|
|
4
|
+
export type EqualityMalloyOperator = '~' | '!~' | '=' | '!=';
|
|
5
|
+
export type CompareMalloyOperator = '<' | '<=' | '>' | '>=' | EqualityMalloyOperator;
|
|
6
|
+
export type BinaryMalloyOperator = ArithmeticMalloyOperator | CompareMalloyOperator | LogicalMalloyOperator;
|
|
7
|
+
export declare function getExprNode(mo: BinaryMalloyOperator): BinaryOperator;
|
|
8
|
+
export declare function isEquality(op: string): op is EqualityMalloyOperator;
|
|
9
|
+
export declare function isComparison(op: string): op is CompareMalloyOperator;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.isComparison = exports.isEquality = exports.getExprNode = void 0;
|
|
10
|
+
function getExprNode(mo) {
|
|
11
|
+
switch (mo) {
|
|
12
|
+
case '~':
|
|
13
|
+
return 'like';
|
|
14
|
+
case '!~':
|
|
15
|
+
return '!like';
|
|
16
|
+
}
|
|
17
|
+
return mo;
|
|
18
|
+
}
|
|
19
|
+
exports.getExprNode = getExprNode;
|
|
20
|
+
function isEquality(op) {
|
|
21
|
+
return op === '=' || op === '!=' || op === '~' || op === '!~';
|
|
22
|
+
}
|
|
23
|
+
exports.isEquality = isEquality;
|
|
24
|
+
function isComparison(op) {
|
|
25
|
+
return (isEquality(op) || op === '>=' || op === '<=' || op === '>' || op === '<');
|
|
26
|
+
}
|
|
27
|
+
exports.isComparison = isComparison;
|
|
28
|
+
//# sourceMappingURL=binary_operators.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type MorphicValues = Record<string,
|
|
1
|
+
import { Expr, TypeDesc } from '../../../model/malloy_types';
|
|
2
|
+
type MorphicValues = Record<string, Expr>;
|
|
3
3
|
export interface ExprResult extends TypeDesc {
|
|
4
|
-
value:
|
|
4
|
+
value: Expr;
|
|
5
5
|
morphic?: MorphicValues;
|
|
6
6
|
}
|
|
7
7
|
export {};
|
|
@@ -2,6 +2,7 @@ import { TimestampUnit, FieldValueType } from '../../../model/malloy_types';
|
|
|
2
2
|
import { ExprValue } from './expr-value';
|
|
3
3
|
import { FieldSpace } from './field-space';
|
|
4
4
|
import { MalloyElement } from './malloy-element';
|
|
5
|
+
import { BinaryMalloyOperator } from './binary_operators';
|
|
5
6
|
/**
|
|
6
7
|
* Root node for any element in an expression. These essentially
|
|
7
8
|
* create a sub-tree in the larger AST. Expression nodes know
|
|
@@ -44,7 +45,7 @@ export declare abstract class ExpressionDef extends MalloyElement {
|
|
|
44
45
|
* @param expr The "other" (besdies 'this') value
|
|
45
46
|
* @return The translated expression
|
|
46
47
|
*/
|
|
47
|
-
apply(fs: FieldSpace, op:
|
|
48
|
+
apply(fs: FieldSpace, op: BinaryMalloyOperator, left: ExpressionDef): ExprValue;
|
|
48
49
|
canSupportPartitionBy(): boolean;
|
|
49
50
|
canSupportOrderBy(): boolean;
|
|
50
51
|
canSupportLimit(): boolean;
|
|
@@ -56,7 +57,7 @@ export declare class ExprDuration extends ExpressionDef {
|
|
|
56
57
|
elementType: string;
|
|
57
58
|
legalChildTypes: import("../../../model/malloy_types").TypeDesc[];
|
|
58
59
|
constructor(n: ExpressionDef, timeframe: TimestampUnit);
|
|
59
|
-
apply(fs: FieldSpace, op:
|
|
60
|
+
apply(fs: FieldSpace, op: BinaryMalloyOperator, left: ExpressionDef): ExprValue;
|
|
60
61
|
getExpression(_fs: FieldSpace): ExprValue;
|
|
61
62
|
}
|
|
62
63
|
export declare function getMorphicValue(mv: ExprValue, mt: FieldValueType): ExprValue | undefined;
|
|
@@ -71,4 +72,4 @@ export declare function getMorphicValue(mv: ExprValue, mt: FieldValueType): Expr
|
|
|
71
72
|
* @param right Right Value
|
|
72
73
|
* @return ExprValue of the expression
|
|
73
74
|
*/
|
|
74
|
-
export declare function applyBinary(fs: FieldSpace, left: ExpressionDef, op:
|
|
75
|
+
export declare function applyBinary(fs: FieldSpace, left: ExpressionDef, op: BinaryMalloyOperator, right: ExpressionDef): ExprValue;
|
|
@@ -28,10 +28,9 @@ const ast_utils_1 = require("../ast-utils");
|
|
|
28
28
|
const utils_1 = require("../expressions/utils");
|
|
29
29
|
const fragtype_utils_1 = require("../fragtype-utils");
|
|
30
30
|
const time_utils_1 = require("../time-utils");
|
|
31
|
-
const comparison_1 = require("./comparison");
|
|
32
|
-
const equality_1 = require("./equality");
|
|
33
31
|
const granular_result_1 = require("./granular-result");
|
|
34
32
|
const malloy_element_1 = require("./malloy-element");
|
|
33
|
+
const binary_operators_1 = require("./binary_operators");
|
|
35
34
|
class TypeMismatch extends Error {
|
|
36
35
|
}
|
|
37
36
|
/**
|
|
@@ -154,7 +153,7 @@ class ExprDuration extends ExpressionDef {
|
|
|
154
153
|
return {
|
|
155
154
|
dataType: 'duration',
|
|
156
155
|
expressionType: 'scalar',
|
|
157
|
-
value:
|
|
156
|
+
value: { node: 'error', message: 'Duration is not a value' },
|
|
158
157
|
evalSpace: 'constant',
|
|
159
158
|
};
|
|
160
159
|
}
|
|
@@ -182,70 +181,64 @@ exports.getMorphicValue = getMorphicValue;
|
|
|
182
181
|
function timeCompare(left, lhs, op, rhs) {
|
|
183
182
|
const leftIsTime = (0, malloy_types_1.isTimeFieldType)(lhs.dataType);
|
|
184
183
|
const rightIsTime = (0, malloy_types_1.isTimeFieldType)(rhs.dataType);
|
|
184
|
+
const node = (0, binary_operators_1.getExprNode)(op);
|
|
185
185
|
if (leftIsTime && rightIsTime) {
|
|
186
186
|
if (lhs.dataType !== rhs.dataType) {
|
|
187
187
|
const lval = willMorphTo(lhs, 'timestamp');
|
|
188
188
|
const rval = willMorphTo(rhs, 'timestamp');
|
|
189
189
|
if (lval && rval) {
|
|
190
|
-
return
|
|
190
|
+
return { node, kids: { left: lval, right: lval } };
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
else {
|
|
194
|
-
return
|
|
194
|
+
return { node, kids: { left: lhs.value, right: rhs.value } };
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
if ((leftIsTime || rightIsTime) &&
|
|
198
198
|
lhs.dataType !== 'null' &&
|
|
199
199
|
rhs.dataType !== 'null') {
|
|
200
200
|
left.log(`Cannot compare a ${lhs.dataType} to a ${rhs.dataType}`);
|
|
201
|
-
return
|
|
201
|
+
return { node: 'false' };
|
|
202
202
|
}
|
|
203
203
|
return undefined;
|
|
204
204
|
}
|
|
205
205
|
function regexEqual(left, right) {
|
|
206
206
|
if (left.dataType === 'string') {
|
|
207
207
|
if (right.dataType === 'regular expression') {
|
|
208
|
-
return
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
expr: left.value,
|
|
213
|
-
regexp: right.value,
|
|
214
|
-
},
|
|
215
|
-
];
|
|
208
|
+
return {
|
|
209
|
+
node: 'regexpMatch',
|
|
210
|
+
kids: { expr: left.value, regex: right.value },
|
|
211
|
+
};
|
|
216
212
|
}
|
|
217
213
|
}
|
|
218
214
|
else if (right.dataType === 'string') {
|
|
219
215
|
if (left.dataType === 'regular expression') {
|
|
220
|
-
return
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
expr: right.value,
|
|
225
|
-
regexp: left.value,
|
|
226
|
-
},
|
|
227
|
-
];
|
|
216
|
+
return {
|
|
217
|
+
node: 'regexpMatch',
|
|
218
|
+
kids: { expr: right.value, regex: left.value },
|
|
219
|
+
};
|
|
228
220
|
}
|
|
229
221
|
}
|
|
230
222
|
return undefined;
|
|
231
223
|
}
|
|
232
224
|
function nullCompare(left, op, right) {
|
|
233
225
|
const not = op === '!=' || op === '!~';
|
|
226
|
+
const nullCmp = not ? 'is-not-null' : 'is-null';
|
|
234
227
|
if (left.dataType === 'null' || right.dataType === 'null') {
|
|
235
|
-
const maybeNot = not ? ' NOT' : '';
|
|
236
228
|
if (left.dataType !== 'null') {
|
|
237
|
-
return
|
|
229
|
+
return { node: nullCmp, e: left.value };
|
|
238
230
|
}
|
|
239
231
|
if (right.dataType !== 'null') {
|
|
240
|
-
return
|
|
232
|
+
return { node: nullCmp, e: right.value };
|
|
241
233
|
}
|
|
242
|
-
return
|
|
234
|
+
return { node: not ? 'false' : 'true' };
|
|
243
235
|
}
|
|
244
236
|
return undefined;
|
|
245
237
|
}
|
|
246
238
|
function equality(fs, left, op, right) {
|
|
247
239
|
const lhs = left.getExpression(fs);
|
|
248
240
|
const rhs = right.getExpression(fs);
|
|
241
|
+
const node = (0, binary_operators_1.getExprNode)(op);
|
|
249
242
|
const err = errorCascade('boolean', lhs, rhs);
|
|
250
243
|
if (err)
|
|
251
244
|
return err;
|
|
@@ -261,15 +254,15 @@ function equality(fs, left, op, right) {
|
|
|
261
254
|
}
|
|
262
255
|
}
|
|
263
256
|
}
|
|
264
|
-
let value = timeCompare(left, lhs, op, rhs) ||
|
|
257
|
+
let value = timeCompare(left, lhs, op, rhs) || {
|
|
258
|
+
node,
|
|
259
|
+
kids: { left: lhs.value, right: rhs.value },
|
|
260
|
+
};
|
|
265
261
|
if (lhs.dataType !== 'error' && rhs.dataType !== 'error') {
|
|
266
262
|
switch (op) {
|
|
267
263
|
case '~':
|
|
268
264
|
case '!~': {
|
|
269
|
-
if (lhs.dataType
|
|
270
|
-
value = (0, utils_1.compose)(lhs.value, 'LIKE', rhs.value);
|
|
271
|
-
}
|
|
272
|
-
else {
|
|
265
|
+
if (lhs.dataType !== 'string' || rhs.dataType !== 'string') {
|
|
273
266
|
const regexCmp = regexEqual(lhs, rhs);
|
|
274
267
|
if (regexCmp === undefined) {
|
|
275
268
|
throw new TypeMismatch("Incompatible types for match('~') operator");
|
|
@@ -282,11 +275,12 @@ function equality(fs, left, op, right) {
|
|
|
282
275
|
case '=':
|
|
283
276
|
case '!=': {
|
|
284
277
|
const nullCmp = nullCompare(lhs, op, rhs);
|
|
278
|
+
const eqNode = value;
|
|
285
279
|
if (nullCmp) {
|
|
286
280
|
value = nullCmp;
|
|
287
281
|
}
|
|
288
282
|
else {
|
|
289
|
-
value = (0, utils_1.nullsafeNot)(regexEqual(lhs, rhs) ||
|
|
283
|
+
value = (0, utils_1.nullsafeNot)(regexEqual(lhs, rhs) || eqNode, op);
|
|
290
284
|
}
|
|
291
285
|
break;
|
|
292
286
|
}
|
|
@@ -310,7 +304,10 @@ function compare(fs, left, op, right) {
|
|
|
310
304
|
if (noCompare) {
|
|
311
305
|
return { ...noCompare, dataType: 'boolean' };
|
|
312
306
|
}
|
|
313
|
-
const value = timeCompare(left, lhs, op, rhs) ||
|
|
307
|
+
const value = timeCompare(left, lhs, op, rhs) || {
|
|
308
|
+
node: (0, binary_operators_1.getExprNode)(op),
|
|
309
|
+
kids: { left: lhs.value, right: rhs.value },
|
|
310
|
+
};
|
|
314
311
|
return {
|
|
315
312
|
dataType: 'boolean',
|
|
316
313
|
expressionType,
|
|
@@ -318,9 +315,6 @@ function compare(fs, left, op, right) {
|
|
|
318
315
|
value: value,
|
|
319
316
|
};
|
|
320
317
|
}
|
|
321
|
-
function oneOf(op, ...operators) {
|
|
322
|
-
return operators.includes(op);
|
|
323
|
-
}
|
|
324
318
|
function numeric(fs, left, op, right) {
|
|
325
319
|
const lhs = left.getExpression(fs);
|
|
326
320
|
const rhs = right.getExpression(fs);
|
|
@@ -342,7 +336,7 @@ function numeric(fs, left, op, right) {
|
|
|
342
336
|
return {
|
|
343
337
|
dataType: 'number',
|
|
344
338
|
expressionType,
|
|
345
|
-
value:
|
|
339
|
+
value: { node: op, kids: { left: lhs.value, right: rhs.value } },
|
|
346
340
|
evalSpace: (0, malloy_types_1.mergeEvalSpaces)(lhs.evalSpace, rhs.evalSpace),
|
|
347
341
|
};
|
|
348
342
|
}
|
|
@@ -389,19 +383,19 @@ function delta(fs, left, op, right) {
|
|
|
389
383
|
* @return ExprValue of the expression
|
|
390
384
|
*/
|
|
391
385
|
function applyBinary(fs, left, op, right) {
|
|
392
|
-
if ((0,
|
|
386
|
+
if ((0, binary_operators_1.isEquality)(op)) {
|
|
393
387
|
return equality(fs, left, op, right);
|
|
394
388
|
}
|
|
395
|
-
if ((0,
|
|
389
|
+
if ((0, binary_operators_1.isComparison)(op)) {
|
|
396
390
|
return compare(fs, left, op, right);
|
|
397
391
|
}
|
|
398
|
-
if (
|
|
392
|
+
if (op === '+' || op === '-') {
|
|
399
393
|
return delta(fs, left, op, right);
|
|
400
394
|
}
|
|
401
395
|
if (op === '*') {
|
|
402
396
|
return numeric(fs, left, op, right);
|
|
403
397
|
}
|
|
404
|
-
if (
|
|
398
|
+
if (op === '/' || op === '%') {
|
|
405
399
|
const num = left.getExpression(fs);
|
|
406
400
|
const denom = right.getExpression(fs);
|
|
407
401
|
const noGo = unsupportError(left, num, right, denom);
|
|
@@ -419,17 +413,15 @@ function applyBinary(fs, left, op, right) {
|
|
|
419
413
|
right.log('Denominator must be a number');
|
|
420
414
|
}
|
|
421
415
|
else {
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
numerator: num.value,
|
|
426
|
-
denominator: denom.value,
|
|
416
|
+
const divmod = {
|
|
417
|
+
node: op,
|
|
418
|
+
kids: { left: num.value, right: denom.value },
|
|
427
419
|
};
|
|
428
420
|
return {
|
|
429
421
|
dataType: 'number',
|
|
430
422
|
expressionType: (0, malloy_types_1.maxExpressionType)(num.expressionType, denom.expressionType),
|
|
431
423
|
evalSpace: (0, malloy_types_1.mergeEvalSpaces)(num.evalSpace, denom.evalSpace),
|
|
432
|
-
value:
|
|
424
|
+
value: divmod,
|
|
433
425
|
};
|
|
434
426
|
}
|
|
435
427
|
return (0, ast_utils_1.errorFor)('divide type mismatch');
|
|
@@ -443,7 +435,7 @@ function errorCascade(dataType, ...es) {
|
|
|
443
435
|
return {
|
|
444
436
|
dataType,
|
|
445
437
|
expressionType: (0, malloy_types_1.maxOfExpressionTypes)(es.map(e => e.expressionType)),
|
|
446
|
-
value:
|
|
438
|
+
value: { node: 'error', message: 'cascading error' },
|
|
447
439
|
evalSpace: (0, malloy_types_1.mergeEvalSpaces)(...es.map(e => e.evalSpace)),
|
|
448
440
|
};
|
|
449
441
|
}
|
|
@@ -455,12 +447,13 @@ function unsupportError(l, lhs, r, rhs) {
|
|
|
455
447
|
const ret = {
|
|
456
448
|
dataType: lhs.dataType,
|
|
457
449
|
expressionType: (0, malloy_types_1.maxExpressionType)(lhs.expressionType, rhs.expressionType),
|
|
458
|
-
value:
|
|
450
|
+
value: { node: 'error', message: 'sql-native unsupported' },
|
|
459
451
|
evalSpace: (0, malloy_types_1.mergeEvalSpaces)(lhs.evalSpace, rhs.evalSpace),
|
|
460
452
|
};
|
|
461
453
|
if (lhs.dataType === 'sql native') {
|
|
462
454
|
l.log(`Unsupported SQL native type '${lhs.rawType}' not allowed in expression[unsupported-sql-native-type-not-allowed-in-expression]`);
|
|
463
|
-
|
|
455
|
+
ret.dataType = rhs.dataType;
|
|
456
|
+
return ret;
|
|
464
457
|
}
|
|
465
458
|
if (rhs.dataType === 'sql native') {
|
|
466
459
|
r.log(`Unsupported SQL native type '${rhs.rawType}' not allowed in expression[unsupported-sql-native-type-not-allowed-in-expression]`);
|
|
@@ -2170,17 +2170,6 @@ export declare class ExprCoalesceContext extends FieldExprContext {
|
|
|
2170
2170
|
exitRule(listener: MalloyParserListener): void;
|
|
2171
2171
|
accept<Result>(visitor: MalloyParserVisitor<Result>): Result;
|
|
2172
2172
|
}
|
|
2173
|
-
export declare class ExprCountDisinctContext extends FieldExprContext {
|
|
2174
|
-
COUNT(): TerminalNode;
|
|
2175
|
-
OPAREN(): TerminalNode;
|
|
2176
|
-
DISTINCT(): TerminalNode;
|
|
2177
|
-
fieldExpr(): FieldExprContext;
|
|
2178
|
-
CPAREN(): TerminalNode;
|
|
2179
|
-
constructor(ctx: FieldExprContext);
|
|
2180
|
-
enterRule(listener: MalloyParserListener): void;
|
|
2181
|
-
exitRule(listener: MalloyParserListener): void;
|
|
2182
|
-
accept<Result>(visitor: MalloyParserVisitor<Result>): Result;
|
|
2183
|
-
}
|
|
2184
2173
|
export declare class ExprPathlessAggregateContext extends FieldExprContext {
|
|
2185
2174
|
aggregate(): AggregateContext;
|
|
2186
2175
|
OPAREN(): TerminalNode;
|