@malloydata/malloy 0.0.223-dev241212225931 → 0.0.223-dev241216182944
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/duckdb/dialect_functions.js +7 -0
- package/dist/dialect/functions/malloy_standard_functions.js +19 -19
- package/dist/dialect/functions/util.d.ts +43 -34
- package/dist/dialect/functions/util.js +87 -92
- package/dist/dialect/trino/dialect_functions.js +3 -3
- package/dist/lang/ast/expressions/expr-array-literal.js +4 -1
- package/dist/lang/ast/expressions/expr-func.js +180 -14
- package/dist/lang/ast/expressions/expr-record-literal.d.ts +12 -3
- package/dist/lang/ast/expressions/expr-record-literal.js +35 -7
- package/dist/lang/ast/types/dialect-name-space.js +1 -0
- package/dist/lang/ast/types/global-name-space.js +1 -0
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +2 -2
- package/dist/lang/lib/Malloy/MalloyParser.js +653 -645
- package/dist/lang/malloy-to-ast.js +7 -12
- package/dist/lang/parse-log.d.ts +8 -0
- package/dist/lang/test/literals.spec.js +14 -0
- package/dist/lang/test/parse-expects.js +11 -0
- package/dist/model/malloy_types.d.ts +54 -7
- package/dist/model/malloy_types.js +9 -4
- package/package.json +1 -1
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.DUCKDB_DIALECT_FUNCTIONS = void 0;
|
|
10
|
+
const list_extract = {
|
|
11
|
+
takes: { 'value': { array: { generic: 'T' } }, 'index': 'number' },
|
|
12
|
+
generic: { 'T': ['any'] },
|
|
13
|
+
returns: { generic: 'T' },
|
|
14
|
+
impl: { sql: 'list_extract(${value}, ${index})' },
|
|
15
|
+
};
|
|
10
16
|
const dayname = {
|
|
11
17
|
takes: { 'date_value': ['date', 'timestamp'] },
|
|
12
18
|
returns: 'string',
|
|
@@ -65,6 +71,7 @@ const string_agg_distinct = {
|
|
|
65
71
|
},
|
|
66
72
|
};
|
|
67
73
|
exports.DUCKDB_DIALECT_FUNCTIONS = {
|
|
74
|
+
list_extract,
|
|
68
75
|
count_approx,
|
|
69
76
|
dayname,
|
|
70
77
|
to_timestamp,
|
|
@@ -54,7 +54,7 @@ const chr = {
|
|
|
54
54
|
impl: { sql: "CASE WHEN ${value} = 0 THEN '' ELSE CHR(${value}) END" },
|
|
55
55
|
};
|
|
56
56
|
const coalesce = {
|
|
57
|
-
generic:
|
|
57
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date', 'json'] },
|
|
58
58
|
takes: { 'value': { variadic: { generic: 'T' } } },
|
|
59
59
|
returns: { generic: 'T' },
|
|
60
60
|
impl: { function: 'COALESCE' },
|
|
@@ -101,13 +101,13 @@ const floor = {
|
|
|
101
101
|
impl: { function: 'FLOOR' },
|
|
102
102
|
};
|
|
103
103
|
const greatest = {
|
|
104
|
-
generic:
|
|
104
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date', 'json'] },
|
|
105
105
|
takes: { 'values': { variadic: { generic: 'T' } } },
|
|
106
106
|
returns: { generic: 'T' },
|
|
107
107
|
impl: { function: 'GREATEST' },
|
|
108
108
|
};
|
|
109
109
|
const ifnull = {
|
|
110
|
-
generic:
|
|
110
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date', 'json'] },
|
|
111
111
|
takes: { 'value': { generic: 'T' }, 'default': { generic: 'T' } },
|
|
112
112
|
returns: { generic: 'T' },
|
|
113
113
|
impl: { function: 'IFNULL' },
|
|
@@ -162,7 +162,7 @@ const ltrim = {
|
|
|
162
162
|
},
|
|
163
163
|
};
|
|
164
164
|
const nullif = {
|
|
165
|
-
generic:
|
|
165
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date', 'json'] },
|
|
166
166
|
takes: { 'value1': { generic: 'T' }, 'value2': { generic: 'T' } },
|
|
167
167
|
returns: { generic: 'T' },
|
|
168
168
|
impl: { function: 'NULLIF' },
|
|
@@ -331,7 +331,7 @@ const stddev = {
|
|
|
331
331
|
// Analytic functions
|
|
332
332
|
const avg_moving = {
|
|
333
333
|
'preceding': {
|
|
334
|
-
generic:
|
|
334
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
335
335
|
takes: {
|
|
336
336
|
'value': { measure: { generic: 'T' } },
|
|
337
337
|
'preceding': { literal: 'number' },
|
|
@@ -344,7 +344,7 @@ const avg_moving = {
|
|
|
344
344
|
},
|
|
345
345
|
},
|
|
346
346
|
'following': {
|
|
347
|
-
generic:
|
|
347
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
348
348
|
takes: {
|
|
349
349
|
'value': { measure: { generic: 'T' } },
|
|
350
350
|
'preceding': { literal: 'number' },
|
|
@@ -359,7 +359,7 @@ const avg_moving = {
|
|
|
359
359
|
},
|
|
360
360
|
};
|
|
361
361
|
const first_value = {
|
|
362
|
-
generic:
|
|
362
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date', 'json'] },
|
|
363
363
|
takes: { 'value': { measure: { generic: 'T' } } },
|
|
364
364
|
returns: { calculation: { generic: 'T' } },
|
|
365
365
|
impl: { function: 'FIRST_VALUE', needsWindowOrderBy: true },
|
|
@@ -374,7 +374,7 @@ const LAG_TYPES = [
|
|
|
374
374
|
];
|
|
375
375
|
const lag = {
|
|
376
376
|
'bare': {
|
|
377
|
-
generic:
|
|
377
|
+
generic: { 'T': LAG_TYPES },
|
|
378
378
|
takes: {
|
|
379
379
|
'value': { measure: { generic: 'T' } },
|
|
380
380
|
},
|
|
@@ -382,7 +382,7 @@ const lag = {
|
|
|
382
382
|
impl: { function: 'LAG', needsWindowOrderBy: true },
|
|
383
383
|
},
|
|
384
384
|
'with_offset': {
|
|
385
|
-
generic:
|
|
385
|
+
generic: { 'T': LAG_TYPES },
|
|
386
386
|
takes: {
|
|
387
387
|
'value': { measure: { generic: 'T' } },
|
|
388
388
|
'offset': { literal: 'number' },
|
|
@@ -391,7 +391,7 @@ const lag = {
|
|
|
391
391
|
impl: { function: 'LAG', needsWindowOrderBy: true },
|
|
392
392
|
},
|
|
393
393
|
'with_default': {
|
|
394
|
-
generic:
|
|
394
|
+
generic: { 'T': LAG_TYPES },
|
|
395
395
|
takes: {
|
|
396
396
|
'value': { measure: { generic: 'T' } },
|
|
397
397
|
'offset': { literal: 'number' },
|
|
@@ -402,7 +402,7 @@ const lag = {
|
|
|
402
402
|
},
|
|
403
403
|
};
|
|
404
404
|
const last_value = {
|
|
405
|
-
generic:
|
|
405
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date', 'json'] },
|
|
406
406
|
takes: { 'value': { measure: { generic: 'T' } } },
|
|
407
407
|
returns: { calculation: { generic: 'T' } },
|
|
408
408
|
impl: {
|
|
@@ -426,25 +426,25 @@ const lead = {
|
|
|
426
426
|
},
|
|
427
427
|
};
|
|
428
428
|
const max_cumulative = {
|
|
429
|
-
generic:
|
|
429
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
430
430
|
takes: { 'value': { measure: { generic: 'T' } } },
|
|
431
431
|
returns: { calculation: { generic: 'T' } },
|
|
432
432
|
impl: { function: 'MAX', needsWindowOrderBy: true },
|
|
433
433
|
};
|
|
434
434
|
const max_window = {
|
|
435
|
-
generic:
|
|
435
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
436
436
|
takes: { 'value': { measure: { generic: 'T' } } },
|
|
437
437
|
returns: { calculation: { generic: 'T' } },
|
|
438
438
|
impl: { function: 'MAX', needsWindowOrderBy: false },
|
|
439
439
|
};
|
|
440
440
|
const min_cumulative = {
|
|
441
|
-
generic:
|
|
441
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
442
442
|
takes: { 'value': { measure: { generic: 'T' } } },
|
|
443
443
|
returns: { calculation: { generic: 'T' } },
|
|
444
444
|
impl: { function: 'MIN', needsWindowOrderBy: true },
|
|
445
445
|
};
|
|
446
446
|
const min_window = {
|
|
447
|
-
generic:
|
|
447
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
448
448
|
takes: { 'value': { measure: { generic: 'T' } } },
|
|
449
449
|
returns: { calculation: { generic: 'T' } },
|
|
450
450
|
impl: { function: 'MIN', needsWindowOrderBy: false },
|
|
@@ -461,14 +461,14 @@ const row_number = {
|
|
|
461
461
|
impl: { function: 'ROW_NUMBER', needsWindowOrderBy: true },
|
|
462
462
|
};
|
|
463
463
|
const sum_cumulative = {
|
|
464
|
-
generic:
|
|
464
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
465
465
|
takes: { 'value': { measure: { generic: 'T' } } },
|
|
466
466
|
returns: { calculation: { generic: 'T' } },
|
|
467
467
|
impl: { function: 'SUM', needsWindowOrderBy: true },
|
|
468
468
|
};
|
|
469
469
|
const sum_moving = {
|
|
470
470
|
'preceding': {
|
|
471
|
-
generic:
|
|
471
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
472
472
|
takes: {
|
|
473
473
|
'value': { measure: { generic: 'T' } },
|
|
474
474
|
'preceding': { literal: 'number' },
|
|
@@ -481,7 +481,7 @@ const sum_moving = {
|
|
|
481
481
|
},
|
|
482
482
|
},
|
|
483
483
|
'following': {
|
|
484
|
-
generic:
|
|
484
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
485
485
|
takes: {
|
|
486
486
|
'value': { measure: { generic: 'T' } },
|
|
487
487
|
'preceding': { literal: 'number' },
|
|
@@ -496,7 +496,7 @@ const sum_moving = {
|
|
|
496
496
|
},
|
|
497
497
|
};
|
|
498
498
|
const sum_window = {
|
|
499
|
-
generic:
|
|
499
|
+
generic: { 'T': ['string', 'number', 'timestamp', 'date'] },
|
|
500
500
|
takes: { 'value': { measure: { generic: 'T' } } },
|
|
501
501
|
returns: { calculation: { generic: 'T' } },
|
|
502
502
|
impl: { function: 'SUM', needsWindowOrderBy: false },
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { FunctionParameterDef, TypeDesc, Expr, FunctionParamTypeDesc, LeafExpressionType } from '../../model/malloy_types';
|
|
1
|
+
import { FunctionParameterDef, TypeDesc, Expr, FunctionParamTypeDesc, LeafExpressionType, FunctionReturnTypeDesc, FunctionParameterTypeDef, ExpressionType, EvalSpace, FunctionGenericTypeDef } from '../../model/malloy_types';
|
|
2
2
|
import { SQLExprElement } from '../../model/utils';
|
|
3
3
|
export interface DialectFunctionOverloadDef {
|
|
4
|
-
returnType:
|
|
4
|
+
returnType: FunctionReturnTypeDesc;
|
|
5
5
|
params: FunctionParameterDef[];
|
|
6
|
+
genericTypes?: {
|
|
7
|
+
name: string;
|
|
8
|
+
acceptibleTypes: FunctionGenericTypeDef[];
|
|
9
|
+
}[];
|
|
6
10
|
e: Expr;
|
|
7
11
|
needsWindowOrderBy?: boolean;
|
|
8
12
|
isSymmetric?: boolean;
|
|
@@ -17,9 +21,15 @@ export interface DialectFunctionOverloadDef {
|
|
|
17
21
|
export declare function arg(name: string): Expr;
|
|
18
22
|
export declare function spread(e: Expr, prefix?: string | undefined, suffix?: string | undefined): Expr;
|
|
19
23
|
export declare function sql(strings: TemplateStringsArray, ...subExprs: SQLExprElement[]): Expr;
|
|
20
|
-
export declare function constant
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
export declare function constant<T extends {
|
|
25
|
+
expressionType: ExpressionType | undefined;
|
|
26
|
+
}>(type: T): T & TypeDescExtras;
|
|
27
|
+
export declare function output<T extends {
|
|
28
|
+
expressionType: ExpressionType | undefined;
|
|
29
|
+
}>(type: T): T & TypeDescExtras;
|
|
30
|
+
export declare function literal<T extends {
|
|
31
|
+
expressionType: ExpressionType | undefined;
|
|
32
|
+
}>(type: T): T & TypeDescExtras;
|
|
23
33
|
export declare function variadicParam(name: string, ...allowedTypes: FunctionParamTypeDesc[]): FunctionParameterDef;
|
|
24
34
|
/**
|
|
25
35
|
* Prefer `makeParam` for future function definitions
|
|
@@ -29,14 +39,18 @@ export declare function makeParam(name: string, ...allowedTypes: FunctionParamTy
|
|
|
29
39
|
param: FunctionParameterDef;
|
|
30
40
|
arg: Expr;
|
|
31
41
|
};
|
|
32
|
-
export declare function maxScalar(type:
|
|
33
|
-
export declare function maxAggregate(type:
|
|
34
|
-
export declare function anyExprType(type:
|
|
35
|
-
export declare function maxUngroupedAggregate(type:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
export declare function maxScalar<T>(type: T): T & TypeDescExtras;
|
|
43
|
+
export declare function maxAggregate<T>(type: T): T & TypeDescExtras;
|
|
44
|
+
export declare function anyExprType<T>(type: T): T & TypeDescExtras;
|
|
45
|
+
export declare function maxUngroupedAggregate(type: FunctionParameterTypeDef): FunctionParamTypeDesc;
|
|
46
|
+
type TypeDescExtras = {
|
|
47
|
+
expressionType: ExpressionType | undefined;
|
|
48
|
+
evalSpace: EvalSpace;
|
|
49
|
+
};
|
|
50
|
+
export declare function maxAnalytic<T>(type: T): T & TypeDescExtras;
|
|
51
|
+
export declare function minScalar<T>(type: T): T & TypeDescExtras;
|
|
52
|
+
export declare function minAggregate<T>(type: T): T & TypeDescExtras;
|
|
53
|
+
export declare function minAnalytic<T>(type: T): T & TypeDescExtras;
|
|
40
54
|
export declare function overload(returnType: TypeDesc, params: FunctionParameterDef[], e: Expr, options?: {
|
|
41
55
|
needsWindowOrderBy?: boolean;
|
|
42
56
|
between?: {
|
|
@@ -49,40 +63,35 @@ export declare function overload(returnType: TypeDesc, params: FunctionParameter
|
|
|
49
63
|
supportsOrderBy?: boolean | 'only_default';
|
|
50
64
|
}): DialectFunctionOverloadDef;
|
|
51
65
|
export interface ArrayBlueprint {
|
|
52
|
-
array:
|
|
66
|
+
array: TypeDescElementBlueprintOrNamedGeneric;
|
|
53
67
|
}
|
|
68
|
+
export type TypeDescElementBlueprintOrNamedGeneric = TypeDescElementBlueprint | NamedGeneric;
|
|
54
69
|
export interface RecordBlueprint {
|
|
55
|
-
record: Record<string,
|
|
70
|
+
record: Record<string, TypeDescElementBlueprintOrNamedGeneric>;
|
|
56
71
|
}
|
|
57
|
-
export type
|
|
58
|
-
export type
|
|
72
|
+
export type LeafPlusType = LeafExpressionType | 'any';
|
|
73
|
+
export type TypeDescElementBlueprint = LeafPlusType | ArrayBlueprint | RecordBlueprint;
|
|
74
|
+
export type NamedGeneric = {
|
|
59
75
|
generic: string;
|
|
76
|
+
};
|
|
77
|
+
export type TypeDescBlueprint = TypeDescElementBlueprintOrNamedGeneric | {
|
|
78
|
+
literal: TypeDescElementBlueprintOrNamedGeneric;
|
|
60
79
|
} | {
|
|
61
|
-
|
|
62
|
-
generic: string;
|
|
63
|
-
};
|
|
80
|
+
constant: TypeDescElementBlueprintOrNamedGeneric;
|
|
64
81
|
} | {
|
|
65
|
-
|
|
66
|
-
generic: string;
|
|
67
|
-
};
|
|
82
|
+
dimension: TypeDescElementBlueprintOrNamedGeneric;
|
|
68
83
|
} | {
|
|
69
|
-
|
|
70
|
-
generic: string;
|
|
71
|
-
};
|
|
84
|
+
measure: TypeDescElementBlueprintOrNamedGeneric;
|
|
72
85
|
} | {
|
|
73
|
-
|
|
74
|
-
generic: string;
|
|
75
|
-
};
|
|
76
|
-
} | {
|
|
77
|
-
calculation: LeafExpressionType | {
|
|
78
|
-
generic: string;
|
|
79
|
-
};
|
|
86
|
+
calculation: TypeDescElementBlueprintOrNamedGeneric;
|
|
80
87
|
};
|
|
81
88
|
type ParamTypeBlueprint = TypeDescBlueprint | TypeDescBlueprint[] | {
|
|
82
89
|
variadic: TypeDescBlueprint | TypeDescBlueprint[];
|
|
83
90
|
};
|
|
84
91
|
export interface SignatureBlueprint {
|
|
85
|
-
generic?:
|
|
92
|
+
generic?: {
|
|
93
|
+
[name: string]: TypeDescElementBlueprintOrNamedGeneric[];
|
|
94
|
+
};
|
|
86
95
|
takes: {
|
|
87
96
|
[name: string]: ParamTypeBlueprint;
|
|
88
97
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
3
|
* Copyright 2023 Google LLC
|
|
4
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
5
|
*
|
|
5
6
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
6
7
|
* a copy of this software and associated documentation files
|
|
@@ -23,7 +24,6 @@
|
|
|
23
24
|
*/
|
|
24
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
26
|
exports.expandOverrideMapFromBase = exports.expandBlueprintMap = exports.overload = exports.minAnalytic = exports.minAggregate = exports.minScalar = exports.maxAnalytic = exports.maxUngroupedAggregate = exports.anyExprType = exports.maxAggregate = exports.maxScalar = exports.makeParam = exports.param = exports.variadicParam = exports.literal = exports.output = exports.constant = exports.sql = exports.spread = exports.arg = void 0;
|
|
26
|
-
const composite_source_utils_1 = require("../../model/composite_source_utils");
|
|
27
27
|
const malloy_types_1 = require("../../model/malloy_types");
|
|
28
28
|
function arg(name) {
|
|
29
29
|
return { node: 'function_parameter', name };
|
|
@@ -106,39 +106,35 @@ function makeParam(name, ...allowedTypes) {
|
|
|
106
106
|
}
|
|
107
107
|
exports.makeParam = makeParam;
|
|
108
108
|
function maxScalar(type) {
|
|
109
|
-
return { type, expressionType: 'scalar', evalSpace: 'input' };
|
|
109
|
+
return { ...type, expressionType: 'scalar', evalSpace: 'input' };
|
|
110
110
|
}
|
|
111
111
|
exports.maxScalar = maxScalar;
|
|
112
112
|
function maxAggregate(type) {
|
|
113
|
-
return { type, expressionType: 'aggregate', evalSpace: 'input' };
|
|
113
|
+
return { ...type, expressionType: 'aggregate', evalSpace: 'input' };
|
|
114
114
|
}
|
|
115
115
|
exports.maxAggregate = maxAggregate;
|
|
116
116
|
function anyExprType(type) {
|
|
117
|
-
return { type, expressionType: undefined, evalSpace: 'input' };
|
|
117
|
+
return { ...type, expressionType: undefined, evalSpace: 'input' };
|
|
118
118
|
}
|
|
119
119
|
exports.anyExprType = anyExprType;
|
|
120
|
-
function anyExprTypeBP(type, generic) {
|
|
121
|
-
const typeDesc = expandReturnTypeBlueprint(type, generic);
|
|
122
|
-
return { ...typeDesc, expressionType: undefined, evalSpace: 'input' };
|
|
123
|
-
}
|
|
124
120
|
function maxUngroupedAggregate(type) {
|
|
125
|
-
return { type, expressionType: 'ungrouped_aggregate', evalSpace: 'input' };
|
|
121
|
+
return { ...type, expressionType: 'ungrouped_aggregate', evalSpace: 'input' };
|
|
126
122
|
}
|
|
127
123
|
exports.maxUngroupedAggregate = maxUngroupedAggregate;
|
|
128
124
|
function maxAnalytic(type) {
|
|
129
|
-
return { type, expressionType: 'aggregate_analytic', evalSpace: 'input' };
|
|
125
|
+
return { ...type, expressionType: 'aggregate_analytic', evalSpace: 'input' };
|
|
130
126
|
}
|
|
131
127
|
exports.maxAnalytic = maxAnalytic;
|
|
132
128
|
function minScalar(type) {
|
|
133
|
-
return { type, expressionType: 'scalar', evalSpace: 'input' };
|
|
129
|
+
return { ...type, expressionType: 'scalar', evalSpace: 'input' };
|
|
134
130
|
}
|
|
135
131
|
exports.minScalar = minScalar;
|
|
136
132
|
function minAggregate(type) {
|
|
137
|
-
return { type, expressionType: 'aggregate', evalSpace: 'input' };
|
|
133
|
+
return { ...type, expressionType: 'aggregate', evalSpace: 'input' };
|
|
138
134
|
}
|
|
139
135
|
exports.minAggregate = minAggregate;
|
|
140
136
|
function minAnalytic(type) {
|
|
141
|
-
return { type, expressionType: 'scalar_analytic', evalSpace: 'input' };
|
|
137
|
+
return { ...type, expressionType: 'scalar_analytic', evalSpace: 'input' };
|
|
142
138
|
}
|
|
143
139
|
exports.minAnalytic = minAnalytic;
|
|
144
140
|
function overload(returnType, params, e, options) {
|
|
@@ -155,86 +151,83 @@ function overload(returnType, params, e, options) {
|
|
|
155
151
|
};
|
|
156
152
|
}
|
|
157
153
|
exports.overload = overload;
|
|
158
|
-
function
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
if (type.generic !== (generic === null || generic === void 0 ? void 0 : generic.name)) {
|
|
163
|
-
throw new Error(`Cannot expand generic name ${type.generic}`);
|
|
154
|
+
function expandTypeDescElementBlueprint(blueprint, allowAny = true, allowGenerics = true) {
|
|
155
|
+
if (!allowAny && blueprint === 'any') {
|
|
156
|
+
throw new Error('Return type cannot include any');
|
|
164
157
|
}
|
|
165
|
-
return generic.type;
|
|
166
|
-
}
|
|
167
|
-
function expandReturnTypeBlueprint(blueprint, generic) {
|
|
168
|
-
var _a;
|
|
169
|
-
let base;
|
|
170
158
|
if (typeof blueprint === 'string') {
|
|
171
|
-
|
|
159
|
+
return { type: blueprint };
|
|
172
160
|
}
|
|
173
161
|
else if ('array' in blueprint) {
|
|
174
|
-
const innerType =
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
base = {
|
|
187
|
-
type: 'array',
|
|
188
|
-
elementTypeDef: { type: 'record_element' },
|
|
189
|
-
fields: innerType.fields,
|
|
190
|
-
expressionType,
|
|
191
|
-
evalSpace,
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
// mtoy todo fix by doing "exapndElementBlueprint" ...
|
|
197
|
-
throw new Error(`TypeDescElementBlueprint should never allow ${blueprint.array}`);
|
|
162
|
+
const innerType = allowAny
|
|
163
|
+
? expandTypeDescElementBlueprint(blueprint.array, true)
|
|
164
|
+
: expandTypeDescElementBlueprint(blueprint.array, false);
|
|
165
|
+
if (innerType.type === 'record') {
|
|
166
|
+
return {
|
|
167
|
+
type: 'array',
|
|
168
|
+
elementTypeDef: { type: 'record_element' },
|
|
169
|
+
fields: innerType.fields,
|
|
170
|
+
};
|
|
198
171
|
}
|
|
172
|
+
return {
|
|
173
|
+
type: 'array',
|
|
174
|
+
elementTypeDef: innerType,
|
|
175
|
+
};
|
|
199
176
|
}
|
|
200
177
|
else if ('record' in blueprint) {
|
|
201
178
|
const fields = [];
|
|
202
179
|
for (const [fieldName, fieldBlueprint] of Object.entries(blueprint.record)) {
|
|
203
|
-
const fieldDesc =
|
|
180
|
+
const fieldDesc = allowAny
|
|
181
|
+
? expandTypeDescElementBlueprint(fieldBlueprint, true)
|
|
182
|
+
: expandTypeDescElementBlueprint(fieldBlueprint, false);
|
|
204
183
|
if (malloy_types_1.TD.isAtomic(fieldDesc)) {
|
|
205
184
|
fields.push((0, malloy_types_1.mkFieldDef)(fieldDesc, fieldName));
|
|
206
185
|
}
|
|
207
186
|
}
|
|
208
|
-
|
|
187
|
+
return {
|
|
209
188
|
type: 'record',
|
|
210
189
|
fields,
|
|
211
|
-
evalSpace: 'input',
|
|
212
|
-
expressionType: 'scalar',
|
|
213
190
|
};
|
|
214
191
|
}
|
|
215
192
|
else if ('generic' in blueprint) {
|
|
216
|
-
|
|
193
|
+
if (!allowGenerics) {
|
|
194
|
+
throw new Error('Cannot use generic');
|
|
195
|
+
}
|
|
196
|
+
return { type: 'generic', generic: blueprint.generic };
|
|
197
|
+
}
|
|
198
|
+
throw new Error('Cannot figure out type');
|
|
199
|
+
}
|
|
200
|
+
function expandReturnTypeBlueprint(blueprint) {
|
|
201
|
+
if (blueprint === 'any') {
|
|
202
|
+
throw new Error('Cannot return any type');
|
|
203
|
+
}
|
|
204
|
+
if (typeof blueprint === 'string') {
|
|
205
|
+
return minScalar({ type: blueprint });
|
|
206
|
+
}
|
|
207
|
+
else if ('array' in blueprint) {
|
|
208
|
+
return anyExprType(expandTypeDescElementBlueprint(blueprint, false));
|
|
209
|
+
}
|
|
210
|
+
else if ('record' in blueprint) {
|
|
211
|
+
return anyExprType(expandTypeDescElementBlueprint(blueprint, false));
|
|
212
|
+
}
|
|
213
|
+
else if ('generic' in blueprint) {
|
|
214
|
+
return minScalar(expandTypeDescElementBlueprint(blueprint, false));
|
|
217
215
|
}
|
|
218
216
|
else if ('literal' in blueprint) {
|
|
219
|
-
|
|
217
|
+
return literal(minScalar(expandTypeDescElementBlueprint(blueprint.literal, false)));
|
|
220
218
|
}
|
|
221
219
|
else if ('constant' in blueprint) {
|
|
222
|
-
|
|
220
|
+
return constant(minScalar(expandTypeDescElementBlueprint(blueprint.constant, false)));
|
|
223
221
|
}
|
|
224
222
|
else if ('dimension' in blueprint) {
|
|
225
|
-
|
|
223
|
+
return minScalar(expandTypeDescElementBlueprint(blueprint.dimension, false));
|
|
226
224
|
}
|
|
227
225
|
else if ('measure' in blueprint) {
|
|
228
|
-
|
|
226
|
+
return minAggregate(expandTypeDescElementBlueprint(blueprint.measure, false));
|
|
229
227
|
}
|
|
230
228
|
else {
|
|
231
|
-
|
|
229
|
+
return minAnalytic(expandTypeDescElementBlueprint(blueprint.calculation, false));
|
|
232
230
|
}
|
|
233
|
-
return {
|
|
234
|
-
...base,
|
|
235
|
-
compositeFieldUsage: (0, composite_source_utils_1.emptyCompositeFieldUsage)(),
|
|
236
|
-
expressionType: (_a = base.expressionType) !== null && _a !== void 0 ? _a : 'scalar',
|
|
237
|
-
};
|
|
238
231
|
}
|
|
239
232
|
function isTypeDescBlueprint(blueprint) {
|
|
240
233
|
return (typeof blueprint === 'string' ||
|
|
@@ -261,51 +254,51 @@ function extractParamTypeBlueprints(blueprint) {
|
|
|
261
254
|
return blueprint.variadic;
|
|
262
255
|
}
|
|
263
256
|
}
|
|
264
|
-
function expandParamTypeBlueprint(blueprint
|
|
257
|
+
function expandParamTypeBlueprint(blueprint) {
|
|
265
258
|
if (typeof blueprint === 'string') {
|
|
266
|
-
return anyExprType(blueprint);
|
|
259
|
+
return anyExprType({ type: blueprint });
|
|
267
260
|
}
|
|
268
261
|
else if ('generic' in blueprint) {
|
|
269
|
-
return anyExprType(
|
|
262
|
+
return anyExprType(expandTypeDescElementBlueprint(blueprint));
|
|
270
263
|
}
|
|
271
264
|
else if ('literal' in blueprint) {
|
|
272
|
-
return literal(maxScalar(
|
|
265
|
+
return literal(maxScalar(expandTypeDescElementBlueprint(blueprint.literal)));
|
|
273
266
|
}
|
|
274
267
|
else if ('constant' in blueprint) {
|
|
275
|
-
return constant(maxScalar(
|
|
268
|
+
return constant(maxScalar(expandTypeDescElementBlueprint(blueprint.constant)));
|
|
276
269
|
}
|
|
277
270
|
else if ('dimension' in blueprint) {
|
|
278
|
-
return maxScalar(
|
|
271
|
+
return maxScalar(expandTypeDescElementBlueprint(blueprint.dimension));
|
|
279
272
|
}
|
|
280
273
|
else if ('measure' in blueprint) {
|
|
281
|
-
return maxAggregate(
|
|
274
|
+
return maxAggregate(expandTypeDescElementBlueprint(blueprint.measure));
|
|
282
275
|
}
|
|
283
276
|
else if ('array' in blueprint) {
|
|
284
|
-
return
|
|
277
|
+
return anyExprType(expandTypeDescElementBlueprint(blueprint, false));
|
|
285
278
|
}
|
|
286
279
|
else if ('record' in blueprint) {
|
|
287
|
-
return
|
|
280
|
+
return anyExprType(expandTypeDescElementBlueprint(blueprint, false));
|
|
288
281
|
}
|
|
289
282
|
else {
|
|
290
|
-
return maxAnalytic(
|
|
283
|
+
return maxAnalytic(expandTypeDescElementBlueprint(blueprint.calculation));
|
|
291
284
|
}
|
|
292
285
|
}
|
|
293
|
-
function expandParamTypeBlueprints(blueprints
|
|
294
|
-
return blueprints.map(blueprint => expandParamTypeBlueprint(blueprint
|
|
286
|
+
function expandParamTypeBlueprints(blueprints) {
|
|
287
|
+
return blueprints.map(blueprint => expandParamTypeBlueprint(blueprint));
|
|
295
288
|
}
|
|
296
289
|
function isVariadicParamBlueprint(blueprint) {
|
|
297
290
|
return typeof blueprint !== 'string' && 'variadic' in blueprint;
|
|
298
291
|
}
|
|
299
|
-
function expandParamBlueprint(name, blueprint
|
|
292
|
+
function expandParamBlueprint(name, blueprint) {
|
|
300
293
|
return {
|
|
301
294
|
name,
|
|
302
|
-
allowedTypes: expandParamTypeBlueprints(extractParamTypeBlueprints(blueprint)
|
|
295
|
+
allowedTypes: expandParamTypeBlueprints(extractParamTypeBlueprints(blueprint)),
|
|
303
296
|
isVariadic: isVariadicParamBlueprint(blueprint),
|
|
304
297
|
};
|
|
305
298
|
}
|
|
306
|
-
function expandParamsBlueprints(blueprints
|
|
299
|
+
function expandParamsBlueprints(blueprints) {
|
|
307
300
|
const paramsArray = Object.entries(blueprints);
|
|
308
|
-
return paramsArray.map(blueprint => expandParamBlueprint(blueprint[0], blueprint[1]
|
|
301
|
+
return paramsArray.map(blueprint => expandParamBlueprint(blueprint[0], blueprint[1]));
|
|
309
302
|
}
|
|
310
303
|
function expandBlueprintSqlInterpolation(sql) {
|
|
311
304
|
const src = [];
|
|
@@ -393,23 +386,25 @@ function expandImplBlueprint(blueprint) {
|
|
|
393
386
|
defaultOrderByArgIndex: blueprint.impl.defaultOrderByArgIndex,
|
|
394
387
|
};
|
|
395
388
|
}
|
|
396
|
-
function
|
|
389
|
+
function expandGenericDefinitions(blueprint) {
|
|
390
|
+
if (blueprint === undefined)
|
|
391
|
+
return undefined;
|
|
392
|
+
return Object.entries(blueprint).map(([name, acceptibleTypes]) => ({
|
|
393
|
+
name: name,
|
|
394
|
+
acceptibleTypes: acceptibleTypes.map(t => expandTypeDescElementBlueprint(t, true, false)),
|
|
395
|
+
}));
|
|
396
|
+
}
|
|
397
|
+
function expandBlueprint(blueprint) {
|
|
397
398
|
return {
|
|
398
|
-
returnType: expandReturnTypeBlueprint(blueprint.returns
|
|
399
|
-
params: expandParamsBlueprints(blueprint.takes
|
|
399
|
+
returnType: expandReturnTypeBlueprint(blueprint.returns),
|
|
400
|
+
params: expandParamsBlueprints(blueprint.takes),
|
|
400
401
|
isSymmetric: blueprint.isSymmetric,
|
|
401
402
|
supportsOrderBy: blueprint.supportsOrderBy,
|
|
402
403
|
supportsLimit: blueprint.supportsLimit,
|
|
404
|
+
genericTypes: expandGenericDefinitions(blueprint.generic),
|
|
403
405
|
...expandImplBlueprint(blueprint),
|
|
404
406
|
};
|
|
405
407
|
}
|
|
406
|
-
function expandBlueprint(blueprint) {
|
|
407
|
-
if (blueprint.generic !== undefined) {
|
|
408
|
-
const name = blueprint.generic[0];
|
|
409
|
-
return blueprint.generic[1].map(type => expandOneBlueprint(blueprint, { name, type }));
|
|
410
|
-
}
|
|
411
|
-
return [expandOneBlueprint(blueprint)];
|
|
412
|
-
}
|
|
413
408
|
function isDefinitionBlueprint(blueprint) {
|
|
414
409
|
return 'takes' in blueprint && 'returns' in blueprint && 'impl' in blueprint;
|
|
415
410
|
}
|
|
@@ -418,7 +413,7 @@ function isImplementationBlueprint(blueprint) {
|
|
|
418
413
|
}
|
|
419
414
|
function expandOverloadedBlueprint(blueprint) {
|
|
420
415
|
if (isDefinitionBlueprint(blueprint)) {
|
|
421
|
-
return expandBlueprint(blueprint);
|
|
416
|
+
return [expandBlueprint(blueprint)];
|
|
422
417
|
}
|
|
423
418
|
else {
|
|
424
419
|
return Object.values(blueprint).flatMap(overload => expandBlueprint(overload));
|
|
@@ -433,7 +428,7 @@ function expandBlueprintMap(blueprints) {
|
|
|
433
428
|
}
|
|
434
429
|
exports.expandBlueprintMap = expandBlueprintMap;
|
|
435
430
|
function expandImplementationBlueprint(base, impl) {
|
|
436
|
-
return expandBlueprint({ ...base, impl });
|
|
431
|
+
return [expandBlueprint({ ...base, impl })];
|
|
437
432
|
}
|
|
438
433
|
function expandOverloadedOverrideBlueprint(name, base, blueprint) {
|
|
439
434
|
if (isImplementationBlueprint(blueprint)) {
|
|
@@ -20,7 +20,7 @@ const approx_percentile = {
|
|
|
20
20
|
},
|
|
21
21
|
};
|
|
22
22
|
const arbitrary = {
|
|
23
|
-
generic:
|
|
23
|
+
generic: { 'T': ['string', 'number', 'date', 'timestamp', 'boolean', 'json'] },
|
|
24
24
|
takes: { 'value': { dimension: { generic: 'T' } } },
|
|
25
25
|
returns: { measure: { generic: 'T' } },
|
|
26
26
|
impl: { function: 'ARBITRARY' },
|
|
@@ -64,7 +64,7 @@ const count_approx = {
|
|
|
64
64
|
isSymmetric: true,
|
|
65
65
|
};
|
|
66
66
|
const max_by = {
|
|
67
|
-
generic:
|
|
67
|
+
generic: { 'T': ['string', 'number', 'date', 'timestamp', 'boolean', 'json'] },
|
|
68
68
|
takes: {
|
|
69
69
|
'value': { dimension: { generic: 'T' } },
|
|
70
70
|
'order_by_val': { dimension: 'any' },
|
|
@@ -74,7 +74,7 @@ const max_by = {
|
|
|
74
74
|
isSymmetric: true,
|
|
75
75
|
};
|
|
76
76
|
const min_by = {
|
|
77
|
-
generic:
|
|
77
|
+
generic: { 'T': ['string', 'number', 'date', 'timestamp', 'boolean', 'json'] },
|
|
78
78
|
takes: {
|
|
79
79
|
'value': { dimension: { generic: 'T' } },
|
|
80
80
|
'order_by_val': { dimension: 'any' },
|