@malloydata/malloy 0.0.434 → 0.0.436
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/foundation/build_targets.d.ts +5 -6
- package/dist/api/foundation/build_targets.js +74 -6
- package/dist/api/foundation/compile.d.ts +0 -1
- package/dist/api/foundation/compile.js +0 -3
- package/dist/api/foundation/core.d.ts +16 -4
- package/dist/api/foundation/core.js +23 -23
- package/dist/api/foundation/index.d.ts +1 -1
- package/dist/api/foundation/runtime.d.ts +21 -3
- package/dist/api/foundation/runtime.js +45 -54
- package/dist/api/foundation/types.d.ts +43 -4
- package/dist/connection/dbmeta.d.ts +29 -0
- package/dist/connection/dbmeta.js +46 -0
- package/dist/connection/index.d.ts +1 -0
- package/dist/connection/index.js +1 -0
- package/dist/dialect/databricks/databricks.d.ts +11 -12
- package/dist/dialect/databricks/databricks.js +24 -36
- package/dist/dialect/dialect.d.ts +70 -171
- package/dist/dialect/dialect.js +123 -92
- package/dist/dialect/dialect_map.js +2 -0
- package/dist/dialect/duckdb/duckdb.d.ts +2 -2
- package/dist/dialect/duckdb/duckdb.js +1 -1
- package/dist/dialect/index.d.ts +3 -2
- package/dist/dialect/index.js +4 -2
- package/dist/dialect/mysql/mysql.d.ts +11 -12
- package/dist/dialect/mysql/mysql.js +20 -32
- package/dist/dialect/pg_impl.d.ts +9 -10
- package/dist/dialect/pg_impl.js +27 -73
- package/dist/dialect/postgres/postgres.d.ts +4 -4
- package/dist/dialect/postgres/postgres.js +4 -12
- package/dist/dialect/snowflake/snowflake.d.ts +11 -13
- package/dist/dialect/snowflake/snowflake.js +30 -82
- package/dist/dialect/sqlserver/dialect_functions.d.ts +2 -0
- package/dist/dialect/sqlserver/dialect_functions.js +42 -0
- package/dist/dialect/sqlserver/function_overrides.d.ts +2 -0
- package/dist/dialect/sqlserver/function_overrides.js +55 -0
- package/dist/dialect/sqlserver/index.d.ts +1 -0
- package/dist/dialect/sqlserver/index.js +22 -0
- package/dist/dialect/sqlserver/sqlserver.d.ts +101 -0
- package/dist/dialect/sqlserver/sqlserver.js +537 -0
- package/dist/dialect/sqlserver/windows_zones.d.ts +1 -0
- package/dist/dialect/sqlserver/windows_zones.js +613 -0
- package/dist/dialect/standardsql/standardsql.d.ts +11 -16
- package/dist/dialect/standardsql/standardsql.js +22 -73
- package/dist/dialect/trino/trino.d.ts +16 -18
- package/dist/dialect/trino/trino.js +127 -181
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -4
- package/dist/lang/ast/expressions/boolean-value.d.ts +24 -0
- package/dist/lang/ast/expressions/boolean-value.js +41 -0
- package/dist/lang/ast/expressions/case.js +7 -0
- package/dist/lang/ast/expressions/expr-alternation-tree.js +11 -0
- package/dist/lang/ast/expressions/expr-cast.js +5 -0
- package/dist/lang/ast/expressions/expr-coalesce.js +4 -0
- package/dist/lang/ast/expressions/expr-func.js +13 -2
- package/dist/lang/ast/expressions/expr-minus.js +5 -2
- package/dist/lang/ast/expressions/expr-null.js +4 -0
- package/dist/lang/ast/expressions/pick-when.js +7 -0
- package/dist/lang/ast/field-space/index-field-space.js +13 -1
- package/dist/lang/ast/field-space/query-spaces.js +11 -0
- package/dist/lang/ast/query-builders/reduce-builder.js +1 -1
- package/dist/lang/ast/query-items/field-declaration.d.ts +5 -0
- package/dist/lang/ast/query-items/field-declaration.js +22 -16
- package/dist/lang/ast/query-items/field-references.d.ts +6 -0
- package/dist/lang/ast/query-items/field-references.js +23 -0
- package/dist/lang/ast/query-properties/filters.js +3 -1
- package/dist/lang/ast/source-elements/named-source.js +0 -2
- package/dist/lang/ast/source-elements/sql-source.js +0 -3
- package/dist/lang/ast/source-elements/table-source.js +1 -2
- package/dist/lang/ast/statements/import-statement.js +17 -0
- package/dist/lang/ast/types/expression-def.js +17 -2
- package/dist/lang/ast/types/malloy-element.d.ts +24 -8
- package/dist/lang/ast/types/malloy-element.js +63 -44
- package/dist/lang/ast/view-elements/reference-view.js +4 -0
- package/dist/lang/ast/view-elements/refine-utils.js +1 -0
- package/dist/lang/composite-source-utils.js +10 -17
- package/dist/lang/parse-log.d.ts +12 -0
- package/dist/lang/parse-log.js +2 -0
- package/dist/lang/parse-malloy.d.ts +17 -2
- package/dist/lang/parse-malloy.js +48 -14
- package/dist/lang/parse-tree-walkers/find-external-references.d.ts +3 -3
- package/dist/lang/parse-tree-walkers/find-external-references.js +17 -16
- package/dist/lang/test/test-translator.d.ts +11 -1
- package/dist/lang/test/test-translator.js +51 -3
- package/dist/model/expression_compiler.js +9 -8
- package/dist/model/filter_compilers.js +13 -12
- package/dist/model/given_binding.d.ts +8 -0
- package/dist/model/given_binding.js +13 -0
- package/dist/model/index.d.ts +1 -1
- package/dist/model/index.js +2 -1
- package/dist/model/query_query.d.ts +3 -1
- package/dist/model/query_query.js +157 -139
- package/dist/model/source_def_utils.d.ts +7 -1
- package/dist/model/source_def_utils.js +20 -0
- package/dist/model/sql_compiled.d.ts +19 -20
- package/dist/model/sql_compiled.js +29 -17
- package/dist/test/index.js +16 -8
- package/dist/test/matchers.d.ts +1 -1
- package/dist/test/matchers.js +1 -1
- package/dist/test/test-models.js +6 -13
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/femto-config.motly +13 -1
- package/package.json +7 -5
|
@@ -32,18 +32,18 @@ class FindExternalReferences {
|
|
|
32
32
|
constructor(trans, tokens) {
|
|
33
33
|
this.trans = trans;
|
|
34
34
|
this.tokens = tokens;
|
|
35
|
-
this.needTables =
|
|
36
|
-
this.needImports =
|
|
37
|
-
this.needConnectionDialects =
|
|
35
|
+
this.needTables = new Map();
|
|
36
|
+
this.needImports = new Map();
|
|
37
|
+
this.needConnectionDialects = new Map();
|
|
38
38
|
}
|
|
39
39
|
registerTableReference(connectionName, tablePath, reference) {
|
|
40
40
|
const key = constructTableKey(connectionName, tablePath);
|
|
41
|
-
if (!this.needTables
|
|
42
|
-
this.needTables
|
|
41
|
+
if (!this.needTables.has(key)) {
|
|
42
|
+
this.needTables.set(key, {
|
|
43
43
|
connectionName,
|
|
44
44
|
tablePath,
|
|
45
45
|
firstReference: reference,
|
|
46
|
-
};
|
|
46
|
+
});
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
enterExploreTable(pcx) {
|
|
@@ -53,22 +53,23 @@ class FindExternalReferences {
|
|
|
53
53
|
this.registerTableReference(connId, tablePath, reference);
|
|
54
54
|
// Register a need for the connection's dialect so the validator in
|
|
55
55
|
// ImportsAndTablesStep can run against it.
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
this.registerConnection(connId, reference);
|
|
57
|
+
}
|
|
58
|
+
registerConnection(connId, reference) {
|
|
59
|
+
if (connId && !this.needConnectionDialects.has(connId)) {
|
|
60
|
+
this.needConnectionDialects.set(connId, { firstReference: reference });
|
|
58
61
|
}
|
|
59
62
|
}
|
|
63
|
+
enterSqlSource(pcx) {
|
|
64
|
+
this.registerConnection((0, parse_utils_1.getId)(pcx.connectionId()), this.trans.rangeFromContext(pcx));
|
|
65
|
+
}
|
|
60
66
|
enterVirtualSource(pcx) {
|
|
61
|
-
|
|
62
|
-
if (connId && !this.needConnectionDialects[connId]) {
|
|
63
|
-
this.needConnectionDialects[connId] = {
|
|
64
|
-
firstReference: this.trans.rangeFromContext(pcx),
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
+
this.registerConnection((0, parse_utils_1.getId)(pcx.connectionId()), this.trans.rangeFromContext(pcx));
|
|
67
68
|
}
|
|
68
69
|
enterImportURL(pcx) {
|
|
69
70
|
const url = getPlainString(pcx);
|
|
70
|
-
if (!this.needImports
|
|
71
|
-
this.needImports
|
|
71
|
+
if (!this.needImports.has(url)) {
|
|
72
|
+
this.needImports.set(url, this.trans.rangeFromContext(pcx));
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
}
|
|
@@ -3,6 +3,7 @@ import { MalloyElement } from '../ast';
|
|
|
3
3
|
import type { NameSpace } from '../ast/types/name-space';
|
|
4
4
|
import type { ModelEntry } from '../ast/types/model-entry';
|
|
5
5
|
import { MalloyChildTranslator, MalloyTranslator } from '../parse-malloy';
|
|
6
|
+
import { Zone } from '../zone';
|
|
6
7
|
import type { DataRequestResponse, SQLSourceRequest, TranslateResponse } from '../translate-response';
|
|
7
8
|
import type { ExprValue } from '../ast/types/expr-value';
|
|
8
9
|
import type { LogSeverity, MessageCode, MessageParameterType } from '../parse-log';
|
|
@@ -28,6 +29,7 @@ export declare const aTableDef: TableSourceDef;
|
|
|
28
29
|
export declare const db2TableDef: TableSourceDef;
|
|
29
30
|
export declare const bqTableDef: SourceDef;
|
|
30
31
|
export declare const pgTableDef: SourceDef;
|
|
32
|
+
export declare const mssqlTableDef: SourceDef;
|
|
31
33
|
/**
|
|
32
34
|
* A TestTranlator never actually talks to connection, instead uses
|
|
33
35
|
* some mocked schema definitions.
|
|
@@ -66,10 +68,18 @@ export interface TestTranslatorOptions {
|
|
|
66
68
|
*/
|
|
67
69
|
compilerFlags?: string[];
|
|
68
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Every connection name a test mentions resolves to a dialect, as it would
|
|
73
|
+
* through a host's connection lookup: the five listed below to theirs, and
|
|
74
|
+
* any other name to `TEST_DIALECT`.
|
|
75
|
+
*/
|
|
76
|
+
declare class TestConnectionDialectZone extends Zone<string> {
|
|
77
|
+
reference(str: string, loc: DocumentLocation): void;
|
|
78
|
+
}
|
|
69
79
|
export declare class TestTranslator extends MalloyTranslator {
|
|
70
80
|
readonly testSrc: string;
|
|
71
|
-
allDialectsEnabled: boolean;
|
|
72
81
|
testRoot?: TestRoot;
|
|
82
|
+
connectionDialectZone: TestConnectionDialectZone;
|
|
73
83
|
internalModel: ModelDef;
|
|
74
84
|
constructor(testSrc: string, options?: TestTranslatorOptions);
|
|
75
85
|
translate(): TranslateResponse;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* SPDX-License-Identifier: MIT
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.BetaExpression = exports.TestTranslator = exports.TestChildTranslator = exports.mockSchema = exports.pgTableDef = exports.bqTableDef = exports.db2TableDef = exports.aTableDef = exports.TEST_DIALECT = void 0;
|
|
8
|
+
exports.BetaExpression = exports.TestTranslator = exports.TestChildTranslator = exports.mockSchema = exports.mssqlTableDef = exports.pgTableDef = exports.bqTableDef = exports.db2TableDef = exports.aTableDef = exports.TEST_DIALECT = void 0;
|
|
9
9
|
exports.pretty = pretty;
|
|
10
10
|
exports.humanify = humanify;
|
|
11
11
|
exports.getExplore = getExplore;
|
|
@@ -29,6 +29,7 @@ const util_1 = require("util");
|
|
|
29
29
|
const malloy_types_1 = require("../../model/malloy_types");
|
|
30
30
|
const ast_1 = require("../ast");
|
|
31
31
|
const parse_malloy_1 = require("../parse-malloy");
|
|
32
|
+
const zone_1 = require("../zone");
|
|
32
33
|
const static_space_1 = require("../ast/field-space/static-space");
|
|
33
34
|
const global_name_space_1 = require("../ast/types/global-name-space");
|
|
34
35
|
const sql_block_1 = require("../../model/sql_block");
|
|
@@ -193,6 +194,16 @@ exports.pgTableDef = {
|
|
|
193
194
|
connection: '_pg_',
|
|
194
195
|
fields: baseFields,
|
|
195
196
|
};
|
|
197
|
+
// SQL Server has no boolean values (booleanType 'none'), so no column of
|
|
198
|
+
// its table is a boolean
|
|
199
|
+
exports.mssqlTableDef = {
|
|
200
|
+
type: 'table',
|
|
201
|
+
name: 'aTable',
|
|
202
|
+
dialect: 'sqlserver',
|
|
203
|
+
tablePath: 'aTable',
|
|
204
|
+
connection: '_mssql_',
|
|
205
|
+
fields: baseFields.filter(f => f.name !== 'abool'),
|
|
206
|
+
};
|
|
196
207
|
/**
|
|
197
208
|
* A TestTranlator never actually talks to connection, instead uses
|
|
198
209
|
* some mocked schema definitions.
|
|
@@ -202,6 +213,7 @@ exports.mockSchema = [
|
|
|
202
213
|
exports.db2TableDef,
|
|
203
214
|
exports.bqTableDef,
|
|
204
215
|
exports.pgTableDef,
|
|
216
|
+
exports.mssqlTableDef,
|
|
205
217
|
{
|
|
206
218
|
type: 'table',
|
|
207
219
|
name: 'carriers',
|
|
@@ -336,14 +348,27 @@ class TestChildTranslator extends parse_malloy_1.MalloyChildTranslator {
|
|
|
336
348
|
}
|
|
337
349
|
exports.TestChildTranslator = TestChildTranslator;
|
|
338
350
|
const testURI = 'internal://test/langtests/root.malloy';
|
|
351
|
+
/**
|
|
352
|
+
* Every connection name a test mentions resolves to a dialect, as it would
|
|
353
|
+
* through a host's connection lookup: the five listed below to theirs, and
|
|
354
|
+
* any other name to `TEST_DIALECT`.
|
|
355
|
+
*/
|
|
356
|
+
class TestConnectionDialectZone extends zone_1.Zone {
|
|
357
|
+
reference(str, loc) {
|
|
358
|
+
super.reference(str, loc);
|
|
359
|
+
if (this.getEntry(str).status === 'reference') {
|
|
360
|
+
this.define(str, exports.TEST_DIALECT);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
339
364
|
class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
340
365
|
constructor(testSrc, options = {}) {
|
|
341
366
|
var _a, _b, _c, _d, _e;
|
|
342
367
|
super(testURI, (_a = options.importBaseURL) !== null && _a !== void 0 ? _a : null, null, (_b = options.eventStream) !== null && _b !== void 0 ? _b : null, (_c = options.restrictedMode) !== null && _c !== void 0 ? _c : false, options.virtualMap);
|
|
343
368
|
this.testSrc = testSrc;
|
|
344
|
-
this.
|
|
369
|
+
this.connectionDialectZone = new TestConnectionDialectZone();
|
|
345
370
|
/*
|
|
346
|
-
* There are
|
|
371
|
+
* There are five connections:
|
|
347
372
|
* _db_ - duckdb dialect, with the following tables ...
|
|
348
373
|
* aTable, malloytest.carriers, malloytest.flights, malloytest.airports
|
|
349
374
|
* _db2_ - duckdb dialect, with one table, aTable. A second connection
|
|
@@ -352,6 +377,8 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
352
377
|
* aTable
|
|
353
378
|
* _pg_ - postgres dialect, with one table
|
|
354
379
|
* aTable
|
|
380
|
+
* _mssql_ - sqlserver dialect, which has no boolean values, with one
|
|
381
|
+
* table, aTable
|
|
355
382
|
*
|
|
356
383
|
* The "aTable" table is a mocked table with one column of each type.
|
|
357
384
|
* The _bq_ version does not have the timestamptz column, and when
|
|
@@ -380,6 +407,7 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
380
407
|
_db2_: { type: 'connection', name: '_db2_' },
|
|
381
408
|
_bq_: { type: 'connection', name: '_bq_' },
|
|
382
409
|
_pg_: { type: 'connection', name: '_pg_' },
|
|
410
|
+
_mssql_: { type: 'connection', name: '_mssql_' },
|
|
383
411
|
a: { ...exports.aTableDef, primaryKey: 'astr', name: 'a' },
|
|
384
412
|
b: { ...exports.aTableDef, primaryKey: 'astr', name: 'b' },
|
|
385
413
|
bq_a: { ...exports.bqTableDef, primaryKey: 'astr', name: 'bq_a' },
|
|
@@ -437,6 +465,7 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
437
465
|
this.connectionDialectZone.define('_db2_', exports.TEST_DIALECT);
|
|
438
466
|
this.connectionDialectZone.define('_bq_', 'standardsql');
|
|
439
467
|
this.connectionDialectZone.define('_pg_', 'postgres');
|
|
468
|
+
this.connectionDialectZone.define('_mssql_', 'sqlserver');
|
|
440
469
|
for (const flag of (_e = options.compilerFlags) !== null && _e !== void 0 ? _e : []) {
|
|
441
470
|
this.compilerFlagSrc.push(`##! ${flag}\n`);
|
|
442
471
|
}
|
|
@@ -644,10 +673,29 @@ function makeModelFunc(options) {
|
|
|
644
673
|
const { prefix, wrap, ...ttOptions } = options;
|
|
645
674
|
return {
|
|
646
675
|
...ms,
|
|
676
|
+
// A marked location is where the mark sits in the whole source, after
|
|
677
|
+
// the prefix. A wrap could put the code anywhere, so marks stay as
|
|
678
|
+
// they are.
|
|
679
|
+
locations: wrap ? ms.locations : ms.locations.map(l => after(prefix, l)),
|
|
647
680
|
translator: new TestTranslator((prefix !== null && prefix !== void 0 ? prefix : '') + (wrap ? wrap(ms.code) : ms.code), ttOptions),
|
|
648
681
|
};
|
|
649
682
|
};
|
|
650
683
|
}
|
|
684
|
+
function after(prefix, l) {
|
|
685
|
+
if (!prefix)
|
|
686
|
+
return l;
|
|
687
|
+
const lines = prefix.split('\n');
|
|
688
|
+
const dLine = lines.length - 1;
|
|
689
|
+
const dChar = lines[dLine].length;
|
|
690
|
+
const shift = (p) => ({
|
|
691
|
+
line: p.line + dLine,
|
|
692
|
+
character: p.line === 0 ? p.character + dChar : p.character,
|
|
693
|
+
});
|
|
694
|
+
return {
|
|
695
|
+
...l,
|
|
696
|
+
range: { start: shift(l.range.start), end: shift(l.range.end) },
|
|
697
|
+
};
|
|
698
|
+
}
|
|
651
699
|
function makeExprFunc(model, sourceName = 'ab', options = {}) {
|
|
652
700
|
return function expr(unmarked, ...marked) {
|
|
653
701
|
const ms = markSource(unmarked, ...marked);
|
|
@@ -109,7 +109,7 @@ function compileExpr(resultSet, context, expr, state = new utils_1.GenerateState
|
|
|
109
109
|
return expr;
|
|
110
110
|
}
|
|
111
111
|
const sql = (() => {
|
|
112
|
-
var _a;
|
|
112
|
+
var _a, _b;
|
|
113
113
|
switch (expr.node) {
|
|
114
114
|
case 'field':
|
|
115
115
|
return generateFieldFragment(resultSet, context, expr, state);
|
|
@@ -176,7 +176,7 @@ function compileExpr(resultSet, context, expr, state = new utils_1.GenerateState
|
|
|
176
176
|
// Malloy inequality comparisons always return a boolean
|
|
177
177
|
case '!=': {
|
|
178
178
|
const notEqual = `${expr.kids.left.sql}!=${expr.kids.right.sql}`;
|
|
179
|
-
return
|
|
179
|
+
return context.dialect.sqlNullIsTrue(notEqual);
|
|
180
180
|
}
|
|
181
181
|
case 'and':
|
|
182
182
|
case 'or':
|
|
@@ -192,13 +192,13 @@ function compileExpr(resultSet, context, expr, state = new utils_1.GenerateState
|
|
|
192
192
|
// null binding collapses to empty-set semantics — not the SQL
|
|
193
193
|
// `IN (NULL)` shape, which has confusing NULL-membership rules.
|
|
194
194
|
if (bound.node === 'null') {
|
|
195
|
-
return expr.not
|
|
195
|
+
return context.dialect.sqlBoolean(expr.not);
|
|
196
196
|
}
|
|
197
197
|
if (bound.node !== 'arrayLiteral') {
|
|
198
198
|
throw new Error(`Internal compiler error: 'inGiven' bound to '${bound.node}', expected 'arrayLiteral'. The translator should have rejected a non-array given here.`);
|
|
199
199
|
}
|
|
200
200
|
if (bound.kids.values.length === 0) {
|
|
201
|
-
return expr.not
|
|
201
|
+
return context.dialect.sqlBoolean(expr.not);
|
|
202
202
|
}
|
|
203
203
|
const elemSqls = bound.kids.values.map(v => exprToSQL(resultSet, context, v, state));
|
|
204
204
|
const verb = expr.not ? 'NOT IN' : 'IN';
|
|
@@ -210,13 +210,14 @@ function compileExpr(resultSet, context, expr, state = new utils_1.GenerateState
|
|
|
210
210
|
const compare = expr.kids.right.node === 'stringLiteral'
|
|
211
211
|
? context.dialect.sqlLike(likeIt, (_a = expr.kids.left.sql) !== null && _a !== void 0 ? _a : '', expr.kids.right.literal)
|
|
212
212
|
: `${expr.kids.left.sql} ${likeIt} ${expr.kids.right.sql}`;
|
|
213
|
-
return expr.node === 'like'
|
|
213
|
+
return expr.node === 'like'
|
|
214
|
+
? compare
|
|
215
|
+
: context.dialect.sqlNullIsTrue(compare);
|
|
214
216
|
}
|
|
215
217
|
case '()':
|
|
216
218
|
return `(${expr.e.sql})`;
|
|
217
219
|
case 'not':
|
|
218
|
-
|
|
219
|
-
return `COALESCE(NOT ${expr.e.sql},TRUE)`;
|
|
220
|
+
return context.dialect.sqlNot((_b = expr.e.sql) !== null && _b !== void 0 ? _b : '');
|
|
220
221
|
case 'unary-':
|
|
221
222
|
return `-${expr.e.sql}`;
|
|
222
223
|
case 'is-null':
|
|
@@ -225,7 +226,7 @@ function compileExpr(resultSet, context, expr, state = new utils_1.GenerateState
|
|
|
225
226
|
return `${expr.e.sql} IS NOT NULL`;
|
|
226
227
|
case 'true':
|
|
227
228
|
case 'false':
|
|
228
|
-
return expr.node;
|
|
229
|
+
return context.dialect.sqlBoolean(expr.node === 'true');
|
|
229
230
|
case 'null':
|
|
230
231
|
return 'NULL';
|
|
231
232
|
case 'case':
|
|
@@ -34,13 +34,13 @@ function unlike(disLiked, x) {
|
|
|
34
34
|
// The `none` filter ("always false") compiles to a constant, independent of
|
|
35
35
|
// column type or value; `not none` is "always true". Shared by the top-level
|
|
36
36
|
// guard and every per-type compiler so the constant lives in one place.
|
|
37
|
-
function noneToSQL(not) {
|
|
38
|
-
return not
|
|
37
|
+
function noneToSQL(not, d) {
|
|
38
|
+
return d.sqlBoolean(not === true);
|
|
39
39
|
}
|
|
40
40
|
exports.FilterCompilers = {
|
|
41
41
|
compile(t, c, x, d, qi = {}) {
|
|
42
42
|
if (c === null) {
|
|
43
|
-
return
|
|
43
|
+
return d.sqlBoolean(true);
|
|
44
44
|
}
|
|
45
45
|
// `none` is the always-false filter (companion to the empty/`null` filter,
|
|
46
46
|
// which is always-true above). It compiles to a constant independent of
|
|
@@ -48,7 +48,7 @@ exports.FilterCompilers = {
|
|
|
48
48
|
// also the primary path for boolean, whose compiler has no switch and
|
|
49
49
|
// would otherwise route `none` through the null/false truth-table.
|
|
50
50
|
if (c.operator === 'none') {
|
|
51
|
-
return noneToSQL(c.not);
|
|
51
|
+
return noneToSQL(c.not, d);
|
|
52
52
|
}
|
|
53
53
|
if (t === 'string' && (0, malloy_filter_1.isStringFilter)(c)) {
|
|
54
54
|
return exports.FilterCompilers.stringCompile(c, x, d);
|
|
@@ -102,7 +102,7 @@ exports.FilterCompilers = {
|
|
|
102
102
|
case 'null':
|
|
103
103
|
return nc.not ? `${x} IS NOT NULL` : `${x} IS NULL`;
|
|
104
104
|
case 'none':
|
|
105
|
-
return noneToSQL(nc.not);
|
|
105
|
+
return noneToSQL(nc.not, d);
|
|
106
106
|
case '()': {
|
|
107
107
|
const wrapped = '(' + exports.FilterCompilers.numberCompile(nc.expr, x, d) + ')';
|
|
108
108
|
return nc.not ? `NOT ${wrapped}` : wrapped;
|
|
@@ -135,7 +135,7 @@ exports.FilterCompilers = {
|
|
|
135
135
|
// Normally intercepted by compile()'s top-level guard; handled here too so
|
|
136
136
|
// booleanCompile is self-safe (this if-chain has no default, and `none`
|
|
137
137
|
// must not fall through to the null/false truth-table below).
|
|
138
|
-
return noneToSQL(bc.not);
|
|
138
|
+
return noneToSQL(bc.not, d);
|
|
139
139
|
}
|
|
140
140
|
else if (bc.operator === '=true') {
|
|
141
141
|
return bc.not ? `NOT ${px}` : x;
|
|
@@ -172,7 +172,7 @@ exports.FilterCompilers = {
|
|
|
172
172
|
case 'null':
|
|
173
173
|
return sc.not ? `${x} IS NOT NULL` : `${x} IS NULL`;
|
|
174
174
|
case 'none':
|
|
175
|
-
return noneToSQL(sc.not);
|
|
175
|
+
return noneToSQL(sc.not, d);
|
|
176
176
|
case 'empty':
|
|
177
177
|
return sc.not ? `COALESCE(${x},'') != ''` : `COALESCE(${x},'') = ''`;
|
|
178
178
|
case '=': {
|
|
@@ -267,7 +267,7 @@ exports.FilterCompilers = {
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
if ((includeEmpty && excludeEmpty) || (includeNull && excludeNull)) {
|
|
270
|
-
return
|
|
270
|
+
return d.sqlBoolean(false);
|
|
271
271
|
}
|
|
272
272
|
let includeSQL = '';
|
|
273
273
|
if (includes.length > 0 || includeNull || includeEmpty) {
|
|
@@ -298,7 +298,7 @@ exports.FilterCompilers = {
|
|
|
298
298
|
? `(${includeSQL}) AND (${excludeSQL})`
|
|
299
299
|
: includeSQL;
|
|
300
300
|
}
|
|
301
|
-
return excludeSQL !== '' ? excludeSQL :
|
|
301
|
+
return excludeSQL !== '' ? excludeSQL : d.sqlBoolean(true);
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
304
|
},
|
|
@@ -331,7 +331,7 @@ class TemporalFilterCompiler {
|
|
|
331
331
|
if (this.timetype !== 'date') {
|
|
332
332
|
return timeSQL;
|
|
333
333
|
}
|
|
334
|
-
|
|
334
|
+
const toDate = {
|
|
335
335
|
node: 'cast',
|
|
336
336
|
e: {
|
|
337
337
|
node: 'genericSQLExpr',
|
|
@@ -342,7 +342,8 @@ class TemporalFilterCompiler {
|
|
|
342
342
|
srcType: { type: 'timestamp' },
|
|
343
343
|
dstType: { type: 'date' },
|
|
344
344
|
safe: false,
|
|
345
|
-
}
|
|
345
|
+
};
|
|
346
|
+
return this.d.sqlTimeCast(this.qi, toDate);
|
|
346
347
|
}
|
|
347
348
|
compile(tc) {
|
|
348
349
|
const x = this.expr;
|
|
@@ -421,7 +422,7 @@ class TemporalFilterCompiler {
|
|
|
421
422
|
case 'null':
|
|
422
423
|
return tc.not ? `${x} IS NOT NULL` : `${x} IS NULL`;
|
|
423
424
|
case 'none':
|
|
424
|
-
return noneToSQL(tc.not);
|
|
425
|
+
return noneToSQL(tc.not, this.d);
|
|
425
426
|
case '()': {
|
|
426
427
|
const wrapped = '(' + this.compile(tc.expr) + ')';
|
|
427
428
|
return tc.not ? `NOT ${wrapped}` : wrapped;
|
|
@@ -27,3 +27,11 @@ export declare function resolveSuppliedGivens(supplied: Record<string, GivenValu
|
|
|
27
27
|
* `resolveGiven`), which needs no ordering.
|
|
28
28
|
*/
|
|
29
29
|
export declare function evaluateInlineGivens(bound: Map<GivenID, Expr>, modelDef: ModelDef | undefined): Map<GivenID, Expr>;
|
|
30
|
+
/**
|
|
31
|
+
* Binds the givens a compile runs under: the supplied values, then each
|
|
32
|
+
* `inline` given's default folded against them. Queries and persistence builds
|
|
33
|
+
* both bind here, so the same values always compile to the same SQL and a
|
|
34
|
+
* persisted table's key is the key a query recomputes. Undefined when nothing
|
|
35
|
+
* binds, which the compiler reads as "no givens".
|
|
36
|
+
*/
|
|
37
|
+
export declare function bindGivens(supplied: Record<string, GivenValue> | undefined, modelDef: ModelDef | undefined): Map<GivenID, Expr> | undefined;
|
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.lookupGivenValue = lookupGivenValue;
|
|
8
8
|
exports.resolveSuppliedGivens = resolveSuppliedGivens;
|
|
9
9
|
exports.evaluateInlineGivens = evaluateInlineGivens;
|
|
10
|
+
exports.bindGivens = bindGivens;
|
|
10
11
|
const luxon_1 = require("luxon");
|
|
11
12
|
const closest_match_1 = require("../util/closest_match");
|
|
12
13
|
const inline_expr_1 = require("./inline_expr");
|
|
@@ -106,6 +107,18 @@ function evaluateInlineGivens(bound, modelDef) {
|
|
|
106
107
|
}
|
|
107
108
|
return bound;
|
|
108
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Binds the givens a compile runs under: the supplied values, then each
|
|
112
|
+
* `inline` given's default folded against them. Queries and persistence builds
|
|
113
|
+
* both bind here, so the same values always compile to the same SQL and a
|
|
114
|
+
* persisted table's key is the key a query recomputes. Undefined when nothing
|
|
115
|
+
* binds, which the compiler reads as "no givens".
|
|
116
|
+
*/
|
|
117
|
+
function bindGivens(supplied, modelDef) {
|
|
118
|
+
const bound = resolveSuppliedGivens(supplied, modelDef);
|
|
119
|
+
evaluateInlineGivens(bound, modelDef);
|
|
120
|
+
return bound.size > 0 ? bound : undefined;
|
|
121
|
+
}
|
|
109
122
|
function valueToExpr(path, type, value) {
|
|
110
123
|
var _a, _b;
|
|
111
124
|
if (value === null) {
|
package/dist/model/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { getResultStructDefForQuery, getResultStructDefForView, } from './query_
|
|
|
7
7
|
export { indent, composeSQLExpr, makeDigest, mkModelDef, mkModelID, pathToKey, typeDefToString, } from './utils';
|
|
8
8
|
export { getModelAnnotations } from './annotation_utils';
|
|
9
9
|
export { constantExprToSQL } from './constant_expression_compiler';
|
|
10
|
-
export { getCompiledSQL, buildIdOptions } from './sql_compiled';
|
|
10
|
+
export { getCompiledSQL, buildIdOptions, givenUsageOfRelation, } from './sql_compiled';
|
|
11
11
|
export type { BuildIdOptions } from './sql_compiled';
|
|
12
12
|
export { MalloyCompileError } from './malloy_compile_error';
|
|
13
13
|
export { mkSourceID, mkBuildID, mkQuerySourceDef, mkSQLSourceDef, mkTableSourceDef, resolveSourceID, resolveSourceRef, sourceNamespaceReference, registerSource, hasSourceRegistryEntry, } from './source_def_utils';
|
package/dist/model/index.js
CHANGED
|
@@ -18,7 +18,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
18
18
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.hasSourceRegistryEntry = exports.registerSource = exports.sourceNamespaceReference = exports.resolveSourceRef = exports.resolveSourceID = exports.mkTableSourceDef = exports.mkSQLSourceDef = exports.mkQuerySourceDef = exports.mkBuildID = exports.mkSourceID = exports.MalloyCompileError = exports.buildIdOptions = exports.getCompiledSQL = exports.constantExprToSQL = exports.getModelAnnotations = exports.typeDefToString = exports.pathToKey = exports.mkModelID = exports.mkModelDef = exports.makeDigest = exports.composeSQLExpr = exports.indent = exports.getResultStructDefForView = exports.getResultStructDefForQuery = exports.QueryModel = exports.QueryQuery = exports.QueryStruct = exports.QueryField = void 0;
|
|
21
|
+
exports.hasSourceRegistryEntry = exports.registerSource = exports.sourceNamespaceReference = exports.resolveSourceRef = exports.resolveSourceID = exports.mkTableSourceDef = exports.mkSQLSourceDef = exports.mkQuerySourceDef = exports.mkBuildID = exports.mkSourceID = exports.MalloyCompileError = exports.givenUsageOfRelation = exports.buildIdOptions = exports.getCompiledSQL = exports.constantExprToSQL = exports.getModelAnnotations = exports.typeDefToString = exports.pathToKey = exports.mkModelID = exports.mkModelDef = exports.makeDigest = exports.composeSQLExpr = exports.indent = exports.getResultStructDefForView = exports.getResultStructDefForQuery = exports.QueryModel = exports.QueryQuery = exports.QueryStruct = exports.QueryField = void 0;
|
|
22
22
|
__exportStar(require("./malloy_types"), exports);
|
|
23
23
|
const query_node_1 = require("./query_node");
|
|
24
24
|
Object.defineProperty(exports, "QueryField", { enumerable: true, get: function () { return query_node_1.QueryField; } });
|
|
@@ -52,6 +52,7 @@ Object.defineProperty(exports, "constantExprToSQL", { enumerable: true, get: fun
|
|
|
52
52
|
var sql_compiled_1 = require("./sql_compiled");
|
|
53
53
|
Object.defineProperty(exports, "getCompiledSQL", { enumerable: true, get: function () { return sql_compiled_1.getCompiledSQL; } });
|
|
54
54
|
Object.defineProperty(exports, "buildIdOptions", { enumerable: true, get: function () { return sql_compiled_1.buildIdOptions; } });
|
|
55
|
+
Object.defineProperty(exports, "givenUsageOfRelation", { enumerable: true, get: function () { return sql_compiled_1.givenUsageOfRelation; } });
|
|
55
56
|
var malloy_compile_error_1 = require("./malloy_compile_error");
|
|
56
57
|
Object.defineProperty(exports, "MalloyCompileError", { enumerable: true, get: function () { return malloy_compile_error_1.MalloyCompileError; } });
|
|
57
58
|
var source_def_utils_1 = require("./source_def_utils");
|
|
@@ -17,8 +17,10 @@ type StageGroupMaping = {
|
|
|
17
17
|
};
|
|
18
18
|
interface StageOutputColumn {
|
|
19
19
|
sql: string;
|
|
20
|
+
expr: string;
|
|
20
21
|
name: string;
|
|
21
22
|
isDimension: boolean;
|
|
23
|
+
constant?: boolean;
|
|
22
24
|
}
|
|
23
25
|
type StageOutputContext = {
|
|
24
26
|
columns: StageOutputColumn[];
|
|
@@ -122,7 +124,7 @@ export declare class QueryQuery extends QueryField {
|
|
|
122
124
|
* This ordering ensures parent arrays are ordered before child arrays.
|
|
123
125
|
*/
|
|
124
126
|
collectArrayJoins(ji: JoinInstance): JoinInstance[];
|
|
125
|
-
genereateSQLOrderBy(queryDef: QuerySegment, resultStruct: FieldInstanceResult): string;
|
|
127
|
+
genereateSQLOrderBy(queryDef: QuerySegment, resultStruct: FieldInstanceResult): string[];
|
|
126
128
|
/**
|
|
127
129
|
* The single-scan form, with no `group_set` fan-out: one `SELECT` over the
|
|
128
130
|
* scan, grouped by the dimensions. Used both for a query with no nests and --
|