@malloydata/malloy 0.0.394 → 0.0.396
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/api/foundation/compile.d.ts +7 -6
- package/dist/api/foundation/compile.js +22 -6
- package/dist/api/foundation/config.d.ts +2 -3
- package/dist/api/foundation/config.js +23 -11
- package/dist/api/foundation/core.js +1 -1
- package/dist/api/foundation/runtime.d.ts +85 -5
- package/dist/api/foundation/runtime.js +204 -14
- package/dist/api/foundation/types.d.ts +2 -0
- package/dist/api/util.js +4 -0
- package/dist/connection/base_connection.js +6 -0
- package/dist/connection/validate_table_path.d.ts +10 -0
- package/dist/connection/validate_table_path.js +56 -0
- package/dist/dialect/databricks/databricks.d.ts +4 -4
- package/dist/dialect/databricks/databricks.js +17 -22
- package/dist/dialect/dialect.d.ts +100 -4
- package/dist/dialect/dialect.js +145 -1
- package/dist/dialect/duckdb/duckdb.d.ts +2 -3
- package/dist/dialect/duckdb/duckdb.js +12 -14
- package/dist/dialect/duckdb/table-path-parser.d.ts +2 -0
- package/dist/dialect/duckdb/table-path-parser.js +57 -0
- package/dist/dialect/index.d.ts +2 -0
- package/dist/dialect/index.js +4 -1
- package/dist/dialect/mysql/mysql.d.ts +4 -4
- package/dist/dialect/mysql/mysql.js +25 -20
- package/dist/dialect/pg_impl.d.ts +3 -1
- package/dist/dialect/pg_impl.js +6 -3
- package/dist/dialect/postgres/postgres.d.ts +1 -3
- package/dist/dialect/postgres/postgres.js +8 -16
- package/dist/dialect/snowflake/snowflake.d.ts +4 -4
- package/dist/dialect/snowflake/snowflake.js +11 -27
- package/dist/dialect/standardsql/standardsql.d.ts +6 -4
- package/dist/dialect/standardsql/standardsql.js +36 -15
- package/dist/dialect/table-path.d.ts +54 -0
- package/dist/dialect/table-path.js +144 -0
- package/dist/dialect/trino/trino.d.ts +0 -3
- package/dist/dialect/trino/trino.js +7 -20
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -2
- package/dist/lang/ast/expressions/expr-func.js +30 -11
- package/dist/lang/ast/expressions/expr-given.js +1 -0
- package/dist/lang/ast/field-space/reference-field.js +1 -1
- package/dist/lang/ast/source-elements/sql-source.js +4 -0
- package/dist/lang/ast/source-elements/table-source.d.ts +1 -7
- package/dist/lang/ast/source-elements/table-source.js +24 -19
- package/dist/lang/ast/statements/define-given.d.ts +1 -0
- package/dist/lang/ast/statements/define-given.js +7 -0
- package/dist/lang/ast/statements/import-statement.js +4 -0
- package/dist/lang/ast/types/annotation-elements.d.ts +1 -0
- package/dist/lang/ast/types/annotation-elements.js +10 -3
- package/dist/lang/ast/types/malloy-element.d.ts +1 -0
- package/dist/lang/ast/types/malloy-element.js +4 -0
- package/dist/lang/malloy-to-ast.d.ts +2 -1
- package/dist/lang/malloy-to-ast.js +11 -1
- package/dist/lang/parse-log.d.ts +2 -0
- package/dist/lang/parse-log.js +4 -0
- package/dist/lang/parse-malloy.d.ts +4 -1
- package/dist/lang/parse-malloy.js +63 -11
- package/dist/lang/parse-tree-walkers/find-external-references.d.ts +2 -15
- package/dist/lang/parse-tree-walkers/find-external-references.js +6 -23
- package/dist/lang/test/test-translator.d.ts +19 -5
- package/dist/lang/test/test-translator.js +15 -12
- package/dist/lang/translate-response.d.ts +1 -1
- package/dist/lang/zone.d.ts +2 -0
- package/dist/lang/zone.js +10 -0
- package/dist/model/constant_expression_compiler.js +14 -5
- package/dist/model/expression_compiler.js +19 -17
- package/dist/model/field_instance.js +7 -3
- package/dist/model/filter_compilers.js +1 -1
- package/dist/model/given_binding.js +26 -21
- package/dist/model/index.d.ts +1 -0
- package/dist/model/index.js +3 -1
- package/dist/model/malloy_compile_error.d.ts +13 -0
- package/dist/model/malloy_compile_error.js +23 -0
- package/dist/model/malloy_types.d.ts +2 -0
- package/dist/model/query_model_impl.js +9 -8
- package/dist/model/query_node.d.ts +5 -5
- package/dist/model/query_node.js +21 -16
- package/dist/model/query_query.js +60 -44
- package/dist/model/sql_compiled.d.ts +2 -4
- package/dist/model/sql_compiled.js +20 -18
- package/dist/test/test-models.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type ValidateTablePathResult = {
|
|
2
|
+
ok: true;
|
|
3
|
+
canonical: string;
|
|
4
|
+
} | {
|
|
5
|
+
ok: false;
|
|
6
|
+
error: string;
|
|
7
|
+
};
|
|
8
|
+
export interface TablePathSegment {
|
|
9
|
+
/** Decoded segment value: delimiters stripped, escapes unescaped. */
|
|
10
|
+
value: string;
|
|
11
|
+
/** Whether the segment appeared in quoted form in the input. */
|
|
12
|
+
quoted: boolean;
|
|
13
|
+
}
|
|
14
|
+
export type DecodeDottedTablePathResult = {
|
|
15
|
+
ok: true;
|
|
16
|
+
segments: TablePathSegment[];
|
|
17
|
+
} | {
|
|
18
|
+
ok: false;
|
|
19
|
+
error: string;
|
|
20
|
+
};
|
|
21
|
+
export type TablePathEscapeStyle = 'doubled' | 'backslash';
|
|
22
|
+
export interface DottedTablePathOptions {
|
|
23
|
+
/** Delimiter for quoted segments (`"`, `` ` ``, …). */
|
|
24
|
+
quoteChar: string;
|
|
25
|
+
/**
|
|
26
|
+
* How a literal `quoteChar` is encoded inside a quoted body:
|
|
27
|
+
* - 'doubled': `qq` inside body escapes one literal `q`.
|
|
28
|
+
* - 'backslash': `\X` is a two-character escape; unescaped `q` closes.
|
|
29
|
+
*/
|
|
30
|
+
escapeStyle: TablePathEscapeStyle;
|
|
31
|
+
/**
|
|
32
|
+
* Regex matching one bare segment, anchored at the start of the input.
|
|
33
|
+
* Must NOT have global/sticky flags; the parser calls `.match()` on
|
|
34
|
+
* `input.slice(i)` and expects the match to start at position 0.
|
|
35
|
+
*/
|
|
36
|
+
bareIdentRegex: RegExp;
|
|
37
|
+
/** Used in error messages only. */
|
|
38
|
+
dialectName: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse `input` as a dotted table path and require end-of-input. On
|
|
42
|
+
* success, returns the decoded segment values — delimiters stripped,
|
|
43
|
+
* escape sequences unescaped — so callers that need the segments
|
|
44
|
+
* (connection metadata lookups) and callers that only need
|
|
45
|
+
* accept/reject (`validateDottedTablePath`) share one parser.
|
|
46
|
+
*/
|
|
47
|
+
export declare function decodeDottedTablePath(input: string, opts: DottedTablePathOptions): DecodeDottedTablePathResult;
|
|
48
|
+
/**
|
|
49
|
+
* Validate `input` as a dotted table path. On success the canonical
|
|
50
|
+
* form is the input verbatim. See `decodeDottedTablePath` for the
|
|
51
|
+
* underlying parser; this is the validate-only wrapper that doesn't
|
|
52
|
+
* expose segment internals.
|
|
53
|
+
*/
|
|
54
|
+
export declare function validateDottedTablePath(input: string, opts: DottedTablePathOptions): ValidateTablePathResult;
|
|
@@ -0,0 +1,144 @@
|
|
|
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.decodeDottedTablePath = decodeDottedTablePath;
|
|
8
|
+
exports.validateDottedTablePath = validateDottedTablePath;
|
|
9
|
+
/**
|
|
10
|
+
* Parse `input` as a dotted table path and require end-of-input. On
|
|
11
|
+
* success, returns the decoded segment values — delimiters stripped,
|
|
12
|
+
* escape sequences unescaped — so callers that need the segments
|
|
13
|
+
* (connection metadata lookups) and callers that only need
|
|
14
|
+
* accept/reject (`validateDottedTablePath`) share one parser.
|
|
15
|
+
*/
|
|
16
|
+
function decodeDottedTablePath(input, opts) {
|
|
17
|
+
const { quoteChar, escapeStyle, bareIdentRegex, dialectName } = opts;
|
|
18
|
+
if (input.length === 0) {
|
|
19
|
+
return { ok: false, error: `${dialectName} table path is empty` };
|
|
20
|
+
}
|
|
21
|
+
const segments = [];
|
|
22
|
+
let i = 0;
|
|
23
|
+
while (true) {
|
|
24
|
+
let segValue;
|
|
25
|
+
let segQuoted;
|
|
26
|
+
if (input[i] === quoteChar) {
|
|
27
|
+
const result = consumeQuotedSegment(input, i, quoteChar, escapeStyle);
|
|
28
|
+
if (result === null) {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
error: `Invalid ${dialectName} table path: ${JSON.stringify(input)} — ` +
|
|
32
|
+
'unterminated quoted segment',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
segValue = result.decoded;
|
|
36
|
+
segQuoted = true;
|
|
37
|
+
i = result.end;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const m = input.slice(i).match(bareIdentRegex);
|
|
41
|
+
if (!m || m.index !== 0 || m[0].length === 0) {
|
|
42
|
+
return {
|
|
43
|
+
ok: false,
|
|
44
|
+
error: `Invalid ${dialectName} table path: ${JSON.stringify(input)} — ` +
|
|
45
|
+
`invalid segment at position ${i}`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
segValue = m[0];
|
|
49
|
+
segQuoted = false;
|
|
50
|
+
i += m[0].length;
|
|
51
|
+
}
|
|
52
|
+
// Defense-in-depth: `;` and `--` are forbidden in any decoded segment,
|
|
53
|
+
// even a legally-quoted one. Real table names don't contain them.
|
|
54
|
+
if (segValue.includes(';') || segValue.includes('--')) {
|
|
55
|
+
return {
|
|
56
|
+
ok: false,
|
|
57
|
+
error: `Invalid ${dialectName} table path: segment ${JSON.stringify(segValue)} ` +
|
|
58
|
+
'contains forbidden character; even when quoted, table-path ' +
|
|
59
|
+
'segments may not contain `;` or `--`.',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
segments.push({ value: segValue, quoted: segQuoted });
|
|
63
|
+
if (i === input.length)
|
|
64
|
+
return { ok: true, segments };
|
|
65
|
+
if (input[i] !== '.') {
|
|
66
|
+
return {
|
|
67
|
+
ok: false,
|
|
68
|
+
error: `Invalid ${dialectName} table path: ${JSON.stringify(input)} — ` +
|
|
69
|
+
`expected '.' at position ${i}`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
i++;
|
|
73
|
+
if (i === input.length) {
|
|
74
|
+
return {
|
|
75
|
+
ok: false,
|
|
76
|
+
error: `Invalid ${dialectName} table path: ${JSON.stringify(input)} — ` +
|
|
77
|
+
'trailing dot',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Validate `input` as a dotted table path. On success the canonical
|
|
84
|
+
* form is the input verbatim. See `decodeDottedTablePath` for the
|
|
85
|
+
* underlying parser; this is the validate-only wrapper that doesn't
|
|
86
|
+
* expose segment internals.
|
|
87
|
+
*/
|
|
88
|
+
function validateDottedTablePath(input, opts) {
|
|
89
|
+
const result = decodeDottedTablePath(input, opts);
|
|
90
|
+
if (!result.ok)
|
|
91
|
+
return result;
|
|
92
|
+
return { ok: true, canonical: input };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Read past a quoted segment starting at `input[i]` (must be `quoteChar`).
|
|
96
|
+
* Returns the segment body (delimiters stripped, escape sequences
|
|
97
|
+
* unescaped) and the index just after the closing quote, or `null` if
|
|
98
|
+
* the segment is unterminated.
|
|
99
|
+
*/
|
|
100
|
+
function consumeQuotedSegment(input, i, quoteChar, escapeStyle) {
|
|
101
|
+
// input[i] === quoteChar
|
|
102
|
+
let j = i + 1;
|
|
103
|
+
let decoded = '';
|
|
104
|
+
while (j < input.length) {
|
|
105
|
+
if (escapeStyle === 'backslash' && input[j] === '\\') {
|
|
106
|
+
if (j + 1 >= input.length)
|
|
107
|
+
return null;
|
|
108
|
+
decoded += decodeBackslashEscape(input[j + 1]);
|
|
109
|
+
j += 2;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (input[j] === quoteChar) {
|
|
113
|
+
if (escapeStyle === 'doubled' && input[j + 1] === quoteChar) {
|
|
114
|
+
decoded += quoteChar;
|
|
115
|
+
j += 2;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
return { decoded, end: j + 1 };
|
|
119
|
+
}
|
|
120
|
+
decoded += input[j];
|
|
121
|
+
j++;
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Decode a single character after a backslash. We intentionally accept
|
|
127
|
+
* any character — we're a translator-time grammar check, not a strict
|
|
128
|
+
* lexical conformance test for any particular engine's quoted-identifier
|
|
129
|
+
* escape table. The engine will surface its own errors at bind time if
|
|
130
|
+
* it doesn't recognize a particular sequence.
|
|
131
|
+
*/
|
|
132
|
+
function decodeBackslashEscape(c) {
|
|
133
|
+
switch (c) {
|
|
134
|
+
case 'n':
|
|
135
|
+
return '\n';
|
|
136
|
+
case 't':
|
|
137
|
+
return '\t';
|
|
138
|
+
case 'r':
|
|
139
|
+
return '\r';
|
|
140
|
+
default:
|
|
141
|
+
return c;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=table-path.js.map
|
|
@@ -30,7 +30,6 @@ export declare class TrinoDialect extends PostgresBase {
|
|
|
30
30
|
supportsTempTables: boolean;
|
|
31
31
|
supportsCountApprox: boolean;
|
|
32
32
|
supportsHyperLogLog: boolean;
|
|
33
|
-
quoteTablePath(tablePath: string): string;
|
|
34
33
|
sqlGroupSetTable(groupSetCount: number): string;
|
|
35
34
|
exprToSQL(qi: QueryInfo, df: Expr): string | undefined;
|
|
36
35
|
sqlAnyValue(groupSet: number, fieldName: string): string;
|
|
@@ -62,8 +61,6 @@ export declare class TrinoDialect extends PostgresBase {
|
|
|
62
61
|
sqlRegexpMatch(reCmp: RegexMatchExpr): string;
|
|
63
62
|
sqlMeasureTimeExpr(mf: MeasureTimeExpr): string;
|
|
64
63
|
sqlSampleTable(tableSQL: string, sample: Sampling | undefined): string;
|
|
65
|
-
sqlLiteralString(literal: string): string;
|
|
66
|
-
sqlLiteralRegexp(literal: string): string;
|
|
67
64
|
getDialectFunctionOverrides(): {
|
|
68
65
|
[name: string]: DialectFunctionOverloadDef[];
|
|
69
66
|
};
|
|
@@ -200,16 +200,9 @@ class TrinoDialect extends pg_impl_1.PostgresBase {
|
|
|
200
200
|
WITH
|
|
201
201
|
WITHIN`.split(/\s/);
|
|
202
202
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return tablePath
|
|
207
|
-
.split('.')
|
|
208
|
-
.map(part => `"${part}"`)
|
|
209
|
-
.join('.');
|
|
210
|
-
}
|
|
211
|
-
return tablePath;
|
|
212
|
-
}
|
|
203
|
+
// Trino bare identifier is strict ANSI (`[A-Za-z_][A-Za-z0-9_]*`),
|
|
204
|
+
// which matches the Dialect default — no override needed. Verified
|
|
205
|
+
// against the live engine.
|
|
213
206
|
sqlGroupSetTable(groupSetCount) {
|
|
214
207
|
return `CROSS JOIN (SELECT row_number() OVER() -1 group_set FROM UNNEST(SEQUENCE(0,${groupSetCount})))`;
|
|
215
208
|
}
|
|
@@ -300,7 +293,7 @@ class TrinoDialect extends pg_impl_1.PostgresBase {
|
|
|
300
293
|
if (childName === '__row_id') {
|
|
301
294
|
return `__row_id_from_${parentAlias}`;
|
|
302
295
|
}
|
|
303
|
-
return `${parentAlias}.${this.
|
|
296
|
+
return `${parentAlias}.${this.sqlQuoteIdentifier(childName)}`;
|
|
304
297
|
}
|
|
305
298
|
sqlUnnestPipelineHead(isSingleton, sourceSQLExpression) {
|
|
306
299
|
let p = sourceSQLExpression;
|
|
@@ -471,12 +464,6 @@ ${(0, utils_1.indent)(sql)}
|
|
|
471
464
|
}
|
|
472
465
|
return tableSQL;
|
|
473
466
|
}
|
|
474
|
-
sqlLiteralString(literal) {
|
|
475
|
-
return "'" + literal.replace(/'/g, "''") + "'";
|
|
476
|
-
}
|
|
477
|
-
sqlLiteralRegexp(literal) {
|
|
478
|
-
return "'" + literal.replace(/'/g, "''") + "'";
|
|
479
|
-
}
|
|
480
467
|
getDialectFunctionOverrides() {
|
|
481
468
|
return (0, functions_1.expandOverrideMap)(function_overrides_1.TRINO_MALLOY_STANDARD_OVERLOADS);
|
|
482
469
|
}
|
|
@@ -503,7 +490,7 @@ ${(0, utils_1.indent)(sql)}
|
|
|
503
490
|
const typeSpec = [];
|
|
504
491
|
for (const f of malloyType.fields) {
|
|
505
492
|
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
506
|
-
typeSpec.push(`${this.
|
|
493
|
+
typeSpec.push(`${this.sqlQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
|
|
507
494
|
}
|
|
508
495
|
}
|
|
509
496
|
return `ROW(${typeSpec.join(',')})`;
|
|
@@ -515,7 +502,7 @@ ${(0, utils_1.indent)(sql)}
|
|
|
515
502
|
const typeSpec = [];
|
|
516
503
|
for (const f of malloyType.fields) {
|
|
517
504
|
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
518
|
-
typeSpec.push(`${this.
|
|
505
|
+
typeSpec.push(`${this.sqlQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
|
|
519
506
|
}
|
|
520
507
|
}
|
|
521
508
|
return `ARRAY<ROW(${typeSpec.join(',')})>`;
|
|
@@ -603,7 +590,7 @@ ${(0, utils_1.indent)(sql)}
|
|
|
603
590
|
const name = (_a = f.as) !== null && _a !== void 0 ? _a : f.name;
|
|
604
591
|
rowVals.push((_c = (_b = (0, malloy_types_1.safeRecordGet)(lit.kids, name)) === null || _b === void 0 ? void 0 : _b.sql) !== null && _c !== void 0 ? _c : 'internal-error-record-literal');
|
|
605
592
|
const elType = this.malloyTypeToSQLType(f);
|
|
606
|
-
rowTypes.push(`${this.
|
|
593
|
+
rowTypes.push(`${this.sqlQuoteIdentifier(name)} ${elType}`);
|
|
607
594
|
}
|
|
608
595
|
}
|
|
609
596
|
return `CAST(ROW(${rowVals.join(',')}) AS ROW(${rowTypes.join(',')}))`;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, DatabricksDialect, registerDialect, arg, qtz, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, param, variadicParam, literal, spread, Dialect, } from './dialect';
|
|
2
|
-
export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, MalloyStandardFunctionImplementations, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, } from './dialect';
|
|
1
|
+
export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, DatabricksDialect, registerDialect, arg, qtz, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, param, variadicParam, literal, spread, Dialect, decodeDottedTablePath, validateDottedTablePath, } from './dialect';
|
|
2
|
+
export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, MalloyStandardFunctionImplementations, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, DecodeDottedTablePathResult, DottedTablePathOptions, TablePathEscapeStyle, TablePathSegment, ValidateTablePathResult, } from './dialect';
|
|
3
3
|
export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildID, BuildManifest, BuildManifestEntry, GivenValue, VirtualMap, } from './model';
|
|
4
4
|
export { isSourceDef, isAtomic, isBasicAtomic, isCompoundArrayData, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
|
|
5
5
|
export { malloyToQuery, MalloyTranslator, } from './lang';
|
package/dist/index.js
CHANGED
|
@@ -33,8 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
37
|
-
exports.makeDigest = exports.EMPTY_BUILD_MANIFEST = exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = 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 = void 0;
|
|
36
|
+
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;
|
|
37
|
+
exports.makeDigest = exports.EMPTY_BUILD_MANIFEST = exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = 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;
|
|
38
38
|
/*
|
|
39
39
|
* Copyright 2023 Google LLC
|
|
40
40
|
*
|
|
@@ -80,6 +80,8 @@ Object.defineProperty(exports, "variadicParam", { enumerable: true, get: functio
|
|
|
80
80
|
Object.defineProperty(exports, "literal", { enumerable: true, get: function () { return dialect_1.literal; } });
|
|
81
81
|
Object.defineProperty(exports, "spread", { enumerable: true, get: function () { return dialect_1.spread; } });
|
|
82
82
|
Object.defineProperty(exports, "Dialect", { enumerable: true, get: function () { return dialect_1.Dialect; } });
|
|
83
|
+
Object.defineProperty(exports, "decodeDottedTablePath", { enumerable: true, get: function () { return dialect_1.decodeDottedTablePath; } });
|
|
84
|
+
Object.defineProperty(exports, "validateDottedTablePath", { enumerable: true, get: function () { return dialect_1.validateDottedTablePath; } });
|
|
83
85
|
var model_1 = require("./model");
|
|
84
86
|
Object.defineProperty(exports, "isSourceDef", { enumerable: true, get: function () { return model_1.isSourceDef; } });
|
|
85
87
|
// Used in Composer Demo
|
|
@@ -58,13 +58,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
58
58
|
exports.ExprFunc = void 0;
|
|
59
59
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
60
60
|
const ast_utils_1 = require("../ast-utils");
|
|
61
|
+
const utils_1 = require("../../../model/utils");
|
|
61
62
|
const struct_space_field_base_1 = require("../field-space/struct-space-field-base");
|
|
62
63
|
const expr_value_1 = require("../types/expr-value");
|
|
63
64
|
const expression_def_1 = require("../types/expression-def");
|
|
64
65
|
const field_space_1 = require("../types/field-space");
|
|
65
|
-
const
|
|
66
|
+
const utils_2 = require("../../../model/utils");
|
|
66
67
|
const TDU = __importStar(require("../typedesc-utils"));
|
|
67
68
|
const composite_source_utils_1 = require("../../composite-source-utils");
|
|
69
|
+
// Built-in functions that take a string literal of user-supplied SQL
|
|
70
|
+
// and emit it directly. Gated by experimental.sql_functions in plain
|
|
71
|
+
// Malloy; rejected unconditionally in restricted queries because they
|
|
72
|
+
// are a raw-SQL escape hatch by definition.
|
|
73
|
+
const SQL_FUNCTION_NAMES = [
|
|
74
|
+
'sql_number',
|
|
75
|
+
'sql_string',
|
|
76
|
+
'sql_date',
|
|
77
|
+
'sql_timestamp',
|
|
78
|
+
'sql_boolean',
|
|
79
|
+
];
|
|
68
80
|
class ExprFunc extends expression_def_1.ExpressionDef {
|
|
69
81
|
constructor(name, args, isRaw, explicitType, source) {
|
|
70
82
|
super({ args: args });
|
|
@@ -86,6 +98,12 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
86
98
|
return true;
|
|
87
99
|
}
|
|
88
100
|
getExpression(fs) {
|
|
101
|
+
if (this.isRaw && this.isRestricted()) {
|
|
102
|
+
const typeStr = this.explicitType
|
|
103
|
+
? (0, utils_1.typeDefToString)(this.explicitType)
|
|
104
|
+
: '';
|
|
105
|
+
return this.loggedErrorExpr('restricted-construct-forbidden', `\`${this.name}!${typeStr}(...)\` cannot be used in a restricted query — direct SQL function calls (\`!type(...)\`) are not permitted.`);
|
|
106
|
+
}
|
|
89
107
|
return this.getPropsExpression(fs);
|
|
90
108
|
}
|
|
91
109
|
findFunctionDef(dialect) {
|
|
@@ -126,7 +144,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
126
144
|
const dataType = (_b = this.explicitType) !== null && _b !== void 0 ? _b : inferredType;
|
|
127
145
|
return (0, expr_value_1.computedExprValue)({
|
|
128
146
|
dataType,
|
|
129
|
-
value: (0,
|
|
147
|
+
value: (0, utils_2.composeSQLExpr)(funcCall),
|
|
130
148
|
from: argExprsWithoutImplicit,
|
|
131
149
|
});
|
|
132
150
|
}
|
|
@@ -290,13 +308,10 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
290
308
|
frag.partitionBy = partitionByFields;
|
|
291
309
|
}
|
|
292
310
|
const sqlFunctionFieldUsage = [];
|
|
293
|
-
if (
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
'sql_timestamp',
|
|
298
|
-
'sql_boolean',
|
|
299
|
-
].includes(func.name)) {
|
|
311
|
+
if (SQL_FUNCTION_NAMES.includes(func.name)) {
|
|
312
|
+
if (this.isRestricted()) {
|
|
313
|
+
return this.loggedErrorExpr('restricted-construct-forbidden', `\`${this.name}(...)\` cannot be used in a restricted query — the \`sql_*\` function family emits user-supplied SQL directly, which is not permitted.`);
|
|
314
|
+
}
|
|
300
315
|
if (!this.inExperiment('sql_functions', true)) {
|
|
301
316
|
return this.loggedErrorExpr('sql-functions-experiment-not-enabled', `Cannot use sql_function \`${func.name}\`; use \`sql_functions\` experiment to enable this behavior`);
|
|
302
317
|
}
|
|
@@ -327,7 +342,11 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
327
342
|
return this.loggedErrorExpr('filter-expression-error', 'Filter expressions cannot be used in sql_ functions');
|
|
328
343
|
}
|
|
329
344
|
if (result.found.refType === 'parameter') {
|
|
330
|
-
expr.push({
|
|
345
|
+
expr.push({
|
|
346
|
+
node: 'parameter',
|
|
347
|
+
path: part.path,
|
|
348
|
+
at: this.args[0].location,
|
|
349
|
+
});
|
|
331
350
|
}
|
|
332
351
|
else {
|
|
333
352
|
sqlFunctionFieldUsage.push({
|
|
@@ -343,7 +362,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
343
362
|
}
|
|
344
363
|
}
|
|
345
364
|
}
|
|
346
|
-
funcCall = (0,
|
|
365
|
+
funcCall = (0, utils_2.composeSQLExpr)(expr);
|
|
347
366
|
}
|
|
348
367
|
}
|
|
349
368
|
const maxEvalSpace = (0, malloy_types_1.mergeEvalSpaces)(...argExprs.map(e => e.evalSpace));
|
|
@@ -88,7 +88,7 @@ class ReferenceField extends space_field_1.SpaceField {
|
|
|
88
88
|
if (malloy_types_1.TD.isAtomic(foundType)) {
|
|
89
89
|
this.queryFieldDef = {
|
|
90
90
|
...(0, malloy_types_1.mkFieldDef)(TDU.atomicDef(foundType), path[0]),
|
|
91
|
-
e: { node: 'parameter', path },
|
|
91
|
+
e: { node: 'parameter', path, at: this.fieldRef.location },
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
94
|
else {
|
|
@@ -100,6 +100,10 @@ class SQLSource extends source_1.Source {
|
|
|
100
100
|
}
|
|
101
101
|
getSourceDef() {
|
|
102
102
|
var _a;
|
|
103
|
+
if (this.isRestricted()) {
|
|
104
|
+
this.logError('restricted-construct-forbidden', `\`${this.connectionName.refString}.sql(...)\` cannot be used in a restricted query — raw SQL is not permitted.`);
|
|
105
|
+
return error_factory_1.ErrorFactory.structDef;
|
|
106
|
+
}
|
|
103
107
|
if (!this.validateConnectionName()) {
|
|
104
108
|
return error_factory_1.ErrorFactory.structDef;
|
|
105
109
|
}
|
|
@@ -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
|
|
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.
|
|
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 = (
|
|
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
|
-
(
|
|
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
|
-
(
|
|
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') {
|
|
@@ -80,6 +94,10 @@ class TableMethodSource extends TableSource {
|
|
|
80
94
|
}
|
|
81
95
|
getTableInfo() {
|
|
82
96
|
var _a;
|
|
97
|
+
if (this.isRestricted()) {
|
|
98
|
+
this.logError('restricted-construct-forbidden', `\`${this.connectionName.refString}.table(...)\` cannot be used in a restricted query — direct table access is not permitted.`);
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
83
101
|
const connection = this.modelEntry(this.connectionName);
|
|
84
102
|
const name = this.connectionName.refString;
|
|
85
103
|
if (connection === undefined) {
|
|
@@ -96,17 +114,4 @@ class TableMethodSource extends TableSource {
|
|
|
96
114
|
}
|
|
97
115
|
}
|
|
98
116
|
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
117
|
//# sourceMappingURL=table-source.js.map
|
|
@@ -209,6 +209,13 @@ class DefineGivens extends malloy_element_1.DocStatementList {
|
|
|
209
209
|
this.elementType = 'defineGivens';
|
|
210
210
|
this.givens = givens;
|
|
211
211
|
}
|
|
212
|
+
executeList(doc) {
|
|
213
|
+
if (this.isRestricted()) {
|
|
214
|
+
this.logError('restricted-construct-forbidden', '`given:` cannot declare new givens in a restricted query — only `$NAME` references to existing givens are allowed.');
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
return super.executeList(doc);
|
|
218
|
+
}
|
|
212
219
|
}
|
|
213
220
|
exports.DefineGivens = DefineGivens;
|
|
214
221
|
//# sourceMappingURL=define-given.js.map
|
|
@@ -89,6 +89,10 @@ class ImportStatement extends malloy_element_1.ListOf {
|
|
|
89
89
|
}
|
|
90
90
|
execute(doc) {
|
|
91
91
|
var _a;
|
|
92
|
+
if (this.isRestricted()) {
|
|
93
|
+
this.logError('restricted-construct-forbidden', `\`import "${this.url}"\` cannot be used in a restricted query — file imports are not permitted.`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
92
96
|
const trans = this.translator();
|
|
93
97
|
if (!trans) {
|
|
94
98
|
this.logError('no-translator-for-import', 'Cannot import without translation context');
|
|
@@ -12,6 +12,7 @@ export declare class ObjectAnnotation extends MalloyElement implements QueryProp
|
|
|
12
12
|
}
|
|
13
13
|
export declare class ModelAnnotation extends ObjectAnnotation implements DocStatement {
|
|
14
14
|
elementType: string;
|
|
15
|
+
getCompilerFlagNotes(): Note[];
|
|
15
16
|
getCompilerFlagLines(): string[];
|
|
16
17
|
execute(doc: Document): void;
|
|
17
18
|
}
|
|
@@ -41,12 +41,19 @@ class ModelAnnotation extends ObjectAnnotation {
|
|
|
41
41
|
super(...arguments);
|
|
42
42
|
this.elementType = 'modelAnnotation';
|
|
43
43
|
}
|
|
44
|
+
getCompilerFlagNotes() {
|
|
45
|
+
return this.notes.filter(note => note.text.match(COMPILER_FLAG_PREFIX));
|
|
46
|
+
}
|
|
44
47
|
getCompilerFlagLines() {
|
|
45
|
-
return this.
|
|
46
|
-
.filter(note => note.text.match(COMPILER_FLAG_PREFIX))
|
|
47
|
-
.map(note => note.text);
|
|
48
|
+
return this.getCompilerFlagNotes().map(note => note.text);
|
|
48
49
|
}
|
|
49
50
|
execute(doc) {
|
|
51
|
+
if (this.isRestricted()) {
|
|
52
|
+
for (const note of this.getCompilerFlagNotes()) {
|
|
53
|
+
const line = note.text.replace(/\n$/, '');
|
|
54
|
+
this.logError('restricted-construct-forbidden', `\`${line}\` cannot be used in a restricted query — compiler-flag annotations are not permitted.`, { at: note.at });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
50
57
|
if (doc.annotation.notes === undefined) {
|
|
51
58
|
doc.annotation.notes = [];
|
|
52
59
|
}
|
|
@@ -37,6 +37,7 @@ export declare abstract class MalloyElement {
|
|
|
37
37
|
*/
|
|
38
38
|
kupuna(): MalloyElement;
|
|
39
39
|
translator(): MalloyTranslation | undefined;
|
|
40
|
+
isRestricted(): boolean;
|
|
40
41
|
setTranslator(x: MalloyTranslation): void;
|
|
41
42
|
addReference(reference: DocumentReference): void;
|
|
42
43
|
private get sourceURL();
|
|
@@ -158,6 +158,10 @@ class MalloyElement {
|
|
|
158
158
|
}
|
|
159
159
|
return undefined;
|
|
160
160
|
}
|
|
161
|
+
isRestricted() {
|
|
162
|
+
var _a, _b;
|
|
163
|
+
return (_b = (_a = this.translator()) === null || _a === void 0 ? void 0 : _a.root.restrictedMode) !== null && _b !== void 0 ? _b : false;
|
|
164
|
+
}
|
|
161
165
|
setTranslator(x) {
|
|
162
166
|
this.xlate = x;
|
|
163
167
|
}
|
|
@@ -35,10 +35,11 @@ type HasAnnotations = ParserRuleContext & {
|
|
|
35
35
|
export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElement> implements MalloyParserVisitor<ast.MalloyElement> {
|
|
36
36
|
readonly parseInfo: MalloyParseInfo;
|
|
37
37
|
readonly msgLog: MessageLogger;
|
|
38
|
+
readonly restrictedMode: boolean;
|
|
38
39
|
readonly timer: Timer;
|
|
39
40
|
private compilerFlagSrc;
|
|
40
41
|
private compilerFlagTag?;
|
|
41
|
-
constructor(parseInfo: MalloyParseInfo, msgLog: MessageLogger, compilerFlagSrc: string[]);
|
|
42
|
+
constructor(parseInfo: MalloyParseInfo, msgLog: MessageLogger, compilerFlagSrc: string[], restrictedMode?: boolean);
|
|
42
43
|
getCompilerFlags(): Tag;
|
|
43
44
|
run(): {
|
|
44
45
|
ast: ast.MalloyElement;
|