@malloydata/malloy 0.0.434 → 0.0.436

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.
Files changed (103) hide show
  1. package/dist/api/foundation/build_targets.d.ts +5 -6
  2. package/dist/api/foundation/build_targets.js +74 -6
  3. package/dist/api/foundation/compile.d.ts +0 -1
  4. package/dist/api/foundation/compile.js +0 -3
  5. package/dist/api/foundation/core.d.ts +16 -4
  6. package/dist/api/foundation/core.js +23 -23
  7. package/dist/api/foundation/index.d.ts +1 -1
  8. package/dist/api/foundation/runtime.d.ts +21 -3
  9. package/dist/api/foundation/runtime.js +45 -54
  10. package/dist/api/foundation/types.d.ts +43 -4
  11. package/dist/connection/dbmeta.d.ts +29 -0
  12. package/dist/connection/dbmeta.js +46 -0
  13. package/dist/connection/index.d.ts +1 -0
  14. package/dist/connection/index.js +1 -0
  15. package/dist/dialect/databricks/databricks.d.ts +11 -12
  16. package/dist/dialect/databricks/databricks.js +24 -36
  17. package/dist/dialect/dialect.d.ts +70 -171
  18. package/dist/dialect/dialect.js +123 -92
  19. package/dist/dialect/dialect_map.js +2 -0
  20. package/dist/dialect/duckdb/duckdb.d.ts +2 -2
  21. package/dist/dialect/duckdb/duckdb.js +1 -1
  22. package/dist/dialect/index.d.ts +3 -2
  23. package/dist/dialect/index.js +4 -2
  24. package/dist/dialect/mysql/mysql.d.ts +11 -12
  25. package/dist/dialect/mysql/mysql.js +20 -32
  26. package/dist/dialect/pg_impl.d.ts +9 -10
  27. package/dist/dialect/pg_impl.js +27 -73
  28. package/dist/dialect/postgres/postgres.d.ts +4 -4
  29. package/dist/dialect/postgres/postgres.js +4 -12
  30. package/dist/dialect/snowflake/snowflake.d.ts +11 -13
  31. package/dist/dialect/snowflake/snowflake.js +30 -82
  32. package/dist/dialect/sqlserver/dialect_functions.d.ts +2 -0
  33. package/dist/dialect/sqlserver/dialect_functions.js +42 -0
  34. package/dist/dialect/sqlserver/function_overrides.d.ts +2 -0
  35. package/dist/dialect/sqlserver/function_overrides.js +55 -0
  36. package/dist/dialect/sqlserver/index.d.ts +1 -0
  37. package/dist/dialect/sqlserver/index.js +22 -0
  38. package/dist/dialect/sqlserver/sqlserver.d.ts +101 -0
  39. package/dist/dialect/sqlserver/sqlserver.js +537 -0
  40. package/dist/dialect/sqlserver/windows_zones.d.ts +1 -0
  41. package/dist/dialect/sqlserver/windows_zones.js +613 -0
  42. package/dist/dialect/standardsql/standardsql.d.ts +11 -16
  43. package/dist/dialect/standardsql/standardsql.js +22 -73
  44. package/dist/dialect/trino/trino.d.ts +16 -18
  45. package/dist/dialect/trino/trino.js +127 -181
  46. package/dist/index.d.ts +2 -2
  47. package/dist/index.js +6 -4
  48. package/dist/lang/ast/expressions/boolean-value.d.ts +24 -0
  49. package/dist/lang/ast/expressions/boolean-value.js +41 -0
  50. package/dist/lang/ast/expressions/case.js +7 -0
  51. package/dist/lang/ast/expressions/expr-alternation-tree.js +11 -0
  52. package/dist/lang/ast/expressions/expr-cast.js +5 -0
  53. package/dist/lang/ast/expressions/expr-coalesce.js +4 -0
  54. package/dist/lang/ast/expressions/expr-func.js +13 -2
  55. package/dist/lang/ast/expressions/expr-minus.js +5 -2
  56. package/dist/lang/ast/expressions/expr-null.js +4 -0
  57. package/dist/lang/ast/expressions/pick-when.js +7 -0
  58. package/dist/lang/ast/field-space/index-field-space.js +13 -1
  59. package/dist/lang/ast/field-space/query-spaces.js +11 -0
  60. package/dist/lang/ast/query-builders/reduce-builder.js +1 -1
  61. package/dist/lang/ast/query-items/field-declaration.d.ts +5 -0
  62. package/dist/lang/ast/query-items/field-declaration.js +22 -16
  63. package/dist/lang/ast/query-items/field-references.d.ts +6 -0
  64. package/dist/lang/ast/query-items/field-references.js +23 -0
  65. package/dist/lang/ast/query-properties/filters.js +3 -1
  66. package/dist/lang/ast/source-elements/named-source.js +0 -2
  67. package/dist/lang/ast/source-elements/sql-source.js +0 -3
  68. package/dist/lang/ast/source-elements/table-source.js +1 -2
  69. package/dist/lang/ast/statements/import-statement.js +17 -0
  70. package/dist/lang/ast/types/expression-def.js +17 -2
  71. package/dist/lang/ast/types/malloy-element.d.ts +24 -8
  72. package/dist/lang/ast/types/malloy-element.js +63 -44
  73. package/dist/lang/ast/view-elements/reference-view.js +4 -0
  74. package/dist/lang/ast/view-elements/refine-utils.js +1 -0
  75. package/dist/lang/composite-source-utils.js +10 -17
  76. package/dist/lang/parse-log.d.ts +12 -0
  77. package/dist/lang/parse-log.js +2 -0
  78. package/dist/lang/parse-malloy.d.ts +17 -2
  79. package/dist/lang/parse-malloy.js +48 -14
  80. package/dist/lang/parse-tree-walkers/find-external-references.d.ts +3 -3
  81. package/dist/lang/parse-tree-walkers/find-external-references.js +17 -16
  82. package/dist/lang/test/test-translator.d.ts +11 -1
  83. package/dist/lang/test/test-translator.js +51 -3
  84. package/dist/model/expression_compiler.js +9 -8
  85. package/dist/model/filter_compilers.js +13 -12
  86. package/dist/model/given_binding.d.ts +8 -0
  87. package/dist/model/given_binding.js +13 -0
  88. package/dist/model/index.d.ts +1 -1
  89. package/dist/model/index.js +2 -1
  90. package/dist/model/query_query.d.ts +3 -1
  91. package/dist/model/query_query.js +157 -139
  92. package/dist/model/source_def_utils.d.ts +7 -1
  93. package/dist/model/source_def_utils.js +20 -0
  94. package/dist/model/sql_compiled.d.ts +19 -20
  95. package/dist/model/sql_compiled.js +29 -17
  96. package/dist/test/index.js +16 -8
  97. package/dist/test/matchers.d.ts +1 -1
  98. package/dist/test/matchers.js +1 -1
  99. package/dist/test/test-models.js +6 -13
  100. package/dist/version.d.ts +1 -1
  101. package/dist/version.js +1 -1
  102. package/femto-config.motly +13 -1
  103. package/package.json +7 -5
package/dist/index.js CHANGED
@@ -37,9 +37,9 @@ var __importStar = (this && this.__importStar) || (function () {
37
37
  };
38
38
  })();
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
- exports.Model = exports.MalloyTranslator = exports.malloyToQuery = exports.constantExprToSQL = exports.isDateUnit = exports.isTimestampUnit = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isBasicArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isCompoundArrayData = exports.isBasicAtomic = exports.isAtomic = exports.isSourceDef = exports.validateDottedTablePath = exports.decodeDottedTablePath = exports.Dialect = exports.spread = exports.literal = exports.variadicParam = exports.param = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.qtz = exports.arg = exports.registerDialect = exports.DatabricksDialect = exports.MySQLDialect = exports.SnowflakeDialect = exports.PostgresDialect = exports.TrinoDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
41
- exports.Reference = exports.EMPTY_BUILD_MANIFEST = exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = exports.tagFromAnnotations = exports.annotationsForRoute = exports.payloadOf = exports.routeOf = exports.RoutedNote = exports.Annotations = exports.sqlKey = exports.API = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = exports.createConnectionsFromConfig = exports.getRegisteredConnectionTypes = exports.getConnectionTypeDisplayName = exports.getConnectionProperties = exports.registerConnectionType = exports.discoverConfig = exports.defaultConfigOverlays = exports.contextOverlay = exports.envOverlay = exports.MalloyConfig = exports.Manifest = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = void 0;
42
- exports.makeDigest = void 0;
40
+ exports.malloyToQuery = exports.constantExprToSQL = exports.isDateUnit = exports.isTimestampUnit = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isBasicArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isCompoundArrayData = exports.isBasicAtomic = exports.isAtomic = exports.isSourceDef = exports.validateDottedTablePath = exports.decodeDottedTablePath = exports.Dialect = exports.spread = exports.literal = exports.variadicParam = exports.param = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.queryZone = exports.arg = exports.getDialect = exports.registerDialect = exports.SQLServerDialect = exports.DatabricksDialect = exports.MySQLDialect = exports.SnowflakeDialect = exports.PostgresDialect = exports.TrinoDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
41
+ exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = exports.tagFromAnnotations = exports.annotationsForRoute = exports.payloadOf = exports.routeOf = exports.RoutedNote = exports.Annotations = exports.sqlKey = exports.API = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = exports.createConnectionsFromConfig = exports.getRegisteredConnectionTypes = exports.getConnectionTypeDisplayName = exports.getConnectionProperties = exports.registerConnectionType = exports.discoverConfig = exports.defaultConfigOverlays = exports.contextOverlay = exports.envOverlay = exports.MalloyConfig = exports.Manifest = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = void 0;
42
+ exports.makeDigest = exports.Reference = exports.EMPTY_BUILD_MANIFEST = void 0;
43
43
  var dialect_1 = require("./dialect");
44
44
  Object.defineProperty(exports, "DuckDBDialect", { enumerable: true, get: function () { return dialect_1.DuckDBDialect; } });
45
45
  Object.defineProperty(exports, "StandardSQLDialect", { enumerable: true, get: function () { return dialect_1.StandardSQLDialect; } });
@@ -48,9 +48,11 @@ Object.defineProperty(exports, "PostgresDialect", { enumerable: true, get: funct
48
48
  Object.defineProperty(exports, "SnowflakeDialect", { enumerable: true, get: function () { return dialect_1.SnowflakeDialect; } });
49
49
  Object.defineProperty(exports, "MySQLDialect", { enumerable: true, get: function () { return dialect_1.MySQLDialect; } });
50
50
  Object.defineProperty(exports, "DatabricksDialect", { enumerable: true, get: function () { return dialect_1.DatabricksDialect; } });
51
+ Object.defineProperty(exports, "SQLServerDialect", { enumerable: true, get: function () { return dialect_1.SQLServerDialect; } });
51
52
  Object.defineProperty(exports, "registerDialect", { enumerable: true, get: function () { return dialect_1.registerDialect; } });
53
+ Object.defineProperty(exports, "getDialect", { enumerable: true, get: function () { return dialect_1.getDialect; } });
52
54
  Object.defineProperty(exports, "arg", { enumerable: true, get: function () { return dialect_1.arg; } });
53
- Object.defineProperty(exports, "qtz", { enumerable: true, get: function () { return dialect_1.qtz; } });
55
+ Object.defineProperty(exports, "queryZone", { enumerable: true, get: function () { return dialect_1.queryZone; } });
54
56
  Object.defineProperty(exports, "overload", { enumerable: true, get: function () { return dialect_1.overload; } });
55
57
  Object.defineProperty(exports, "minScalar", { enumerable: true, get: function () { return dialect_1.minScalar; } });
56
58
  Object.defineProperty(exports, "anyExprType", { enumerable: true, get: function () { return dialect_1.anyExprType; } });
@@ -0,0 +1,24 @@
1
+ import type { ExprValue } from '../types/expr-value';
2
+ import type { FieldSpace } from '../types/field-space';
3
+ import type { MalloyElement } from '../types/malloy-element';
4
+ /**
5
+ * On a dialect with booleanType 'none' a boolean is a condition and never a
6
+ * value. When `type` is a boolean about to be used as a value, logs an error
7
+ * at `logTo` and returns an error-typed value for the caller to return in
8
+ * place of what it was building, so the enclosing expressions see an error
9
+ * and stay quiet. Otherwise returns undefined. `where` says how the boolean
10
+ * was used, `hint` what to write instead.
11
+ */
12
+ export declare function booleanValueError(fs: FieldSpace, type: {
13
+ type: string;
14
+ } | undefined, where: string, logTo: MalloyElement, hint: string): ExprValue | undefined;
15
+ /** The hint where a boolean's unknown state is examined: `is null`, `??` */
16
+ export declare const CONDITION_HINT = "test the condition itself; unknown already tests as false";
17
+ /** The hint for a boolean compared with anything */
18
+ export declare const COMPARE_HINT = "test the condition itself, or its not";
19
+ /** The hint where a number would do: a function argument, a cast */
20
+ export declare const NUMBER_HINT = "write the value, pick 1 when \u2026 else 0";
21
+ /** The hint for a boolean as a result column, from the source text it came from */
22
+ export declare function resultColumnHint(src: string): string;
23
+ /** The hint for a `pick` or `case` whose result is a boolean */
24
+ export declare const CHOICE_HINT = "write values, pick 'yes' when \u2026 else 'no', or the condition itself with and, or and not";
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.CHOICE_HINT = exports.NUMBER_HINT = exports.COMPARE_HINT = exports.CONDITION_HINT = void 0;
8
+ exports.booleanValueError = booleanValueError;
9
+ exports.resultColumnHint = resultColumnHint;
10
+ /**
11
+ * On a dialect with booleanType 'none' a boolean is a condition and never a
12
+ * value. When `type` is a boolean about to be used as a value, logs an error
13
+ * at `logTo` and returns an error-typed value for the caller to return in
14
+ * place of what it was building, so the enclosing expressions see an error
15
+ * and stay quiet. Otherwise returns undefined. `where` says how the boolean
16
+ * was used, `hint` what to write instead.
17
+ */
18
+ function booleanValueError(fs, type, where, logTo, hint) {
19
+ const dialect = fs.dialectObj();
20
+ if ((type === null || type === void 0 ? void 0 : type.type) !== 'boolean' || (dialect === null || dialect === void 0 ? void 0 : dialect.booleanType) !== 'none') {
21
+ return undefined;
22
+ }
23
+ return logTo.loggedErrorExpr('boolean-value-unsupported', {
24
+ dialect: dialect.name,
25
+ where,
26
+ hint,
27
+ });
28
+ }
29
+ /** The hint where a boolean's unknown state is examined: `is null`, `??` */
30
+ exports.CONDITION_HINT = 'test the condition itself; unknown already tests as false';
31
+ /** The hint for a boolean compared with anything */
32
+ exports.COMPARE_HINT = 'test the condition itself, or its not';
33
+ /** The hint where a number would do: a function argument, a cast */
34
+ exports.NUMBER_HINT = 'write the value, pick 1 when … else 0';
35
+ /** The hint for a boolean as a result column, from the source text it came from */
36
+ function resultColumnHint(src) {
37
+ return `write the value, pick 'yes' when ${src} else 'no'`;
38
+ }
39
+ /** The hint for a `pick` or `case` whose result is a boolean */
40
+ exports.CHOICE_HINT = "write values, pick 'yes' when … else 'no', or the condition itself with and, or and not";
41
+ //# sourceMappingURL=boolean-value.js.map
@@ -42,6 +42,7 @@ const expr_value_1 = require("../types/expr-value");
42
42
  const expression_def_1 = require("../types/expression-def");
43
43
  const malloy_element_1 = require("../types/malloy-element");
44
44
  const TDU = __importStar(require("../typedesc-utils"));
45
+ const boolean_value_1 = require("./boolean-value");
45
46
  function typeCoalesce(ev1, ev2) {
46
47
  return ev1 === undefined || ev1.type === 'null' || ev1.type === 'error'
47
48
  ? ev2
@@ -68,6 +69,9 @@ class Case extends expression_def_1.ExpressionDef {
68
69
  let value = undefined;
69
70
  if (this.value) {
70
71
  const v = this.value.getExpression(fs);
72
+ const noSubject = (0, boolean_value_1.booleanValueError)(fs, v, 'as the subject of a case', this.value, 'write the conditions, case when … then …');
73
+ if (noSubject)
74
+ return noSubject;
71
75
  dependents.push(v);
72
76
  resultExpr.kids.caseValue = v.value;
73
77
  value = v;
@@ -118,6 +122,9 @@ class Case extends expression_def_1.ExpressionDef {
118
122
  dependents.push(elseValue);
119
123
  resultExpr.kids.caseElse = elseValue.value;
120
124
  }
125
+ const noCase = (0, boolean_value_1.booleanValueError)(fs, returnType, 'as the result of a case', this, boolean_value_1.CHOICE_HINT);
126
+ if (noCase)
127
+ return noCase;
121
128
  return (0, expr_value_1.computedExprValue)({
122
129
  value: resultExpr,
123
130
  dataType: returnType ? TDU.atomicDef(returnType) : { type: 'null' },
@@ -8,6 +8,7 @@ exports.ExprAlternationTree = void 0;
8
8
  const expr_value_1 = require("../types/expr-value");
9
9
  const expression_def_1 = require("../types/expression-def");
10
10
  const binary_operators_1 = require("../types/binary_operators");
11
+ const boolean_value_1 = require("./boolean-value");
11
12
  /**
12
13
  * Return a flattened version of an alternation tree, if the tree is
13
14
  * composed entirely values and "or"s.
@@ -58,6 +59,16 @@ class ExprAlternationTree extends expression_def_1.ExpressionDef {
58
59
  if (inList.length > 0 && (applyOp === '=' || applyOp === '!=')) {
59
60
  const isIn = expr.getExpression(fs);
60
61
  const values = inList.map(v => v.getExpression(fs));
62
+ // A boolean on either side of the comparison, the tested value or
63
+ // any of the choices, is a boolean compared with something.
64
+ for (const [el, val] of [
65
+ [expr, isIn],
66
+ ...inList.map((el, i) => [el, values[i]]),
67
+ ]) {
68
+ const noIn = (0, boolean_value_1.booleanValueError)(fs, val, `compared with ${applyOp}`, el, boolean_value_1.COMPARE_HINT);
69
+ if (noIn)
70
+ return noIn;
71
+ }
61
72
  return (0, expr_value_1.computedExprValue)({
62
73
  dataType: { type: 'boolean' },
63
74
  value: {
@@ -8,6 +8,7 @@ exports.ExprCast = void 0;
8
8
  const time_utils_1 = require("../time-utils");
9
9
  const expr_value_1 = require("../types/expr-value");
10
10
  const expression_def_1 = require("../types/expression-def");
11
+ const boolean_value_1 = require("./boolean-value");
11
12
  class ExprCast extends expression_def_1.ExpressionDef {
12
13
  constructor(expr, castType, safe = false) {
13
14
  super({ expr: expr });
@@ -38,6 +39,10 @@ class ExprCast extends expression_def_1.ExpressionDef {
38
39
  }
39
40
  }
40
41
  }
42
+ const noCast = (0, boolean_value_1.booleanValueError)(fs, expr, 'in a cast', this, boolean_value_1.NUMBER_HINT) ||
43
+ (0, boolean_value_1.booleanValueError)(fs, dataType, 'as the type of a cast', this, 'write a comparison');
44
+ if (noCast)
45
+ return noCast;
41
46
  return (0, expr_value_1.computedExprValue)({
42
47
  dataType,
43
48
  value: (0, time_utils_1.castTo)(this.castType, expr.value, expr.type, this.safe),
@@ -42,6 +42,7 @@ const model_1 = require("../../../model");
42
42
  const composite_source_utils_1 = require("../../composite-source-utils");
43
43
  const TDU = __importStar(require("../typedesc-utils"));
44
44
  const expression_def_1 = require("../types/expression-def");
45
+ const boolean_value_1 = require("./boolean-value");
45
46
  class ExprCoalesce extends expression_def_1.ExpressionDef {
46
47
  constructor(expr, altExpr) {
47
48
  super({ expr, altExpr });
@@ -53,6 +54,9 @@ class ExprCoalesce extends expression_def_1.ExpressionDef {
53
54
  computeExpression(fs) {
54
55
  const maybeNull = this.expr.getExpression(fs);
55
56
  const whenNull = this.altExpr.getExpression(fs);
57
+ const noCoalesce = (0, boolean_value_1.booleanValueError)(fs, maybeNull, 'in ??', this, boolean_value_1.CONDITION_HINT);
58
+ if (noCoalesce)
59
+ return noCoalesce;
56
60
  if (maybeNull.type === 'null') {
57
61
  return whenNull;
58
62
  }
@@ -48,6 +48,7 @@ const field_space_1 = require("../types/field-space");
48
48
  const utils_2 = require("../../../model/utils");
49
49
  const TDU = __importStar(require("../typedesc-utils"));
50
50
  const composite_source_utils_1 = require("../../composite-source-utils");
51
+ const boolean_value_1 = require("./boolean-value");
51
52
  // Built-in functions that take a string literal of user-supplied SQL
52
53
  // and emit it directly. Gated by experimental.sql_functions in plain
53
54
  // Malloy; rejected unconditionally in restricted queries because they
@@ -111,9 +112,14 @@ class ExprFunc extends expression_def_1.ExpressionDef {
111
112
  return { found: func, error: undefined };
112
113
  }
113
114
  getPropsExpression(fs, props) {
114
- var _a, _b, _c, _d, _e;
115
+ var _a, _b, _c, _d, _e, _f;
115
116
  const argExprsWithoutImplicit = this.args.map(arg => arg.getExpression(fs));
116
117
  if (this.isRaw) {
118
+ for (const [i, argExpr] of argExprsWithoutImplicit.entries()) {
119
+ const noArg = (0, boolean_value_1.booleanValueError)(fs, argExpr, `as an argument of ${this.name}`, this.args[i], boolean_value_1.NUMBER_HINT);
120
+ if (noArg)
121
+ return noArg;
122
+ }
117
123
  const funcCall = [`${this.name}(`];
118
124
  argExprsWithoutImplicit.forEach((expr, i) => {
119
125
  if (i !== 0) {
@@ -182,6 +188,11 @@ class ExprFunc extends expression_def_1.ExpressionDef {
182
188
  .join(', ')})`);
183
189
  }
184
190
  const { overload, expressionTypeErrors, evalSpaceErrors, nullabilityErrors, returnType, } = result;
191
+ for (const [i, argExpr] of argExprs.entries()) {
192
+ const noArg = (0, boolean_value_1.booleanValueError)(fs, argExpr, `as an argument of ${this.name}`, (_e = this.args[i - (implicitExpr ? 1 : 0)]) !== null && _e !== void 0 ? _e : this, boolean_value_1.NUMBER_HINT);
193
+ if (noArg)
194
+ return noArg;
195
+ }
185
196
  // Report errors for expression type mismatch
186
197
  for (const error of expressionTypeErrors) {
187
198
  const adjustedIndex = error.argIndex - (implicitExpr ? 1 : 0);
@@ -214,7 +225,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
214
225
  }
215
226
  const type = overload.returnType;
216
227
  const expressionType = (0, malloy_types_1.maxOfExpressionTypes)([
217
- (_e = type.expressionType) !== null && _e !== void 0 ? _e : 'scalar',
228
+ (_f = type.expressionType) !== null && _f !== void 0 ? _f : 'scalar',
218
229
  ...argExprs.map(e => e.expressionType),
219
230
  ]);
220
231
  if (!(0, malloy_types_1.expressionIsAggregate)(overload.returnType.expressionType) &&
@@ -38,7 +38,6 @@ var __importStar = (this && this.__importStar) || (function () {
38
38
  })();
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
40
  exports.ExprMinus = void 0;
41
- const ast_utils_1 = require("../ast-utils");
42
41
  const TDU = __importStar(require("../typedesc-utils"));
43
42
  const expression_def_1 = require("../types/expression-def");
44
43
  class ExprMinus extends expression_def_1.ExpressionDef {
@@ -50,6 +49,10 @@ class ExprMinus extends expression_def_1.ExpressionDef {
50
49
  }
51
50
  computeExpression(fs) {
52
51
  const expr = this.expr.getExpression(fs);
52
+ // An error is already logged; it stays an error so nothing else logs it
53
+ if (expr.type === 'error') {
54
+ return expr;
55
+ }
53
56
  if (TDU.typeIn(expr, this.legalChildTypes)) {
54
57
  return {
55
58
  ...expr,
@@ -57,7 +60,7 @@ class ExprMinus extends expression_def_1.ExpressionDef {
57
60
  value: { node: 'unary-', e: expr.value },
58
61
  };
59
62
  }
60
- return (0, ast_utils_1.errorFor)('negate requires number');
63
+ return this.expr.loggedErrorExpr('expression-type-error', `'${this.elementType}' Can't use type ${TDU.inspect(expr)}`);
61
64
  }
62
65
  }
63
66
  exports.ExprMinus = ExprMinus;
@@ -7,11 +7,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.ExprIsNull = exports.PartialIsNull = exports.ExprNULL = void 0;
8
8
  const expr_value_1 = require("../types/expr-value");
9
9
  const expression_def_1 = require("../types/expression-def");
10
+ const boolean_value_1 = require("./boolean-value");
10
11
  function doIsNull(fs, op, expr) {
11
12
  // Build a new value rather than retyping the operand's in place: what
12
13
  // getExpression hands back is shared, and the operand is usually asked for
13
14
  // its value again after this.
14
15
  const nullCmp = expr.getExpression(fs);
16
+ const noTest = (0, boolean_value_1.booleanValueError)(fs, nullCmp, 'in a null test', expr, boolean_value_1.CONDITION_HINT);
17
+ if (noTest)
18
+ return noTest;
15
19
  return (0, expr_value_1.computedExprValue)({
16
20
  dataType: { type: 'boolean' },
17
21
  value: {
@@ -42,6 +42,7 @@ const TDU = __importStar(require("../typedesc-utils"));
42
42
  const expr_value_1 = require("../types/expr-value");
43
43
  const expression_def_1 = require("../types/expression-def");
44
44
  const malloy_element_1 = require("../types/malloy-element");
45
+ const boolean_value_1 = require("./boolean-value");
45
46
  function typeCoalesce(ev1, ev2) {
46
47
  if (ev1 === undefined || ev1.type === 'null' || ev1.type === 'error') {
47
48
  return ev2;
@@ -131,6 +132,9 @@ class Pick extends expression_def_1.ExpressionDef {
131
132
  if (definedReturnType.type === 'filter expression') {
132
133
  return this.loggedErrorExpr('filter-expression-error', 'Pick statments cannot have filter expression values');
133
134
  }
135
+ const noPick = (0, boolean_value_1.booleanValueError)(fs, definedReturnType, 'as the result of a pick', this, boolean_value_1.CHOICE_HINT);
136
+ if (noPick)
137
+ return noPick;
134
138
  caseValue.kids.caseElse = defaultVal.value;
135
139
  return (0, expr_value_1.computedExprValue)({
136
140
  dataType: definedReturnType,
@@ -193,6 +197,9 @@ class Pick extends expression_def_1.ExpressionDef {
193
197
  if (definedReturnType.type === 'filter expression') {
194
198
  return this.loggedErrorExpr('filter-expression-error', 'Pick statments cannot have filter expression values');
195
199
  }
200
+ const noPick = (0, boolean_value_1.booleanValueError)(fs, definedReturnType, 'as the result of a pick', this, boolean_value_1.CHOICE_HINT);
201
+ if (noPick)
202
+ return noPick;
196
203
  pick.kids.caseElse = defVal.value;
197
204
  return (0, expr_value_1.computedExprValue)({
198
205
  dataType: definedReturnType,
@@ -8,6 +8,7 @@ exports.IndexFieldSpace = void 0;
8
8
  const composite_source_utils_1 = require("../../composite-source-utils");
9
9
  const malloy_types_1 = require("../../../model/malloy_types");
10
10
  const error_factory_1 = require("../error-factory");
11
+ const boolean_value_1 = require("../expressions/boolean-value");
11
12
  const field_references_1 = require("../query-items/field-references");
12
13
  const space_field_1 = require("../types/space-field");
13
14
  const query_spaces_1 = require("./query-spaces");
@@ -98,10 +99,21 @@ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
98
99
  }
99
100
  else {
100
101
  const eTypeDesc = entry.typeDesc();
102
+ if (
101
103
  // Don't index arrays and records
102
- if (malloy_types_1.TD.isBasicAtomic(eTypeDesc) &&
104
+ malloy_types_1.TD.isBasicAtomic(eTypeDesc) &&
103
105
  (0, malloy_types_1.expressionIsScalar)(eTypeDesc.expressionType) &&
104
106
  (dialect === undefined || !dialect.ignoreInProject(name))) {
107
+ if (eTypeDesc.type === 'boolean' && (dialect === null || dialect === void 0 ? void 0 : dialect.booleanType) === 'none') {
108
+ const path = [...joinPath, name].join('.');
109
+ wild.logWarning('wildcard-omits-boolean', {
110
+ dialect: dialect.name,
111
+ wildcard: wild.refString,
112
+ name: path,
113
+ hint: (0, boolean_value_1.resultColumnHint)(path),
114
+ });
115
+ continue;
116
+ }
105
117
  expandEntries.push({ name: indexName, entry });
106
118
  this.expandedWild.set(indexName, {
107
119
  path: joinPath.concat(name),
@@ -48,6 +48,7 @@ const static_space_1 = require("./static-space");
48
48
  const query_input_space_1 = require("./query-input-space");
49
49
  const composite_source_utils_1 = require("../../composite-source-utils");
50
50
  const error_factory_1 = require("../error-factory");
51
+ const boolean_value_1 = require("../expressions/boolean-value");
51
52
  const reference_field_1 = require("./reference-field");
52
53
  const refine_from_space_field_1 = require("./refine-from-space-field");
53
54
  /**
@@ -158,6 +159,16 @@ class QueryOperationSpace extends refined_space_1.RefinedSpace {
158
159
  if (model.TD.isAtomic(eType) &&
159
160
  model.expressionIsScalar(eType.expressionType) &&
160
161
  (dialect === undefined || !dialect.ignoreInProject(name))) {
162
+ if (eType.type === 'boolean' && (dialect === null || dialect === void 0 ? void 0 : dialect.booleanType) === 'none') {
163
+ const path = joinPath.concat(name).join('.');
164
+ wild.logWarning('wildcard-omits-boolean', {
165
+ dialect: dialect.name,
166
+ wildcard: wild.refString,
167
+ name: path,
168
+ hint: (0, boolean_value_1.resultColumnHint)(path),
169
+ });
170
+ continue;
171
+ }
161
172
  expandEntries.push({ name, entry });
162
173
  this.expandedWild.set(name, {
163
174
  path: joinPath.concat(name),
@@ -55,7 +55,7 @@ class QuerySegmentBuilder {
55
55
  }
56
56
  refineFrom(from, to) {
57
57
  if (from && from.type !== 'index' && from.type !== 'raw') {
58
- if (!this.limit && from.orderBy && !from.defaultOrderBy) {
58
+ if (!this.order && from.orderBy && !from.defaultOrderBy) {
59
59
  to.orderBy = from.orderBy;
60
60
  }
61
61
  if (!this.limit && from.limit) {
@@ -19,24 +19,29 @@ export declare abstract class AtomicFieldDeclaration extends MalloyElement imple
19
19
  fieldDef(fs: FieldSpace, exprName: string): FieldDef;
20
20
  abstract typecheckExprValue(expr: ExprValue): void;
21
21
  executesInOutputSpace(): boolean;
22
+ outputsValue(): boolean;
22
23
  queryFieldDef(exprFS: FieldSpace, exprName: string): AtomicFieldDef;
23
24
  makeEntry(fs: DynamicSpace): void;
24
25
  }
25
26
  export declare class CalculateFieldDeclaration extends AtomicFieldDeclaration {
26
27
  elementType: string;
28
+ outputsValue(): boolean;
27
29
  typecheckExprValue(expr: ExprValue): void;
28
30
  executesInOutputSpace(): boolean;
29
31
  }
30
32
  export declare class AggregateFieldDeclaration extends AtomicFieldDeclaration {
31
33
  elementType: string;
34
+ outputsValue(): boolean;
32
35
  typecheckExprValue(expr: ExprValue): void;
33
36
  }
34
37
  export declare class GroupByFieldDeclaration extends AtomicFieldDeclaration {
35
38
  elementType: string;
39
+ outputsValue(): boolean;
36
40
  typecheckExprValue(expr: ExprValue): void;
37
41
  }
38
42
  export declare class ProjectFieldDeclaration extends AtomicFieldDeclaration {
39
43
  elementType: string;
44
+ outputsValue(): boolean;
40
45
  typecheckExprValue(expr: ExprValue): void;
41
46
  }
42
47
  export declare class DeclareFieldDeclaration extends AtomicFieldDeclaration {
@@ -45,6 +45,7 @@ const malloy_element_1 = require("../types/malloy-element");
45
45
  const typecheck_utils_1 = require("./typecheck_utils");
46
46
  const space_field_1 = require("../types/space-field");
47
47
  const def_space_1 = require("../field-space/def-space");
48
+ const boolean_value_1 = require("../expressions/boolean-value");
48
49
  class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
49
50
  constructor(expr, defineName, exprSrc) {
50
51
  super({ expr: expr });
@@ -71,6 +72,10 @@ class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
71
72
  executesInOutputSpace() {
72
73
  return false;
73
74
  }
75
+ // The declaration is a result column of a query
76
+ outputsValue() {
77
+ return false;
78
+ }
74
79
  queryFieldDef(exprFS, exprName) {
75
80
  var _a;
76
81
  let exprValue;
@@ -105,27 +110,16 @@ class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
105
110
  }
106
111
  if ((0, malloy_types_1.isAtomicFieldType)(exprValue.type) && exprValue.type !== 'error') {
107
112
  this.typecheckExprValue(exprValue);
113
+ if (this.outputsValue() &&
114
+ (0, boolean_value_1.booleanValueError)(exprFS, exprValue, 'as a result column', this.expr, (0, boolean_value_1.resultColumnHint)((_a = this.exprSrc) !== null && _a !== void 0 ? _a : '…'))) {
115
+ return { name: exprName, type: 'error' };
116
+ }
108
117
  const ret = (0, malloy_types_1.mkFieldDef)(TDU.atomicDef(exprValue), exprName);
109
118
  if (malloy_types_1.TD.isTemporal(ret) && (0, granular_result_1.isGranularResult)(exprValue)) {
110
119
  ret.timeframe = exprValue.timeframe;
111
120
  }
112
121
  ret.location = this.location;
113
- if (exprValue.type === 'boolean' &&
114
- ((_a = exprFS.dialectObj()) === null || _a === void 0 ? void 0 : _a.booleanType) === 'none') {
115
- // when generating a boolean field on a database without boolean support
116
- // map it to integers
117
- ret.e = {
118
- node: 'case',
119
- kids: {
120
- caseWhen: [exprValue.value],
121
- caseThen: [{ node: 'numberLiteral', literal: '1' }],
122
- caseElse: { node: 'numberLiteral', literal: '0' },
123
- },
124
- };
125
- }
126
- else {
127
- ret.e = exprValue.value;
128
- }
122
+ ret.e = exprValue.value;
129
123
  ret.drillExpression = this.expr.drillExpression();
130
124
  ret.refSummary = exprValue.refSummary;
131
125
  ret.ungroupings = exprValue.ungroupings;
@@ -163,6 +157,9 @@ class CalculateFieldDeclaration extends AtomicFieldDeclaration {
163
157
  super(...arguments);
164
158
  this.elementType = 'calculateFieldDeclaration';
165
159
  }
160
+ outputsValue() {
161
+ return true;
162
+ }
166
163
  typecheckExprValue(expr) {
167
164
  (0, typecheck_utils_1.typecheckCalculate)(expr, this);
168
165
  }
@@ -176,6 +173,9 @@ class AggregateFieldDeclaration extends AtomicFieldDeclaration {
176
173
  super(...arguments);
177
174
  this.elementType = 'aggregateFieldDeclaration';
178
175
  }
176
+ outputsValue() {
177
+ return true;
178
+ }
179
179
  typecheckExprValue(expr) {
180
180
  (0, typecheck_utils_1.typecheckAggregate)(expr, this);
181
181
  }
@@ -186,6 +186,9 @@ class GroupByFieldDeclaration extends AtomicFieldDeclaration {
186
186
  super(...arguments);
187
187
  this.elementType = 'groupByFieldDeclaration';
188
188
  }
189
+ outputsValue() {
190
+ return true;
191
+ }
189
192
  typecheckExprValue(expr) {
190
193
  (0, typecheck_utils_1.typecheckGroupBy)(expr, this);
191
194
  }
@@ -196,6 +199,9 @@ class ProjectFieldDeclaration extends AtomicFieldDeclaration {
196
199
  super(...arguments);
197
200
  this.elementType = 'projectFieldDeclaration';
198
201
  }
202
+ outputsValue() {
203
+ return true;
204
+ }
199
205
  typecheckExprValue(expr) {
200
206
  (0, typecheck_utils_1.typecheckProject)(expr, this);
201
207
  }
@@ -25,6 +25,7 @@ export declare abstract class FieldReference extends ListOf<FieldName> implement
25
25
  get sourceString(): string | undefined;
26
26
  get nameString(): string;
27
27
  abstract typecheck(type: TypeDesc): void;
28
+ outputsValue(): boolean;
28
29
  getField(fs: FieldSpace): LookupResult;
29
30
  }
30
31
  export declare class AcceptExceptFieldReference extends FieldReference {
@@ -61,27 +62,32 @@ export declare class DrillFieldReference extends FieldReference {
61
62
  }
62
63
  export declare class CalculateFieldReference extends FieldReference {
63
64
  elementType: string;
65
+ outputsValue(): boolean;
64
66
  protected autoRenameDeclarationCtor(): typeof CalculateFieldDeclaration;
65
67
  typecheck(type: TypeDesc): void;
66
68
  }
67
69
  export declare class IndexFieldReference extends FieldReference {
68
70
  elementType: string;
71
+ outputsValue(): boolean;
69
72
  typecheck(type: TypeDesc): void;
70
73
  static indexOutputName(path: string[]): string;
71
74
  get outputName(): string;
72
75
  }
73
76
  export declare class AggregateFieldReference extends FieldReference {
74
77
  elementType: string;
78
+ outputsValue(): boolean;
75
79
  protected autoRenameDeclarationCtor(): typeof AggregateFieldDeclaration;
76
80
  typecheck(type: TypeDesc): void;
77
81
  }
78
82
  export declare class GroupByFieldReference extends FieldReference {
79
83
  elementType: string;
84
+ outputsValue(): boolean;
80
85
  protected autoRenameDeclarationCtor(): typeof GroupByFieldDeclaration;
81
86
  typecheck(type: TypeDesc): void;
82
87
  }
83
88
  export declare class ProjectFieldReference extends FieldReference {
84
89
  elementType: string;
90
+ outputsValue(): boolean;
85
91
  protected autoRenameDeclarationCtor(): typeof ProjectFieldDeclaration;
86
92
  typecheck(type: TypeDesc): void;
87
93
  }
@@ -10,6 +10,7 @@ const definition_list_1 = require("../types/definition-list");
10
10
  const field_space_1 = require("../types/field-space");
11
11
  const malloy_element_1 = require("../types/malloy-element");
12
12
  const expr_id_reference_1 = require("../expressions/expr-id-reference");
13
+ const boolean_value_1 = require("../expressions/boolean-value");
13
14
  const field_declaration_1 = require("./field-declaration");
14
15
  const typecheck_utils_1 = require("./typecheck_utils");
15
16
  class FieldReference extends malloy_element_1.ListOf {
@@ -108,11 +109,18 @@ class FieldReference extends malloy_element_1.ListOf {
108
109
  get nameString() {
109
110
  return this.list[this.list.length - 1].refString;
110
111
  }
112
+ // The reference is a result column of a query
113
+ outputsValue() {
114
+ return false;
115
+ }
111
116
  getField(fs) {
112
117
  const result = fs.lookup(this.list);
113
118
  if (result.found) {
114
119
  const actualType = result.found.typeDesc();
115
120
  this.typecheck(actualType);
121
+ if (this.outputsValue()) {
122
+ (0, boolean_value_1.booleanValueError)(fs, actualType, 'as a result column', this, (0, boolean_value_1.resultColumnHint)(this.refString));
123
+ }
116
124
  }
117
125
  return result;
118
126
  }
@@ -210,6 +218,9 @@ class CalculateFieldReference extends FieldReference {
210
218
  super(...arguments);
211
219
  this.elementType = 'calculateFieldReference';
212
220
  }
221
+ outputsValue() {
222
+ return true;
223
+ }
213
224
  autoRenameDeclarationCtor() {
214
225
  return field_declaration_1.CalculateFieldDeclaration;
215
226
  }
@@ -223,6 +234,9 @@ class IndexFieldReference extends FieldReference {
223
234
  super(...arguments);
224
235
  this.elementType = 'indexFieldReference';
225
236
  }
237
+ outputsValue() {
238
+ return true;
239
+ }
226
240
  typecheck(type) {
227
241
  (0, typecheck_utils_1.typecheckIndex)(type, this);
228
242
  }
@@ -240,6 +254,9 @@ class AggregateFieldReference extends FieldReference {
240
254
  super(...arguments);
241
255
  this.elementType = 'aggregateFieldReference';
242
256
  }
257
+ outputsValue() {
258
+ return true;
259
+ }
243
260
  autoRenameDeclarationCtor() {
244
261
  return field_declaration_1.AggregateFieldDeclaration;
245
262
  }
@@ -253,6 +270,9 @@ class GroupByFieldReference extends FieldReference {
253
270
  super(...arguments);
254
271
  this.elementType = 'groupByFieldReference';
255
272
  }
273
+ outputsValue() {
274
+ return true;
275
+ }
256
276
  autoRenameDeclarationCtor() {
257
277
  return field_declaration_1.GroupByFieldDeclaration;
258
278
  }
@@ -266,6 +286,9 @@ class ProjectFieldReference extends FieldReference {
266
286
  super(...arguments);
267
287
  this.elementType = 'projectFieldReference';
268
288
  }
289
+ outputsValue() {
290
+ return true;
291
+ }
269
292
  autoRenameDeclarationCtor() {
270
293
  return field_declaration_1.ProjectFieldDeclaration;
271
294
  }
@@ -50,7 +50,9 @@ class FilterElement extends malloy_element_1.MalloyElement {
50
50
  filterCondition(fs) {
51
51
  const exprVal = this.expr.getExpression(fs);
52
52
  if (exprVal.type !== 'boolean') {
53
- this.expr.logError('non-boolean-filter', 'Filter expression must have boolean value');
53
+ if (exprVal.type !== 'error') {
54
+ this.expr.logError('non-boolean-filter', 'Filter expression must have boolean value');
55
+ }
54
56
  return {
55
57
  node: 'filterCondition',
56
58
  code: this.exprSrc,
@@ -52,7 +52,6 @@ class NamedSource extends source_1.Source {
52
52
  }
53
53
  }
54
54
  modelStruct() {
55
- var _a;
56
55
  const modelEnt = this.modelEntry(this.ref);
57
56
  const entry = modelEnt === null || modelEnt === void 0 ? void 0 : modelEnt.entry;
58
57
  if (!entry) {
@@ -89,7 +88,6 @@ class NamedSource extends source_1.Source {
89
88
  return;
90
89
  }
91
90
  else {
92
- (_a = this.document()) === null || _a === void 0 ? void 0 : _a.checkExperimentalDialect(this, entry.dialect);
93
91
  if ((0, malloy_types_1.isSourceDef)(entry)) {
94
92
  // This struct is created as an unmodified reference to `entry`. Mark it
95
93
  // with entry's own identity; the modification path (DynamicSpace) clears