@malloydata/malloy 0.0.435 → 0.0.437
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/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 -2
- package/dist/api/foundation/runtime.js +44 -31
- package/dist/api/foundation/types.d.ts +43 -3
- 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 +56 -170
- package/dist/dialect/dialect.js +89 -90
- package/dist/dialect/duckdb/duckdb.d.ts +2 -2
- package/dist/dialect/duckdb/duckdb.js +1 -1
- package/dist/dialect/index.d.ts +1 -1
- package/dist/dialect/index.js +2 -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 +10 -14
- package/dist/dialect/snowflake/snowflake.d.ts +11 -13
- package/dist/dialect/snowflake/snowflake.js +30 -82
- package/dist/dialect/sqlserver/sqlserver.d.ts +12 -13
- package/dist/dialect/sqlserver/sqlserver.js +46 -47
- 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 +2 -2
- 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/expr-props.js +1 -1
- package/dist/lang/ast/expressions/pick-when.js +7 -0
- package/dist/lang/ast/expressions/time-literal.js +6 -1
- 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/drill.js +7 -1
- package/dist/lang/ast/query-properties/filters.js +3 -1
- package/dist/lang/ast/statements/import-statement.js +13 -0
- package/dist/lang/ast/types/expression-def.js +17 -2
- package/dist/lang/ast/types/malloy-element.d.ts +24 -1
- package/dist/lang/ast/types/malloy-element.js +63 -26
- 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/lib/Malloy/MalloyLexer.js +976 -978
- package/dist/lang/parse-log.d.ts +12 -0
- package/dist/lang/parse-log.js +2 -0
- package/dist/lang/test/test-translator.d.ts +2 -1
- package/dist/lang/test/test-translator.js +37 -3
- package/dist/model/expression_compiler.js +8 -7
- 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.js +11 -2
- package/dist/model/sql_compiled.d.ts +19 -20
- package/dist/model/sql_compiled.js +29 -17
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -9,6 +9,7 @@ exports.isDocStatement = isDocStatement;
|
|
|
9
9
|
exports.isDocStatementOrDocStatementList = isDocStatementOrDocStatementList;
|
|
10
10
|
const dialect_1 = require("../../../dialect");
|
|
11
11
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
12
|
+
const sql_compiled_1 = require("../../../model/sql_compiled");
|
|
12
13
|
const utils_1 = require("../../../model/utils");
|
|
13
14
|
const malloy_tag_1 = require("@malloydata/malloy-tag");
|
|
14
15
|
const parse_log_1 = require("../../parse-log");
|
|
@@ -436,6 +437,10 @@ class Document extends MalloyElement {
|
|
|
436
437
|
this.documentModel = new Map();
|
|
437
438
|
this.documentSrcRegistry = {};
|
|
438
439
|
this.documentGivens = new Map();
|
|
440
|
+
/** Every persistent source an `import` brought within reach of this model's
|
|
441
|
+
* builder, with the import that did so. Checked at end of compile: the
|
|
442
|
+
* model has to be able to supply every given their SQL reads. */
|
|
443
|
+
this.importedPersistSources = new Map();
|
|
439
444
|
/** {@link ModelAnnotationEntry} of every imported/extended model in the
|
|
440
445
|
* closure, keyed by ModelID, accumulated as imports/extends are processed;
|
|
441
446
|
* copied into the result `modelAnnotations` in {@link modelDef}, which then
|
|
@@ -512,6 +517,7 @@ class Document extends MalloyElement {
|
|
|
512
517
|
if (needs === undefined) {
|
|
513
518
|
this.checkGivenAliasCollisions();
|
|
514
519
|
this.checkQueryGivenSatisfiability();
|
|
520
|
+
this.checkPersistSourceGivenSatisfiability();
|
|
515
521
|
}
|
|
516
522
|
const ret = {
|
|
517
523
|
modelDef: {
|
|
@@ -553,40 +559,46 @@ class Document extends MalloyElement {
|
|
|
553
559
|
`with a default-chain reference: \`given: NEW_NAME :: T is $${sourceName}\`.`);
|
|
554
560
|
}
|
|
555
561
|
}
|
|
562
|
+
/**
|
|
563
|
+
* The givens in `usage` this model can neither supply nor default: not
|
|
564
|
+
* surfaced in the namespace and declared without a default. The set checked
|
|
565
|
+
* is each id plus its precomputed default-chain closure (`Given.givenUsage`),
|
|
566
|
+
* which is already transitive, so there is no recursion here.
|
|
567
|
+
*/
|
|
568
|
+
unsatisfiedGivens(usage) {
|
|
569
|
+
var _a, _b;
|
|
570
|
+
const namespaceGivens = new Set();
|
|
571
|
+
for (const m of this.documentModel.values()) {
|
|
572
|
+
if (m.entry.type === 'given')
|
|
573
|
+
namespaceGivens.add(m.entry.id);
|
|
574
|
+
}
|
|
575
|
+
const allIds = new Set();
|
|
576
|
+
for (const g of usage) {
|
|
577
|
+
allIds.add(g.id);
|
|
578
|
+
const decl = this.documentGivens.get(g.id);
|
|
579
|
+
for (const t of (_a = decl === null || decl === void 0 ? void 0 : decl.givenUsage) !== null && _a !== void 0 ? _a : [])
|
|
580
|
+
allIds.add(t.id);
|
|
581
|
+
}
|
|
582
|
+
const unsatisfied = [];
|
|
583
|
+
for (const id of allIds) {
|
|
584
|
+
if (namespaceGivens.has(id))
|
|
585
|
+
continue;
|
|
586
|
+
if (((_b = this.documentGivens.get(id)) === null || _b === void 0 ? void 0 : _b.default) !== undefined)
|
|
587
|
+
continue;
|
|
588
|
+
unsatisfied.push(id);
|
|
589
|
+
}
|
|
590
|
+
return unsatisfied;
|
|
591
|
+
}
|
|
556
592
|
checkQueryGivenSatisfiability() {
|
|
557
593
|
// Always runs at end-of-compile, not gated on imports — a notebook cell
|
|
558
594
|
// that calls `extendModel` with a prior modelDef inherits that model's
|
|
559
595
|
// queries and givens, and a query inherited from cell N can become
|
|
560
596
|
// unsatisfiable in cell N+1 if the satisfying given is removed (or
|
|
561
597
|
// never re-supplied). Cheap when there's nothing to check.
|
|
562
|
-
const namespaceGivens = new Set();
|
|
563
|
-
for (const m of this.documentModel.values()) {
|
|
564
|
-
if (m.entry.type === 'given')
|
|
565
|
-
namespaceGivens.add(m.entry.id);
|
|
566
|
-
}
|
|
567
598
|
const checkOne = (q, label) => {
|
|
568
599
|
var _a;
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
return;
|
|
572
|
-
// Build the full set of ids the query transitively needs: each id
|
|
573
|
-
// in Q.givenUsage, plus each id's precomputed default-chain closure
|
|
574
|
-
// (Given.givenUsage). Since the closure is already transitive, no
|
|
575
|
-
// recursion at check time.
|
|
576
|
-
const allIds = new Set();
|
|
577
|
-
for (const g of usage) {
|
|
578
|
-
allIds.add(g.id);
|
|
579
|
-
const decl = this.documentGivens.get(g.id);
|
|
580
|
-
for (const t of (_a = decl === null || decl === void 0 ? void 0 : decl.givenUsage) !== null && _a !== void 0 ? _a : [])
|
|
581
|
-
allIds.add(t.id);
|
|
582
|
-
}
|
|
583
|
-
for (const id of allIds) {
|
|
584
|
-
if (namespaceGivens.has(id))
|
|
585
|
-
continue;
|
|
586
|
-
const decl = this.documentGivens.get(id);
|
|
587
|
-
if ((decl === null || decl === void 0 ? void 0 : decl.default) !== undefined)
|
|
588
|
-
continue;
|
|
589
|
-
this.logError('unsatisfied-given-in-query', unsatisfiedGivenMessage(label, decl, id), { at: q.location });
|
|
600
|
+
for (const id of this.unsatisfiedGivens((_a = q.givenUsage) !== null && _a !== void 0 ? _a : [])) {
|
|
601
|
+
this.logError('unsatisfied-given-in-query', unsatisfiedGivenMessage(label, this.documentGivens.get(id), id), { at: q.location });
|
|
590
602
|
}
|
|
591
603
|
};
|
|
592
604
|
// Named queries in the namespace (locally defined OR imported).
|
|
@@ -599,6 +611,31 @@ class Document extends MalloyElement {
|
|
|
599
611
|
checkOne(q, 'run: statement');
|
|
600
612
|
}
|
|
601
613
|
}
|
|
614
|
+
/**
|
|
615
|
+
* A persisted source is built from whatever model a builder is handed, so a
|
|
616
|
+
* model that imports one has to be able to supply every given its SQL reads;
|
|
617
|
+
* an import that cannot is a source no build or query here could ever use.
|
|
618
|
+
* Checked at end of compile rather than at the import, since the given may
|
|
619
|
+
* be imported by a later statement. A locally declared source cannot fail
|
|
620
|
+
* this: `$NAME` only resolves to a given in scope.
|
|
621
|
+
*/
|
|
622
|
+
checkPersistSourceGivenSatisfiability() {
|
|
623
|
+
var _a;
|
|
624
|
+
// One import routinely reaches several sources that share a table — a
|
|
625
|
+
// persisted source and its extensions — so each given is reported once
|
|
626
|
+
// per import, against the first source that reads it.
|
|
627
|
+
const reported = new Map();
|
|
628
|
+
for (const { source, at } of this.importedPersistSources.values()) {
|
|
629
|
+
const seen = (_a = reported.get(at)) !== null && _a !== void 0 ? _a : new Set();
|
|
630
|
+
reported.set(at, seen);
|
|
631
|
+
for (const id of this.unsatisfiedGivens((0, sql_compiled_1.givenUsageOfRelation)(source))) {
|
|
632
|
+
if (seen.has(id))
|
|
633
|
+
continue;
|
|
634
|
+
seen.add(id);
|
|
635
|
+
this.logError('unsatisfied-given-in-persist-source', unsatisfiedGivenMessage(`Imported persisted source \`${(0, malloy_types_1.activeName)(source)}\``, this.documentGivens.get(id), id), { at });
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
602
639
|
hasAnnotation() {
|
|
603
640
|
return ((this.annotations.notes && this.annotations.notes.length > 0) ||
|
|
604
641
|
this.annotations.inherits !== undefined);
|
|
@@ -8,6 +8,7 @@ exports.ReferenceView = void 0;
|
|
|
8
8
|
const composite_source_utils_1 = require("../../composite-source-utils");
|
|
9
9
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
10
10
|
const error_factory_1 = require("../error-factory");
|
|
11
|
+
const boolean_value_1 = require("../expressions/boolean-value");
|
|
11
12
|
const drill_1 = require("../query-properties/drill");
|
|
12
13
|
const space_field_1 = require("../types/space-field");
|
|
13
14
|
const refine_utils_1 = require("./refine-utils");
|
|
@@ -55,6 +56,9 @@ class ReferenceView extends view_1.View {
|
|
|
55
56
|
throw new Error('Expected field to have definition');
|
|
56
57
|
}
|
|
57
58
|
if ((0, malloy_types_1.isAtomic)(fieldDef)) {
|
|
59
|
+
if ((0, boolean_value_1.booleanValueError)(fs, fieldDef, 'as a result column', this.reference, (0, boolean_value_1.resultColumnHint)(this.reference.refString))) {
|
|
60
|
+
return oops();
|
|
61
|
+
}
|
|
58
62
|
const name = this.reference.nameString;
|
|
59
63
|
const outputStruct = {
|
|
60
64
|
...(0, malloy_types_1.sourceBase)(fs.structDef()),
|
|
@@ -33,6 +33,7 @@ function refine(logTo, refineTo, refineFrom) {
|
|
|
33
33
|
if (from.orderBy !== undefined && !from.defaultOrderBy) {
|
|
34
34
|
if (to.orderBy === undefined || to.defaultOrderBy) {
|
|
35
35
|
to.orderBy = from.orderBy;
|
|
36
|
+
delete to.defaultOrderBy;
|
|
36
37
|
}
|
|
37
38
|
else {
|
|
38
39
|
logTo.logError('ordering-overridden-in-refinement', 'refinement cannot override existing ordering');
|
|
@@ -28,6 +28,7 @@ exports.pathBegins = pathBegins;
|
|
|
28
28
|
exports.hasCompositesAnywhere = hasCompositesAnywhere;
|
|
29
29
|
exports.logCompositeError = logCompositeError;
|
|
30
30
|
const malloy_filter_1 = require("@malloydata/malloy-filter");
|
|
31
|
+
const sql_compiled_1 = require("../model/sql_compiled");
|
|
31
32
|
const malloy_types_1 = require("../model/malloy_types");
|
|
32
33
|
const utils_1 = require("./utils");
|
|
33
34
|
const utils_2 = require("../model/utils");
|
|
@@ -1214,9 +1215,12 @@ function computeQueryGivenUsage(pipeline) {
|
|
|
1214
1215
|
return result;
|
|
1215
1216
|
}
|
|
1216
1217
|
// Returns every given a SourceDef references — its own filterList plus any
|
|
1217
|
-
// givens hiding inside an embedded Query.
|
|
1218
|
-
//
|
|
1219
|
-
//
|
|
1218
|
+
// givens hiding inside an embedded Query. For a persistable source the
|
|
1219
|
+
// embedded part is `givenUsageOfRelation` (model/sql_compiled.ts), which is
|
|
1220
|
+
// also what persistence keys a table on; the filterList is added here because
|
|
1221
|
+
// a query over the source applies it, but a table built from the source does
|
|
1222
|
+
// not. When a future SourceDef variant grows an embedded Query, teach that
|
|
1223
|
+
// helper or this one.
|
|
1220
1224
|
//
|
|
1221
1225
|
// Composite sources: composite-source support across the codebase is
|
|
1222
1226
|
// partial; the givens work isn't chasing it. The `composite` arm here is
|
|
@@ -1226,23 +1230,12 @@ function computeQueryGivenUsage(pipeline) {
|
|
|
1226
1230
|
// reaches here (e.g. composites in join positions if/when those work),
|
|
1227
1231
|
// the conservative union over all branches is the safe fallback.
|
|
1228
1232
|
function givenUsageOfSource(sd) {
|
|
1229
|
-
var _a
|
|
1233
|
+
var _a;
|
|
1230
1234
|
const fromFilters = ((_a = sd.filterList) !== null && _a !== void 0 ? _a : []).flatMap(f => (0, malloy_types_1.givenUsageFrom)(f.refSummary));
|
|
1231
1235
|
switch (sd.type) {
|
|
1232
1236
|
case 'query_source':
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
const fromSegments = ((_c = sd.selectSegments) !== null && _c !== void 0 ? _c : []).flatMap(seg => {
|
|
1236
|
-
var _a;
|
|
1237
|
-
if ((0, malloy_types_1.isSegmentSQL)(seg))
|
|
1238
|
-
return [];
|
|
1239
|
-
if ((0, malloy_types_1.isSegmentSource)(seg))
|
|
1240
|
-
return givenUsageOfSource(seg);
|
|
1241
|
-
// Remaining variant of SQLPhraseSegment is `Query`
|
|
1242
|
-
return (_a = seg.givenUsage) !== null && _a !== void 0 ? _a : [];
|
|
1243
|
-
});
|
|
1244
|
-
return [...fromFilters, ...fromSegments];
|
|
1245
|
-
}
|
|
1237
|
+
case 'sql_select':
|
|
1238
|
+
return [...fromFilters, ...(0, sql_compiled_1.givenUsageOfRelation)(sd)];
|
|
1246
1239
|
case 'composite':
|
|
1247
1240
|
return [
|
|
1248
1241
|
...fromFilters,
|