@malloydata/malloy 0.0.434 → 0.0.435
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 +0 -1
- package/dist/api/foundation/compile.js +0 -3
- package/dist/api/foundation/runtime.d.ts +0 -1
- package/dist/api/foundation/runtime.js +1 -23
- package/dist/api/foundation/types.d.ts +0 -1
- package/dist/dialect/dialect.d.ts +14 -1
- package/dist/dialect/dialect.js +34 -2
- package/dist/dialect/dialect_map.js +2 -0
- package/dist/dialect/index.d.ts +2 -1
- package/dist/dialect/index.js +3 -1
- 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 +102 -0
- package/dist/dialect/sqlserver/sqlserver.js +538 -0
- package/dist/dialect/sqlserver/windows_zones.d.ts +1 -0
- package/dist/dialect/sqlserver/windows_zones.js +613 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -3
- 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 +4 -0
- package/dist/lang/ast/types/malloy-element.d.ts +0 -7
- package/dist/lang/ast/types/malloy-element.js +0 -18
- 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 +10 -1
- package/dist/lang/test/test-translator.js +15 -1
- package/dist/model/expression_compiler.js +1 -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/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
package/dist/index.js
CHANGED
|
@@ -37,9 +37,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
};
|
|
38
38
|
})();
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
-
exports.
|
|
41
|
-
exports.
|
|
42
|
-
exports.makeDigest = void 0;
|
|
40
|
+
exports.malloyToQuery = exports.constantExprToSQL = exports.isDateUnit = exports.isTimestampUnit = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isBasicArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isCompoundArrayData = exports.isBasicAtomic = exports.isAtomic = exports.isSourceDef = exports.validateDottedTablePath = exports.decodeDottedTablePath = exports.Dialect = exports.spread = exports.literal = exports.variadicParam = exports.param = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.qtz = exports.arg = exports.getDialect = exports.registerDialect = exports.SQLServerDialect = exports.DatabricksDialect = exports.MySQLDialect = exports.SnowflakeDialect = exports.PostgresDialect = exports.TrinoDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
|
|
41
|
+
exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = exports.tagFromAnnotations = exports.annotationsForRoute = exports.payloadOf = exports.routeOf = exports.RoutedNote = exports.Annotations = exports.sqlKey = exports.API = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = exports.createConnectionsFromConfig = exports.getRegisteredConnectionTypes = exports.getConnectionTypeDisplayName = exports.getConnectionProperties = exports.registerConnectionType = exports.discoverConfig = exports.defaultConfigOverlays = exports.contextOverlay = exports.envOverlay = exports.MalloyConfig = exports.Manifest = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = void 0;
|
|
42
|
+
exports.makeDigest = exports.Reference = exports.EMPTY_BUILD_MANIFEST = void 0;
|
|
43
43
|
var dialect_1 = require("./dialect");
|
|
44
44
|
Object.defineProperty(exports, "DuckDBDialect", { enumerable: true, get: function () { return dialect_1.DuckDBDialect; } });
|
|
45
45
|
Object.defineProperty(exports, "StandardSQLDialect", { enumerable: true, get: function () { return dialect_1.StandardSQLDialect; } });
|
|
@@ -48,7 +48,9 @@ Object.defineProperty(exports, "PostgresDialect", { enumerable: true, get: funct
|
|
|
48
48
|
Object.defineProperty(exports, "SnowflakeDialect", { enumerable: true, get: function () { return dialect_1.SnowflakeDialect; } });
|
|
49
49
|
Object.defineProperty(exports, "MySQLDialect", { enumerable: true, get: function () { return dialect_1.MySQLDialect; } });
|
|
50
50
|
Object.defineProperty(exports, "DatabricksDialect", { enumerable: true, get: function () { return dialect_1.DatabricksDialect; } });
|
|
51
|
+
Object.defineProperty(exports, "SQLServerDialect", { enumerable: true, get: function () { return dialect_1.SQLServerDialect; } });
|
|
51
52
|
Object.defineProperty(exports, "registerDialect", { enumerable: true, get: function () { return dialect_1.registerDialect; } });
|
|
53
|
+
Object.defineProperty(exports, "getDialect", { enumerable: true, get: function () { return dialect_1.getDialect; } });
|
|
52
54
|
Object.defineProperty(exports, "arg", { enumerable: true, get: function () { return dialect_1.arg; } });
|
|
53
55
|
Object.defineProperty(exports, "qtz", { enumerable: true, get: function () { return dialect_1.qtz; } });
|
|
54
56
|
Object.defineProperty(exports, "overload", { enumerable: true, get: function () { return dialect_1.overload; } });
|
|
@@ -52,7 +52,6 @@ class NamedSource extends source_1.Source {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
modelStruct() {
|
|
55
|
-
var _a;
|
|
56
55
|
const modelEnt = this.modelEntry(this.ref);
|
|
57
56
|
const entry = modelEnt === null || modelEnt === void 0 ? void 0 : modelEnt.entry;
|
|
58
57
|
if (!entry) {
|
|
@@ -89,7 +88,6 @@ class NamedSource extends source_1.Source {
|
|
|
89
88
|
return;
|
|
90
89
|
}
|
|
91
90
|
else {
|
|
92
|
-
(_a = this.document()) === null || _a === void 0 ? void 0 : _a.checkExperimentalDialect(this, entry.dialect);
|
|
93
91
|
if ((0, malloy_types_1.isSourceDef)(entry)) {
|
|
94
92
|
// This struct is created as an unmodified reference to `entry`. Mark it
|
|
95
93
|
// with entry's own identity; the modification path (DynamicSpace) clears
|
|
@@ -12,7 +12,7 @@ const error_factory_1 = require("../error-factory");
|
|
|
12
12
|
const dialect_1 = require("../../../dialect");
|
|
13
13
|
class TableSource extends source_1.Source {
|
|
14
14
|
getSourceDef() {
|
|
15
|
-
var _a, _b
|
|
15
|
+
var _a, _b;
|
|
16
16
|
const info = this.getTableInfo();
|
|
17
17
|
if (info === undefined) {
|
|
18
18
|
return error_factory_1.ErrorFactory.structDef;
|
|
@@ -36,7 +36,6 @@ class TableSource extends source_1.Source {
|
|
|
36
36
|
let msg = `Schema read failure for table '${tablePath}' for connection '${connectionName}'`;
|
|
37
37
|
if (tableDefEntry) {
|
|
38
38
|
if (tableDefEntry.status === 'present') {
|
|
39
|
-
(_c = this.document()) === null || _c === void 0 ? void 0 : _c.checkExperimentalDialect(this, tableDefEntry.value.dialect);
|
|
40
39
|
tableDefEntry.value.location = this.location;
|
|
41
40
|
tableDefEntry.value.fields.forEach(field => {
|
|
42
41
|
field.location = this.location;
|
|
@@ -152,6 +152,10 @@ class ImportStatement extends malloy_element_1.ListOf {
|
|
|
152
152
|
}
|
|
153
153
|
const importMe = { ...sourceEntry };
|
|
154
154
|
importMe.as = dstName;
|
|
155
|
+
const dialect = (0, source_def_utils_1.dialectOfEntry)(importMe, importedModel);
|
|
156
|
+
if (dialect !== undefined) {
|
|
157
|
+
trans.checkExperimentalDialect(dialect, this.location);
|
|
158
|
+
}
|
|
155
159
|
doc.setEntry(dstName, { entry: importMe, exported: false });
|
|
156
160
|
// Every source the walk touched, routes included — not just the
|
|
157
161
|
// persistent ones. A `#@ -persist` wrapper that adds a join is
|
|
@@ -152,13 +152,6 @@ export declare class Document extends MalloyElement implements NameSpace {
|
|
|
152
152
|
modelDef(): ModelDef;
|
|
153
153
|
getEntry(str: string): ModelEntry | undefined;
|
|
154
154
|
setEntry(str: string, ent: ModelEntry): void;
|
|
155
|
-
/**
|
|
156
|
-
* Return an error message if this dialect is the first reference to this particular
|
|
157
|
-
* dialect, and the dialect is marked as experimental, and we are not running tests.
|
|
158
|
-
* @param dialect The dialect name
|
|
159
|
-
* @returns The error message or undefined
|
|
160
|
-
*/
|
|
161
|
-
checkExperimentalDialect(me: MalloyElement, dialect: string): void;
|
|
162
155
|
private readonly dialectNameSpaces;
|
|
163
156
|
getDialectNamespace(dialectName: string): NameSpace | undefined;
|
|
164
157
|
}
|
|
@@ -656,9 +656,6 @@ class Document extends MalloyElement {
|
|
|
656
656
|
if (this.globalNameSpace.getEntry(str) !== undefined) {
|
|
657
657
|
this.logError('name-conflict-with-global', `Cannot redefine '${str}', which is in global namespace`);
|
|
658
658
|
}
|
|
659
|
-
if ((0, malloy_types_1.isSourceDef)(ent.entry)) {
|
|
660
|
-
this.checkExperimentalDialect(this, ent.entry.dialect);
|
|
661
|
-
}
|
|
662
659
|
// Track if the model was modified after initialization
|
|
663
660
|
if (this.didInitModel) {
|
|
664
661
|
this.modelWasModified = true;
|
|
@@ -675,21 +672,6 @@ class Document extends MalloyElement {
|
|
|
675
672
|
};
|
|
676
673
|
}
|
|
677
674
|
}
|
|
678
|
-
/**
|
|
679
|
-
* Return an error message if this dialect is the first reference to this particular
|
|
680
|
-
* dialect, and the dialect is marked as experimental, and we are not running tests.
|
|
681
|
-
* @param dialect The dialect name
|
|
682
|
-
* @returns The error message or undefined
|
|
683
|
-
*/
|
|
684
|
-
checkExperimentalDialect(me, dialect) {
|
|
685
|
-
const t = this.translator();
|
|
686
|
-
if (t &&
|
|
687
|
-
t.firstReferenceToDialect(dialect) &&
|
|
688
|
-
(0, dialect_1.getDialect)(dialect).experimental &&
|
|
689
|
-
!t.experimentalDialectEnabled(dialect)) {
|
|
690
|
-
me.logError('experimental-dialect-not-enabled', { dialect });
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
675
|
getDialectNamespace(dialectName) {
|
|
694
676
|
if (this.dialectNameSpaces.has(dialectName)) {
|
|
695
677
|
return this.dialectNameSpaces.get(dialectName);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DocumentLocation, DocumentPosition, DocumentReference, ImportLocation, ModelDef, SourceDef, SQLSourceDef, DependencyTree, DocumentRange, VirtualMap } from '../model/malloy_types';
|
|
2
2
|
import type { LogMessage, LogMessageOptions, MessageCode, MessageParameterType } from './parse-log';
|
|
3
3
|
import { BaseMessageLogger } from './parse-log';
|
|
4
|
+
import type { FindReferencesData } from './parse-tree-walkers/find-external-references';
|
|
4
5
|
import type { ZoneData } from './zone';
|
|
5
6
|
import { Zone } from './zone';
|
|
6
7
|
import { ReferenceList } from './reference-list';
|
|
@@ -52,7 +53,7 @@ declare class ParseStep implements TranslationStep {
|
|
|
52
53
|
}
|
|
53
54
|
declare class ImportsAndTablesStep implements TranslationStep {
|
|
54
55
|
readonly parseStep: ParseStep;
|
|
55
|
-
|
|
56
|
+
parseReferences: FindReferencesData | undefined;
|
|
56
57
|
constructor(parseStep: ParseStep);
|
|
57
58
|
step(that: MalloyTranslation): DataRequestResponse | ParseResponse;
|
|
58
59
|
}
|
|
@@ -61,6 +62,16 @@ declare class ASTStep implements TranslationStep {
|
|
|
61
62
|
response?: ASTResponse;
|
|
62
63
|
private walked;
|
|
63
64
|
constructor(importStep: ImportsAndTablesStep);
|
|
65
|
+
/**
|
|
66
|
+
* A file acknowledges an experimental dialect with
|
|
67
|
+
* `##! experimental.dialect.NAME` wherever it names a connection on that
|
|
68
|
+
* dialect. Every connection name in this file is already resolved to a
|
|
69
|
+
* dialect by the time the AST exists, and the file's compiler flags are
|
|
70
|
+
* known only now, so this is the first moment the check can run. The
|
|
71
|
+
* other place a file takes on a dialect is `import`, checked by
|
|
72
|
+
* `ImportStatement`.
|
|
73
|
+
*/
|
|
74
|
+
private checkExperimentalDialects;
|
|
64
75
|
step(that: MalloyTranslation): ASTResponse;
|
|
65
76
|
}
|
|
66
77
|
declare class MetadataStep implements TranslationStep {
|
|
@@ -166,8 +177,12 @@ export declare abstract class MalloyTranslation {
|
|
|
166
177
|
rangeFromContext(pcx: ParserRuleContext): DocumentRange;
|
|
167
178
|
private dialectAlreadyChecked;
|
|
168
179
|
firstReferenceToDialect(dialect: string): boolean;
|
|
169
|
-
allDialectsEnabled: boolean;
|
|
170
180
|
experimentalDialectEnabled(dialect: string): boolean;
|
|
181
|
+
/**
|
|
182
|
+
* Log, once per dialect per file, that this file uses an experimental
|
|
183
|
+
* dialect without acknowledging it.
|
|
184
|
+
*/
|
|
185
|
+
checkExperimentalDialect(dialect: string, at: DocumentLocation): void;
|
|
171
186
|
}
|
|
172
187
|
export declare class MalloyChildTranslator extends MalloyTranslation {
|
|
173
188
|
readonly root: MalloyTranslator;
|
|
@@ -38,6 +38,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
38
38
|
})();
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
exports.MalloyTranslator = exports.MalloyChildTranslator = exports.MalloyTranslation = void 0;
|
|
41
|
+
const malloy_types_1 = require("../model/malloy_types");
|
|
41
42
|
const utils_1 = require("../model/utils");
|
|
42
43
|
const annotation_utils_1 = require("../model/annotation_utils");
|
|
43
44
|
const ast = __importStar(require("./ast"));
|
|
@@ -132,14 +133,13 @@ class ImportsAndTablesStep {
|
|
|
132
133
|
// Register connection dialects and imports immediately. Table
|
|
133
134
|
// references are deferred until dialects are resolved, because
|
|
134
135
|
// validating a table path requires knowing its dialect's grammar.
|
|
135
|
-
for (const connName
|
|
136
|
+
for (const [connName, need] of this.parseReferences.connectionDialects) {
|
|
136
137
|
that.root.connectionDialectZone.reference(connName, {
|
|
137
138
|
url: that.sourceURL,
|
|
138
|
-
range:
|
|
139
|
+
range: need.firstReference,
|
|
139
140
|
});
|
|
140
141
|
}
|
|
141
|
-
for (const relativeRef
|
|
142
|
-
const firstRef = this.parseReferences.urls[relativeRef];
|
|
142
|
+
for (const [relativeRef, firstRef] of this.parseReferences.urls) {
|
|
143
143
|
try {
|
|
144
144
|
const ref = decodeURI(new URL(relativeRef, that.importBaseURL || that.sourceURL).toString());
|
|
145
145
|
that.addChild(ref);
|
|
@@ -171,8 +171,7 @@ class ImportsAndTablesStep {
|
|
|
171
171
|
// Invalid paths are dropped here and re-reported by the AST step.
|
|
172
172
|
// tableRequests feeds the missing-table loop below.
|
|
173
173
|
const tableRequests = {};
|
|
174
|
-
for (const
|
|
175
|
-
const info = this.parseReferences.tables[rawKey];
|
|
174
|
+
for (const info of this.parseReferences.tables.values()) {
|
|
176
175
|
const dialectName = that.root.connectionDialectZone.get(info.connectionName);
|
|
177
176
|
if (dialectName === undefined)
|
|
178
177
|
continue;
|
|
@@ -204,7 +203,9 @@ class ImportsAndTablesStep {
|
|
|
204
203
|
}
|
|
205
204
|
const missingDialects = that.root.connectionDialectZone.getUndefined();
|
|
206
205
|
if (missingDialects) {
|
|
207
|
-
|
|
206
|
+
// Keyed by connection name, user text: a plain `{}` would turn a
|
|
207
|
+
// connection named `__proto__` into a prototype and drop the request.
|
|
208
|
+
const connectionDialects = (0, malloy_types_1.mkSafeRecord)();
|
|
208
209
|
for (const connName of missingDialects) {
|
|
209
210
|
connectionDialects[connName] = { connectionName: connName };
|
|
210
211
|
}
|
|
@@ -237,6 +238,31 @@ class ASTStep {
|
|
|
237
238
|
this.importStep = importStep;
|
|
238
239
|
this.walked = false;
|
|
239
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* A file acknowledges an experimental dialect with
|
|
243
|
+
* `##! experimental.dialect.NAME` wherever it names a connection on that
|
|
244
|
+
* dialect. Every connection name in this file is already resolved to a
|
|
245
|
+
* dialect by the time the AST exists, and the file's compiler flags are
|
|
246
|
+
* known only now, so this is the first moment the check can run. The
|
|
247
|
+
* other place a file takes on a dialect is `import`, checked by
|
|
248
|
+
* `ImportStatement`.
|
|
249
|
+
*/
|
|
250
|
+
checkExperimentalDialects(that) {
|
|
251
|
+
var _a;
|
|
252
|
+
const connections = (_a = this.importStep.parseReferences) === null || _a === void 0 ? void 0 : _a.connectionDialects;
|
|
253
|
+
if (!connections) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
for (const [connName, need] of connections) {
|
|
257
|
+
const dialect = that.root.connectionDialectZone.get(connName);
|
|
258
|
+
if (dialect !== undefined) {
|
|
259
|
+
that.checkExperimentalDialect(dialect, {
|
|
260
|
+
url: that.sourceURL,
|
|
261
|
+
range: need.firstReference,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
240
266
|
step(that) {
|
|
241
267
|
const stepTimer = new timing_1.Timer('ast_step');
|
|
242
268
|
if (this.response) {
|
|
@@ -262,6 +288,7 @@ class ASTStep {
|
|
|
262
288
|
const { ast: newAST, compilerFlagSrc, timingInfo } = secondPass.run();
|
|
263
289
|
stepTimer.contribute([timingInfo]);
|
|
264
290
|
that.compilerFlagSrc = compilerFlagSrc;
|
|
291
|
+
this.checkExperimentalDialects(that);
|
|
265
292
|
if (newAST.elementType === 'unimplemented') {
|
|
266
293
|
newAST.logError('untranslated-parse-node', 'INTERNAL COMPILER ERROR: Untranslated parse node');
|
|
267
294
|
}
|
|
@@ -429,9 +456,9 @@ class TranslateStep {
|
|
|
429
456
|
// seeding (e.g. TestTranslator's compilerFlags option) survive.
|
|
430
457
|
if (extendingModel && !this.importedAnnotations) {
|
|
431
458
|
const parseCompilerFlagsTimer = new timing_1.Timer('parse_compiler_flags');
|
|
432
|
-
//
|
|
433
|
-
//
|
|
434
|
-
//
|
|
459
|
+
// `##!` is a pragma: it governs the file it sits in and does not cross
|
|
460
|
+
// `import`. An extension is a continuation of the base's text, so the
|
|
461
|
+
// base's flags are in force here.
|
|
435
462
|
that.compilerFlagSrc.push(...new annotation_1.Annotations((0, annotation_utils_1.getModelAnnotations)(extendingModel)).texts('!'));
|
|
436
463
|
stepTimer.contribute([parseCompilerFlagsTimer.stop()]);
|
|
437
464
|
this.importedAnnotations = true;
|
|
@@ -515,7 +542,6 @@ class MalloyTranslation {
|
|
|
515
542
|
Not sure where the logic for this needs to go, this is just my first guess
|
|
516
543
|
*/
|
|
517
544
|
this.dialectAlreadyChecked = {};
|
|
518
|
-
this.allDialectsEnabled = false;
|
|
519
545
|
this.childTranslators = new Map();
|
|
520
546
|
this.modelDef = (0, utils_1.mkModelDef)(sourceURL, (0, utils_1.mkModelID)(sourceURL));
|
|
521
547
|
/**
|
|
@@ -753,13 +779,21 @@ class MalloyTranslation {
|
|
|
753
779
|
return true;
|
|
754
780
|
}
|
|
755
781
|
experimentalDialectEnabled(dialect) {
|
|
756
|
-
if (this.allDialectsEnabled) {
|
|
757
|
-
return true;
|
|
758
|
-
}
|
|
759
782
|
const experimental = this.getCompilerFlags().tag('experimental');
|
|
760
783
|
return (experimental !== undefined &&
|
|
761
784
|
(experimental.bare() || experimental.has('dialect', dialect)));
|
|
762
785
|
}
|
|
786
|
+
/**
|
|
787
|
+
* Log, once per dialect per file, that this file uses an experimental
|
|
788
|
+
* dialect without acknowledging it.
|
|
789
|
+
*/
|
|
790
|
+
checkExperimentalDialect(dialect, at) {
|
|
791
|
+
if (this.firstReferenceToDialect(dialect) &&
|
|
792
|
+
(0, dialect_1.getDialect)(dialect).isExperimental() &&
|
|
793
|
+
!this.experimentalDialectEnabled(dialect)) {
|
|
794
|
+
this.root.logError('experimental-dialect-not-enabled', { dialect }, { at });
|
|
795
|
+
}
|
|
796
|
+
}
|
|
763
797
|
}
|
|
764
798
|
exports.MalloyTranslation = MalloyTranslation;
|
|
765
799
|
class MalloyChildTranslator extends MalloyTranslation {
|
|
@@ -2,13 +2,13 @@ import type { CommonTokenStream } from 'antlr4ts';
|
|
|
2
2
|
import type { ParseTree } from 'antlr4ts/tree';
|
|
3
3
|
import type { DocumentRange } from '../../model/malloy_types';
|
|
4
4
|
import type { MalloyTranslation } from '../parse-malloy';
|
|
5
|
-
type NeedImports =
|
|
6
|
-
type NeedTables =
|
|
5
|
+
type NeedImports = Map<string, DocumentRange>;
|
|
6
|
+
type NeedTables = Map<string, {
|
|
7
7
|
connectionName: string;
|
|
8
8
|
tablePath: string;
|
|
9
9
|
firstReference: DocumentRange;
|
|
10
10
|
}>;
|
|
11
|
-
type NeedConnectionDialects =
|
|
11
|
+
type NeedConnectionDialects = Map<string, {
|
|
12
12
|
firstReference: DocumentRange;
|
|
13
13
|
}>;
|
|
14
14
|
export declare function constructTableKey(connectionName: string, tablePath: string): string;
|
|
@@ -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';
|
|
@@ -66,10 +67,18 @@ export interface TestTranslatorOptions {
|
|
|
66
67
|
*/
|
|
67
68
|
compilerFlags?: string[];
|
|
68
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Every connection name a test mentions resolves to a dialect, as it would
|
|
72
|
+
* through a host's connection lookup: the four listed below to theirs, and
|
|
73
|
+
* any other name to `TEST_DIALECT`.
|
|
74
|
+
*/
|
|
75
|
+
declare class TestConnectionDialectZone extends Zone<string> {
|
|
76
|
+
reference(str: string, loc: DocumentLocation): void;
|
|
77
|
+
}
|
|
69
78
|
export declare class TestTranslator extends MalloyTranslator {
|
|
70
79
|
readonly testSrc: string;
|
|
71
|
-
allDialectsEnabled: boolean;
|
|
72
80
|
testRoot?: TestRoot;
|
|
81
|
+
connectionDialectZone: TestConnectionDialectZone;
|
|
73
82
|
internalModel: ModelDef;
|
|
74
83
|
constructor(testSrc: string, options?: TestTranslatorOptions);
|
|
75
84
|
translate(): TranslateResponse;
|
|
@@ -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");
|
|
@@ -336,12 +337,25 @@ class TestChildTranslator extends parse_malloy_1.MalloyChildTranslator {
|
|
|
336
337
|
}
|
|
337
338
|
exports.TestChildTranslator = TestChildTranslator;
|
|
338
339
|
const testURI = 'internal://test/langtests/root.malloy';
|
|
340
|
+
/**
|
|
341
|
+
* Every connection name a test mentions resolves to a dialect, as it would
|
|
342
|
+
* through a host's connection lookup: the four listed below to theirs, and
|
|
343
|
+
* any other name to `TEST_DIALECT`.
|
|
344
|
+
*/
|
|
345
|
+
class TestConnectionDialectZone extends zone_1.Zone {
|
|
346
|
+
reference(str, loc) {
|
|
347
|
+
super.reference(str, loc);
|
|
348
|
+
if (this.getEntry(str).status === 'reference') {
|
|
349
|
+
this.define(str, exports.TEST_DIALECT);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
339
353
|
class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
340
354
|
constructor(testSrc, options = {}) {
|
|
341
355
|
var _a, _b, _c, _d, _e;
|
|
342
356
|
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
357
|
this.testSrc = testSrc;
|
|
344
|
-
this.
|
|
358
|
+
this.connectionDialectZone = new TestConnectionDialectZone();
|
|
345
359
|
/*
|
|
346
360
|
* There are four connections:
|
|
347
361
|
* _db_ - duckdb dialect, with the following tables ...
|
|
@@ -225,7 +225,7 @@ function compileExpr(resultSet, context, expr, state = new utils_1.GenerateState
|
|
|
225
225
|
return `${expr.e.sql} IS NOT NULL`;
|
|
226
226
|
case 'true':
|
|
227
227
|
case 'false':
|
|
228
|
-
return expr.node;
|
|
228
|
+
return context.dialect.sqlBoolean(expr.node === 'true');
|
|
229
229
|
case 'null':
|
|
230
230
|
return 'NULL';
|
|
231
231
|
case 'case':
|
|
@@ -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 --
|