@malloydata/malloy 0.0.393 → 0.0.395

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 (71) hide show
  1. package/dist/api/foundation/config.d.ts +2 -3
  2. package/dist/api/foundation/config.js +23 -11
  3. package/dist/api/foundation/core.d.ts +0 -4
  4. package/dist/api/foundation/core.js +14 -11
  5. package/dist/api/foundation/runtime.js +21 -1
  6. package/dist/api/util.js +4 -0
  7. package/dist/connection/base_connection.js +6 -0
  8. package/dist/connection/validate_table_path.d.ts +10 -0
  9. package/dist/connection/validate_table_path.js +56 -0
  10. package/dist/dialect/databricks/databricks.d.ts +4 -4
  11. package/dist/dialect/databricks/databricks.js +17 -22
  12. package/dist/dialect/dialect.d.ts +100 -4
  13. package/dist/dialect/dialect.js +145 -1
  14. package/dist/dialect/duckdb/duckdb.d.ts +2 -3
  15. package/dist/dialect/duckdb/duckdb.js +12 -14
  16. package/dist/dialect/duckdb/table-path-parser.d.ts +2 -0
  17. package/dist/dialect/duckdb/table-path-parser.js +57 -0
  18. package/dist/dialect/index.d.ts +2 -0
  19. package/dist/dialect/index.js +4 -1
  20. package/dist/dialect/mysql/mysql.d.ts +4 -4
  21. package/dist/dialect/mysql/mysql.js +25 -20
  22. package/dist/dialect/pg_impl.d.ts +3 -1
  23. package/dist/dialect/pg_impl.js +6 -3
  24. package/dist/dialect/postgres/postgres.d.ts +1 -3
  25. package/dist/dialect/postgres/postgres.js +8 -16
  26. package/dist/dialect/snowflake/snowflake.d.ts +4 -4
  27. package/dist/dialect/snowflake/snowflake.js +11 -27
  28. package/dist/dialect/standardsql/standardsql.d.ts +6 -4
  29. package/dist/dialect/standardsql/standardsql.js +36 -15
  30. package/dist/dialect/table-path.d.ts +54 -0
  31. package/dist/dialect/table-path.js +144 -0
  32. package/dist/dialect/trino/trino.d.ts +0 -3
  33. package/dist/dialect/trino/trino.js +7 -20
  34. package/dist/index.d.ts +2 -2
  35. package/dist/index.js +4 -2
  36. package/dist/lang/ast/expressions/expr-compare.d.ts +15 -0
  37. package/dist/lang/ast/expressions/expr-compare.js +82 -2
  38. package/dist/lang/ast/source-elements/table-source.d.ts +1 -7
  39. package/dist/lang/ast/source-elements/table-source.js +20 -19
  40. package/dist/lang/ast/statements/define-given.d.ts +2 -1
  41. package/dist/lang/ast/statements/define-given.js +52 -1
  42. package/dist/lang/ast/types/malloy-element.js +2 -0
  43. package/dist/lang/lib/Malloy/MalloyParser.d.ts +188 -167
  44. package/dist/lang/lib/Malloy/MalloyParser.js +2582 -2442
  45. package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +24 -0
  46. package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +15 -0
  47. package/dist/lang/malloy-to-ast.d.ts +9 -2
  48. package/dist/lang/malloy-to-ast.js +37 -2
  49. package/dist/lang/parse-log.d.ts +23 -0
  50. package/dist/lang/parse-log.js +6 -0
  51. package/dist/lang/parse-malloy.js +37 -7
  52. package/dist/lang/parse-tree-walkers/find-external-references.d.ts +2 -15
  53. package/dist/lang/parse-tree-walkers/find-external-references.js +6 -23
  54. package/dist/lang/test/expr-to-str.js +3 -0
  55. package/dist/lang/translate-response.d.ts +1 -1
  56. package/dist/model/expression_compiler.js +38 -11
  57. package/dist/model/filter_compilers.js +1 -1
  58. package/dist/model/given_binding.d.ts +15 -0
  59. package/dist/model/given_binding.js +35 -0
  60. package/dist/model/inline_expr.d.ts +30 -0
  61. package/dist/model/inline_expr.js +184 -0
  62. package/dist/model/malloy_types.d.ts +19 -1
  63. package/dist/model/query_model_impl.js +7 -7
  64. package/dist/model/query_query.d.ts +1 -1
  65. package/dist/model/query_query.js +37 -33
  66. package/dist/model/sql_compiled.d.ts +2 -4
  67. package/dist/model/sql_compiled.js +14 -15
  68. package/dist/test/test-models.js +2 -2
  69. package/dist/version.d.ts +1 -1
  70. package/dist/version.js +1 -1
  71. package/package.json +4 -4
@@ -55,9 +55,12 @@ var __importStar = (this && this.__importStar) || (function () {
55
55
  };
56
56
  })();
57
57
  Object.defineProperty(exports, "__esModule", { value: true });
58
- exports.ExprLegacyIn = exports.ExprEquality = exports.ExprCompare = void 0;
58
+ exports.ExprInGiven = exports.ExprLegacyIn = exports.ExprEquality = exports.ExprCompare = void 0;
59
+ const malloy_types_1 = require("../../../model/malloy_types");
60
+ const utils_1 = require("../../../model/utils");
59
61
  const TDU = __importStar(require("../typedesc-utils"));
60
62
  const expr_value_1 = require("../types/expr-value");
63
+ const expr_value_2 = require("../types/expr-value");
61
64
  const expression_def_1 = require("../types/expression-def");
62
65
  const binary_boolean_1 = require("./binary-boolean");
63
66
  const compareTypes = {
@@ -112,7 +115,7 @@ class ExprLegacyIn extends expression_def_1.ExpressionDef {
112
115
  getExpression(fs) {
113
116
  const lookFor = this.expr.getExpression(fs);
114
117
  const oneOf = this.choices.map(e => e.getExpression(fs));
115
- return (0, expr_value_1.computedExprValue)({
118
+ return (0, expr_value_2.computedExprValue)({
116
119
  dataType: { type: 'boolean' },
117
120
  value: {
118
121
  node: 'in',
@@ -124,4 +127,81 @@ class ExprLegacyIn extends expression_def_1.ExpressionDef {
124
127
  }
125
128
  }
126
129
  exports.ExprLegacyIn = ExprLegacyIn;
130
+ /**
131
+ * `expr in $ARRAY_GIVEN` — runtime test of a basic-typed expression
132
+ * against the elements of a runtime-bound array given. The translator
133
+ * verifies the given is `T[]` and the LHS is the same basic `T`; SQL
134
+ * emission expands the bound array's elements at compile time.
135
+ */
136
+ class ExprInGiven extends expression_def_1.ExpressionDef {
137
+ constructor(expr, notIn, givenRef) {
138
+ super();
139
+ this.expr = expr;
140
+ this.notIn = notIn;
141
+ this.givenRef = givenRef;
142
+ this.elementType = 'inGiven';
143
+ this.has({ expr, givenRef });
144
+ }
145
+ getExpression(fs) {
146
+ const lookFor = this.expr.getExpression(fs);
147
+ const givenVal = this.givenRef.getExpression(fs);
148
+ // `in` is logically a boolean — every error path returns a
149
+ // boolean-typed error so a `where:` clause around us doesn't pile a
150
+ // "filter must be boolean" complaint on top of our own diagnostic.
151
+ const boolError = () => (0, expr_value_1.computedErrorExprValue)({
152
+ dataType: { type: 'boolean' },
153
+ error: 'in-given type error',
154
+ from: [lookFor, givenVal],
155
+ });
156
+ if (lookFor.type === 'error' || givenVal.type === 'error') {
157
+ return boolError();
158
+ }
159
+ // GivenReference only ever returns a `given` ExprValue on the
160
+ // success path; the error branch is filtered above. No other case
161
+ // is reachable here.
162
+ const givenNode = givenVal.value;
163
+ if (givenNode.node !== 'given') {
164
+ throw this.internalError(`expected GivenReference to produce a 'given' node, got '${givenNode.node}'`);
165
+ }
166
+ if (!malloy_types_1.TD.isAtomic(givenVal) || givenVal.type !== 'array') {
167
+ this.logError('in-given-rhs-not-array', {
168
+ givenName: this.givenRef.name,
169
+ actualType: malloy_types_1.TD.isAtomic(givenVal)
170
+ ? (0, utils_1.typeDefToString)(givenVal)
171
+ : givenVal.type,
172
+ });
173
+ return boolError();
174
+ }
175
+ if ((0, malloy_types_1.isRepeatedRecord)(givenVal)) {
176
+ this.logError('in-given-rhs-not-basic-array', {
177
+ givenName: this.givenRef.name,
178
+ elementType: (0, utils_1.typeDefToString)(givenVal),
179
+ });
180
+ return boolError();
181
+ }
182
+ // givenVal is BasicArrayTypeDef-shaped — the union for array
183
+ // AtomicTypeDefs is BasicArray | RepeatedRecord, and the
184
+ // RepeatedRecord branch returned above.
185
+ const elemType = givenVal.elementTypeDef;
186
+ if (!malloy_types_1.TD.isBasicAtomic(lookFor) || lookFor.type !== elemType.type) {
187
+ this.logError('in-given-type-mismatch', {
188
+ lhsType: malloy_types_1.TD.isAtomic(lookFor) ? (0, utils_1.typeDefToString)(lookFor) : lookFor.type,
189
+ elementType: (0, utils_1.typeDefToString)(elemType),
190
+ });
191
+ return boolError();
192
+ }
193
+ const inGivenNode = {
194
+ node: 'inGiven',
195
+ not: this.notIn,
196
+ givenRef: givenNode,
197
+ e: lookFor.value,
198
+ };
199
+ return (0, expr_value_2.computedExprValue)({
200
+ dataType: { type: 'boolean' },
201
+ value: inGivenNode,
202
+ from: [lookFor, givenVal],
203
+ });
204
+ }
205
+ }
206
+ exports.ExprInGiven = ExprInGiven;
127
207
  //# sourceMappingURL=expr-compare.js.map
@@ -3,7 +3,7 @@ import { Source } from './source';
3
3
  import type { ModelEntryReference } from '../types/malloy-element';
4
4
  type TableInfo = {
5
5
  tablePath: string;
6
- connectionName?: string | undefined;
6
+ connectionName: string;
7
7
  };
8
8
  export declare abstract class TableSource extends Source {
9
9
  abstract getTableInfo(): TableInfo | undefined;
@@ -16,10 +16,4 @@ export declare class TableMethodSource extends TableSource {
16
16
  constructor(connectionName: ModelEntryReference, tablePath: string);
17
17
  getTableInfo(): TableInfo | undefined;
18
18
  }
19
- export declare class TableFunctionSource extends TableSource {
20
- readonly tableURI: string;
21
- elementType: string;
22
- constructor(tableURI: string);
23
- getTableInfo(): TableInfo | undefined;
24
- }
25
19
  export {};
@@ -22,24 +22,38 @@
22
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.TableFunctionSource = exports.TableMethodSource = exports.TableSource = void 0;
25
+ exports.TableMethodSource = exports.TableSource = void 0;
26
26
  const find_external_references_1 = require("../../parse-tree-walkers/find-external-references");
27
27
  const source_1 = require("./source");
28
28
  const error_factory_1 = require("../error-factory");
29
+ const dialect_1 = require("../../../dialect");
29
30
  class TableSource extends source_1.Source {
30
31
  getSourceDef() {
31
- var _a, _b, _c;
32
+ var _a, _b, _c, _d;
32
33
  const info = this.getTableInfo();
33
34
  if (info === undefined) {
34
35
  return error_factory_1.ErrorFactory.structDef;
35
36
  }
36
- const { tablePath, connectionName } = info;
37
+ const { tablePath: rawTablePath, connectionName } = info;
38
+ // Re-validate the table path. ImportsAndTablesStep validated and
39
+ // silently skipped invalid entries; we re-validate here so we can
40
+ // log a precise translator error at the AST element's location.
41
+ let tablePath = rawTablePath;
42
+ const dialectName = (_a = this.translator()) === null || _a === void 0 ? void 0 : _a.root.connectionDialectZone.get(connectionName);
43
+ if (dialectName !== undefined) {
44
+ const validation = (0, dialect_1.getDialect)(dialectName).sqlValidateTableName(rawTablePath);
45
+ if (!validation.ok) {
46
+ this.logError('invalid-table-path', validation.error);
47
+ return error_factory_1.ErrorFactory.structDef;
48
+ }
49
+ tablePath = validation.canonical;
50
+ }
37
51
  const key = (0, find_external_references_1.constructTableKey)(connectionName, tablePath);
38
- const tableDefEntry = (_a = this.translator()) === null || _a === void 0 ? void 0 : _a.root.schemaZone.getEntry(key);
52
+ const tableDefEntry = (_b = this.translator()) === null || _b === void 0 ? void 0 : _b.root.schemaZone.getEntry(key);
39
53
  let msg = `Schema read failure for table '${tablePath}' for connection '${connectionName}'`;
40
54
  if (tableDefEntry) {
41
55
  if (tableDefEntry.status === 'present') {
42
- (_b = this.document()) === null || _b === void 0 ? void 0 : _b.checkExperimentalDialect(this, tableDefEntry.value.dialect);
56
+ (_c = this.document()) === null || _c === void 0 ? void 0 : _c.checkExperimentalDialect(this, tableDefEntry.value.dialect);
43
57
  tableDefEntry.value.location = this.location;
44
58
  tableDefEntry.value.fields.forEach(field => {
45
59
  field.location = this.location;
@@ -58,7 +72,7 @@ class TableSource extends source_1.Source {
58
72
  }),
59
73
  location: this.location,
60
74
  };
61
- (_c = this.document()) === null || _c === void 0 ? void 0 : _c.rememberToAddModelAnnotations(ret);
75
+ (_d = this.document()) === null || _d === void 0 ? void 0 : _d.rememberToAddModelAnnotations(ret);
62
76
  return ret;
63
77
  }
64
78
  if (tableDefEntry.status === 'error') {
@@ -96,17 +110,4 @@ class TableMethodSource extends TableSource {
96
110
  }
97
111
  }
98
112
  exports.TableMethodSource = TableMethodSource;
99
- class TableFunctionSource extends TableSource {
100
- constructor(tableURI) {
101
- super();
102
- this.tableURI = tableURI;
103
- this.elementType = 'tableFunctionSource';
104
- }
105
- getTableInfo() {
106
- // This use of `deprecatedParseTableURI` is ok because it is for handling the
107
- // old, soon-to-be-deprecated table syntax.
108
- return (0, find_external_references_1.deprecatedParseTableURI)(this.tableURI);
109
- }
110
- }
111
- exports.TableFunctionSource = TableFunctionSource;
112
113
  //# sourceMappingURL=table-source.js.map
@@ -7,12 +7,13 @@ import { extendNoteMethod } from '../types/noteable';
7
7
  export declare class GivenDeclaration extends MalloyElement implements DocStatement, Noteable {
8
8
  readonly name: string;
9
9
  readonly typeDef: GivenTypeDef;
10
+ readonly inline: boolean;
10
11
  elementType: string;
11
12
  readonly isNoteableObj = true;
12
13
  extendNote: typeof extendNoteMethod;
13
14
  note?: Annotation;
14
15
  readonly default?: ConstantExpression;
15
- constructor(name: string, typeDef: GivenTypeDef, defaultExpr?: ConstantExpression);
16
+ constructor(name: string, typeDef: GivenTypeDef, defaultExpr?: ConstantExpression, inline?: boolean);
16
17
  protected varInfo(): string;
17
18
  execute(doc: Document): void;
18
19
  }
@@ -6,6 +6,7 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.DefineGivens = exports.GivenDeclaration = void 0;
8
8
  const malloy_types_1 = require("../../../model/malloy_types");
9
+ const inline_expr_1 = require("../../../model/inline_expr");
9
10
  const source_def_utils_1 = require("../../../model/source_def_utils");
10
11
  const utils_1 = require("../../../model/utils");
11
12
  const expression_def_1 = require("../types/expression-def");
@@ -20,11 +21,43 @@ function filterTypeMismatch(declared, constVal) {
20
21
  return ((declared.type === 'filter expression') !==
21
22
  (constVal.type === 'filter expression'));
22
23
  }
24
+ /**
25
+ * Walk an Expr tree and collect every node string that isn't in the
26
+ * allowed inline operator/leaf sets.
27
+ *
28
+ * The translator caller is gated on a clean translation of the default
29
+ * (`constVal.type !== 'error'`): we don't pile bad-operator errors on
30
+ * top of a default that didn't translate cleanly for more fundamental
31
+ * reasons (an unknown `$REF`, a type mismatch, etc.). Every bad node
32
+ * is collected so the author sees the full list in one diagnostic.
33
+ */
34
+ function collectInlineBadOps(e, bad) {
35
+ if (!inline_expr_1.INLINE_OPS.has(e.node) && !inline_expr_1.INLINE_LEAVES.has(e.node)) {
36
+ bad.add(e.node);
37
+ }
38
+ if ((0, malloy_types_1.exprHasE)(e)) {
39
+ collectInlineBadOps(e.e, bad);
40
+ }
41
+ else if ((0, malloy_types_1.exprHasKids)(e)) {
42
+ for (const kid of Object.values(e.kids)) {
43
+ if (kid === null)
44
+ continue;
45
+ if (Array.isArray(kid)) {
46
+ for (const k of kid)
47
+ collectInlineBadOps(k, bad);
48
+ }
49
+ else {
50
+ collectInlineBadOps(kid, bad);
51
+ }
52
+ }
53
+ }
54
+ }
23
55
  class GivenDeclaration extends malloy_element_1.MalloyElement {
24
- constructor(name, typeDef, defaultExpr) {
56
+ constructor(name, typeDef, defaultExpr, inline = false) {
25
57
  super();
26
58
  this.name = name;
27
59
  this.typeDef = typeDef;
60
+ this.inline = inline;
28
61
  this.elementType = 'given';
29
62
  this.isNoteableObj = true;
30
63
  this.extendNote = noteable_1.extendNoteMethod;
@@ -44,6 +77,12 @@ class GivenDeclaration extends malloy_element_1.MalloyElement {
44
77
  this.logError('given-definition-name-conflict', `Cannot redefine '${this.name}'`);
45
78
  return;
46
79
  }
80
+ // An inline given with no default has nothing to evaluate at bind
81
+ // time. Log and keep going — the given still registers in the
82
+ // namespace so downstream errors don't cascade pointlessly.
83
+ if (this.inline && !this.default) {
84
+ this.logError('inline-no-default', { name: this.name });
85
+ }
47
86
  // Default expression. ConstantExpression evaluates through a
48
87
  // ConstantFieldSpace that errors on every name lookup, so any
49
88
  // non-constant subexpression (field refs, aggregates, etc.) gets
@@ -112,6 +151,17 @@ class GivenDeclaration extends malloy_element_1.MalloyElement {
112
151
  }
113
152
  givenUsage = closure;
114
153
  }
154
+ // Ensure inline expression is resolveable at compile time.
155
+ if (this.inline) {
156
+ const bad = new Set();
157
+ collectInlineBadOps(defaultExpr, bad);
158
+ if (bad.size > 0) {
159
+ this.default.logError('inline-bad-operator', {
160
+ name: this.name,
161
+ operators: [...bad].sort().join(', '),
162
+ });
163
+ }
164
+ }
115
165
  }
116
166
  }
117
167
  const id = (0, source_def_utils_1.mkGivenID)(this.name, (_c = this.location) === null || _c === void 0 ? void 0 : _c.url);
@@ -124,6 +174,7 @@ class GivenDeclaration extends malloy_element_1.MalloyElement {
124
174
  givenUsage,
125
175
  location: this.location,
126
176
  annotation: this.note,
177
+ ...(this.inline ? { inline: true } : {}),
127
178
  };
128
179
  doc.documentGivens.set(id, givenIR);
129
180
  const entry = { type: 'given', name: this.name, id };
@@ -239,10 +239,12 @@ class MalloyElement {
239
239
  const kiddle = this.children[kidLabel];
240
240
  if (kiddle instanceof MalloyElement) {
241
241
  yield kiddle;
242
+ yield* kiddle.walk();
242
243
  }
243
244
  else {
244
245
  for (const k of kiddle) {
245
246
  yield k;
247
+ yield* k.walk();
246
248
  }
247
249
  }
248
250
  }