@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
|
@@ -40,7 +40,6 @@ import { ExprNotContext } from "./MalloyParser";
|
|
|
40
40
|
import { ExprLogicalAndContext } from "./MalloyParser";
|
|
41
41
|
import { ExprLogicalOrContext } from "./MalloyParser";
|
|
42
42
|
import { ExprCoalesceContext } from "./MalloyParser";
|
|
43
|
-
import { ExprCountDisinctContext } from "./MalloyParser";
|
|
44
43
|
import { ExprPathlessAggregateContext } from "./MalloyParser";
|
|
45
44
|
import { ExprAggregateContext } from "./MalloyParser";
|
|
46
45
|
import { ExprExprContext } from "./MalloyParser";
|
|
@@ -707,18 +706,6 @@ export interface MalloyParserListener extends ParseTreeListener {
|
|
|
707
706
|
* @param ctx the parse tree
|
|
708
707
|
*/
|
|
709
708
|
exitExprCoalesce?: (ctx: ExprCoalesceContext) => void;
|
|
710
|
-
/**
|
|
711
|
-
* Enter a parse tree produced by the `exprCountDisinct`
|
|
712
|
-
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
713
|
-
* @param ctx the parse tree
|
|
714
|
-
*/
|
|
715
|
-
enterExprCountDisinct?: (ctx: ExprCountDisinctContext) => void;
|
|
716
|
-
/**
|
|
717
|
-
* Exit a parse tree produced by the `exprCountDisinct`
|
|
718
|
-
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
719
|
-
* @param ctx the parse tree
|
|
720
|
-
*/
|
|
721
|
-
exitExprCountDisinct?: (ctx: ExprCountDisinctContext) => void;
|
|
722
709
|
/**
|
|
723
710
|
* Enter a parse tree produced by the `exprPathlessAggregate`
|
|
724
711
|
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
@@ -40,7 +40,6 @@ import { ExprNotContext } from "./MalloyParser";
|
|
|
40
40
|
import { ExprLogicalAndContext } from "./MalloyParser";
|
|
41
41
|
import { ExprLogicalOrContext } from "./MalloyParser";
|
|
42
42
|
import { ExprCoalesceContext } from "./MalloyParser";
|
|
43
|
-
import { ExprCountDisinctContext } from "./MalloyParser";
|
|
44
43
|
import { ExprPathlessAggregateContext } from "./MalloyParser";
|
|
45
44
|
import { ExprAggregateContext } from "./MalloyParser";
|
|
46
45
|
import { ExprExprContext } from "./MalloyParser";
|
|
@@ -505,13 +504,6 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
|
|
|
505
504
|
* @return the visitor result
|
|
506
505
|
*/
|
|
507
506
|
visitExprCoalesce?: (ctx: ExprCoalesceContext) => Result;
|
|
508
|
-
/**
|
|
509
|
-
* Visit a parse tree produced by the `exprCountDisinct`
|
|
510
|
-
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
511
|
-
* @param ctx the parse tree
|
|
512
|
-
* @return the visitor result
|
|
513
|
-
*/
|
|
514
|
-
visitExprCountDisinct?: (ctx: ExprCountDisinctContext) => Result;
|
|
515
507
|
/**
|
|
516
508
|
* Visit a parse tree produced by the `exprPathlessAggregate`
|
|
517
509
|
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
@@ -167,7 +167,6 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
|
|
|
167
167
|
visitExprAddSub(pcx: parse.ExprAddSubContext): ast.ExprAddSub;
|
|
168
168
|
visitExprMulDiv(pcx: parse.ExprMulDivContext): ast.ExprMulDiv;
|
|
169
169
|
visitExprCompare(pcx: parse.ExprCompareContext): ast.ExprCompare;
|
|
170
|
-
visitExprCountDisinct(pcx: parse.ExprCountDisinctContext): ast.ExprCountDistinct;
|
|
171
170
|
visitExprUngroup(pcx: parse.ExprUngroupContext): ast.ExprUngroup;
|
|
172
171
|
symmetricAggregateUsageError(aggFunc: string): string;
|
|
173
172
|
asymmetricAggregateUsageError(aggFunc: string): string;
|
|
@@ -919,10 +919,6 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
919
919
|
}
|
|
920
920
|
throw this.internalError(pcx, `untranslatable comparison operator '${op}'`);
|
|
921
921
|
}
|
|
922
|
-
visitExprCountDisinct(pcx) {
|
|
923
|
-
this.m4advisory(pcx, '`count(distinct expression)` deprecated, use `count(expression)` instead');
|
|
924
|
-
return this.astAt(new ast.ExprCountDistinct(this.getFieldExpr(pcx.fieldExpr())), pcx);
|
|
925
|
-
}
|
|
926
922
|
visitExprUngroup(pcx) {
|
|
927
923
|
const flist = pcx.fieldName().map(fcx => this.getFieldName(fcx));
|
|
928
924
|
const kw = pcx.ungroup().text.toLowerCase();
|
|
@@ -22,31 +22,42 @@
|
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
const model_1 = require("../../model");
|
|
26
25
|
const test_translator_1 = require("./test-translator");
|
|
27
26
|
require("./parse-expects");
|
|
28
27
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* @param expr Compiled expression
|
|
32
|
-
* @returns A string with variables A,B,... substituded for non string elements
|
|
28
|
+
* Try and write a generic version of the expression, might some day be the basis for
|
|
29
|
+
* a much better expression matcher.
|
|
33
30
|
*/
|
|
34
|
-
function exprToString(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
function exprToString(e, symbols = {}) {
|
|
32
|
+
switch (e.node) {
|
|
33
|
+
case '=':
|
|
34
|
+
case '>':
|
|
35
|
+
case '>=':
|
|
36
|
+
case '<':
|
|
37
|
+
case '<=':
|
|
38
|
+
case '+':
|
|
39
|
+
case '-':
|
|
40
|
+
case '*':
|
|
41
|
+
case '/':
|
|
42
|
+
case '%':
|
|
43
|
+
return `${exprToString(e.kids.left, symbols)}${e.node}${exprToString(e.kids.right, symbols)}`;
|
|
44
|
+
case 'and':
|
|
45
|
+
case 'or':
|
|
46
|
+
return `(${exprToString(e.kids.left, symbols)})${e.node}(${exprToString(e.kids.right, symbols)})`;
|
|
47
|
+
case 'field': {
|
|
48
|
+
const ref = e.path.join('.');
|
|
49
|
+
if (symbols[ref] === undefined) {
|
|
50
|
+
const nSyms = Object.keys(symbols).length;
|
|
51
|
+
symbols[ref] = String.fromCharCode('A'.charCodeAt(0) + nSyms);
|
|
52
|
+
}
|
|
53
|
+
return symbols[ref];
|
|
54
|
+
}
|
|
55
|
+
case '()':
|
|
56
|
+
return `(${exprToString(e.e, symbols)})`;
|
|
57
|
+
case 'not':
|
|
58
|
+
return `not(${exprToString(e.e, symbols)})`;
|
|
59
|
+
}
|
|
60
|
+
return `{${e.node}}`;
|
|
50
61
|
}
|
|
51
62
|
describe('expressions', () => {
|
|
52
63
|
describe('timeframes', () => {
|
|
@@ -160,25 +171,25 @@ describe('expressions', () => {
|
|
|
160
171
|
const compare = (0, test_translator_1.expr) `ad = ad.quarter`;
|
|
161
172
|
expect(compare).toTranslate();
|
|
162
173
|
const compare_expr = compare.translator.generated().value;
|
|
163
|
-
expect(exprToString(compare_expr)).toEqual('A=
|
|
174
|
+
expect(exprToString(compare_expr)).toEqual('A={trunc}');
|
|
164
175
|
});
|
|
165
176
|
test('compare to granular result expression uses straight comparison', () => {
|
|
166
177
|
const compare = (0, test_translator_1.expr) `ad = ad.quarter + 1`;
|
|
167
178
|
expect(compare).toTranslate();
|
|
168
179
|
const compare_expr = compare.translator.generated().value;
|
|
169
|
-
expect(exprToString(compare_expr)).toEqual('A=
|
|
180
|
+
expect(exprToString(compare_expr)).toEqual('A={delta}');
|
|
170
181
|
});
|
|
171
182
|
test('apply granular-truncation uses range', () => {
|
|
172
183
|
const compare = (0, test_translator_1.expr) `ad ? ad.quarter`;
|
|
173
184
|
expect(compare).toTranslate();
|
|
174
185
|
const compare_expr = compare.translator.generated().value;
|
|
175
|
-
expect(exprToString(compare_expr)).toEqual('(A>=
|
|
186
|
+
expect(exprToString(compare_expr)).toEqual('(A>={trunc})and(A<{delta})');
|
|
176
187
|
});
|
|
177
|
-
test('apply granular-literal alternation uses range', () => {
|
|
188
|
+
test('apply granular-literal alternation uses all literals for range', () => {
|
|
178
189
|
const compare = (0, test_translator_1.expr) `ad ? @2020 | @2022`;
|
|
179
190
|
expect(compare).toTranslate();
|
|
180
191
|
const compare_expr = compare.translator.generated().value;
|
|
181
|
-
expect(exprToString(compare_expr)).toEqual('((A>=
|
|
192
|
+
expect(exprToString(compare_expr)).toEqual('((A>={timeLiteral})and(A<{timeLiteral}))or((A>={timeLiteral})and(A<{timeLiteral}))');
|
|
182
193
|
});
|
|
183
194
|
// this should use range, but it uses = and alternations are
|
|
184
195
|
// kind of needing help so this is a placeholder for
|
|
@@ -700,13 +711,6 @@ describe('expressions', () => {
|
|
|
700
711
|
calculate: bar is lag(sum(output))
|
|
701
712
|
}`).translationToFailWith("'output' is not defined");
|
|
702
713
|
});
|
|
703
|
-
test('count(distinct column)', () => {
|
|
704
|
-
expect((0, test_translator_1.model) `
|
|
705
|
-
##! m4warnings=warn
|
|
706
|
-
run: a -> {
|
|
707
|
-
aggregate: x is count(distinct astr)
|
|
708
|
-
}`).toTranslateWithWarnings('`count(distinct expression)` deprecated, use `count(expression)` instead');
|
|
709
|
-
});
|
|
710
714
|
});
|
|
711
715
|
describe('pick statements', () => {
|
|
712
716
|
test('full', () => {
|
|
@@ -807,59 +811,11 @@ describe('expressions', () => {
|
|
|
807
811
|
});
|
|
808
812
|
});
|
|
809
813
|
test('paren and applied div', () => {
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
const
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
expect(queryDef).toBeDefined();
|
|
816
|
-
expect(queryDef === null || queryDef === void 0 ? void 0 : queryDef.type).toBe('query');
|
|
817
|
-
if (queryDef && queryDef.type === 'query') {
|
|
818
|
-
const qSeg = queryDef.pipeline[0];
|
|
819
|
-
expect(qSeg.type).toEqual('reduce');
|
|
820
|
-
if (qSeg.type === 'reduce') {
|
|
821
|
-
const x = qSeg.queryFields[0];
|
|
822
|
-
if (x.type !== 'fieldref' &&
|
|
823
|
-
(0, model_1.isFieldTypeDef)(x) &&
|
|
824
|
-
x.type === 'number' &&
|
|
825
|
-
x.e) {
|
|
826
|
-
expect(x).toMatchObject({
|
|
827
|
-
'e': [
|
|
828
|
-
{
|
|
829
|
-
'function': 'numberLiteral',
|
|
830
|
-
'literal': '1',
|
|
831
|
-
'type': 'dialect',
|
|
832
|
-
},
|
|
833
|
-
// TODO not sure why there are TWO sets of parentheses... A previous version of this test
|
|
834
|
-
// just checked that there were ANY parens, so that went under the radar. Not fixing now.
|
|
835
|
-
'+((',
|
|
836
|
-
{
|
|
837
|
-
'denominator': [
|
|
838
|
-
{
|
|
839
|
-
'function': 'numberLiteral',
|
|
840
|
-
'literal': '4',
|
|
841
|
-
'type': 'dialect',
|
|
842
|
-
},
|
|
843
|
-
],
|
|
844
|
-
'function': 'div',
|
|
845
|
-
'numerator': [
|
|
846
|
-
{
|
|
847
|
-
'function': 'numberLiteral',
|
|
848
|
-
'literal': '3',
|
|
849
|
-
'type': 'dialect',
|
|
850
|
-
},
|
|
851
|
-
],
|
|
852
|
-
'type': 'dialect',
|
|
853
|
-
},
|
|
854
|
-
'))',
|
|
855
|
-
],
|
|
856
|
-
});
|
|
857
|
-
}
|
|
858
|
-
else {
|
|
859
|
-
fail('expression with parens compiled oddly');
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
}
|
|
814
|
+
const one34 = (0, test_translator_1.expr) `1+(3/4)`;
|
|
815
|
+
expect(one34).toTranslate();
|
|
816
|
+
const exprVal = one34.translator.generated();
|
|
817
|
+
const exprE = exprVal.value;
|
|
818
|
+
expect(exprToString(exprE)).toEqual('{numberLiteral}+({numberLiteral}/{numberLiteral})');
|
|
863
819
|
});
|
|
864
820
|
test.each([
|
|
865
821
|
['ats', 'timestamp'],
|
|
@@ -144,11 +144,13 @@ describe('structdef comprehension', () => {
|
|
|
144
144
|
structRelationship: {
|
|
145
145
|
type: 'one',
|
|
146
146
|
matrixOperation: 'left',
|
|
147
|
-
onExpression:
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
147
|
+
onExpression: {
|
|
148
|
+
node: '=',
|
|
149
|
+
kids: {
|
|
150
|
+
left: { node: 'field', path: ['aKey'] },
|
|
151
|
+
right: { node: 'field', path: ['t', 'a'] },
|
|
152
|
+
},
|
|
153
|
+
},
|
|
152
154
|
},
|
|
153
155
|
structSource: { type: 'table', tablePath: 't' },
|
|
154
156
|
fields: [{ type: 'string', name: 'a' }],
|
|
@@ -187,7 +189,7 @@ describe('structdef comprehension', () => {
|
|
|
187
189
|
cOptStr: {
|
|
188
190
|
name: 'cOptStr',
|
|
189
191
|
type: 'string',
|
|
190
|
-
value:
|
|
192
|
+
value: { node: 'stringLiteral', literal: 'value' },
|
|
191
193
|
},
|
|
192
194
|
};
|
|
193
195
|
const space = new static_space_1.StaticSpace(struct);
|
|
@@ -33,7 +33,7 @@ describe('literals', () => {
|
|
|
33
33
|
test('string', () => {
|
|
34
34
|
const m = new test_translator_1.BetaExpression("'forty two'");
|
|
35
35
|
expect(m).toTranslate();
|
|
36
|
-
const m42 = m.generated().value
|
|
36
|
+
const m42 = m.generated().value;
|
|
37
37
|
expect(m42).toMatchObject({ literal: 'forty two' });
|
|
38
38
|
});
|
|
39
39
|
test('string with quoted quote', () => {
|
|
@@ -99,7 +99,7 @@ describe('literals', () => {
|
|
|
99
99
|
else {
|
|
100
100
|
expect((0, granular_result_1.isGranularResult)(ir)).toBeFalsy();
|
|
101
101
|
}
|
|
102
|
-
expect(ir.value
|
|
102
|
+
expect(ir.value).toEqual(expect.objectContaining(result));
|
|
103
103
|
});
|
|
104
104
|
const morphicLiterals = [
|
|
105
105
|
['@1960', '1960-01-01 00:00:00'],
|
|
@@ -117,7 +117,7 @@ describe('literals', () => {
|
|
|
117
117
|
if (morphic) {
|
|
118
118
|
expect(morphTo).toBeDefined();
|
|
119
119
|
if (morphTo) {
|
|
120
|
-
expect(morphTo
|
|
120
|
+
expect(morphTo).toEqual(expect.objectContaining({ literal: morphic }));
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
else {
|
|
@@ -187,7 +187,7 @@ describe('literals', () => {
|
|
|
187
187
|
right
|
|
188
188
|
"""`);
|
|
189
189
|
expect(checking).toTranslate();
|
|
190
|
-
const v = checking.generated().value
|
|
190
|
+
const v = checking.generated().value;
|
|
191
191
|
expect(v).toMatchObject({ literal: '\nleft\n mid\n right\n' });
|
|
192
192
|
});
|
|
193
193
|
test('multi-line indent decreasing', () => {
|
|
@@ -197,13 +197,13 @@ describe('literals', () => {
|
|
|
197
197
|
left
|
|
198
198
|
"""`);
|
|
199
199
|
expect(checking).toTranslate();
|
|
200
|
-
const v = checking.generated().value
|
|
200
|
+
const v = checking.generated().value;
|
|
201
201
|
expect(v).toMatchObject({ literal: '\n right\n mid\nleft\n' });
|
|
202
202
|
});
|
|
203
203
|
test('multi-line indent keep', () => {
|
|
204
204
|
const checking = new test_translator_1.BetaExpression('"""right\n mid\nleft"""');
|
|
205
205
|
expect(checking).toTranslate();
|
|
206
|
-
const v = checking.generated().value
|
|
206
|
+
const v = checking.generated().value;
|
|
207
207
|
expect(v).toMatchObject({ literal: 'right\n mid\nleft' });
|
|
208
208
|
});
|
|
209
209
|
test('timezone single quote', () => {
|
|
@@ -41,7 +41,7 @@ exports.CHILD_EXPLORE = {
|
|
|
41
41
|
type: 'number',
|
|
42
42
|
name: 'flight_count',
|
|
43
43
|
expressionType: 'aggregate',
|
|
44
|
-
e:
|
|
44
|
+
e: { node: 'aggregate', function: 'count', e: { node: '' } },
|
|
45
45
|
},
|
|
46
46
|
],
|
|
47
47
|
};
|
|
@@ -62,7 +62,7 @@ exports.PARENT_EXPLORE = {
|
|
|
62
62
|
type: 'number',
|
|
63
63
|
name: 'some_parent_count',
|
|
64
64
|
expressionType: 'aggregate',
|
|
65
|
-
e:
|
|
65
|
+
e: { node: 'aggregate', function: 'count', e: { node: '' } },
|
|
66
66
|
},
|
|
67
67
|
],
|
|
68
68
|
};
|
|
@@ -83,7 +83,7 @@ exports.GRADPARENT_EXPLORE = {
|
|
|
83
83
|
type: 'number',
|
|
84
84
|
name: 'some_gradparent_count',
|
|
85
85
|
expressionType: 'aggregate',
|
|
86
|
-
e:
|
|
86
|
+
e: { node: 'aggregate', function: 'count', e: { node: '' } },
|
|
87
87
|
},
|
|
88
88
|
],
|
|
89
89
|
};
|
|
@@ -104,14 +104,14 @@ exports.SOURCE_EXPLORE = {
|
|
|
104
104
|
type: 'number',
|
|
105
105
|
name: 'some_child_count',
|
|
106
106
|
expressionType: 'aggregate',
|
|
107
|
-
e:
|
|
107
|
+
e: { node: 'aggregate', function: 'count', e: { node: '' } },
|
|
108
108
|
},
|
|
109
109
|
],
|
|
110
110
|
};
|
|
111
111
|
describe('serializeModel', () => {
|
|
112
112
|
test('Stringify on an `explore` with no parent nor source explore', async () => {
|
|
113
113
|
const parent_explore = new malloy_1.Explore(exports.PARENT_EXPLORE);
|
|
114
|
-
expect(JSON.stringify(parent_explore)).toStrictEqual('{"_structDef":{"type":"struct","name":"some_ns.parent","as":"parent","dialect":"standardsql","structSource":{"type":"table","tablePath":"some_ns.parent"},"structRelationship":{"type":"basetable","connectionName":"bigquery"},"primaryKey":"id2","fields":[{"type":"string","name":"name"},{"type":"number","name":"some_parent_count","expressionType":"aggregate","e":
|
|
114
|
+
expect(JSON.stringify(parent_explore)).toStrictEqual('{"_structDef":{"type":"struct","name":"some_ns.parent","as":"parent","dialect":"standardsql","structSource":{"type":"table","tablePath":"some_ns.parent"},"structRelationship":{"type":"basetable","connectionName":"bigquery"},"primaryKey":"id2","fields":[{"type":"string","name":"name"},{"type":"number","name":"some_parent_count","expressionType":"aggregate","e":{"node":"aggregate","function":"count","e":{"node":""}}}]}}');
|
|
115
115
|
});
|
|
116
116
|
test('No parent nor source explore', async () => {
|
|
117
117
|
const parent_explore = new malloy_1.Explore(exports.PARENT_EXPLORE);
|
|
@@ -210,7 +210,7 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
210
210
|
this.allDialectsEnabled = true;
|
|
211
211
|
/*
|
|
212
212
|
* All test source files can assume that an import of this
|
|
213
|
-
|
|
213
|
+
|
|
214
214
|
*
|
|
215
215
|
* Also the following tables will be available on _db_
|
|
216
216
|
* aTable, malloytest.carriers, malloytest.flights, malloytest.airports
|
|
@@ -242,11 +242,13 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
242
242
|
structRelationship: {
|
|
243
243
|
type: 'one',
|
|
244
244
|
matrixOperation: 'left',
|
|
245
|
-
onExpression:
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
245
|
+
onExpression: {
|
|
246
|
+
node: '=',
|
|
247
|
+
kids: {
|
|
248
|
+
left: { node: 'field', path: ['astr'] },
|
|
249
|
+
right: { node: 'field', path: ['b', 'astr'] },
|
|
250
|
+
},
|
|
251
|
+
},
|
|
250
252
|
},
|
|
251
253
|
},
|
|
252
254
|
{
|
|
@@ -254,7 +256,7 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
254
256
|
name: 'acount',
|
|
255
257
|
numberType: 'integer',
|
|
256
258
|
expressionType: 'aggregate',
|
|
257
|
-
e:
|
|
259
|
+
e: { node: 'aggregate', function: 'count', e: { node: '' } },
|
|
258
260
|
code: 'count()',
|
|
259
261
|
},
|
|
260
262
|
{
|
package/dist/malloy.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { RunSQLOptions } from './run_sql_options';
|
|
3
3
|
import { DocumentCompletion as DocumentCompletionDefinition, DocumentSymbol as DocumentSymbolDefinition, LogMessage, MalloyTranslator } from './lang';
|
|
4
4
|
import { DocumentHelpContext } from './lang/parse-tree-walkers/document-help-context-walker';
|
|
5
|
-
import { CompiledQuery, DocumentLocation, DocumentReference, FieldBooleanDef, FieldDateDef, FieldJSONDef, FieldNumberDef, FieldStringDef, FieldTimestampDef, FieldTypeDef,
|
|
5
|
+
import { CompiledQuery, DocumentLocation, DocumentReference, FieldBooleanDef, FieldDateDef, FieldJSONDef, FieldNumberDef, FieldStringDef, FieldTimestampDef, FieldTypeDef, FilterCondition, Query as InternalQuery, ModelDef, DocumentPosition as ModelDocumentPosition, NamedQuery, QueryData, QueryDataRow, QueryResult, SQLBlock, SQLBlockSource, SQLBlockStructDef, SearchIndexResult, SearchValueMapResult, StructDef, TurtleDef, FeldNativeUnsupportedDef, QueryRunStats, ImportLocation, Annotation } from './model';
|
|
6
6
|
import { ModelString, ModelURL, QueryString, QueryURL, URLReader } from './runtime_types';
|
|
7
7
|
import { Connection, InfoConnection, LookupConnection } from './connection/types';
|
|
8
8
|
import { Tag, TagParse, TagParseSpec, Taggable } from './tags';
|
|
@@ -459,7 +459,7 @@ export declare class PreparedResult implements Taggable {
|
|
|
459
459
|
get resultExplore(): Explore;
|
|
460
460
|
get sourceExplore(): Explore;
|
|
461
461
|
get _sourceExploreName(): string;
|
|
462
|
-
get _sourceFilters():
|
|
462
|
+
get _sourceFilters(): FilterCondition[];
|
|
463
463
|
}
|
|
464
464
|
/**
|
|
465
465
|
* A URL reader which always throws an error when a URL's contents is requested.
|
|
@@ -578,7 +578,7 @@ export declare class Explore extends Entity implements Taggable {
|
|
|
578
578
|
get parentExplore(): Explore | undefined;
|
|
579
579
|
get sourceRelationship(): SourceRelationship;
|
|
580
580
|
hasParentExplore(): this is ExploreField;
|
|
581
|
-
get filters():
|
|
581
|
+
get filters(): FilterCondition[];
|
|
582
582
|
get limit(): number | undefined;
|
|
583
583
|
get structDef(): StructDef;
|
|
584
584
|
get queryTimezone(): string | undefined;
|
package/dist/malloy.js
CHANGED
|
@@ -1146,7 +1146,7 @@ class Explore extends Entity {
|
|
|
1146
1146
|
hasParentExplore() {
|
|
1147
1147
|
return this instanceof ExploreField;
|
|
1148
1148
|
}
|
|
1149
|
-
// TODO wrapper type for
|
|
1149
|
+
// TODO wrapper type for FilterCondition
|
|
1150
1150
|
get filters() {
|
|
1151
1151
|
var _a;
|
|
1152
1152
|
return ((_a = this.structDef.resultMetadata) === null || _a === void 0 ? void 0 : _a.filterList) || [];
|
package/dist/model/index.d.ts
CHANGED
package/dist/model/index.js
CHANGED
|
@@ -36,11 +36,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
36
36
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.indent = exports.QueryModel = exports.Segment = void 0;
|
|
39
|
+
exports.composeSQLExpr = exports.indent = exports.QueryModel = exports.Segment = void 0;
|
|
40
40
|
__exportStar(require("./malloy_types"), exports);
|
|
41
41
|
var malloy_query_1 = require("./malloy_query");
|
|
42
42
|
Object.defineProperty(exports, "Segment", { enumerable: true, get: function () { return malloy_query_1.Segment; } });
|
|
43
43
|
Object.defineProperty(exports, "QueryModel", { enumerable: true, get: function () { return malloy_query_1.QueryModel; } });
|
|
44
44
|
var utils_1 = require("./utils");
|
|
45
45
|
Object.defineProperty(exports, "indent", { enumerable: true, get: function () { return utils_1.indent; } });
|
|
46
|
+
Object.defineProperty(exports, "composeSQLExpr", { enumerable: true, get: function () { return utils_1.composeSQLExpr; } });
|
|
46
47
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Dialect, DialectFieldList } from '../dialect';
|
|
2
|
-
import {
|
|
2
|
+
import { AggregateFunctionType, Annotation, CompiledQuery, Expr, FieldDef, Filtered, FunctionOverloadDef, FunctionParameterDef, JoinRelationship, ModelDef, OrderBy, OutputFieldNode, Parameter, ParameterNode, PipeSegment, Query, QueryFieldDef, QuerySegment, ResultMetadataDef, ResultStructMetadataDef, SearchIndexResult, SegmentFieldDef, StructDef, StructRef, TurtleDef, FunctionOrderBy, Argument, AggregateExpr, FilterCondition, GenericSQLExpr, FieldnameNode, FunctionCallNode, UngroupNode, SourceReferenceNode, PickExpr, SpreadExpr, FilteredExpr } from './malloy_types';
|
|
3
3
|
import { Connection } from '../connection/types';
|
|
4
4
|
import { AndChain } from './utils';
|
|
5
5
|
import { QueryInfo } from '../dialect/dialect';
|
|
@@ -66,31 +66,30 @@ declare class QueryField extends QueryNode {
|
|
|
66
66
|
getJoinableParent(): QueryStruct;
|
|
67
67
|
caseGroup(groupSets: number[], s: string): string;
|
|
68
68
|
getFullOutputName(): string;
|
|
69
|
-
generateFieldFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr:
|
|
70
|
-
generateOutputFieldFragment(resultSet: FieldInstanceResult, _context: QueryStruct, frag:
|
|
71
|
-
|
|
69
|
+
generateFieldFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr: FieldnameNode, state: GenerateState): string;
|
|
70
|
+
generateOutputFieldFragment(resultSet: FieldInstanceResult, _context: QueryStruct, frag: OutputFieldNode, _state: GenerateState): string;
|
|
71
|
+
stringsFromSQLExpression(resultSet: FieldInstanceResult, context: QueryStruct, e: GenericSQLExpr, state: GenerateState): Generator<string, void, unknown>;
|
|
72
72
|
private getParameterMap;
|
|
73
73
|
private expandFunctionCall;
|
|
74
74
|
getFunctionOrderBy(resultSet: FieldInstanceResult, context: QueryStruct, state: GenerateState, orderBy: FunctionOrderBy[], args: Expr[], overload: FunctionOverloadDef): string | undefined;
|
|
75
75
|
generateAsymmetricStringAggExpression(resultSet: FieldInstanceResult, context: QueryStruct, value: Expr, separator: Expr | undefined, distinctKey: string, orderBy: FunctionOrderBy[] | undefined, dialectName: string, state: GenerateState): string;
|
|
76
76
|
getParamForArgIndex(params: FunctionParameterDef[], argIndex: number): FunctionParameterDef;
|
|
77
|
-
generateFunctionCallExpression(resultSet: FieldInstanceResult, context: QueryStruct, frag:
|
|
78
|
-
generateSpread(_resultSet: FieldInstanceResult, _context: QueryStruct, _frag:
|
|
79
|
-
generateParameterFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr:
|
|
80
|
-
generateFilterFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr:
|
|
77
|
+
generateFunctionCallExpression(resultSet: FieldInstanceResult, context: QueryStruct, frag: FunctionCallNode, state: GenerateState): string;
|
|
78
|
+
generateSpread(_resultSet: FieldInstanceResult, _context: QueryStruct, _frag: SpreadExpr, _state: GenerateState): string;
|
|
79
|
+
generateParameterFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr: ParameterNode, state: GenerateState): string;
|
|
80
|
+
generateFilterFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr: FilteredExpr, state: GenerateState): string;
|
|
81
81
|
generateDimFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr: Expr, state: GenerateState): string;
|
|
82
|
-
generateUngroupedFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr:
|
|
82
|
+
generateUngroupedFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr: UngroupNode, state: GenerateState): string;
|
|
83
83
|
generateDistinctKeyIfNecessary(resultSet: FieldInstanceResult, context: QueryStruct, structPath: string[] | undefined): string | undefined;
|
|
84
|
-
generateSumFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr:
|
|
85
|
-
generateSymmetricFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr:
|
|
86
|
-
generateAvgFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr:
|
|
87
|
-
generateCountFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr:
|
|
88
|
-
|
|
89
|
-
generateSqlString(resultSet: FieldInstanceResult, context: QueryStruct, expr: SqlStringFragment, state: GenerateState): string;
|
|
90
|
-
generateSourceReference(resultSet: FieldInstanceResult, context: QueryStruct, expr: SourceReferenceFragment): string;
|
|
84
|
+
generateSumFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr: AggregateExpr, state: GenerateState): string;
|
|
85
|
+
generateSymmetricFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr: AggregateExpr, state: GenerateState): string;
|
|
86
|
+
generateAvgFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr: AggregateExpr, state: GenerateState): string;
|
|
87
|
+
generateCountFragment(resultSet: FieldInstanceResult, context: QueryStruct, expr: AggregateExpr, state: GenerateState): string;
|
|
88
|
+
generateSourceReference(resultSet: FieldInstanceResult, context: QueryStruct, expr: SourceReferenceNode): string;
|
|
91
89
|
getAnalyticPartitions(resultStruct: FieldInstanceResult, extraPartitionFields?: string[]): string[];
|
|
92
90
|
generateAnalyticFragment(resultStruct: FieldInstanceResult, context: QueryStruct, expr: Expr, overload: FunctionOverloadDef, state: GenerateState, args: Expr[], partitionByFields?: string[], funcOrdering?: string): string;
|
|
93
|
-
|
|
91
|
+
generatePickSQL(pf: PickExpr): string;
|
|
92
|
+
exprToSQL(resultSet: FieldInstanceResult, context: QueryStruct, exprToTranslate: Expr, state?: GenerateState): string;
|
|
94
93
|
getExpr(): Expr;
|
|
95
94
|
generateExpression(resultSet: FieldInstanceResult): string;
|
|
96
95
|
}
|
|
@@ -98,7 +97,7 @@ declare class QueryAtomicField extends QueryField {
|
|
|
98
97
|
includeInWildcard(): boolean;
|
|
99
98
|
isCalculated(): boolean;
|
|
100
99
|
isAggregate(): boolean;
|
|
101
|
-
getFilterList():
|
|
100
|
+
getFilterList(): FilterCondition[];
|
|
102
101
|
hasExpression(): boolean;
|
|
103
102
|
}
|
|
104
103
|
declare class QueryFieldBoolean extends QueryAtomicField {
|
|
@@ -148,6 +147,12 @@ declare class FieldInstanceResult implements FieldInstance {
|
|
|
148
147
|
ungroupedSets: Map<string, UngroupSet>;
|
|
149
148
|
resultUsesUngrouped: boolean;
|
|
150
149
|
constructor(turtleDef: TurtleDef, parent: FieldInstanceResult | undefined);
|
|
150
|
+
/**
|
|
151
|
+
* Information about the query containing this result set. Invented
|
|
152
|
+
* to pass on timezone information, but maybe more things will
|
|
153
|
+
* eventually go in here.
|
|
154
|
+
* @returns QueryInfo
|
|
155
|
+
*/
|
|
151
156
|
getQueryInfo(): QueryInfo;
|
|
152
157
|
addField(as: string, field: QueryField, usage: FieldUsage): void;
|
|
153
158
|
parentGroupSet(): number;
|
|
@@ -249,7 +254,7 @@ declare class QueryQuery extends QueryField {
|
|
|
249
254
|
getSegmentFields(resultStruct: FieldInstanceResult): SegmentFieldDef[];
|
|
250
255
|
expandFields(resultStruct: FieldInstanceResult): void;
|
|
251
256
|
expandFilters(resultStruct: FieldInstanceResult): void;
|
|
252
|
-
generateSQLFilters(resultStruct: FieldInstanceResult, which: 'where' | 'having'
|
|
257
|
+
generateSQLFilters(resultStruct: FieldInstanceResult, which: 'where' | 'having'): AndChain;
|
|
253
258
|
prepare(_stageWriter: StageWriter | undefined): void;
|
|
254
259
|
getResultMetadata(fi: FieldInstance): ResultStructMetadataDef | ResultMetadataDef | undefined;
|
|
255
260
|
/** returns a fields and primary key of a struct for this query */
|