@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.
- package/dist/api/foundation/config.d.ts +2 -3
- package/dist/api/foundation/config.js +23 -11
- package/dist/api/foundation/core.d.ts +0 -4
- package/dist/api/foundation/core.js +14 -11
- package/dist/api/foundation/runtime.js +21 -1
- 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-compare.d.ts +15 -0
- package/dist/lang/ast/expressions/expr-compare.js +82 -2
- package/dist/lang/ast/source-elements/table-source.d.ts +1 -7
- package/dist/lang/ast/source-elements/table-source.js +20 -19
- package/dist/lang/ast/statements/define-given.d.ts +2 -1
- package/dist/lang/ast/statements/define-given.js +52 -1
- package/dist/lang/ast/types/malloy-element.js +2 -0
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +188 -167
- package/dist/lang/lib/Malloy/MalloyParser.js +2582 -2442
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +24 -0
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +15 -0
- package/dist/lang/malloy-to-ast.d.ts +9 -2
- package/dist/lang/malloy-to-ast.js +37 -2
- package/dist/lang/parse-log.d.ts +23 -0
- package/dist/lang/parse-log.js +6 -0
- package/dist/lang/parse-malloy.js +37 -7
- 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/expr-to-str.js +3 -0
- package/dist/lang/translate-response.d.ts +1 -1
- package/dist/model/expression_compiler.js +38 -11
- package/dist/model/filter_compilers.js +1 -1
- package/dist/model/given_binding.d.ts +15 -0
- package/dist/model/given_binding.js +35 -0
- package/dist/model/inline_expr.d.ts +30 -0
- package/dist/model/inline_expr.js +184 -0
- package/dist/model/malloy_types.d.ts +19 -1
- package/dist/model/query_model_impl.js +7 -7
- package/dist/model/query_query.d.ts +1 -1
- package/dist/model/query_query.js +37 -33
- package/dist/model/sql_compiled.d.ts +2 -4
- package/dist/model/sql_compiled.js +14 -15
- 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
|
@@ -6,6 +6,9 @@ export declare class SnowflakeDialect extends Dialect {
|
|
|
6
6
|
name: string;
|
|
7
7
|
experimental: boolean;
|
|
8
8
|
hasTimestamptz: boolean;
|
|
9
|
+
stringLiteralStyle: "backslash";
|
|
10
|
+
identifierEscapeStyle: "doubled";
|
|
11
|
+
identifierQuoteChar: string;
|
|
9
12
|
defaultNumberType: string;
|
|
10
13
|
defaultDecimalType: string;
|
|
11
14
|
udfPrefix: string;
|
|
@@ -26,8 +29,8 @@ export declare class SnowflakeDialect extends Dialect {
|
|
|
26
29
|
supportsQualify: boolean;
|
|
27
30
|
supportsPipelinesInViews: boolean;
|
|
28
31
|
supportsComplexFilteredSources: boolean;
|
|
32
|
+
tablePathBareIdentRegex: RegExp;
|
|
29
33
|
integerTypeMappings: IntegerTypeMapping[];
|
|
30
|
-
quoteTablePath(tablePath: string): string;
|
|
31
34
|
sqlGroupSetTable(groupSetCount: number): string;
|
|
32
35
|
sqlAnyValue(groupSet: number, fieldName: string): string;
|
|
33
36
|
mapFields(fieldList: DialectFieldList): string;
|
|
@@ -45,7 +48,6 @@ export declare class SnowflakeDialect extends Dialect {
|
|
|
45
48
|
sqlCreateFunction(_id: string, _funcText: string): string;
|
|
46
49
|
sqlCreateFunctionCombineLastStage(_lastStageName: string): string;
|
|
47
50
|
sqlSelectAliasAsStruct(alias: string): string;
|
|
48
|
-
sqlMaybeQuoteIdentifier(identifier: string): string;
|
|
49
51
|
sqlCreateTableAsSelect(tableName: string, sql: string): string;
|
|
50
52
|
sqlConvertToCivilTime(expr: string, timezone: string, typeDef: AtomicTypeDef): {
|
|
51
53
|
sql: string;
|
|
@@ -65,8 +67,6 @@ export declare class SnowflakeDialect extends Dialect {
|
|
|
65
67
|
sqlRegexpMatch(compare: RegexMatchExpr): string;
|
|
66
68
|
sqlSampleTable(tableSQL: string, sample: Sampling | undefined): string;
|
|
67
69
|
sqlOrderBy(orderTerms: string[]): string;
|
|
68
|
-
sqlLiteralString(literal: string): string;
|
|
69
|
-
sqlLiteralRegexp(literal: string): string;
|
|
70
70
|
getDialectFunctionOverrides(): {
|
|
71
71
|
[name: string]: DialectFunctionOverloadDef[];
|
|
72
72
|
};
|
|
@@ -78,6 +78,9 @@ class SnowflakeDialect extends dialect_1.Dialect {
|
|
|
78
78
|
this.name = 'snowflake';
|
|
79
79
|
this.experimental = false;
|
|
80
80
|
this.hasTimestamptz = true;
|
|
81
|
+
this.stringLiteralStyle = dialect_1.EscapeStyle.Backslash;
|
|
82
|
+
this.identifierEscapeStyle = dialect_1.EscapeStyle.Doubled;
|
|
83
|
+
this.identifierQuoteChar = '"';
|
|
81
84
|
this.defaultNumberType = 'NUMBER';
|
|
82
85
|
this.defaultDecimalType = 'NUMBER';
|
|
83
86
|
this.udfPrefix = '__udf';
|
|
@@ -98,21 +101,14 @@ class SnowflakeDialect extends dialect_1.Dialect {
|
|
|
98
101
|
this.supportsQualify = false;
|
|
99
102
|
this.supportsPipelinesInViews = false;
|
|
100
103
|
this.supportsComplexFilteredSources = false;
|
|
104
|
+
// Snowflake bare-identifier continuation allows `$` (verified against
|
|
105
|
+
// the live engine).
|
|
106
|
+
this.tablePathBareIdentRegex = /^[A-Za-z_][A-Za-z0-9_$]*/;
|
|
101
107
|
// Snowflake uses NUMBER(38,0) for all integers - can exceed JS Number precision
|
|
102
108
|
this.integerTypeMappings = [
|
|
103
109
|
{ min: dialect_1.MIN_DECIMAL38, max: dialect_1.MAX_DECIMAL38, numberType: 'bigint' },
|
|
104
110
|
];
|
|
105
111
|
}
|
|
106
|
-
quoteTablePath(tablePath) {
|
|
107
|
-
// Quote with double quotes if contains dangerous characters
|
|
108
|
-
if (tablePath.match(/[;-]/)) {
|
|
109
|
-
return tablePath
|
|
110
|
-
.split('.')
|
|
111
|
-
.map(part => `"${part}"`)
|
|
112
|
-
.join('.');
|
|
113
|
-
}
|
|
114
|
-
return tablePath;
|
|
115
|
-
}
|
|
116
112
|
sqlGroupSetTable(groupSetCount) {
|
|
117
113
|
return `CROSS JOIN (SELECT index as group_set FROM TABLE(FLATTEN(ARRAY_GENERATE_RANGE(0, ${groupSetCount + 1}))))`;
|
|
118
114
|
}
|
|
@@ -126,7 +122,7 @@ class SnowflakeDialect extends dialect_1.Dialect {
|
|
|
126
122
|
}
|
|
127
123
|
mapFieldsForObjectConstruct(fieldList) {
|
|
128
124
|
return fieldList
|
|
129
|
-
.map(f =>
|
|
125
|
+
.map(f => `${this.sqlLiteralString(f.rawName)}, (${f.sqlExpression})`)
|
|
130
126
|
.join(', ');
|
|
131
127
|
}
|
|
132
128
|
sqlAggregateTurtle(groupSet, fieldList, orderBy) {
|
|
@@ -152,7 +148,7 @@ class SnowflakeDialect extends dialect_1.Dialect {
|
|
|
152
148
|
return `COALESCE(ARRAY_AGG(CASE WHEN group_set=${groupSet} THEN OBJECT_CONSTRUCT_KEEP_NULL(${fields}) END)[0], OBJECT_CONSTRUCT_KEEP_NULL(${nullValues}))`;
|
|
153
149
|
}
|
|
154
150
|
sqlUnnestAlias(source, alias, _fieldList, _needDistinctKey, isArray, _isInNestedPipeline) {
|
|
155
|
-
const as = this.
|
|
151
|
+
const as = this.sqlQuoteIdentifier(alias);
|
|
156
152
|
if (isArray) {
|
|
157
153
|
return `LEFT JOIN lateral flatten(input => ${source}) as ${as}`;
|
|
158
154
|
}
|
|
@@ -202,7 +198,7 @@ class SnowflakeDialect extends dialect_1.Dialect {
|
|
|
202
198
|
return 'UUID_STRING()';
|
|
203
199
|
}
|
|
204
200
|
sqlFieldReference(parentAlias, parentType, childName, childType) {
|
|
205
|
-
const sqlName = this.
|
|
201
|
+
const sqlName = this.sqlQuoteIdentifier(childName);
|
|
206
202
|
if (childName === '__row_id') {
|
|
207
203
|
return `"${parentAlias}".INDEX::varchar`;
|
|
208
204
|
}
|
|
@@ -250,9 +246,6 @@ class SnowflakeDialect extends dialect_1.Dialect {
|
|
|
250
246
|
sqlSelectAliasAsStruct(alias) {
|
|
251
247
|
return `OBJECT_CONSTRUCT_KEEP_NULL(${alias}.*)`;
|
|
252
248
|
}
|
|
253
|
-
sqlMaybeQuoteIdentifier(identifier) {
|
|
254
|
-
return '"' + identifier.replace(/"/g, '""') + '"';
|
|
255
|
-
}
|
|
256
249
|
sqlCreateTableAsSelect(tableName, sql) {
|
|
257
250
|
return `
|
|
258
251
|
CREATE TEMP TABLE IF NOT EXISTS \`${tableName}\`
|
|
@@ -425,14 +418,6 @@ ${(0, utils_1.indent)(sql)}
|
|
|
425
418
|
sqlOrderBy(orderTerms) {
|
|
426
419
|
return `ORDER BY ${orderTerms.map(t => `${t} NULLS LAST`).join(',')}`;
|
|
427
420
|
}
|
|
428
|
-
sqlLiteralString(literal) {
|
|
429
|
-
const noVirgule = literal.replace(/\\/g, '\\\\');
|
|
430
|
-
return "'" + noVirgule.replace(/'/g, "\\'") + "'";
|
|
431
|
-
}
|
|
432
|
-
sqlLiteralRegexp(literal) {
|
|
433
|
-
const noVirgule = literal.replace(/\\/g, '\\\\');
|
|
434
|
-
return "'" + noVirgule.replace(/'/g, "\\'") + "'";
|
|
435
|
-
}
|
|
436
421
|
getDialectFunctionOverrides() {
|
|
437
422
|
return (0, functions_1.expandOverrideMap)(function_overrides_1.SNOWFLAKE_MALLOY_STANDARD_OVERLOADS);
|
|
438
423
|
}
|
|
@@ -457,7 +442,7 @@ ${(0, utils_1.indent)(sql)}
|
|
|
457
442
|
var _a;
|
|
458
443
|
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
459
444
|
const name = (_a = f.as) !== null && _a !== void 0 ? _a : f.name;
|
|
460
|
-
const oneSchema = `${this.
|
|
445
|
+
const oneSchema = `${this.sqlQuoteIdentifier(name)} ${this.malloyTypeToSQLType(f)}`;
|
|
461
446
|
ret.push(oneSchema);
|
|
462
447
|
}
|
|
463
448
|
return ret;
|
|
@@ -521,9 +506,8 @@ ${(0, utils_1.indent)(sql)}
|
|
|
521
506
|
const rowVals = [];
|
|
522
507
|
for (const f of lit.typeDef.fields) {
|
|
523
508
|
const name = (_a = f.as) !== null && _a !== void 0 ? _a : f.name;
|
|
524
|
-
const propName = `'${name}'`;
|
|
525
509
|
const propVal = (_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';
|
|
526
|
-
rowVals.push(`${
|
|
510
|
+
rowVals.push(`${this.sqlLiteralString(name)},${propVal}`);
|
|
527
511
|
}
|
|
528
512
|
return `OBJECT_CONSTRUCT_KEEP_NULL(${rowVals.join(',')})`;
|
|
529
513
|
}
|
|
@@ -4,6 +4,9 @@ import type { CompiledOrderBy, DialectFieldList, IntegerTypeMapping, OrderByRequ
|
|
|
4
4
|
import { Dialect, type LateralJoinExpression } from '../dialect';
|
|
5
5
|
export declare class StandardSQLDialect extends Dialect {
|
|
6
6
|
name: string;
|
|
7
|
+
stringLiteralStyle: "backslash";
|
|
8
|
+
identifierEscapeStyle: "backslash";
|
|
9
|
+
identifierQuoteChar: string;
|
|
7
10
|
experimental: boolean;
|
|
8
11
|
defaultNumberType: string;
|
|
9
12
|
defaultDecimalType: string;
|
|
@@ -29,7 +32,9 @@ export declare class StandardSQLDialect extends Dialect {
|
|
|
29
32
|
supportsHyperLogLog: boolean;
|
|
30
33
|
likeEscape: boolean;
|
|
31
34
|
integerTypeMappings: IntegerTypeMapping[];
|
|
32
|
-
|
|
35
|
+
private bqRejectBacktick;
|
|
36
|
+
sqlQuoteIdentifier(identifier: string): string;
|
|
37
|
+
tablePathBareIdentRegex: RegExp;
|
|
33
38
|
needsCivilTimeComputation(typeDef: AtomicTypeDef, truncateTo: TimestampUnit | undefined, offsetUnit: TimestampUnit | undefined, qi: QueryInfo): {
|
|
34
39
|
needed: boolean;
|
|
35
40
|
tz: string | undefined;
|
|
@@ -50,7 +55,6 @@ export declare class StandardSQLDialect extends Dialect {
|
|
|
50
55
|
sqlCreateTableAsSelect(tableName: string, sql: string): string;
|
|
51
56
|
sqlCreateFunctionCombineLastStage(lastStageName: string): string;
|
|
52
57
|
sqlSelectAliasAsStruct(alias: string): string;
|
|
53
|
-
sqlMaybeQuoteIdentifier(identifier: string): string;
|
|
54
58
|
sqlNowExpr(): string;
|
|
55
59
|
sqlTimeExtractExpr(qi: QueryInfo, te: TimeExtractExpr): string;
|
|
56
60
|
sqlConvertToCivilTime(expr: string, timezone: string, _typeDef: AtomicTypeDef): {
|
|
@@ -68,8 +72,6 @@ export declare class StandardSQLDialect extends Dialect {
|
|
|
68
72
|
sqlTimestamptzLiteral(_qi: QueryInfo, _literal: string, _timezone: string): string;
|
|
69
73
|
sqlMeasureTimeExpr(measure: MeasureTimeExpr): string;
|
|
70
74
|
sqlSampleTable(tableSQL: string, sample: Sampling | undefined): string;
|
|
71
|
-
sqlLiteralString(literal: string): string;
|
|
72
|
-
sqlLiteralRegexp(literal: string): string;
|
|
73
75
|
getDialectFunctionOverrides(): {
|
|
74
76
|
[name: string]: DialectFunctionOverloadDef[];
|
|
75
77
|
};
|
|
@@ -76,6 +76,9 @@ class StandardSQLDialect extends dialect_1.Dialect {
|
|
|
76
76
|
constructor() {
|
|
77
77
|
super(...arguments);
|
|
78
78
|
this.name = 'standardsql';
|
|
79
|
+
this.stringLiteralStyle = dialect_1.EscapeStyle.Backslash;
|
|
80
|
+
this.identifierEscapeStyle = dialect_1.EscapeStyle.Backslash;
|
|
81
|
+
this.identifierQuoteChar = '`';
|
|
79
82
|
this.experimental = false;
|
|
80
83
|
this.defaultNumberType = 'FLOAT64';
|
|
81
84
|
this.defaultDecimalType = 'NUMERIC';
|
|
@@ -101,13 +104,42 @@ class StandardSQLDialect extends dialect_1.Dialect {
|
|
|
101
104
|
this.integerTypeMappings = [
|
|
102
105
|
{ min: dialect_1.MIN_INT64, max: dialect_1.MAX_INT64, numberType: 'bigint' },
|
|
103
106
|
];
|
|
107
|
+
// BigQuery bare-identifier continuation allows dashes (verified
|
|
108
|
+
// against the live engine: `proj-foo.dataset.table` resolves to a
|
|
109
|
+
// table reference, both bare and inside per-segment backticks). The
|
|
110
|
+
// base `sqlValidateTableName` handles every shape we accept —
|
|
111
|
+
// bare-dotted, whole-backticked, and per-segment-backticked — because
|
|
112
|
+
// its grammar is `Segment ('.' Segment)*` and a segment is either
|
|
113
|
+
// bare or quoted with this dialect's `identifierQuoteChar` /
|
|
114
|
+
// `identifierEscapeStyle` (`` ` `` / Backslash). The whole-path form
|
|
115
|
+
// (`` `proj.dataset.table` ``) is accepted naturally as a single
|
|
116
|
+
// quoted segment.
|
|
117
|
+
//
|
|
118
|
+
// `*` is intentionally NOT in this regex. BigQuery's parser only
|
|
119
|
+
// accepts `*` inside backticks (wildcard tables must be quoted, e.g.
|
|
120
|
+
// `` `dataset.events_*` ``). Bare wildcards would fail at the engine,
|
|
121
|
+
// so we reject them up front and require the user to type the
|
|
122
|
+
// backticks they'd need anyway.
|
|
123
|
+
this.tablePathBareIdentRegex = /^[A-Za-z_][A-Za-z0-9_-]*/;
|
|
104
124
|
}
|
|
105
125
|
sqlLateralJoinBag(expressions) {
|
|
106
126
|
const fields = expressions.map(e => `${e.sql} as ${e.name}`);
|
|
107
127
|
return `LEFT JOIN UNNEST([STRUCT(${fields.join(',\n')})]) as __lateral_join_bag\n`;
|
|
108
128
|
}
|
|
109
|
-
|
|
110
|
-
|
|
129
|
+
// BigQuery's parser accepts `\`` as a backtick escape inside quoted
|
|
130
|
+
// identifiers, but BigQuery's schema layer rejects field/table names
|
|
131
|
+
// containing a literal backtick. Refuse here so the error names the
|
|
132
|
+
// dialect; the rest of the escape (backslash-doubling) is handled by
|
|
133
|
+
// the base via identifierEscapeStyle.
|
|
134
|
+
// Reference: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical
|
|
135
|
+
bqRejectBacktick(name, kind) {
|
|
136
|
+
if (name.includes('`')) {
|
|
137
|
+
throw new Error(`BigQuery ${kind} cannot contain a backtick: ${JSON.stringify(name)}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
sqlQuoteIdentifier(identifier) {
|
|
141
|
+
this.bqRejectBacktick(identifier, 'identifier');
|
|
142
|
+
return super.sqlQuoteIdentifier(identifier);
|
|
111
143
|
}
|
|
112
144
|
needsCivilTimeComputation(typeDef, truncateTo, offsetUnit, qi) {
|
|
113
145
|
// In addition to using "civil" space for units where a query time zone is
|
|
@@ -193,7 +225,7 @@ class StandardSQLDialect extends dialect_1.Dialect {
|
|
|
193
225
|
return 'GENERATE_UUID()';
|
|
194
226
|
}
|
|
195
227
|
sqlFieldReference(parentAlias, _parentType, childName, _childType) {
|
|
196
|
-
const child = this.
|
|
228
|
+
const child = this.sqlQuoteIdentifier(childName);
|
|
197
229
|
return `${parentAlias}.${child}`;
|
|
198
230
|
}
|
|
199
231
|
sqlUnnestPipelineHead(isSingleton, sourceSQLExpression) {
|
|
@@ -223,9 +255,6 @@ ${(0, utils_1.indent)(sql)}
|
|
|
223
255
|
sqlSelectAliasAsStruct(alias) {
|
|
224
256
|
return `(SELECT AS STRUCT ${alias}.*)`;
|
|
225
257
|
}
|
|
226
|
-
sqlMaybeQuoteIdentifier(identifier) {
|
|
227
|
-
return '`' + identifier + '`';
|
|
228
|
-
}
|
|
229
258
|
sqlNowExpr() {
|
|
230
259
|
return 'CURRENT_TIMESTAMP()';
|
|
231
260
|
}
|
|
@@ -358,14 +387,6 @@ ${(0, utils_1.indent)(sql)}
|
|
|
358
387
|
}
|
|
359
388
|
return tableSQL;
|
|
360
389
|
}
|
|
361
|
-
sqlLiteralString(literal) {
|
|
362
|
-
const noVirgule = literal.replace(/\\/g, '\\\\');
|
|
363
|
-
return "'" + noVirgule.replace(/'/g, "\\'") + "'";
|
|
364
|
-
}
|
|
365
|
-
sqlLiteralRegexp(literal) {
|
|
366
|
-
const noVirgule = literal.replace(/\\/g, '\\\\');
|
|
367
|
-
return "'" + noVirgule.replace(/'/g, "\\'") + "'";
|
|
368
|
-
}
|
|
369
390
|
getDialectFunctionOverrides() {
|
|
370
391
|
return (0, functions_1.expandOverrideMap)(function_overrides_1.STANDARDSQL_MALLOY_STANDARD_OVERLOADS);
|
|
371
392
|
}
|
|
@@ -432,7 +453,7 @@ ${(0, utils_1.indent)(sql)}
|
|
|
432
453
|
const ents = [];
|
|
433
454
|
for (const [name, val] of Object.entries(lit.kids)) {
|
|
434
455
|
const expr = val.sql || 'internal-error-literal-record';
|
|
435
|
-
ents.push(`${expr} AS ${this.
|
|
456
|
+
ents.push(`${expr} AS ${this.sqlQuoteIdentifier(name)}`);
|
|
436
457
|
}
|
|
437
458
|
return `STRUCT(${ents.join(',')})`;
|
|
438
459
|
}
|
|
@@ -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
|
|
@@ -3,6 +3,7 @@ import type { ExprValue } from '../types/expr-value';
|
|
|
3
3
|
import { ExpressionDef } from '../types/expression-def';
|
|
4
4
|
import type { FieldSpace } from '../types/field-space';
|
|
5
5
|
import { BinaryBoolean } from './binary-boolean';
|
|
6
|
+
import type { GivenReference } from './expr-given';
|
|
6
7
|
export declare class ExprCompare extends BinaryBoolean<CompareMalloyOperator> {
|
|
7
8
|
elementType: string;
|
|
8
9
|
constructor(left: ExpressionDef, op: CompareMalloyOperator, right: ExpressionDef);
|
|
@@ -28,3 +29,17 @@ export declare class ExprLegacyIn extends ExpressionDef {
|
|
|
28
29
|
constructor(expr: ExpressionDef, notIn: boolean, choices: ExpressionDef[]);
|
|
29
30
|
getExpression(fs: FieldSpace): ExprValue;
|
|
30
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* `expr in $ARRAY_GIVEN` — runtime test of a basic-typed expression
|
|
34
|
+
* against the elements of a runtime-bound array given. The translator
|
|
35
|
+
* verifies the given is `T[]` and the LHS is the same basic `T`; SQL
|
|
36
|
+
* emission expands the bound array's elements at compile time.
|
|
37
|
+
*/
|
|
38
|
+
export declare class ExprInGiven extends ExpressionDef {
|
|
39
|
+
readonly expr: ExpressionDef;
|
|
40
|
+
readonly notIn: boolean;
|
|
41
|
+
readonly givenRef: GivenReference;
|
|
42
|
+
elementType: string;
|
|
43
|
+
constructor(expr: ExpressionDef, notIn: boolean, givenRef: GivenReference);
|
|
44
|
+
getExpression(fs: FieldSpace): ExprValue;
|
|
45
|
+
}
|