@malloydata/malloy 0.0.198-dev241010005107 → 0.0.198-dev241010181909

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.
@@ -0,0 +1,18 @@
1
+ import { ExprValue } from '../types/expr-value';
2
+ import { ExpressionDef } from '../types/expression-def';
3
+ import { FieldSpace } from '../types/field-space';
4
+ import { MalloyElement } from '../types/malloy-element';
5
+ export declare class Case extends ExpressionDef {
6
+ readonly value: ExpressionDef | undefined;
7
+ readonly choices: CaseWhen[];
8
+ readonly elseValue?: ExpressionDef | undefined;
9
+ elementType: string;
10
+ constructor(value: ExpressionDef | undefined, choices: CaseWhen[], elseValue?: ExpressionDef | undefined);
11
+ getExpression(fs: FieldSpace): ExprValue;
12
+ }
13
+ export declare class CaseWhen extends MalloyElement {
14
+ readonly when: ExpressionDef;
15
+ readonly then: ExpressionDef;
16
+ elementType: string;
17
+ constructor(when: ExpressionDef, then: ExpressionDef);
18
+ }
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.CaseWhen = exports.Case = void 0;
10
+ const expression_def_1 = require("../types/expression-def");
11
+ const malloy_element_1 = require("../types/malloy-element");
12
+ const fragtype_utils_1 = require("../fragtype-utils");
13
+ const model_1 = require("../../../model");
14
+ function typeCoalesce(ev1, ev2) {
15
+ return ev1 === undefined ||
16
+ ev1.dataType === 'null' ||
17
+ ev1.dataType === 'error'
18
+ ? ev2
19
+ : ev1;
20
+ }
21
+ class Case extends expression_def_1.ExpressionDef {
22
+ constructor(value, choices, elseValue) {
23
+ super({ choices });
24
+ this.value = value;
25
+ this.choices = choices;
26
+ this.elseValue = elseValue;
27
+ this.elementType = 'case';
28
+ this.has({ elseValue, value });
29
+ }
30
+ getExpression(fs) {
31
+ var _a;
32
+ const resultExpr = {
33
+ node: 'case',
34
+ kids: {
35
+ caseWhen: [],
36
+ caseThen: [],
37
+ },
38
+ };
39
+ let expressionType = 'scalar';
40
+ let evalSpace = 'constant';
41
+ let value = undefined;
42
+ if (this.value) {
43
+ value = this.value.getExpression(fs);
44
+ expressionType = (0, model_1.maxExpressionType)(expressionType, value.expressionType);
45
+ evalSpace = (0, model_1.mergeEvalSpaces)(evalSpace, value.evalSpace);
46
+ resultExpr.kids.caseValue = value.value;
47
+ }
48
+ const choiceValues = [];
49
+ for (const c of this.choices) {
50
+ const when = c.when.getExpression(fs);
51
+ const then = c.then.getExpression(fs);
52
+ choiceValues.push({ when, then });
53
+ }
54
+ let returnType;
55
+ for (const aChoice of choiceValues) {
56
+ if (value !== undefined) {
57
+ if (!fragtype_utils_1.FT.typeEq(aChoice.when, value)) {
58
+ return this.loggedErrorExpr('case-when-type-does-not-match', {
59
+ whenType: aChoice.when.dataType,
60
+ valueType: value.dataType,
61
+ });
62
+ }
63
+ }
64
+ else {
65
+ if (!fragtype_utils_1.FT.typeEq(aChoice.when, fragtype_utils_1.FT.boolT)) {
66
+ return this.loggedErrorExpr('case-when-must-be-boolean', {
67
+ whenType: aChoice.when.dataType,
68
+ });
69
+ }
70
+ }
71
+ if (returnType && !fragtype_utils_1.FT.typeEq(returnType, aChoice.then, true)) {
72
+ return this.loggedErrorExpr('case-then-type-does-not-match', {
73
+ thenType: aChoice.then.dataType,
74
+ returnType: returnType.dataType,
75
+ });
76
+ }
77
+ returnType = typeCoalesce(returnType, aChoice.then);
78
+ expressionType = (0, model_1.maxExpressionType)(expressionType, (0, model_1.maxExpressionType)(aChoice.then.expressionType, aChoice.when.expressionType));
79
+ evalSpace = (0, model_1.mergeEvalSpaces)(evalSpace, aChoice.then.evalSpace, aChoice.when.evalSpace);
80
+ resultExpr.kids.caseWhen.push(aChoice.when.value);
81
+ resultExpr.kids.caseThen.push(aChoice.then.value);
82
+ }
83
+ if (this.elseValue) {
84
+ const elseValue = this.elseValue.getExpression(fs);
85
+ if (returnType && !fragtype_utils_1.FT.typeEq(returnType, elseValue, true)) {
86
+ return this.loggedErrorExpr('case-else-type-does-not-match', {
87
+ elseType: elseValue.dataType,
88
+ returnType: returnType.dataType,
89
+ });
90
+ }
91
+ returnType = typeCoalesce(returnType, elseValue);
92
+ expressionType = (0, model_1.maxExpressionType)(expressionType, elseValue.expressionType);
93
+ evalSpace = (0, model_1.mergeEvalSpaces)(evalSpace, elseValue.evalSpace);
94
+ resultExpr.kids.caseElse = elseValue.value;
95
+ }
96
+ return {
97
+ value: resultExpr,
98
+ dataType: (_a = returnType === null || returnType === void 0 ? void 0 : returnType.dataType) !== null && _a !== void 0 ? _a : 'null',
99
+ expressionType,
100
+ evalSpace,
101
+ };
102
+ }
103
+ }
104
+ exports.Case = Case;
105
+ class CaseWhen extends malloy_element_1.MalloyElement {
106
+ constructor(when, then) {
107
+ super({ when, then });
108
+ this.when = when;
109
+ this.then = then;
110
+ this.elementType = 'caseWhen';
111
+ }
112
+ }
113
+ exports.CaseWhen = CaseWhen;
114
+ //# sourceMappingURL=case.js.map
@@ -62,11 +62,10 @@ class Pick extends expression_def_1.ExpressionDef {
62
62
  }
63
63
  apply(fs, op, expr) {
64
64
  const caseValue = {
65
- node: 'pick',
65
+ node: 'case',
66
66
  kids: {
67
- pickWhen: [],
68
- pickThen: [],
69
- pickElse: { node: 'error', message: 'pick statement not complete' },
67
+ caseWhen: [],
68
+ caseThen: [],
70
69
  },
71
70
  };
72
71
  let returnType;
@@ -86,8 +85,8 @@ class Pick extends expression_def_1.ExpressionDef {
86
85
  });
87
86
  }
88
87
  returnType = typeCoalesce(returnType, thenExpr);
89
- caseValue.kids.pickWhen.push(whenExpr.value);
90
- caseValue.kids.pickThen.push(thenExpr.value);
88
+ caseValue.kids.caseWhen.push(whenExpr.value);
89
+ caseValue.kids.caseThen.push(thenExpr.value);
91
90
  }
92
91
  const elsePart = this.elsePick || expr;
93
92
  const elseVal = elsePart.getExpression(fs);
@@ -106,7 +105,7 @@ class Pick extends expression_def_1.ExpressionDef {
106
105
  });
107
106
  }
108
107
  }
109
- caseValue.kids.pickElse = elseVal.value;
108
+ caseValue.kids.caseElse = elseVal.value;
110
109
  return {
111
110
  dataType: returnType.dataType,
112
111
  expressionType: (0, malloy_types_1.maxExpressionType)(anyExpressionType, elseVal.expressionType),
@@ -116,11 +115,10 @@ class Pick extends expression_def_1.ExpressionDef {
116
115
  }
117
116
  getExpression(fs) {
118
117
  const pick = {
119
- node: 'pick',
118
+ node: 'case',
120
119
  kids: {
121
- pickWhen: [],
122
- pickThen: [],
123
- pickElse: { node: 'error', message: 'pick statement not complete' },
120
+ caseWhen: [],
121
+ caseThen: [],
124
122
  },
125
123
  };
126
124
  if (this.elsePick === undefined) {
@@ -131,8 +129,8 @@ class Pick extends expression_def_1.ExpressionDef {
131
129
  if (c.pick === undefined) {
132
130
  return this.loggedErrorExpr('pick-missing-value', 'pick with no value can only be used with apply');
133
131
  }
134
- const pickWhen = c.when.requestExpression(fs);
135
- if (pickWhen === undefined) {
132
+ const caseWhen = c.when.requestExpression(fs);
133
+ if (caseWhen === undefined) {
136
134
  this.loggedErrorExpr('pick-illegal-partial', 'pick with partial when can only be used with apply');
137
135
  }
138
136
  choiceValues.push({
@@ -158,8 +156,8 @@ class Pick extends expression_def_1.ExpressionDef {
158
156
  returnType = typeCoalesce(returnType, aChoice.pick);
159
157
  anyExpressionType = (0, malloy_types_1.maxExpressionType)(anyExpressionType, (0, malloy_types_1.maxExpressionType)(aChoice.pick.expressionType, aChoice.when.expressionType));
160
158
  anyEvalSpace = (0, malloy_types_1.mergeEvalSpaces)(anyEvalSpace, aChoice.pick.evalSpace, aChoice.when.evalSpace);
161
- pick.kids.pickWhen.push(aChoice.when.value);
162
- pick.kids.pickThen.push(aChoice.pick.value);
159
+ pick.kids.caseWhen.push(aChoice.when.value);
160
+ pick.kids.caseThen.push(aChoice.pick.value);
163
161
  }
164
162
  const defVal = this.elsePick.getExpression(fs);
165
163
  anyExpressionType = (0, malloy_types_1.maxExpressionType)(anyExpressionType, defVal.expressionType);
@@ -171,7 +169,7 @@ class Pick extends expression_def_1.ExpressionDef {
171
169
  returnType: returnType.dataType,
172
170
  });
173
171
  }
174
- pick.kids.pickElse = defVal.value;
172
+ pick.kids.caseElse = defVal.value;
175
173
  return {
176
174
  dataType: returnType.dataType,
177
175
  expressionType: anyExpressionType,
@@ -186,7 +184,7 @@ class PickWhen extends malloy_element_1.MalloyElement {
186
184
  super({ when: when });
187
185
  this.pick = pick;
188
186
  this.when = when;
189
- this.elementType = 'pickWhen';
187
+ this.elementType = 'caseWhen';
190
188
  this.has({ pick: pick });
191
189
  }
192
190
  }
@@ -52,6 +52,7 @@ export * from './expressions/time-literal';
52
52
  export * from './expressions/partial-compare';
53
53
  export * from './expressions/partition_by';
54
54
  export * from './expressions/pick-when';
55
+ export * from './expressions/case';
55
56
  export * from './expressions/expr-record-literal';
56
57
  export * from './expressions/range';
57
58
  export * from './expressions/time-frame';
@@ -90,6 +90,7 @@ __exportStar(require("./expressions/time-literal"), exports);
90
90
  __exportStar(require("./expressions/partial-compare"), exports);
91
91
  __exportStar(require("./expressions/partition_by"), exports);
92
92
  __exportStar(require("./expressions/pick-when"), exports);
93
+ __exportStar(require("./expressions/case"), exports);
93
94
  __exportStar(require("./expressions/expr-record-literal"), exports);
94
95
  __exportStar(require("./expressions/range"), exports);
95
96
  __exportStar(require("./expressions/time-frame"), exports);
@@ -281,24 +281,26 @@ export declare class MalloyParser extends Parser {
281
281
  static readonly RULE_partialAllowedFieldExpr = 115;
282
282
  static readonly RULE_pickStatement = 116;
283
283
  static readonly RULE_pick = 117;
284
- static readonly RULE_recordKey = 118;
285
- static readonly RULE_recordElement = 119;
286
- static readonly RULE_argumentList = 120;
287
- static readonly RULE_fieldNameList = 121;
288
- static readonly RULE_fieldCollection = 122;
289
- static readonly RULE_collectionWildCard = 123;
290
- static readonly RULE_starQualified = 124;
291
- static readonly RULE_taggedRef = 125;
292
- static readonly RULE_refExpr = 126;
293
- static readonly RULE_collectionMember = 127;
294
- static readonly RULE_fieldPath = 128;
295
- static readonly RULE_joinName = 129;
296
- static readonly RULE_fieldName = 130;
297
- static readonly RULE_justExpr = 131;
298
- static readonly RULE_sqlExploreNameRef = 132;
299
- static readonly RULE_nameSQLBlock = 133;
300
- static readonly RULE_connectionName = 134;
301
- static readonly RULE_experimentalStatementForTesting = 135;
284
+ static readonly RULE_caseStatement = 118;
285
+ static readonly RULE_caseWhen = 119;
286
+ static readonly RULE_recordKey = 120;
287
+ static readonly RULE_recordElement = 121;
288
+ static readonly RULE_argumentList = 122;
289
+ static readonly RULE_fieldNameList = 123;
290
+ static readonly RULE_fieldCollection = 124;
291
+ static readonly RULE_collectionWildCard = 125;
292
+ static readonly RULE_starQualified = 126;
293
+ static readonly RULE_taggedRef = 127;
294
+ static readonly RULE_refExpr = 128;
295
+ static readonly RULE_collectionMember = 129;
296
+ static readonly RULE_fieldPath = 130;
297
+ static readonly RULE_joinName = 131;
298
+ static readonly RULE_fieldName = 132;
299
+ static readonly RULE_justExpr = 133;
300
+ static readonly RULE_sqlExploreNameRef = 134;
301
+ static readonly RULE_nameSQLBlock = 135;
302
+ static readonly RULE_connectionName = 136;
303
+ static readonly RULE_experimentalStatementForTesting = 137;
302
304
  static readonly ruleNames: string[];
303
305
  private static readonly _LITERAL_NAMES;
304
306
  private static readonly _SYMBOLIC_NAMES;
@@ -430,6 +432,8 @@ export declare class MalloyParser extends Parser {
430
432
  partialAllowedFieldExpr(): PartialAllowedFieldExprContext;
431
433
  pickStatement(): PickStatementContext;
432
434
  pick(): PickContext;
435
+ caseStatement(): CaseStatementContext;
436
+ caseWhen(): CaseWhenContext;
433
437
  recordKey(): RecordKeyContext;
434
438
  recordElement(): RecordElementContext;
435
439
  argumentList(): ArgumentListContext;
@@ -2261,6 +2265,13 @@ export declare class ExprPickContext extends FieldExprContext {
2261
2265
  exitRule(listener: MalloyParserListener): void;
2262
2266
  accept<Result>(visitor: MalloyParserVisitor<Result>): Result;
2263
2267
  }
2268
+ export declare class ExprCaseContext extends FieldExprContext {
2269
+ caseStatement(): CaseStatementContext;
2270
+ constructor(ctx: FieldExprContext);
2271
+ enterRule(listener: MalloyParserListener): void;
2272
+ exitRule(listener: MalloyParserListener): void;
2273
+ accept<Result>(visitor: MalloyParserVisitor<Result>): Result;
2274
+ }
2264
2275
  export declare class ExprUngroupContext extends FieldExprContext {
2265
2276
  ungroup(): UngroupContext;
2266
2277
  OPAREN(): TerminalNode;
@@ -2311,6 +2322,35 @@ export declare class PickContext extends ParserRuleContext {
2311
2322
  exitRule(listener: MalloyParserListener): void;
2312
2323
  accept<Result>(visitor: MalloyParserVisitor<Result>): Result;
2313
2324
  }
2325
+ export declare class CaseStatementContext extends ParserRuleContext {
2326
+ _valueExpr: FieldExprContext;
2327
+ _caseElse: FieldExprContext;
2328
+ CASE(): TerminalNode;
2329
+ END(): TerminalNode;
2330
+ caseWhen(): CaseWhenContext[];
2331
+ caseWhen(i: number): CaseWhenContext;
2332
+ ELSE(): TerminalNode | undefined;
2333
+ fieldExpr(): FieldExprContext[];
2334
+ fieldExpr(i: number): FieldExprContext;
2335
+ constructor(parent: ParserRuleContext | undefined, invokingState: number);
2336
+ get ruleIndex(): number;
2337
+ enterRule(listener: MalloyParserListener): void;
2338
+ exitRule(listener: MalloyParserListener): void;
2339
+ accept<Result>(visitor: MalloyParserVisitor<Result>): Result;
2340
+ }
2341
+ export declare class CaseWhenContext extends ParserRuleContext {
2342
+ _condition: FieldExprContext;
2343
+ _result: FieldExprContext;
2344
+ WHEN(): TerminalNode;
2345
+ THEN(): TerminalNode;
2346
+ fieldExpr(): FieldExprContext[];
2347
+ fieldExpr(i: number): FieldExprContext;
2348
+ constructor(parent: ParserRuleContext | undefined, invokingState: number);
2349
+ get ruleIndex(): number;
2350
+ enterRule(listener: MalloyParserListener): void;
2351
+ exitRule(listener: MalloyParserListener): void;
2352
+ accept<Result>(visitor: MalloyParserVisitor<Result>): Result;
2353
+ }
2314
2354
  export declare class RecordKeyContext extends ParserRuleContext {
2315
2355
  id(): IdContext;
2316
2356
  constructor(parent: ParserRuleContext | undefined, invokingState: number);