@malloydata/malloy 0.0.203-dev241021134413 → 0.0.203-dev241022191525
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 +11 -0
- package/dist/dialect/dialect.js +27 -0
- package/dist/dialect/duckdb/duckdb.js +2 -2
- package/dist/dialect/mysql/mysql.js +12 -15
- package/dist/dialect/pg_impl.js +7 -9
- package/dist/dialect/snowflake/snowflake.js +12 -17
- package/dist/dialect/standardsql/standardsql.js +13 -16
- package/dist/dialect/trino/trino.js +9 -12
- package/dist/lang/ast/expressions/expr-granular-time.js +1 -1
- package/dist/lang/ast/expressions/expr-record-literal.d.ts +1 -1
- package/dist/lang/ast/expressions/expr-record-literal.js +28 -25
- package/dist/lang/ast/expressions/expr-time-extract.js +3 -3
- package/dist/lang/ast/expressions/expr-time.js +2 -2
- package/dist/lang/ast/expressions/for-range.js +1 -1
- package/dist/lang/ast/expressions/time-literal.js +1 -1
- package/dist/lang/ast/query-builders/index-builder.d.ts +1 -0
- package/dist/lang/ast/query-builders/index-builder.js +4 -0
- package/dist/lang/ast/query-builders/reduce-builder.d.ts +1 -0
- package/dist/lang/ast/query-builders/reduce-builder.js +4 -0
- package/dist/lang/ast/source-properties/join.js +1 -0
- package/dist/lang/ast/time-utils.d.ts +1 -3
- package/dist/lang/ast/time-utils.js +24 -34
- package/dist/lang/ast/types/expression-def.js +2 -2
- package/dist/lang/ast/types/query-builder.d.ts +1 -0
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +49 -14
- package/dist/lang/lib/Malloy/MalloyParser.js +1784 -1538
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +48 -11
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +30 -7
- package/dist/lang/malloy-to-ast.d.ts +4 -1
- package/dist/lang/malloy-to-ast.js +21 -32
- package/dist/lang/test/query.spec.js +7 -2
- package/dist/lang/test/test-translator.js +1 -1
- package/dist/model/malloy_query.d.ts +1 -0
- package/dist/model/malloy_query.js +15 -1
- package/dist/model/malloy_types.d.ts +43 -14
- package/dist/model/malloy_types.js +83 -2
- package/package.json +1 -1
|
@@ -24,6 +24,8 @@ import { TableMethodContext } from "./MalloyParser";
|
|
|
24
24
|
import { NestDefContext } from "./MalloyParser";
|
|
25
25
|
import { ExprFieldPathContext } from "./MalloyParser";
|
|
26
26
|
import { ExprLiteralContext } from "./MalloyParser";
|
|
27
|
+
import { ExprArrayLiteralContext } from "./MalloyParser";
|
|
28
|
+
import { ExprLiteralRecordContext } from "./MalloyParser";
|
|
27
29
|
import { ExprFieldPropsContext } from "./MalloyParser";
|
|
28
30
|
import { ExprDurationContext } from "./MalloyParser";
|
|
29
31
|
import { ExprTimeTruncContext } from "./MalloyParser";
|
|
@@ -215,10 +217,11 @@ import { CollectionMemberContext } from "./MalloyParser";
|
|
|
215
217
|
import { FieldPathContext } from "./MalloyParser";
|
|
216
218
|
import { JoinNameContext } from "./MalloyParser";
|
|
217
219
|
import { FieldNameContext } from "./MalloyParser";
|
|
218
|
-
import { JustExprContext } from "./MalloyParser";
|
|
219
220
|
import { SqlExploreNameRefContext } from "./MalloyParser";
|
|
220
221
|
import { NameSQLBlockContext } from "./MalloyParser";
|
|
221
222
|
import { ConnectionNameContext } from "./MalloyParser";
|
|
223
|
+
import { DebugExprContext } from "./MalloyParser";
|
|
224
|
+
import { DebugPartialContext } from "./MalloyParser";
|
|
222
225
|
import { ExperimentalStatementForTestingContext } from "./MalloyParser";
|
|
223
226
|
/**
|
|
224
227
|
* This interface defines a complete listener for a parse tree produced by
|
|
@@ -525,6 +528,30 @@ export interface MalloyParserListener extends ParseTreeListener {
|
|
|
525
528
|
* @param ctx the parse tree
|
|
526
529
|
*/
|
|
527
530
|
exitExprLiteral?: (ctx: ExprLiteralContext) => void;
|
|
531
|
+
/**
|
|
532
|
+
* Enter a parse tree produced by the `exprArrayLiteral`
|
|
533
|
+
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
534
|
+
* @param ctx the parse tree
|
|
535
|
+
*/
|
|
536
|
+
enterExprArrayLiteral?: (ctx: ExprArrayLiteralContext) => void;
|
|
537
|
+
/**
|
|
538
|
+
* Exit a parse tree produced by the `exprArrayLiteral`
|
|
539
|
+
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
540
|
+
* @param ctx the parse tree
|
|
541
|
+
*/
|
|
542
|
+
exitExprArrayLiteral?: (ctx: ExprArrayLiteralContext) => void;
|
|
543
|
+
/**
|
|
544
|
+
* Enter a parse tree produced by the `exprLiteralRecord`
|
|
545
|
+
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
546
|
+
* @param ctx the parse tree
|
|
547
|
+
*/
|
|
548
|
+
enterExprLiteralRecord?: (ctx: ExprLiteralRecordContext) => void;
|
|
549
|
+
/**
|
|
550
|
+
* Exit a parse tree produced by the `exprLiteralRecord`
|
|
551
|
+
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
552
|
+
* @param ctx the parse tree
|
|
553
|
+
*/
|
|
554
|
+
exitExprLiteralRecord?: (ctx: ExprLiteralRecordContext) => void;
|
|
528
555
|
/**
|
|
529
556
|
* Enter a parse tree produced by the `exprFieldProps`
|
|
530
557
|
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
@@ -2549,16 +2576,6 @@ export interface MalloyParserListener extends ParseTreeListener {
|
|
|
2549
2576
|
* @param ctx the parse tree
|
|
2550
2577
|
*/
|
|
2551
2578
|
exitFieldName?: (ctx: FieldNameContext) => void;
|
|
2552
|
-
/**
|
|
2553
|
-
* Enter a parse tree produced by `MalloyParser.justExpr`.
|
|
2554
|
-
* @param ctx the parse tree
|
|
2555
|
-
*/
|
|
2556
|
-
enterJustExpr?: (ctx: JustExprContext) => void;
|
|
2557
|
-
/**
|
|
2558
|
-
* Exit a parse tree produced by `MalloyParser.justExpr`.
|
|
2559
|
-
* @param ctx the parse tree
|
|
2560
|
-
*/
|
|
2561
|
-
exitJustExpr?: (ctx: JustExprContext) => void;
|
|
2562
2579
|
/**
|
|
2563
2580
|
* Enter a parse tree produced by `MalloyParser.sqlExploreNameRef`.
|
|
2564
2581
|
* @param ctx the parse tree
|
|
@@ -2589,6 +2606,26 @@ export interface MalloyParserListener extends ParseTreeListener {
|
|
|
2589
2606
|
* @param ctx the parse tree
|
|
2590
2607
|
*/
|
|
2591
2608
|
exitConnectionName?: (ctx: ConnectionNameContext) => void;
|
|
2609
|
+
/**
|
|
2610
|
+
* Enter a parse tree produced by `MalloyParser.debugExpr`.
|
|
2611
|
+
* @param ctx the parse tree
|
|
2612
|
+
*/
|
|
2613
|
+
enterDebugExpr?: (ctx: DebugExprContext) => void;
|
|
2614
|
+
/**
|
|
2615
|
+
* Exit a parse tree produced by `MalloyParser.debugExpr`.
|
|
2616
|
+
* @param ctx the parse tree
|
|
2617
|
+
*/
|
|
2618
|
+
exitDebugExpr?: (ctx: DebugExprContext) => void;
|
|
2619
|
+
/**
|
|
2620
|
+
* Enter a parse tree produced by `MalloyParser.debugPartial`.
|
|
2621
|
+
* @param ctx the parse tree
|
|
2622
|
+
*/
|
|
2623
|
+
enterDebugPartial?: (ctx: DebugPartialContext) => void;
|
|
2624
|
+
/**
|
|
2625
|
+
* Exit a parse tree produced by `MalloyParser.debugPartial`.
|
|
2626
|
+
* @param ctx the parse tree
|
|
2627
|
+
*/
|
|
2628
|
+
exitDebugPartial?: (ctx: DebugPartialContext) => void;
|
|
2592
2629
|
/**
|
|
2593
2630
|
* Enter a parse tree produced by `MalloyParser.experimentalStatementForTesting`.
|
|
2594
2631
|
* @param ctx the parse tree
|
|
@@ -24,6 +24,8 @@ import { TableMethodContext } from "./MalloyParser";
|
|
|
24
24
|
import { NestDefContext } from "./MalloyParser";
|
|
25
25
|
import { ExprFieldPathContext } from "./MalloyParser";
|
|
26
26
|
import { ExprLiteralContext } from "./MalloyParser";
|
|
27
|
+
import { ExprArrayLiteralContext } from "./MalloyParser";
|
|
28
|
+
import { ExprLiteralRecordContext } from "./MalloyParser";
|
|
27
29
|
import { ExprFieldPropsContext } from "./MalloyParser";
|
|
28
30
|
import { ExprDurationContext } from "./MalloyParser";
|
|
29
31
|
import { ExprTimeTruncContext } from "./MalloyParser";
|
|
@@ -215,10 +217,11 @@ import { CollectionMemberContext } from "./MalloyParser";
|
|
|
215
217
|
import { FieldPathContext } from "./MalloyParser";
|
|
216
218
|
import { JoinNameContext } from "./MalloyParser";
|
|
217
219
|
import { FieldNameContext } from "./MalloyParser";
|
|
218
|
-
import { JustExprContext } from "./MalloyParser";
|
|
219
220
|
import { SqlExploreNameRefContext } from "./MalloyParser";
|
|
220
221
|
import { NameSQLBlockContext } from "./MalloyParser";
|
|
221
222
|
import { ConnectionNameContext } from "./MalloyParser";
|
|
223
|
+
import { DebugExprContext } from "./MalloyParser";
|
|
224
|
+
import { DebugPartialContext } from "./MalloyParser";
|
|
222
225
|
import { ExperimentalStatementForTestingContext } from "./MalloyParser";
|
|
223
226
|
/**
|
|
224
227
|
* This interface defines a complete generic visitor for a parse tree produced
|
|
@@ -403,6 +406,20 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
|
|
|
403
406
|
* @return the visitor result
|
|
404
407
|
*/
|
|
405
408
|
visitExprLiteral?: (ctx: ExprLiteralContext) => Result;
|
|
409
|
+
/**
|
|
410
|
+
* Visit a parse tree produced by the `exprArrayLiteral`
|
|
411
|
+
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
412
|
+
* @param ctx the parse tree
|
|
413
|
+
* @return the visitor result
|
|
414
|
+
*/
|
|
415
|
+
visitExprArrayLiteral?: (ctx: ExprArrayLiteralContext) => Result;
|
|
416
|
+
/**
|
|
417
|
+
* Visit a parse tree produced by the `exprLiteralRecord`
|
|
418
|
+
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
419
|
+
* @param ctx the parse tree
|
|
420
|
+
* @return the visitor result
|
|
421
|
+
*/
|
|
422
|
+
visitExprLiteralRecord?: (ctx: ExprLiteralRecordContext) => Result;
|
|
406
423
|
/**
|
|
407
424
|
* Visit a parse tree produced by the `exprFieldProps`
|
|
408
425
|
* labeled alternative in `MalloyParser.fieldExpr`.
|
|
@@ -1606,12 +1623,6 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
|
|
|
1606
1623
|
* @return the visitor result
|
|
1607
1624
|
*/
|
|
1608
1625
|
visitFieldName?: (ctx: FieldNameContext) => Result;
|
|
1609
|
-
/**
|
|
1610
|
-
* Visit a parse tree produced by `MalloyParser.justExpr`.
|
|
1611
|
-
* @param ctx the parse tree
|
|
1612
|
-
* @return the visitor result
|
|
1613
|
-
*/
|
|
1614
|
-
visitJustExpr?: (ctx: JustExprContext) => Result;
|
|
1615
1626
|
/**
|
|
1616
1627
|
* Visit a parse tree produced by `MalloyParser.sqlExploreNameRef`.
|
|
1617
1628
|
* @param ctx the parse tree
|
|
@@ -1630,6 +1641,18 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
|
|
|
1630
1641
|
* @return the visitor result
|
|
1631
1642
|
*/
|
|
1632
1643
|
visitConnectionName?: (ctx: ConnectionNameContext) => Result;
|
|
1644
|
+
/**
|
|
1645
|
+
* Visit a parse tree produced by `MalloyParser.debugExpr`.
|
|
1646
|
+
* @param ctx the parse tree
|
|
1647
|
+
* @return the visitor result
|
|
1648
|
+
*/
|
|
1649
|
+
visitDebugExpr?: (ctx: DebugExprContext) => Result;
|
|
1650
|
+
/**
|
|
1651
|
+
* Visit a parse tree produced by `MalloyParser.debugPartial`.
|
|
1652
|
+
* @param ctx the parse tree
|
|
1653
|
+
* @return the visitor result
|
|
1654
|
+
*/
|
|
1655
|
+
visitDebugPartial?: (ctx: DebugPartialContext) => Result;
|
|
1633
1656
|
/**
|
|
1634
1657
|
* Visit a parse tree produced by `MalloyParser.experimentalStatementForTesting`.
|
|
1635
1658
|
* @param ctx the parse tree
|
|
@@ -200,7 +200,7 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
|
|
|
200
200
|
visitLiteralQuarter(pcx: parse.LiteralQuarterContext): ast.ExpressionDef;
|
|
201
201
|
visitLiteralYear(pcx: parse.LiteralYearContext): ast.ExpressionDef;
|
|
202
202
|
visitImportStatement(pcx: parse.ImportStatementContext): ast.ImportStatement;
|
|
203
|
-
|
|
203
|
+
visitDebugExpr(pcx: parse.DebugExprContext): ast.ExpressionDef;
|
|
204
204
|
visitSampleStatement(pcx: parse.SampleStatementContext): ast.SampleProperty;
|
|
205
205
|
visitDocAnnotations(pcx: parse.DocAnnotationsContext): ast.ModelAnnotation;
|
|
206
206
|
visitIgnoredObjectAnnotations(pcx: parse.IgnoredObjectAnnotationsContext): IgnoredElement;
|
|
@@ -224,6 +224,9 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
|
|
|
224
224
|
visitSQTable(pcx: parse.SQTableContext): ast.SQSource | ErrorNode;
|
|
225
225
|
visitSQSQL(pcx: parse.SQSQLContext): ast.SQSource;
|
|
226
226
|
visitExperimentalStatementForTesting(pcx: parse.ExperimentalStatementForTestingContext): ast.ExperimentalExperiment;
|
|
227
|
+
visitRecordRef(pcx: parse.RecordRefContext): ast.RecordElement;
|
|
228
|
+
visitRecordExpr(pcx: parse.RecordExprContext): ast.RecordElement;
|
|
229
|
+
visitExprLiteralRecord(pcx: parse.ExprLiteralRecordContext): ast.RecordLiteral;
|
|
227
230
|
visitExprWarnLike(pcx: parse.ExprWarnLikeContext): ast.ExprCompare;
|
|
228
231
|
visitExprWarnNullCmp(pcx: parse.ExprWarnNullCmpContext): ast.ExprCompare;
|
|
229
232
|
visitExprWarnIn(pcx: parse.ExprWarnInContext): ast.ExprLegacyIn;
|
|
@@ -419,9 +419,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
419
419
|
return { joinAs, joinFrom: new ast.SQReference(joinAs), notes: [] };
|
|
420
420
|
}
|
|
421
421
|
visitQueryJoinStatement(pcx) {
|
|
422
|
-
|
|
423
|
-
this.m4advisory(pcx, 'join-statement-in-view', 'Joins in queries are deprecated, move into an `extend:` block.');
|
|
424
|
-
return result;
|
|
422
|
+
return this.astAt(this.visit(pcx.joinStatement()), pcx);
|
|
425
423
|
}
|
|
426
424
|
visitJoinOn(pcx) {
|
|
427
425
|
var _a;
|
|
@@ -1203,7 +1201,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
1203
1201
|
}
|
|
1204
1202
|
return importStmt;
|
|
1205
1203
|
}
|
|
1206
|
-
|
|
1204
|
+
visitDebugExpr(pcx) {
|
|
1207
1205
|
return this.getFieldExpr(pcx.fieldExpr());
|
|
1208
1206
|
}
|
|
1209
1207
|
visitSampleStatement(pcx) {
|
|
@@ -1336,34 +1334,25 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
1336
1334
|
this.inExperiment('compilerTestExperimentParse', pcx);
|
|
1337
1335
|
return this.astAt(new ast.ExperimentalExperiment('compilerTestExperimentTranslate'), pcx);
|
|
1338
1336
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
// }
|
|
1359
|
-
// visitExprLiteralRecord(pcx: parse.ExprLiteralRecordContext) {
|
|
1360
|
-
// const els = this.only<ast.RecordElement>(
|
|
1361
|
-
// pcx.recordElement().map(elCx => this.astAt(this.visit(elCx), elCx)),
|
|
1362
|
-
// visited => visited instanceof ast.RecordElement && visited,
|
|
1363
|
-
// 'a key value pair'
|
|
1364
|
-
// );
|
|
1365
|
-
// return new ast.RecordLiteral(els);
|
|
1366
|
-
// }
|
|
1337
|
+
visitRecordRef(pcx) {
|
|
1338
|
+
const pathCx = pcx.fieldPath();
|
|
1339
|
+
const tailEl = pathCx.fieldName().at(-1);
|
|
1340
|
+
if (tailEl) {
|
|
1341
|
+
const elementKey = (0, parse_utils_1.getId)(tailEl);
|
|
1342
|
+
const idRef = new ast.ExprIdReference(this.getFieldPath(pathCx, ast.ExpressionFieldReference));
|
|
1343
|
+
return new ast.RecordElement(elementKey, idRef);
|
|
1344
|
+
}
|
|
1345
|
+
throw this.internalError(pathCx, 'IMPOSSIBLY A PATH CONTAINED ZERO ELEMENTS');
|
|
1346
|
+
}
|
|
1347
|
+
visitRecordExpr(pcx) {
|
|
1348
|
+
const elementKey = (0, parse_utils_1.getId)(pcx.recordKey());
|
|
1349
|
+
const elementVal = this.getFieldExpr(pcx.fieldExpr());
|
|
1350
|
+
return new ast.RecordElement(elementKey, elementVal);
|
|
1351
|
+
}
|
|
1352
|
+
visitExprLiteralRecord(pcx) {
|
|
1353
|
+
const els = this.only(pcx.recordElement().map(elCx => this.astAt(this.visit(elCx), elCx)), visited => visited instanceof ast.RecordElement && visited, 'a key value pair');
|
|
1354
|
+
return new ast.RecordLiteral(els);
|
|
1355
|
+
}
|
|
1367
1356
|
visitExprWarnLike(pcx) {
|
|
1368
1357
|
let op = '~';
|
|
1369
1358
|
const left = pcx.fieldExpr(0);
|
|
@@ -923,8 +923,13 @@ describe('query:', () => {
|
|
|
923
923
|
source: a2 is a extend { ${'declare: x is 1'} }`).toLog((0, test_translator_1.warningMessage)('`declare:` is deprecated; use `dimension:` or `measure:` inside a source or `extend:` block'));
|
|
924
924
|
});
|
|
925
925
|
test('joins in query', () => {
|
|
926
|
-
expect((0, test_translator_1.markSource)
|
|
927
|
-
run: a -> {
|
|
926
|
+
expect((0, test_translator_1.markSource) `
|
|
927
|
+
run: a -> {
|
|
928
|
+
join_one: b on true
|
|
929
|
+
join_many: c is b on true
|
|
930
|
+
join_cross: d is b on true
|
|
931
|
+
group_by: b.astr
|
|
932
|
+
}`).toTranslate();
|
|
928
933
|
});
|
|
929
934
|
});
|
|
930
935
|
test('refine query with extended source', () => {
|
|
@@ -387,7 +387,7 @@ exports.TestTranslator = TestTranslator;
|
|
|
387
387
|
TestTranslator.inspectCompile = false;
|
|
388
388
|
class BetaExpression extends TestTranslator {
|
|
389
389
|
constructor(src) {
|
|
390
|
-
super(src, null, null, '
|
|
390
|
+
super(src, null, null, 'debugExpr');
|
|
391
391
|
}
|
|
392
392
|
testFS() {
|
|
393
393
|
const aStruct = this.internalModel.contents['ab'];
|
|
@@ -264,6 +264,7 @@ declare class QueryQuery extends QueryField {
|
|
|
264
264
|
expandFilters(resultStruct: FieldInstanceResult): void;
|
|
265
265
|
generateSQLFilters(resultStruct: FieldInstanceResult, which: 'where' | 'having'): AndChain;
|
|
266
266
|
prepare(_stageWriter: StageWriter | undefined): void;
|
|
267
|
+
addAlwaysJoins(rootResult: FieldInstanceResultRoot): void;
|
|
267
268
|
getResultMetadata(fi: FieldInstance): ResultStructMetadataDef | ResultMetadataDef | undefined;
|
|
268
269
|
/** returns a fields and primary key of a struct for this query */
|
|
269
270
|
getResultStructDef(resultStruct?: FieldInstanceResult, isRoot?: boolean): SourceDef;
|
|
@@ -965,7 +965,7 @@ class QueryFieldDate extends QueryAtomicField {
|
|
|
965
965
|
else {
|
|
966
966
|
const truncated = {
|
|
967
967
|
node: 'trunc',
|
|
968
|
-
e:
|
|
968
|
+
e: (0, malloy_types_1.mkTemporal)(this.getExpr(), 'date'),
|
|
969
969
|
units: fd.timeframe,
|
|
970
970
|
};
|
|
971
971
|
return this.exprToSQL(resultSet, this.parent, truncated);
|
|
@@ -1802,10 +1802,24 @@ class QueryQuery extends QueryField {
|
|
|
1802
1802
|
this.expandFields(this.rootResult);
|
|
1803
1803
|
this.rootResult.addStructToJoin(this.parent, this, undefined, []);
|
|
1804
1804
|
this.rootResult.findJoins(this);
|
|
1805
|
+
this.addAlwaysJoins(this.rootResult);
|
|
1805
1806
|
this.rootResult.calculateSymmetricAggregates();
|
|
1806
1807
|
this.prepared = true;
|
|
1807
1808
|
}
|
|
1808
1809
|
}
|
|
1810
|
+
addAlwaysJoins(rootResult) {
|
|
1811
|
+
var _a;
|
|
1812
|
+
const stage = this.fieldDef.pipeline[0];
|
|
1813
|
+
if (stage.type !== 'raw') {
|
|
1814
|
+
const alwaysJoins = (_a = stage.alwaysJoins) !== null && _a !== void 0 ? _a : [];
|
|
1815
|
+
for (const joinName of alwaysJoins) {
|
|
1816
|
+
const qs = this.parent.getChildByName(joinName);
|
|
1817
|
+
if (qs instanceof QueryStruct) {
|
|
1818
|
+
rootResult.addStructToJoin(qs, this, undefined, []);
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1809
1823
|
// get the source fieldname and filters associated with the field (so we can drill later)
|
|
1810
1824
|
getResultMetadata(fi) {
|
|
1811
1825
|
if (fi instanceof FieldInstanceField) {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export interface ExprLeaf {
|
|
10
10
|
node: string;
|
|
11
|
-
|
|
11
|
+
typeDef?: AtomicTypeDef;
|
|
12
12
|
sql?: string;
|
|
13
13
|
}
|
|
14
14
|
export interface ExprE extends ExprLeaf {
|
|
@@ -24,11 +24,11 @@ export type AnyExpr = ExprE | ExprOptionalE | ExprWithKids | ExprLeaf;
|
|
|
24
24
|
export declare function exprHasKids(e: AnyExpr): e is ExprWithKids;
|
|
25
25
|
export declare function exprHasE(e: AnyExpr): e is ExprE;
|
|
26
26
|
export declare function exprIsLeaf(e: AnyExpr): boolean;
|
|
27
|
-
export type Expr = BinaryExpr | UnaryExpr | FunctionCallNode | OutputFieldNode | FilterCondition | FilteredExpr | AggregateExpr | EmptyExpr | UngroupNode | FunctionParameterNode | SpreadExpr | AggregateOrderByNode | AggregateLimitNode | FieldnameNode | SourceReferenceNode | ParameterNode | NowNode | MeasureTimeExpr | TimeDeltaExpr | TimeTruncExpr |
|
|
28
|
-
interface
|
|
29
|
-
|
|
27
|
+
export type Expr = BinaryExpr | UnaryExpr | FunctionCallNode | OutputFieldNode | FilterCondition | FilteredExpr | AggregateExpr | EmptyExpr | UngroupNode | FunctionParameterNode | SpreadExpr | AggregateOrderByNode | AggregateLimitNode | FieldnameNode | SourceReferenceNode | ParameterNode | NowNode | MeasureTimeExpr | TimeExtractExpr | TimeDeltaExpr | TimeTruncExpr | TimeLiteralNode | TypecastExpr | RegexMatchExpr | RegexLiteralNode | StringLiteralNode | NumberLiteralNode | BooleanLiteralNode | RecordLiteralNode | ArrayLiteralNode | FunctionOrderBy | GenericSQLExpr | NullNode | CaseExpr | InCompareExpr | ErrorNode;
|
|
28
|
+
interface HasTypeDef {
|
|
29
|
+
typeDef: AtomicTypeDef;
|
|
30
30
|
}
|
|
31
|
-
export type TypedExpr = Expr &
|
|
31
|
+
export type TypedExpr = Expr & HasTypeDef;
|
|
32
32
|
export type BinaryOperator = '+' | '-' | '*' | '%' | '/' | 'and' | 'or' | '=' | '!=' | '>' | '<' | '>=' | '<=' | 'coalesce' | 'like' | '!like';
|
|
33
33
|
export interface BinaryExpr extends ExprWithKids {
|
|
34
34
|
node: BinaryOperator;
|
|
@@ -118,9 +118,10 @@ export interface NowNode extends ExprLeaf {
|
|
|
118
118
|
node: 'now';
|
|
119
119
|
}
|
|
120
120
|
interface HasTimeValue {
|
|
121
|
-
|
|
121
|
+
typeDef: TemporalTypeDef;
|
|
122
122
|
}
|
|
123
123
|
type TimeExpr = Expr & HasTimeValue;
|
|
124
|
+
export declare function mkTemporal(e: Expr, timeType: TemporalTypeDef | TemporalFieldType): TimeExpr;
|
|
124
125
|
export interface MeasureTimeExpr extends ExprWithKids {
|
|
125
126
|
node: 'timeDiff';
|
|
126
127
|
units: TimestampUnit;
|
|
@@ -148,15 +149,22 @@ export interface TimeExtractExpr extends ExprE {
|
|
|
148
149
|
e: TimeExpr;
|
|
149
150
|
units: ExtractUnit;
|
|
150
151
|
}
|
|
151
|
-
export interface
|
|
152
|
+
export interface MalloyTypecastExpr extends ExprE {
|
|
152
153
|
node: 'cast';
|
|
153
154
|
safe: boolean;
|
|
154
155
|
e: Expr;
|
|
155
|
-
dstType:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
dstType: LeafAtomicTypeDef;
|
|
157
|
+
srcType?: LeafAtomicTypeDef;
|
|
158
|
+
}
|
|
159
|
+
interface RawTypeCastExpr extends ExprE {
|
|
160
|
+
node: 'cast';
|
|
161
|
+
safe: boolean;
|
|
162
|
+
e: Expr;
|
|
163
|
+
dstSQLType: string;
|
|
164
|
+
srcType?: LeafAtomicTypeDef;
|
|
159
165
|
}
|
|
166
|
+
export type TypecastExpr = MalloyTypecastExpr | RawTypeCastExpr;
|
|
167
|
+
export declare function isRawCast(te: TypecastExpr): te is RawTypeCastExpr;
|
|
160
168
|
export interface RegexMatchExpr extends ExprWithKids {
|
|
161
169
|
node: 'regexpMatch';
|
|
162
170
|
kids: {
|
|
@@ -167,7 +175,7 @@ export interface RegexMatchExpr extends ExprWithKids {
|
|
|
167
175
|
export interface TimeLiteralNode extends ExprLeaf {
|
|
168
176
|
node: 'timeLiteral';
|
|
169
177
|
literal: string;
|
|
170
|
-
|
|
178
|
+
typeDef: TemporalTypeDef;
|
|
171
179
|
timezone?: string;
|
|
172
180
|
}
|
|
173
181
|
export interface StringLiteralNode extends ExprLeaf {
|
|
@@ -194,7 +202,7 @@ export interface ArrayLiteralNode extends ExprWithKids {
|
|
|
194
202
|
kids: {
|
|
195
203
|
values: Expr[];
|
|
196
204
|
};
|
|
197
|
-
|
|
205
|
+
typeDef: ArrayTypeDef;
|
|
198
206
|
}
|
|
199
207
|
export interface ErrorNode extends ExprLeaf {
|
|
200
208
|
node: 'error';
|
|
@@ -531,6 +539,7 @@ export interface IndexSegment extends Filtered {
|
|
|
531
539
|
limit?: number;
|
|
532
540
|
weightMeasure?: string;
|
|
533
541
|
sample?: Sampling;
|
|
542
|
+
alwaysJoins?: string[];
|
|
534
543
|
}
|
|
535
544
|
export declare function isIndexSegment(pe: PipeSegment): pe is IndexSegment;
|
|
536
545
|
export interface QuerySegment extends Filtered {
|
|
@@ -541,6 +550,7 @@ export interface QuerySegment extends Filtered {
|
|
|
541
550
|
by?: By;
|
|
542
551
|
orderBy?: OrderBy[];
|
|
543
552
|
queryTimezone?: string;
|
|
553
|
+
alwaysJoins?: string[];
|
|
544
554
|
}
|
|
545
555
|
export interface TurtleDef extends NamedObject, Pipeline {
|
|
546
556
|
type: 'turtle';
|
|
@@ -658,7 +668,7 @@ export type LeafAtomicTypeDef = StringTypeDef | TemporalTypeDef | NumberTypeDef
|
|
|
658
668
|
export type AtomicTypeDef = LeafAtomicTypeDef | ArrayTypeDef | RecordTypeDef;
|
|
659
669
|
export type LeafAtomicDef = LeafAtomicTypeDef & FieldAtomicBase;
|
|
660
670
|
export type AtomicFieldDef = AtomicTypeDef & FieldAtomicBase;
|
|
661
|
-
export declare function isLeafAtomic(fd: FieldDef | QueryFieldDef): fd is LeafAtomicDef;
|
|
671
|
+
export declare function isLeafAtomic(fd: FieldDef | QueryFieldDef | AtomicTypeDef): fd is LeafAtomicDef;
|
|
662
672
|
export type FieldDef = AtomicFieldDef | JoinFieldDef | TurtleDef;
|
|
663
673
|
export interface RefToField {
|
|
664
674
|
type: 'fieldref';
|
|
@@ -779,4 +789,23 @@ export interface PrepareResultOptions {
|
|
|
779
789
|
replaceMaterializedReferences?: boolean;
|
|
780
790
|
materializedTablePrefix?: string;
|
|
781
791
|
}
|
|
792
|
+
type UTD = AtomicTypeDef | undefined;
|
|
793
|
+
export declare const TD: {
|
|
794
|
+
isA: (td: UTD, ...tList: string[]) => boolean | undefined;
|
|
795
|
+
notA: (td: UTD, ...tList: string[]) => boolean | undefined;
|
|
796
|
+
isString: (td: UTD) => td is StringTypeDef;
|
|
797
|
+
isNumber: (td: UTD) => td is NumberTypeDef;
|
|
798
|
+
isBoolean: (td: UTD) => td is BooleanTypeDef;
|
|
799
|
+
isJSON: (td: UTD) => td is JSONTypeDef;
|
|
800
|
+
isSQL: (td: UTD) => td is NativeUnsupportedTypeDef;
|
|
801
|
+
isDate: (td: UTD) => td is DateTypeDef;
|
|
802
|
+
isTimestamp: (td: UTD) => td is TimestampTypeDef;
|
|
803
|
+
isError: (td: UTD) => td is ErrorTypeDef;
|
|
804
|
+
eq: (x: UTD, y: UTD) => boolean;
|
|
805
|
+
timestamp: () => TimestampTypeDef;
|
|
806
|
+
date: () => DateTypeDef;
|
|
807
|
+
string: () => StringTypeDef;
|
|
808
|
+
number: () => NumberTypeDef;
|
|
809
|
+
error: () => ErrorTypeDef;
|
|
810
|
+
};
|
|
782
811
|
export {};
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.
|
|
26
|
-
exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.getAtomicFields = exports.isAtomic = exports.isTurtleDef = exports.getIdentifier = exports.isLeafAtomic = void 0;
|
|
25
|
+
exports.isScalarArray = exports.isBaseTable = exports.isSourceDef = exports.sourceBase = exports.isSegmentSQL = exports.isIndexSegment = exports.isRawSegment = exports.isSamplingEnable = exports.isSamplingPercent = exports.isSamplingRows = exports.isQuerySegment = exports.isProjectSegment = exports.isPartialSegment = exports.isReduceSegment = exports.structHasErrors = exports.segmentHasErrors = exports.refIsStructDef = exports.isByExpression = exports.isByName = exports.ValueType = exports.isExtractUnit = exports.isTimestampUnit = exports.isDateUnit = exports.isJoinedSource = exports.isJoined = exports.isJoinable = exports.isMatrixOperation = exports.isRepeatedRecord = exports.arrayEachFields = exports.fieldIsIntrinsic = exports.isCastType = exports.isAtomicFieldType = exports.isTemporalField = exports.hasExpression = exports.maxOfExpressionTypes = exports.maxExpressionType = exports.isExpressionTypeLEQ = exports.expressionIsAnalytic = exports.expressionIsCalculation = exports.expressionInvolvesAggregate = exports.expressionIsUngroupedAggregate = exports.expressionIsAggregate = exports.expressionIsScalar = exports.paramHasValue = exports.isRawCast = exports.mkTemporal = exports.isAsymmetricExpr = exports.exprIsLeaf = exports.exprHasE = exports.exprHasKids = void 0;
|
|
26
|
+
exports.TD = exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.getAtomicFields = exports.isAtomic = exports.isTurtleDef = exports.getIdentifier = exports.isLeafAtomic = exports.mergeEvalSpaces = exports.isLiteral = void 0;
|
|
27
27
|
function exprHasKids(e) {
|
|
28
28
|
return 'kids' in e;
|
|
29
29
|
}
|
|
@@ -41,6 +41,33 @@ function isAsymmetricExpr(f) {
|
|
|
41
41
|
['sum', 'avg', 'count', 'distinct'].includes(f.function));
|
|
42
42
|
}
|
|
43
43
|
exports.isAsymmetricExpr = isAsymmetricExpr;
|
|
44
|
+
/**
|
|
45
|
+
* Return true if this node can be turned into a temporal node by simply
|
|
46
|
+
* appending a time type to the typedef. The type systsem makes this hard
|
|
47
|
+
* because while it is theoretically possible to pass an array typed Expr,
|
|
48
|
+
* the reality is that type checking will stop this from ever happening.
|
|
49
|
+
*
|
|
50
|
+
* The list here is the list of Expr types which have a fixed typeDef,
|
|
51
|
+
* which are not of time type.
|
|
52
|
+
*
|
|
53
|
+
* If !canMakeTemporal then mkTemporal is going to return something
|
|
54
|
+
* which will probably error at SQL generation time, so don't do that.
|
|
55
|
+
*/
|
|
56
|
+
function canMakeTemporal(e) {
|
|
57
|
+
return e.node !== 'arrayLiteral' && e.node !== 'recordLiteral';
|
|
58
|
+
}
|
|
59
|
+
function mkTemporal(e, timeType) {
|
|
60
|
+
const ttd = typeof timeType === 'string' ? { type: timeType } : timeType;
|
|
61
|
+
if (canMakeTemporal(e)) {
|
|
62
|
+
return { ...e, typeDef: { ...ttd } };
|
|
63
|
+
}
|
|
64
|
+
return e;
|
|
65
|
+
}
|
|
66
|
+
exports.mkTemporal = mkTemporal;
|
|
67
|
+
function isRawCast(te) {
|
|
68
|
+
return 'dstSQLType' in te;
|
|
69
|
+
}
|
|
70
|
+
exports.isRawCast = isRawCast;
|
|
44
71
|
function paramHasValue(p) {
|
|
45
72
|
return p.value !== null;
|
|
46
73
|
}
|
|
@@ -369,5 +396,59 @@ function isValueDate(value, field) {
|
|
|
369
396
|
return field.type === 'date';
|
|
370
397
|
}
|
|
371
398
|
exports.isValueDate = isValueDate;
|
|
399
|
+
exports.TD = {
|
|
400
|
+
isA: (td, ...tList) => td && tList.includes(td.type),
|
|
401
|
+
notA: (td, ...tList) => td && !tList.includes(td.type),
|
|
402
|
+
isString: (td) => td !== undefined && td.type === 'string',
|
|
403
|
+
isNumber: (td) => td !== undefined && td.type === 'number',
|
|
404
|
+
isBoolean: (td) => td !== undefined && td.type === 'boolean',
|
|
405
|
+
isJSON: (td) => td !== undefined && td.type === 'json',
|
|
406
|
+
isSQL: (td) => td !== undefined && td.type === 'sql native',
|
|
407
|
+
isDate: (td) => td !== undefined && td.type === 'date',
|
|
408
|
+
isTimestamp: (td) => td !== undefined && td.type === 'timestamp',
|
|
409
|
+
isError: (td) => td !== undefined && td.type === 'error',
|
|
410
|
+
eq: function (x, y) {
|
|
411
|
+
if (x === undefined || y === undefined) {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
function checkFields(a, b) {
|
|
415
|
+
const aSchema = {};
|
|
416
|
+
for (const aEnt of a['fields'] || []) {
|
|
417
|
+
if (aEnt.name) {
|
|
418
|
+
aSchema[aEnt.name] = aEnt;
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
for (const bEnt of b['fields'] || []) {
|
|
425
|
+
if (!exports.TD.eq(aSchema[bEnt.name], bEnt)) {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
if (x.type === 'array' && y.type === 'array') {
|
|
432
|
+
if (x.elementTypeDef.type !== y.elementTypeDef.type) {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
if (x.elementTypeDef.type !== 'record_element' && // Both are equal, but to make this
|
|
436
|
+
y.elementTypeDef.type !== 'record_element' // typecheck, we need the && clause.
|
|
437
|
+
) {
|
|
438
|
+
return exports.TD.eq(x.elementTypeDef, y.elementTypeDef);
|
|
439
|
+
}
|
|
440
|
+
return checkFields(x, y);
|
|
441
|
+
}
|
|
442
|
+
else if (x.type === 'record' && y.type === 'record') {
|
|
443
|
+
return checkFields(x, y);
|
|
444
|
+
}
|
|
445
|
+
return x.type === y.type;
|
|
446
|
+
},
|
|
447
|
+
timestamp: () => ({ type: 'timestamp' }),
|
|
448
|
+
date: () => ({ type: 'date' }),
|
|
449
|
+
string: () => ({ type: 'string' }),
|
|
450
|
+
number: () => ({ type: 'number', numberType: 'float' }),
|
|
451
|
+
error: () => ({ type: 'error' }),
|
|
452
|
+
};
|
|
372
453
|
// clang-format on
|
|
373
454
|
//# sourceMappingURL=malloy_types.js.map
|