@malloydata/malloy 0.0.38-dev230605182241 → 0.0.38-dev230606235314

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.
@@ -29,6 +29,9 @@ const fragtype_utils_1 = require("../fragtype-utils");
29
29
  const expression_def_1 = require("../types/expression-def");
30
30
  const malloy_element_1 = require("../types/malloy-element");
31
31
  const utils_1 = require("./utils");
32
+ function typeCoalesce(ev1, ev2) {
33
+ return ev1 === undefined || ev1.dataType === 'null' ? ev2 : ev1;
34
+ }
32
35
  class Pick extends expression_def_1.ExpressionDef {
33
36
  constructor(choices, elsePick) {
34
37
  super({ choices });
@@ -65,21 +68,17 @@ class Pick extends expression_def_1.ExpressionDef {
65
68
  ? choice.pick.getExpression(fs)
66
69
  : expr.getExpression(fs);
67
70
  anyExpressionType = (0, malloy_types_1.maxExpressionType)(anyExpressionType, (0, malloy_types_1.maxExpressionType)(whenExpr.expressionType, thenExpr.expressionType));
68
- if (returnType) {
69
- if (!fragtype_utils_1.FT.typeEq(returnType, thenExpr, true)) {
70
- const whenType = fragtype_utils_1.FT.inspect(thenExpr);
71
- this.log(`pick type '${whenType}', expected '${returnType.dataType}'`);
72
- return (0, ast_utils_1.errorFor)('pick when type');
73
- }
74
- }
75
- else {
76
- returnType = thenExpr;
71
+ if (returnType && !fragtype_utils_1.FT.typeEq(returnType, thenExpr, true)) {
72
+ const whenType = fragtype_utils_1.FT.inspect(thenExpr);
73
+ this.log(`pick type '${whenType}', expected '${returnType.dataType}'`);
74
+ return (0, ast_utils_1.errorFor)('pick when type');
77
75
  }
76
+ returnType = typeCoalesce(returnType, thenExpr);
78
77
  caseValue.push(' WHEN ', ...whenExpr.value, ' THEN ', ...thenExpr.value);
79
78
  }
80
79
  const elsePart = this.elsePick || expr;
81
80
  const elseVal = elsePart.getExpression(fs);
82
- returnType || (returnType = elseVal);
81
+ returnType = typeCoalesce(returnType, elseVal);
83
82
  if (!fragtype_utils_1.FT.typeEq(returnType, elseVal, true)) {
84
83
  const errSrc = this.elsePick ? 'else' : 'pick default';
85
84
  this.log(`${errSrc} type '${fragtype_utils_1.FT.inspect(elseVal)}', expected '${returnType.dataType}'`);
@@ -112,24 +111,26 @@ class Pick extends expression_def_1.ExpressionDef {
112
111
  when: c.when.getExpression(fs),
113
112
  });
114
113
  }
115
- const returnType = choiceValues[0].pick;
114
+ let returnType;
116
115
  const caseValue = ['CASE'];
117
- let anyExpressionType = returnType.expressionType;
116
+ let anyExpressionType = 'scalar';
118
117
  for (const aChoice of choiceValues) {
119
118
  if (!fragtype_utils_1.FT.typeEq(aChoice.when, fragtype_utils_1.FT.boolT)) {
120
119
  this.log(`when expression must be boolean, not '${fragtype_utils_1.FT.inspect(aChoice.when)}`);
121
120
  return (0, ast_utils_1.errorFor)('pick when type');
122
121
  }
123
- if (!fragtype_utils_1.FT.typeEq(returnType, aChoice.pick, true)) {
122
+ if (returnType && !fragtype_utils_1.FT.typeEq(returnType, aChoice.pick, true)) {
124
123
  const whenType = fragtype_utils_1.FT.inspect(aChoice.pick);
125
124
  this.log(`pick type '${whenType}', expected '${returnType.dataType}'`);
126
125
  return (0, ast_utils_1.errorFor)('pick value type');
127
126
  }
127
+ returnType = typeCoalesce(returnType, aChoice.pick);
128
128
  anyExpressionType = (0, malloy_types_1.maxExpressionType)(anyExpressionType, (0, malloy_types_1.maxExpressionType)(aChoice.pick.expressionType, aChoice.when.expressionType));
129
129
  caseValue.push(' WHEN ', ...aChoice.when.value, ' THEN ', ...aChoice.pick.value);
130
130
  }
131
131
  const defVal = this.elsePick.getExpression(fs);
132
132
  anyExpressionType = (0, malloy_types_1.maxExpressionType)(anyExpressionType, defVal.expressionType);
133
+ returnType = typeCoalesce(returnType, defVal);
133
134
  if (!fragtype_utils_1.FT.typeEq(returnType, defVal, true)) {
134
135
  this.elsePick.log(`else type '${fragtype_utils_1.FT.inspect(defVal)}', expected '${returnType.dataType}'`);
135
136
  return (0, ast_utils_1.errorFor)('pick value type mismatch');
@@ -37,6 +37,14 @@ function exprOK(s) {
37
37
  return undefined;
38
38
  };
39
39
  }
40
+ function exprType(s, t) {
41
+ return () => {
42
+ const expr = new test_translator_1.BetaExpression(s);
43
+ expect(expr).modelParsed();
44
+ expect(expr.generated().dataType).toBe(t);
45
+ return undefined;
46
+ };
47
+ }
40
48
  function modelOK(s) {
41
49
  return () => {
42
50
  const m = new test_translator_1.TestTranslator(s);
@@ -720,6 +728,9 @@ describe('expressions', () => {
720
728
  test('filtering', exprOK(`
721
729
  astr ? pick 'missing value' when NULL
722
730
  `));
731
+ test('null branch with else', exprType("astr ? pick null when = '42' else 3", 'number'));
732
+ test('null branch no else', exprType("astr ? pick null when = '42'", 'string'));
733
+ test('null branch no apply', exprType('pick null when 1 = 1 else 3', 'number'));
723
734
  test('tiering', exprOK(`
724
735
  ai ?
725
736
  pick 1 when < 10
package/dist/malloy.d.ts CHANGED
@@ -397,6 +397,10 @@ export declare class PreparedResult {
397
397
  */
398
398
  get resultExplore(): Explore;
399
399
  get sourceExplore(): Explore;
400
+ /**
401
+ * @return The query timezone.
402
+ */
403
+ get queryTimezone(): string | undefined;
400
404
  get _sourceExploreName(): string;
401
405
  get _sourceFilters(): FilterExpression[];
402
406
  }
package/dist/malloy.js CHANGED
@@ -224,6 +224,7 @@ class Malloy {
224
224
  // TODO feature-sql-block There is no source explore...
225
225
  sourceExplore: '',
226
226
  sourceFilters: [],
227
+ queryTimezone: sqlStruct.queryTimezone,
227
228
  }, {
228
229
  name: 'empty_model',
229
230
  exports: [],
@@ -725,6 +726,12 @@ class PreparedResult {
725
726
  }
726
727
  throw new Error(`'${name} is not an explore`);
727
728
  }
729
+ /**
730
+ * @return The query timezone.
731
+ */
732
+ get queryTimezone() {
733
+ return this.inner.queryTimezone;
734
+ }
728
735
  get _sourceExploreName() {
729
736
  return this.inner.sourceExplore;
730
737
  }
@@ -519,6 +519,7 @@ export interface CompiledQuery extends DrillSource {
519
519
  malloy: string;
520
520
  queryName?: string | undefined;
521
521
  connectionName: string;
522
+ queryTimezone?: string;
522
523
  }
523
524
  /** Result type for running a Malloy query. */
524
525
  export interface QueryResult extends CompiledQuery {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.38-dev230605182241",
3
+ "version": "0.0.38-dev230606235314",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",