@malloydata/malloy 0.0.120-dev240131220408 → 0.0.120
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_map.js +12 -2
- package/dist/dialect/functions/all_functions.js +3 -0
- package/dist/dialect/functions/string_agg.d.ts +3 -0
- package/dist/dialect/functions/string_agg.js +47 -0
- package/dist/dialect/functions/util.d.ts +5 -0
- package/dist/dialect/functions/util.js +3 -0
- package/dist/dialect/postgres/functions/postgres_functions.js +3 -0
- package/dist/dialect/postgres/functions/string_agg.d.ts +3 -0
- package/dist/dialect/postgres/functions/string_agg.js +47 -0
- package/dist/dialect/standardsql/functions/standardsql_functions.js +3 -0
- package/dist/dialect/standardsql/functions/string_agg.d.ts +3 -0
- package/dist/dialect/standardsql/functions/string_agg.js +49 -0
- package/dist/index.d.ts +2 -2
- package/dist/lang/ast/expressions/expr-func.d.ts +11 -0
- package/dist/lang/ast/expressions/expr-func.js +69 -10
- package/dist/lang/ast/expressions/{expr-filter.d.ts → expr-props.d.ts} +5 -4
- package/dist/lang/ast/expressions/expr-props.js +122 -0
- package/dist/lang/ast/expressions/function-ordering.d.ts +18 -0
- package/dist/lang/ast/expressions/function-ordering.js +75 -0
- package/dist/lang/ast/expressions/partition_by.d.ts +7 -0
- package/dist/lang/ast/expressions/partition_by.js +35 -0
- package/dist/lang/ast/index.d.ts +4 -1
- package/dist/lang/ast/index.js +4 -1
- package/dist/lang/ast/query-items/field-references.d.ts +4 -0
- package/dist/lang/ast/query-items/field-references.js +12 -1
- package/dist/lang/ast/types/expression-def.d.ts +4 -0
- package/dist/lang/ast/types/expression-def.js +12 -0
- package/dist/lang/ast/types/field-prop-statement.d.ts +7 -0
- package/dist/lang/ast/types/field-prop-statement.js +37 -0
- package/dist/lang/lib/Malloy/MalloyLexer.d.ts +136 -135
- package/dist/lang/lib/Malloy/MalloyLexer.js +1186 -1174
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +278 -213
- package/dist/lang/lib/Malloy/MalloyParser.js +2200 -1683
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +76 -36
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +48 -22
- package/dist/lang/malloy-to-ast.d.ts +6 -2
- package/dist/lang/malloy-to-ast.js +33 -9
- package/dist/lang/test/expressions.spec.js +132 -9
- package/dist/model/malloy_query.d.ts +2 -2
- package/dist/model/malloy_query.js +59 -25
- package/dist/model/malloy_types.d.ts +20 -2
- package/dist/model/malloy_types.js +5 -1
- package/dist/run_sql_options.d.ts +1 -0
- package/dist/runtime_types.d.ts +4 -1
- package/package.json +1 -1
- package/dist/lang/ast/expressions/expr-filter.js +0 -66
|
@@ -249,12 +249,12 @@ class QueryField extends QueryNode {
|
|
|
249
249
|
return [param.name, { param, argIndexes }];
|
|
250
250
|
}));
|
|
251
251
|
}
|
|
252
|
-
expandFunctionCall(dialect, overload, args) {
|
|
252
|
+
expandFunctionCall(dialect, overload, args, orderBy, limit) {
|
|
253
253
|
const paramMap = this.getParameterMap(overload, args.length);
|
|
254
254
|
if (overload.dialect[dialect] === undefined) {
|
|
255
255
|
throw new Error(`Function is not defined for dialect ${dialect}`);
|
|
256
256
|
}
|
|
257
|
-
return (0, utils_1.exprMap)(overload.dialect[dialect], fragment => {
|
|
257
|
+
return (0, utils_1.exprMap)(overload.dialect[dialect].e, fragment => {
|
|
258
258
|
if (typeof fragment === 'string') {
|
|
259
259
|
return [fragment];
|
|
260
260
|
}
|
|
@@ -264,7 +264,6 @@ class QueryField extends QueryNode {
|
|
|
264
264
|
typeof param === 'string' ||
|
|
265
265
|
param.type !== 'function_parameter') {
|
|
266
266
|
throw new Error('Invalid function definition. Argument to spread must be a function parameter.');
|
|
267
|
-
return [];
|
|
268
267
|
}
|
|
269
268
|
const entry = paramMap.get(param.name);
|
|
270
269
|
if (entry === undefined) {
|
|
@@ -287,17 +286,34 @@ class QueryField extends QueryNode {
|
|
|
287
286
|
return args[entry.argIndexes[0]];
|
|
288
287
|
}
|
|
289
288
|
}
|
|
289
|
+
else if (fragment.type === 'aggregate_order_by') {
|
|
290
|
+
return orderBy ? [` ${orderBy}`] : [];
|
|
291
|
+
}
|
|
292
|
+
else if (fragment.type === 'aggregate_limit') {
|
|
293
|
+
return limit ? [` ${limit}`] : [];
|
|
294
|
+
}
|
|
290
295
|
return [fragment];
|
|
291
296
|
});
|
|
292
297
|
}
|
|
293
298
|
generateFunctionCallExpression(resultSet, context, frag, state) {
|
|
294
|
-
var _a;
|
|
299
|
+
var _a, _b;
|
|
295
300
|
const overload = frag.overload;
|
|
296
301
|
const args = frag.args;
|
|
297
302
|
const isSymmetric = (_a = frag.overload.isSymmetric) !== null && _a !== void 0 ? _a : false;
|
|
298
303
|
const distinctKey = (0, malloy_types_1.expressionIsAggregate)(overload.returnType.expressionType) &&
|
|
299
304
|
!isSymmetric &&
|
|
300
305
|
this.generateDistinctKeyIfNecessary(resultSet, context, frag.structPath);
|
|
306
|
+
const aggregateOrderBy = frag.orderBy
|
|
307
|
+
? 'ORDER BY ' +
|
|
308
|
+
frag.orderBy
|
|
309
|
+
.map(ob => {
|
|
310
|
+
const osql = this.generateDimFragment(resultSet, context, ob.e, state);
|
|
311
|
+
const dirsql = ob.dir === 'asc' ? ' ASC' : ob.dir === 'desc' ? ' DESC' : '';
|
|
312
|
+
return `${osql}${dirsql}`;
|
|
313
|
+
})
|
|
314
|
+
.join(', ')
|
|
315
|
+
: undefined;
|
|
316
|
+
const aggregateLimit = frag.limit ? `LIMIT ${frag.limit}` : undefined;
|
|
301
317
|
if (distinctKey) {
|
|
302
318
|
if (!context.dialect.supportsAggDistinct) {
|
|
303
319
|
throw new Error(`Asymmetric aggregates are not supported for custom functions in ${context.dialect.name}.`);
|
|
@@ -306,26 +322,39 @@ class QueryField extends QueryNode {
|
|
|
306
322
|
return this.generateDimFragment(resultSet, context, arg, state);
|
|
307
323
|
});
|
|
308
324
|
return context.dialect.sqlAggDistinct(distinctKey, argsExpressions, valNames => {
|
|
309
|
-
const funcCall = this.expandFunctionCall(context.dialect.name, overload, valNames.map(v => [v]));
|
|
325
|
+
const funcCall = this.expandFunctionCall(context.dialect.name, overload, valNames.map(v => [v]), aggregateOrderBy, aggregateLimit);
|
|
310
326
|
return this.generateExpressionFromExpr(resultSet, context, funcCall, state);
|
|
311
327
|
});
|
|
312
328
|
}
|
|
313
329
|
else {
|
|
314
330
|
const mappedArgs = (0, malloy_types_1.expressionIsAggregate)(overload.returnType.expressionType)
|
|
315
|
-
? args.map(arg => {
|
|
331
|
+
? args.map((arg, index) => {
|
|
316
332
|
// TODO We assume that all arguments to this aggregate-returning function need to
|
|
317
333
|
// have filters applied to them. This is not necessarily true in the general case,
|
|
318
334
|
// e.g. in a function `avg_plus(a, b) = avg(a) + b` -- here, `b` should not be
|
|
319
335
|
// be filtered. But since there aren't any aggregate functions like this in the
|
|
320
336
|
// standard library we have planned, we ignore this for now.
|
|
321
|
-
|
|
337
|
+
// Update: Now we apply this only to arguments whose parameter is not constant-requiring.
|
|
338
|
+
// So in `string_agg(val, sep)`, `sep` does not get filters applied to it because
|
|
339
|
+
// it must be constant
|
|
340
|
+
const param = overload.params[index];
|
|
341
|
+
// TODO technically this should probably look at _which_ allowed param type was matched
|
|
342
|
+
// for this argument and see if that type is at most constant... but we lose type information
|
|
343
|
+
// by this point in the compilation, so that info would have to be passed into the func call
|
|
344
|
+
// fragment.
|
|
345
|
+
return param.allowedTypes.every(t => (0, malloy_types_1.isLiteral)(t.evalSpace))
|
|
346
|
+
? arg
|
|
347
|
+
: [this.generateDimFragment(resultSet, context, arg, state)];
|
|
322
348
|
})
|
|
323
349
|
: args;
|
|
324
|
-
const funcCall = this.expandFunctionCall(context.dialect.name, overload, mappedArgs);
|
|
350
|
+
const funcCall = this.expandFunctionCall(context.dialect.name, overload, mappedArgs, aggregateOrderBy, aggregateLimit);
|
|
325
351
|
if ((0, malloy_types_1.expressionIsAnalytic)(overload.returnType.expressionType)) {
|
|
352
|
+
const extraPartitions = ((_b = frag.partitionBy) !== null && _b !== void 0 ? _b : []).map(outputName => {
|
|
353
|
+
return `(${resultSet.getField(outputName).getAnalyticalSQL(false)})`;
|
|
354
|
+
});
|
|
326
355
|
// TODO probably need to pass in the function and arguments separately
|
|
327
356
|
// in order to generate parameter SQL correctly in BQ re: partition
|
|
328
|
-
return this.generateAnalyticFragment(resultSet, context, funcCall, overload, state, args);
|
|
357
|
+
return this.generateAnalyticFragment(resultSet, context, funcCall, overload, state, args, extraPartitions, aggregateOrderBy);
|
|
329
358
|
}
|
|
330
359
|
return this.generateExpressionFromExpr(resultSet, context, funcCall, state);
|
|
331
360
|
}
|
|
@@ -510,7 +539,7 @@ class QueryField extends QueryNode {
|
|
|
510
539
|
return context.getFieldByName(expr.path).getIdentifier();
|
|
511
540
|
}
|
|
512
541
|
}
|
|
513
|
-
getAnalyticPartitions(resultStruct) {
|
|
542
|
+
getAnalyticPartitions(resultStruct, extraPartitionFields) {
|
|
514
543
|
const ret = [];
|
|
515
544
|
let p = resultStruct.parent;
|
|
516
545
|
while (p !== undefined) {
|
|
@@ -519,23 +548,23 @@ class QueryField extends QueryNode {
|
|
|
519
548
|
ret.push(...partitionSQLs);
|
|
520
549
|
p = p.parent;
|
|
521
550
|
}
|
|
522
|
-
|
|
551
|
+
if (extraPartitionFields) {
|
|
552
|
+
ret.push(...extraPartitionFields);
|
|
553
|
+
}
|
|
554
|
+
return ret;
|
|
523
555
|
}
|
|
524
|
-
generateAnalyticFragment(resultStruct, context, expr, overload, state, args) {
|
|
525
|
-
let partitionBy = '';
|
|
556
|
+
generateAnalyticFragment(resultStruct, context, expr, overload, state, args, partitionByFields, funcOrdering) {
|
|
526
557
|
const isComplex = resultStruct.root().isComplexQuery;
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
let orderBy = '';
|
|
538
|
-
if (overload.needsWindowOrderBy) {
|
|
558
|
+
const partitionFields = this.getAnalyticPartitions(resultStruct, partitionByFields);
|
|
559
|
+
const allPartitions = [
|
|
560
|
+
...(isComplex ? ['group_set'] : []),
|
|
561
|
+
...partitionFields,
|
|
562
|
+
];
|
|
563
|
+
const partitionBy = allPartitions.length > 0
|
|
564
|
+
? `PARTITION BY ${allPartitions.join(', ')}`
|
|
565
|
+
: '';
|
|
566
|
+
let orderBy = funcOrdering !== null && funcOrdering !== void 0 ? funcOrdering : '';
|
|
567
|
+
if (!funcOrdering && overload.needsWindowOrderBy) {
|
|
539
568
|
// calculate the ordering.
|
|
540
569
|
const obSQL = [];
|
|
541
570
|
let orderingField;
|
|
@@ -1548,6 +1577,11 @@ class QueryQuery extends QueryField {
|
|
|
1548
1577
|
if ((0, malloy_types_1.expressionIsAnalytic)(expr.overload.returnType.expressionType)) {
|
|
1549
1578
|
resultStruct.root().queryUsesPartitioning = true;
|
|
1550
1579
|
}
|
|
1580
|
+
if (expr.orderBy) {
|
|
1581
|
+
for (const ob of expr.orderBy) {
|
|
1582
|
+
this.addDependantExpr(resultStruct, context, ob.e, joinStack);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1551
1585
|
}
|
|
1552
1586
|
}
|
|
1553
1587
|
}
|
|
@@ -124,11 +124,20 @@ export interface FunctionParameterFragment {
|
|
|
124
124
|
name: string;
|
|
125
125
|
}
|
|
126
126
|
export declare function isFunctionParameterFragment(f: Fragment): f is FunctionParameterFragment;
|
|
127
|
+
export interface AggregateOrderByFragment {
|
|
128
|
+
type: 'aggregate_order_by';
|
|
129
|
+
}
|
|
130
|
+
export interface AggregateLimitFragment {
|
|
131
|
+
type: 'aggregate_limit';
|
|
132
|
+
}
|
|
127
133
|
export interface FunctionCallFragment {
|
|
128
134
|
type: 'function_call';
|
|
129
135
|
overload: FunctionOverloadDef;
|
|
130
136
|
expressionType: ExpressionType;
|
|
131
137
|
args: Expr[];
|
|
138
|
+
orderBy?: FunctionOrderBy[];
|
|
139
|
+
limit?: number;
|
|
140
|
+
partitionBy?: string[];
|
|
132
141
|
structPath?: string[];
|
|
133
142
|
}
|
|
134
143
|
export declare function isFunctionCallFragment(f: Fragment): f is FunctionCallFragment;
|
|
@@ -240,7 +249,7 @@ export interface NumberLiteralFragment extends DialectFragmentBase {
|
|
|
240
249
|
literal: string;
|
|
241
250
|
}
|
|
242
251
|
export type DialectFragment = DivFragment | TimeLiteralFragment | NowFragment | TimeDeltaFragment | TimeDiffFragment | TimeTruncFragment | TypecastFragment | TimeExtractFragment | StringLiteralFragment | RegexpLiteralFragment | NumberLiteralFragment | RegexpMatchFragment;
|
|
243
|
-
export type Fragment = string | ApplyFragment | ApplyValueFragment | FieldFragment | SourceReferenceFragment | SqlStringFragment | ParameterFragment | FilterFragment | OutputFieldFragment | AggregateFragment | UngroupFragment | DialectFragment | FunctionParameterFragment | FunctionCallFragment | SQLExpressionFragment | SpreadFragment;
|
|
252
|
+
export type Fragment = string | ApplyFragment | ApplyValueFragment | FieldFragment | SourceReferenceFragment | SqlStringFragment | ParameterFragment | FilterFragment | OutputFieldFragment | AggregateFragment | UngroupFragment | DialectFragment | FunctionParameterFragment | AggregateOrderByFragment | AggregateLimitFragment | FunctionCallFragment | SQLExpressionFragment | SpreadFragment;
|
|
244
253
|
export type Expr = Fragment[];
|
|
245
254
|
export interface TypedValue {
|
|
246
255
|
value: Expr;
|
|
@@ -377,6 +386,10 @@ export interface OrderBy {
|
|
|
377
386
|
field: string | number;
|
|
378
387
|
dir?: 'asc' | 'desc';
|
|
379
388
|
}
|
|
389
|
+
export interface FunctionOrderBy {
|
|
390
|
+
e: Expr;
|
|
391
|
+
dir?: 'asc' | 'desc';
|
|
392
|
+
}
|
|
380
393
|
export interface ByName {
|
|
381
394
|
by: 'name';
|
|
382
395
|
name: string;
|
|
@@ -561,6 +574,7 @@ export interface FunctionParamTypeDesc {
|
|
|
561
574
|
evalSpace: EvalSpace;
|
|
562
575
|
}
|
|
563
576
|
export type EvalSpace = 'constant' | 'input' | 'output' | 'literal';
|
|
577
|
+
export declare function isLiteral(evalSpace: EvalSpace): boolean;
|
|
564
578
|
export declare function mergeEvalSpaces(...evalSpaces: EvalSpace[]): EvalSpace;
|
|
565
579
|
export interface TypeDesc {
|
|
566
580
|
dataType: FieldValueType;
|
|
@@ -583,7 +597,11 @@ export interface FunctionOverloadDef {
|
|
|
583
597
|
isSymmetric?: boolean;
|
|
584
598
|
params: FunctionParameterDef[];
|
|
585
599
|
dialect: {
|
|
586
|
-
[dialect: string]:
|
|
600
|
+
[dialect: string]: {
|
|
601
|
+
e: Expr;
|
|
602
|
+
supportsOrderBy?: boolean;
|
|
603
|
+
supportsLimit?: boolean;
|
|
604
|
+
};
|
|
587
605
|
};
|
|
588
606
|
}
|
|
589
607
|
export interface FunctionDef extends NamedObject {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.isIndexSegment = exports.isRawSegment = exports.isSamplingEnable = exports.isSamplingPercent = exports.isSamplingRows = exports.isQuerySegment = exports.isProjectSegment = exports.isPartialSegment = exports.isReduceSegment = exports.refIsStructDef = exports.isByExpression = exports.isByName = exports.ValueType = exports.isExtractUnit = exports.isTimestampUnit = exports.isDateUnit = exports.FieldIsIntrinsic = exports.isCastType = exports.isAtomicFieldType = exports.isTimeFieldType = exports.hasExpression = exports.maxOfExpressionTypes = exports.maxExpressionType = exports.isExpressionTypeLEQ = exports.expressionIsAnalytic = exports.expressionIsCalculation = exports.expressionInvolvesAggregate = exports.expressionIsUngroupedAggregate = exports.expressionIsAggregate = exports.expressionIsScalar = exports.mkExpr = exports.isApplyFragment = exports.isApplyValue = exports.isParameterFragment = exports.isSourceReferenceFragment = exports.isSqlStringFragment = exports.isFieldFragment = exports.isSpreadFragment = exports.isSQLExpressionFragment = exports.isFunctionCallFragment = exports.isFunctionParameterFragment = exports.isUngroupFragment = exports.isAsymmetricFragment = exports.isAggregateFragment = exports.isDialectFragment = exports.isFilterFragment = exports.isOutputFieldFragment = exports.paramHasValue = exports.isConditionParameter = exports.isValueParameter = void 0;
|
|
26
|
-
exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.isMeasureLike = exports.getPhysicalFields = exports.getDimensions = exports.isPhysical = exports.isDimensional = exports.isAtomicField = exports.isTurtleDef = exports.getIdentifier = exports.isFieldStructDef = exports.isFieldTimeBased = exports.isFieldTypeDef = exports.isSQLBlockStruct = exports.mergeEvalSpaces = exports.isSQLFragment = exports.isJoinOn = exports.isMatrixOperation = void 0;
|
|
26
|
+
exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.isMeasureLike = exports.getPhysicalFields = exports.getDimensions = exports.isPhysical = exports.isDimensional = exports.isAtomicField = exports.isTurtleDef = exports.getIdentifier = exports.isFieldStructDef = exports.isFieldTimeBased = exports.isFieldTypeDef = exports.isSQLBlockStruct = exports.mergeEvalSpaces = exports.isLiteral = exports.isSQLFragment = exports.isJoinOn = exports.isMatrixOperation = void 0;
|
|
27
27
|
function isValueParameter(p) {
|
|
28
28
|
return p.value !== undefined;
|
|
29
29
|
}
|
|
@@ -329,6 +329,10 @@ function isSQLFragment(f) {
|
|
|
329
329
|
return f.sql !== undefined;
|
|
330
330
|
}
|
|
331
331
|
exports.isSQLFragment = isSQLFragment;
|
|
332
|
+
function isLiteral(evalSpace) {
|
|
333
|
+
return evalSpace === 'literal';
|
|
334
|
+
}
|
|
335
|
+
exports.isLiteral = isLiteral;
|
|
332
336
|
function mergeEvalSpaces(...evalSpaces) {
|
|
333
337
|
if (evalSpaces.every(e => e === 'constant' || e === 'literal')) {
|
|
334
338
|
return 'constant';
|
package/dist/runtime_types.d.ts
CHANGED
|
@@ -79,7 +79,10 @@ export interface ConnectionParameter {
|
|
|
79
79
|
defaultValue?: ConnectionParameterValue;
|
|
80
80
|
}
|
|
81
81
|
export type ConnectionConfigSchema = ConnectionParameter[];
|
|
82
|
-
export
|
|
82
|
+
export interface ConnectionConfig {
|
|
83
|
+
name: string;
|
|
84
|
+
[key: string]: ConnectionParameterValue | undefined;
|
|
85
|
+
}
|
|
83
86
|
export interface ConnectionFactory {
|
|
84
87
|
connectionName: string;
|
|
85
88
|
configSchema: ConnectionConfigSchema;
|
package/package.json
CHANGED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2023 Google LLC
|
|
4
|
-
*
|
|
5
|
-
* Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
-
* a copy of this software and associated documentation files
|
|
7
|
-
* (the "Software"), to deal in the Software without restriction,
|
|
8
|
-
* including without limitation the rights to use, copy, modify, merge,
|
|
9
|
-
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
10
|
-
* and to permit persons to whom the Software is furnished to do so,
|
|
11
|
-
* subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be
|
|
14
|
-
* included in all copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
-
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
-
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
-
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
-
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.ExprFilter = void 0;
|
|
26
|
-
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
|
-
const ast_utils_1 = require("../ast-utils");
|
|
28
|
-
const fragtype_utils_1 = require("../fragtype-utils");
|
|
29
|
-
const expression_def_1 = require("../types/expression-def");
|
|
30
|
-
class ExprFilter extends expression_def_1.ExpressionDef {
|
|
31
|
-
constructor(expr, filter) {
|
|
32
|
-
super({ expr: expr, filter: filter });
|
|
33
|
-
this.expr = expr;
|
|
34
|
-
this.filter = filter;
|
|
35
|
-
this.elementType = 'filtered expression';
|
|
36
|
-
this.legalChildTypes = fragtype_utils_1.FT.anyAtomicT;
|
|
37
|
-
}
|
|
38
|
-
getExpression(fs) {
|
|
39
|
-
const testList = this.filter.getFilterList(fs);
|
|
40
|
-
const resultExpr = this.expr.getExpression(fs);
|
|
41
|
-
if (!(0, malloy_types_1.expressionIsAggregate)(resultExpr.expressionType)) {
|
|
42
|
-
this.expr.log('Filtered expression requires an aggregate computation');
|
|
43
|
-
return resultExpr;
|
|
44
|
-
}
|
|
45
|
-
if (testList.find(cond => (0, malloy_types_1.expressionIsCalculation)(cond.expressionType))) {
|
|
46
|
-
this.filter.log('Cannot filter an expresion with an aggregate or analytical computation');
|
|
47
|
-
return resultExpr;
|
|
48
|
-
}
|
|
49
|
-
if (this.typeCheck(this.expr, { ...resultExpr, expressionType: 'scalar' })) {
|
|
50
|
-
return {
|
|
51
|
-
...resultExpr,
|
|
52
|
-
value: [
|
|
53
|
-
{
|
|
54
|
-
type: 'filterExpression',
|
|
55
|
-
e: resultExpr.value,
|
|
56
|
-
filterList: testList,
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
this.expr.log(`Cannot filter '${resultExpr.dataType}' data`);
|
|
62
|
-
return (0, ast_utils_1.errorFor)('cannot filter type');
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
exports.ExprFilter = ExprFilter;
|
|
66
|
-
//# sourceMappingURL=expr-filter.js.map
|