@malloydata/malloy 0.0.422 → 0.0.424
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/README.md +3 -3
- package/dist/dialect/databricks/databricks.js +9 -2
- package/dist/dialect/mysql/mysql.js +9 -2
- package/dist/dialect/postgres/postgres.js +26 -0
- package/dist/dialect/snowflake/snowflake.js +30 -1
- package/dist/dialect/standardsql/standardsql.js +15 -0
- package/dist/dialect/trino/trino.js +5 -0
- package/dist/lang/ast/expressions/expr-time-extract.js +3 -2
- package/dist/lang/ast/field-space/include-utils.js +5 -5
- package/dist/lang/ast/field-space/query-spaces.js +1 -0
- package/dist/lang/ast/field-space/reference-field.js +1 -1
- package/dist/lang/ast/query-builders/project-builder.js +1 -2
- package/dist/lang/ast/query-elements/anonymous-query.d.ts +1 -3
- package/dist/lang/ast/query-elements/anonymous-query.js +1 -3
- package/dist/lang/ast/query-items/field-declaration.d.ts +1 -3
- package/dist/lang/ast/query-items/field-declaration.js +2 -4
- package/dist/lang/ast/query-items/field-references.d.ts +2 -5
- package/dist/lang/ast/query-items/field-references.js +2 -5
- package/dist/lang/ast/query-properties/aggregate.d.ts +1 -0
- package/dist/lang/ast/query-properties/aggregate.js +1 -0
- package/dist/lang/ast/query-properties/group-by.d.ts +1 -0
- package/dist/lang/ast/query-properties/group-by.js +1 -0
- package/dist/lang/ast/query-properties/indexing.d.ts +1 -0
- package/dist/lang/ast/query-properties/indexing.js +1 -0
- package/dist/lang/ast/query-properties/nest.d.ts +1 -0
- package/dist/lang/ast/query-properties/nest.js +2 -1
- package/dist/lang/ast/query-properties/nests.d.ts +1 -0
- package/dist/lang/ast/query-properties/nests.js +1 -0
- package/dist/lang/ast/query-properties/project-statement.d.ts +1 -0
- package/dist/lang/ast/query-properties/project-statement.js +1 -0
- package/dist/lang/ast/query-properties/qop-desc.js +12 -1
- package/dist/lang/ast/query-properties/sampling.d.ts +1 -0
- package/dist/lang/ast/query-properties/sampling.js +1 -0
- package/dist/lang/ast/source-properties/join.d.ts +1 -3
- package/dist/lang/ast/source-properties/join.js +4 -6
- package/dist/lang/ast/source-properties/renames.d.ts +2 -3
- package/dist/lang/ast/source-properties/renames.js +1 -3
- package/dist/lang/ast/source-properties/user-type-shape.d.ts +1 -3
- package/dist/lang/ast/source-properties/user-type-shape.js +5 -7
- package/dist/lang/ast/source-properties/view-field-declaration.d.ts +1 -3
- package/dist/lang/ast/source-properties/view-field-declaration.js +1 -3
- package/dist/lang/ast/source-query-elements/include-item.d.ts +2 -5
- package/dist/lang/ast/source-query-elements/include-item.js +0 -3
- package/dist/lang/ast/statements/define-given.d.ts +1 -3
- package/dist/lang/ast/statements/define-given.js +2 -4
- package/dist/lang/ast/statements/define-query.d.ts +1 -3
- package/dist/lang/ast/statements/define-query.js +3 -5
- package/dist/lang/ast/statements/define-source.d.ts +1 -3
- package/dist/lang/ast/statements/define-source.js +4 -6
- package/dist/lang/ast/statements/define-user-type.d.ts +1 -3
- package/dist/lang/ast/statements/define-user-type.js +2 -4
- package/dist/lang/ast/types/definition-list.d.ts +2 -4
- package/dist/lang/ast/types/definition-list.js +6 -11
- package/dist/lang/ast/types/malloy-element.d.ts +1 -3
- package/dist/lang/ast/types/malloy-element.js +2 -3
- package/dist/lang/ast/types/noteable.d.ts +3 -4
- package/dist/lang/ast/types/noteable.js +5 -7
- package/dist/lang/ast/types/query-property-interface.d.ts +1 -0
- package/dist/lang/composite-source-utils.js +1 -2
- package/dist/lang/malloy-to-ast.js +33 -32
- package/dist/model/filter_compilers.js +27 -1
- package/dist/model/malloy_types.d.ts +3 -3
- package/dist/model/query_query.d.ts +1 -1
- package/dist/model/query_query.js +7 -3
- package/dist/model/utils.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -34,8 +34,8 @@ In practice, much of this loop is handled by various database plugins:
|
|
|
34
34
|
- [Postgres](https://github.com/malloydata/malloy/tree/main/packages/malloy-db-postgres)
|
|
35
35
|
- [Snowflake](https://github.com/malloydata/malloy/tree/main/packages/malloy-db-snowflake)
|
|
36
36
|
|
|
37
|
-
##
|
|
37
|
+
## What's built with these libraries?
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
The [Malloy CLI](https://github.com/malloydata/malloy-cli) uses them to run Malloy queries from the command line.
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
For a more complex use case, our [VS Code extension](https://github.com/malloydata/malloy-vscode-extension) uses them to power a full Malloy editing and query experience.
|
|
@@ -389,8 +389,15 @@ class DatabricksDialect extends dialect_1.Dialect {
|
|
|
389
389
|
throw new Error('Databricks does not support timestamptz');
|
|
390
390
|
}
|
|
391
391
|
sqlMeasureTimeExpr(df) {
|
|
392
|
-
|
|
393
|
-
|
|
392
|
+
const from = df.kids.left;
|
|
393
|
+
const to = df.kids.right;
|
|
394
|
+
let lVal = from.sql;
|
|
395
|
+
let rVal = to.sql;
|
|
396
|
+
if (malloy_types_1.TD.isDate(from.typeDef) &&
|
|
397
|
+
malloy_types_1.TD.isDate(to.typeDef) &&
|
|
398
|
+
['week', 'month', 'quarter', 'year'].includes(df.units)) {
|
|
399
|
+
return `TIMESTAMPDIFF(${df.units.toUpperCase()}, ${lVal}, ${rVal})`;
|
|
400
|
+
}
|
|
394
401
|
if (inSeconds[df.units]) {
|
|
395
402
|
lVal = `UNIX_MICROS(CAST(${lVal} AS TIMESTAMP))`;
|
|
396
403
|
rVal = `UNIX_MICROS(CAST(${rVal} AS TIMESTAMP))`;
|
|
@@ -415,8 +415,15 @@ class MySQLDialect extends dialect_1.Dialect {
|
|
|
415
415
|
throw new Error('MySQL does not support timestamptz');
|
|
416
416
|
}
|
|
417
417
|
sqlMeasureTimeExpr(df) {
|
|
418
|
-
|
|
419
|
-
|
|
418
|
+
const from = df.kids.left;
|
|
419
|
+
const to = df.kids.right;
|
|
420
|
+
let lVal = from.sql;
|
|
421
|
+
let rVal = to.sql;
|
|
422
|
+
if (malloy_types_1.TD.isDate(from.typeDef) &&
|
|
423
|
+
malloy_types_1.TD.isDate(to.typeDef) &&
|
|
424
|
+
['week', 'month', 'quarter', 'year'].includes(df.units)) {
|
|
425
|
+
return `TIMESTAMPDIFF(${df.units.toUpperCase()}, ${lVal}, ${rVal})`;
|
|
426
|
+
}
|
|
420
427
|
if (inSeconds[df.units]) {
|
|
421
428
|
lVal = `UNIX_TIMESTAMP(${lVal})`;
|
|
422
429
|
rVal = `UNIX_TIMESTAMP(${rVal})`;
|
|
@@ -228,6 +228,32 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
|
|
|
228
228
|
const to = df.kids.right;
|
|
229
229
|
let lVal = from.sql;
|
|
230
230
|
let rVal = to.sql;
|
|
231
|
+
if (malloy_types_1.TD.isDate(from.typeDef) &&
|
|
232
|
+
malloy_types_1.TD.isDate(to.typeDef) &&
|
|
233
|
+
['week', 'month', 'quarter', 'year'].includes(df.units)) {
|
|
234
|
+
const earlier = `LEAST(${lVal}, ${rVal})`;
|
|
235
|
+
const later = `GREATEST(${lVal}, ${rVal})`;
|
|
236
|
+
const age = `AGE(${later}, ${earlier})`;
|
|
237
|
+
const months = `(EXTRACT(YEAR FROM ${age}) * 12 + EXTRACT(MONTH FROM ${age}))`;
|
|
238
|
+
let measured;
|
|
239
|
+
if (df.units === 'week') {
|
|
240
|
+
measured = `TRUNC((${later} - ${earlier}) / 7.0)`;
|
|
241
|
+
}
|
|
242
|
+
else if (df.units === 'month') {
|
|
243
|
+
measured = months;
|
|
244
|
+
}
|
|
245
|
+
else if (df.units === 'quarter') {
|
|
246
|
+
measured = `TRUNC(${months} / 3.0)`;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
measured = `EXTRACT(YEAR FROM ${age})`;
|
|
250
|
+
}
|
|
251
|
+
return `CASE
|
|
252
|
+
WHEN ${lVal} IS NULL OR ${rVal} IS NULL THEN NULL
|
|
253
|
+
WHEN ${rVal} >= ${lVal} THEN ${measured}
|
|
254
|
+
ELSE -(${measured})
|
|
255
|
+
END`;
|
|
256
|
+
}
|
|
231
257
|
if (inSeconds[df.units]) {
|
|
232
258
|
lVal = `EXTRACT(EPOCH FROM ${lVal})`;
|
|
233
259
|
rVal = `EXTRACT(EPOCH FROM ${rVal})`;
|
|
@@ -52,7 +52,12 @@ const snowflakeToMalloyTypes = {
|
|
|
52
52
|
'timestamptz': { type: 'timestamptz' },
|
|
53
53
|
'timestamp_tz': { type: 'timestamptz' },
|
|
54
54
|
'timestamp with time zone': { type: 'timestamptz' },
|
|
55
|
-
|
|
55
|
+
// TIMESTAMP_LTZ is a genuine instant (persisted UTC); under Malloy's UTC
|
|
56
|
+
// session pin it is indistinguishable from NTZ, so it maps to `timestamp`
|
|
57
|
+
// like NTZ. malloyTypeToSQLType writes instants here too.
|
|
58
|
+
'timestampltz': { type: 'timestamp' },
|
|
59
|
+
'timestamp_ltz': { type: 'timestamp' },
|
|
60
|
+
'timestamp with local time zone': { type: 'timestamp' },
|
|
56
61
|
};
|
|
57
62
|
class SnowflakeDialect extends dialect_1.Dialect {
|
|
58
63
|
constructor() {
|
|
@@ -374,6 +379,22 @@ ${(0, utils_1.indent)(sql)}
|
|
|
374
379
|
sqlMeasureTimeExpr(df) {
|
|
375
380
|
const from = df.kids.left;
|
|
376
381
|
const to = df.kids.right;
|
|
382
|
+
if (malloy_types_1.TD.isDate(from.typeDef) &&
|
|
383
|
+
malloy_types_1.TD.isDate(to.typeDef) &&
|
|
384
|
+
['week', 'month', 'quarter', 'year'].includes(df.units)) {
|
|
385
|
+
const lVal = from.sql;
|
|
386
|
+
const rVal = to.sql;
|
|
387
|
+
const earlier = `LEAST(${lVal}, ${rVal})`;
|
|
388
|
+
const later = `GREATEST(${lVal}, ${rVal})`;
|
|
389
|
+
const candidate = `DATEDIFF(${df.units}, ${earlier}, ${later})`;
|
|
390
|
+
const anniversary = `DATEADD(${df.units}, ${candidate}, ${earlier})`;
|
|
391
|
+
const measured = `(${candidate} - CASE WHEN ${anniversary} > ${later} THEN 1 ELSE 0 END)`;
|
|
392
|
+
return `CASE
|
|
393
|
+
WHEN ${lVal} IS NULL OR ${rVal} IS NULL THEN NULL
|
|
394
|
+
WHEN ${rVal} >= ${lVal} THEN ${measured}
|
|
395
|
+
ELSE -(${measured})
|
|
396
|
+
END`;
|
|
397
|
+
}
|
|
377
398
|
let extractUnits = 'nanoseconds';
|
|
378
399
|
if (malloy_types_1.TD.isDate(from.typeDef) || malloy_types_1.TD.isDate(to.typeDef)) {
|
|
379
400
|
extractUnits = 'seconds';
|
|
@@ -447,6 +468,14 @@ ${(0, utils_1.indent)(sql)}
|
|
|
447
468
|
else if (malloyType.type === 'timestamptz') {
|
|
448
469
|
return 'TIMESTAMP_TZ';
|
|
449
470
|
}
|
|
471
|
+
else if (malloyType.type === 'timestamp') {
|
|
472
|
+
// A Malloy `timestamp` is an instant, and TIMESTAMP_LTZ is Snowflake's
|
|
473
|
+
// instant type. Emit it explicitly rather than the bare word TIMESTAMP,
|
|
474
|
+
// whose type is decided per account (TIMESTAMP_TYPE_MAPPING: NTZ or LTZ).
|
|
475
|
+
// NTZ only reads as an instant under the UTC session pin; LTZ is correct
|
|
476
|
+
// without it, and leaves NTZ for the future `datetime` type.
|
|
477
|
+
return 'TIMESTAMP_LTZ';
|
|
478
|
+
}
|
|
450
479
|
return malloyType.type;
|
|
451
480
|
}
|
|
452
481
|
sqlTypeToMalloyType(sqlType) {
|
|
@@ -341,6 +341,21 @@ ${(0, utils_1.indent)(sql)}
|
|
|
341
341
|
const to = measure.kids.right;
|
|
342
342
|
let lVal = from.sql;
|
|
343
343
|
let rVal = to.sql;
|
|
344
|
+
if (malloy_types_1.TD.isDate(from.typeDef) &&
|
|
345
|
+
malloy_types_1.TD.isDate(to.typeDef) &&
|
|
346
|
+
['week', 'month', 'quarter', 'year'].includes(measure.units)) {
|
|
347
|
+
const earlier = `LEAST(${lVal},${rVal})`;
|
|
348
|
+
const later = `GREATEST(${lVal},${rVal})`;
|
|
349
|
+
const unit = measure.units.toUpperCase();
|
|
350
|
+
const candidate = `DATE_DIFF(${later},${earlier},${unit})`;
|
|
351
|
+
const anniversary = `DATE_ADD(${earlier}, INTERVAL ${candidate} ${unit})`;
|
|
352
|
+
const measured = `(${candidate} - CASE WHEN ${anniversary} > ${later} THEN 1 ELSE 0 END)`;
|
|
353
|
+
return `CASE
|
|
354
|
+
WHEN ${lVal} IS NULL OR ${rVal} IS NULL THEN NULL
|
|
355
|
+
WHEN ${rVal} >= ${lVal} THEN ${measured}
|
|
356
|
+
ELSE -(${measured})
|
|
357
|
+
END`;
|
|
358
|
+
}
|
|
344
359
|
if (measureMap[measure.units]) {
|
|
345
360
|
const { use: measureIn, ratio } = measureMap[measure.units];
|
|
346
361
|
if (!timestampMeasureable(measureIn)) {
|
|
@@ -439,6 +439,11 @@ ${(0, utils_1.indent)(sql)}
|
|
|
439
439
|
const to = mf.kids.right;
|
|
440
440
|
let lVal = from.sql;
|
|
441
441
|
let rVal = to.sql;
|
|
442
|
+
if (malloy_types_1.TD.isDate(from.typeDef) &&
|
|
443
|
+
malloy_types_1.TD.isDate(to.typeDef) &&
|
|
444
|
+
['week', 'month', 'quarter', 'year'].includes(mf.units)) {
|
|
445
|
+
return `DATE_DIFF('${mf.units}',${lVal},${rVal})`;
|
|
446
|
+
}
|
|
442
447
|
if (measureMap[mf.units]) {
|
|
443
448
|
const { use: measureIn, ratio } = measureMap[mf.units];
|
|
444
449
|
if (!timestampMeasureable(measureIn)) {
|
|
@@ -70,8 +70,9 @@ class ExprTimeExtract extends expression_def_1.ExpressionDef {
|
|
|
70
70
|
return from.first.loggedErrorExpr('invalid-types-for-time-measurement', `Cannot measure from ${first.type} to ${last.type}`);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
if (['week', 'month', 'quarter', 'year'].includes(extractTo)
|
|
74
|
-
|
|
73
|
+
if (['week', 'month', 'quarter', 'year'].includes(extractTo) &&
|
|
74
|
+
(first.type !== 'date' || last.type !== 'date')) {
|
|
75
|
+
return this.loggedErrorExpr('invalid-timeframe-for-time-measurement', `Cannot measure interval using '${extractTo}' for '${first.type}' values; calendar interval measurement requires dates`);
|
|
75
76
|
}
|
|
76
77
|
if (!(0, malloy_types_1.isTimestampUnit)(extractTo)) {
|
|
77
78
|
return this.loggedErrorExpr('invalid-time-extraction-unit', `Cannot extract ${extractTo} from a range`);
|
|
@@ -114,8 +114,8 @@ function processIncludeList(includeItems, from) {
|
|
|
114
114
|
else {
|
|
115
115
|
joinState.star = (_c = item.kind) !== null && _c !== void 0 ? _c : 'inherit';
|
|
116
116
|
joinState.starNote = {
|
|
117
|
-
notes: (_e = (_d = f.
|
|
118
|
-
blockNotes: (_g = (_f = item.
|
|
117
|
+
notes: (_e = (_d = f.ownAnnotation) === null || _d === void 0 ? void 0 : _d.notes) !== null && _e !== void 0 ? _e : [],
|
|
118
|
+
blockNotes: (_g = (_f = item.ownAnnotation) === null || _f === void 0 ? void 0 : _f.blockNotes) !== null && _g !== void 0 ? _g : [],
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -149,10 +149,10 @@ function processIncludeList(includeItems, from) {
|
|
|
149
149
|
joinState.modifiers.set((_h = f.as) !== null && _h !== void 0 ? _h : name, item.kind);
|
|
150
150
|
}
|
|
151
151
|
joinState.fieldsIncluded.add(name);
|
|
152
|
-
if (f.
|
|
152
|
+
if (f.ownAnnotation || item.ownAnnotation) {
|
|
153
153
|
joinState.notes.set(name, {
|
|
154
|
-
notes: (_k = (_j = f.
|
|
155
|
-
blockNotes: (_m = (_l = item.
|
|
154
|
+
notes: (_k = (_j = f.ownAnnotation) === null || _j === void 0 ? void 0 : _j.notes) !== null && _k !== void 0 ? _k : [],
|
|
155
|
+
blockNotes: (_m = (_l = item.ownAnnotation) === null || _l === void 0 ? void 0 : _l.blockNotes) !== null && _m !== void 0 ? _m : [],
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
158
|
}
|
|
@@ -211,6 +211,7 @@ class QuerySpace extends QueryOperationSpace {
|
|
|
211
211
|
for (const field of refineThis.queryFields) {
|
|
212
212
|
if (field.type === 'fieldref') {
|
|
213
213
|
const fieldReference = new field_references_1.RefineFromFieldReference(field.path.map(f => new field_space_1.FieldName(f)));
|
|
214
|
+
fieldReference.ownAnnotation = field.annotations;
|
|
214
215
|
this.astEl.has({ fieldReference });
|
|
215
216
|
const referenceField = new reference_field_1.ReferenceField(fieldReference, this.exprSpace);
|
|
216
217
|
const name = field.path[field.path.length - 1];
|
|
@@ -94,7 +94,7 @@ class ReferenceField extends space_field_1.SpaceField {
|
|
|
94
94
|
if (refTo instanceof space_field_1.SpaceField) {
|
|
95
95
|
const origFd = refTo.constructorFieldDef();
|
|
96
96
|
if (origFd) {
|
|
97
|
-
const notes = this.fieldRef.
|
|
97
|
+
const notes = this.fieldRef.ownAnnotation;
|
|
98
98
|
if (origFd.annotations || notes) {
|
|
99
99
|
const annotations = {
|
|
100
100
|
...(notes !== null && notes !== void 0 ? notes : {}),
|
|
@@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.ProjectBuilder = void 0;
|
|
8
8
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
9
9
|
const error_factory_1 = require("../error-factory");
|
|
10
|
-
const group_by_1 = require("../query-properties/group-by");
|
|
11
10
|
const project_field_space_1 = require("../field-space/project-field-space");
|
|
12
11
|
const reduce_builder_1 = require("./reduce-builder");
|
|
13
12
|
class ProjectBuilder extends reduce_builder_1.QuerySegmentBuilder {
|
|
@@ -18,7 +17,7 @@ class ProjectBuilder extends reduce_builder_1.QuerySegmentBuilder {
|
|
|
18
17
|
this.inputFS = this.resultFS.inputSpace();
|
|
19
18
|
}
|
|
20
19
|
execute(qp) {
|
|
21
|
-
if (qp.elementType === 'having'
|
|
20
|
+
if (qp.elementType === 'having') {
|
|
22
21
|
qp.logError('illegal-operation-in-select-segment', 'Illegal statement in a select query operation');
|
|
23
22
|
}
|
|
24
23
|
else {
|
|
@@ -2,14 +2,12 @@ import type { AnnotationsDef } from '../../../model';
|
|
|
2
2
|
import type { DocStatement, Document } from '../types/malloy-element';
|
|
3
3
|
import { MalloyElement } from '../types/malloy-element';
|
|
4
4
|
import type { Noteable } from '../types/noteable';
|
|
5
|
-
import { extendNoteMethod } from '../types/noteable';
|
|
6
5
|
import type { SourceQueryElement } from '../source-query-elements/source-query-element';
|
|
7
6
|
export declare class AnonymousQuery extends MalloyElement implements DocStatement, Noteable {
|
|
8
7
|
readonly queryExpr: SourceQueryElement;
|
|
9
8
|
elementType: string;
|
|
10
9
|
constructor(queryExpr: SourceQueryElement);
|
|
11
10
|
readonly isNoteableObj = true;
|
|
12
|
-
|
|
13
|
-
note?: AnnotationsDef;
|
|
11
|
+
ownAnnotation?: AnnotationsDef;
|
|
14
12
|
execute(doc: Document): void;
|
|
15
13
|
}
|
|
@@ -6,14 +6,12 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.AnonymousQuery = void 0;
|
|
8
8
|
const malloy_element_1 = require("../types/malloy-element");
|
|
9
|
-
const noteable_1 = require("../types/noteable");
|
|
10
9
|
class AnonymousQuery extends malloy_element_1.MalloyElement {
|
|
11
10
|
constructor(queryExpr) {
|
|
12
11
|
super();
|
|
13
12
|
this.queryExpr = queryExpr;
|
|
14
13
|
this.elementType = 'anonymousQuery';
|
|
15
14
|
this.isNoteableObj = true;
|
|
16
|
-
this.extendNote = noteable_1.extendNoteMethod;
|
|
17
15
|
this.has({ queryExpr });
|
|
18
16
|
}
|
|
19
17
|
execute(doc) {
|
|
@@ -23,7 +21,7 @@ class AnonymousQuery extends malloy_element_1.MalloyElement {
|
|
|
23
21
|
return;
|
|
24
22
|
}
|
|
25
23
|
const modelQuery = { ...queryObj.query() };
|
|
26
|
-
const annotation = this.
|
|
24
|
+
const annotation = this.ownAnnotation || {};
|
|
27
25
|
if (modelQuery.annotations) {
|
|
28
26
|
annotation.inherits = modelQuery.annotations;
|
|
29
27
|
}
|
|
@@ -5,7 +5,6 @@ import type { FieldSpace } from '../types/field-space';
|
|
|
5
5
|
import { MalloyElement } from '../types/malloy-element';
|
|
6
6
|
import type { MakeEntry } from '../types/space-entry';
|
|
7
7
|
import type { Noteable } from '../types/noteable';
|
|
8
|
-
import { extendNoteMethod } from '../types/noteable';
|
|
9
8
|
import type { DynamicSpace } from '../field-space/dynamic-space';
|
|
10
9
|
import { SpaceField } from '../types/space-field';
|
|
11
10
|
export type FieldDeclarationConstructor = new (expr: ExpressionDef, defineName: string, exprSrc?: string) => AtomicFieldDeclaration;
|
|
@@ -14,8 +13,7 @@ export declare abstract class AtomicFieldDeclaration extends MalloyElement imple
|
|
|
14
13
|
readonly defineName: string;
|
|
15
14
|
readonly exprSrc?: string | undefined;
|
|
16
15
|
readonly isNoteableObj = true;
|
|
17
|
-
|
|
18
|
-
note?: AnnotationsDef;
|
|
16
|
+
ownAnnotation?: AnnotationsDef;
|
|
19
17
|
constructor(expr: ExpressionDef, defineName: string, exprSrc?: string | undefined);
|
|
20
18
|
getName(): string;
|
|
21
19
|
fieldDef(fs: FieldSpace, exprName: string): FieldDef;
|
|
@@ -43,7 +43,6 @@ const TDU = __importStar(require("../typedesc-utils"));
|
|
|
43
43
|
const granular_result_1 = require("../types/granular-result");
|
|
44
44
|
const malloy_element_1 = require("../types/malloy-element");
|
|
45
45
|
const typecheck_utils_1 = require("./typecheck_utils");
|
|
46
|
-
const noteable_1 = require("../types/noteable");
|
|
47
46
|
const space_field_1 = require("../types/space-field");
|
|
48
47
|
const def_space_1 = require("../field-space/def-space");
|
|
49
48
|
class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
|
|
@@ -53,7 +52,6 @@ class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
|
|
|
53
52
|
this.defineName = defineName;
|
|
54
53
|
this.exprSrc = exprSrc;
|
|
55
54
|
this.isNoteableObj = true;
|
|
56
|
-
this.extendNote = noteable_1.extendNoteMethod;
|
|
57
55
|
}
|
|
58
56
|
getName() {
|
|
59
57
|
return this.defineName;
|
|
@@ -138,8 +136,8 @@ class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
|
|
|
138
136
|
if (this.exprSrc) {
|
|
139
137
|
ret.code = this.exprSrc;
|
|
140
138
|
}
|
|
141
|
-
if (this.
|
|
142
|
-
ret.annotations = { ...this.
|
|
139
|
+
if (this.ownAnnotation) {
|
|
140
|
+
ret.annotations = { ...this.ownAnnotation };
|
|
143
141
|
}
|
|
144
142
|
return ret;
|
|
145
143
|
}
|
|
@@ -6,15 +6,13 @@ import { FieldName } from '../types/field-space';
|
|
|
6
6
|
import type { LookupResult } from '../types/lookup-result';
|
|
7
7
|
import { ListOf, MalloyElement } from '../types/malloy-element';
|
|
8
8
|
import type { Noteable } from '../types/noteable';
|
|
9
|
-
import { extendNoteMethod } from '../types/noteable';
|
|
10
9
|
import type { MakeEntry } from '../types/space-entry';
|
|
11
10
|
import type { FieldDeclarationConstructor } from './field-declaration';
|
|
12
11
|
import { AggregateFieldDeclaration, CalculateFieldDeclaration, GroupByFieldDeclaration, ProjectFieldDeclaration } from './field-declaration';
|
|
13
12
|
export type FieldReferenceConstructor = new (names: FieldName[]) => FieldReference;
|
|
14
13
|
export declare abstract class FieldReference extends ListOf<FieldName> implements Noteable, MakeEntry {
|
|
15
14
|
readonly isNoteableObj = true;
|
|
16
|
-
|
|
17
|
-
extendNote: typeof extendNoteMethod;
|
|
15
|
+
ownAnnotation?: AnnotationsDef;
|
|
18
16
|
constructor(names: FieldName[]);
|
|
19
17
|
protected autoRenameDeclarationCtor(): FieldDeclarationConstructor | undefined;
|
|
20
18
|
makeEntry(fs: DynamicSpace): void;
|
|
@@ -106,9 +104,8 @@ export declare class ViewOrScalarFieldReference extends FieldReference {
|
|
|
106
104
|
export declare class WildcardFieldReference extends MalloyElement implements Noteable {
|
|
107
105
|
readonly joinPath: FieldReference | undefined;
|
|
108
106
|
elementType: string;
|
|
109
|
-
|
|
107
|
+
ownAnnotation?: AnnotationsDef;
|
|
110
108
|
readonly isNoteableObj = true;
|
|
111
|
-
extendNote: typeof extendNoteMethod;
|
|
112
109
|
except: Set<string>;
|
|
113
110
|
constructor(joinPath: FieldReference | undefined);
|
|
114
111
|
getFieldDef(): FieldDef;
|
|
@@ -9,7 +9,6 @@ const reference_field_1 = require("../field-space/reference-field");
|
|
|
9
9
|
const definition_list_1 = require("../types/definition-list");
|
|
10
10
|
const field_space_1 = require("../types/field-space");
|
|
11
11
|
const malloy_element_1 = require("../types/malloy-element");
|
|
12
|
-
const noteable_1 = require("../types/noteable");
|
|
13
12
|
const expr_id_reference_1 = require("../expressions/expr-id-reference");
|
|
14
13
|
const field_declaration_1 = require("./field-declaration");
|
|
15
14
|
const typecheck_utils_1 = require("./typecheck_utils");
|
|
@@ -17,7 +16,6 @@ class FieldReference extends malloy_element_1.ListOf {
|
|
|
17
16
|
constructor(names) {
|
|
18
17
|
super(names);
|
|
19
18
|
this.isNoteableObj = true;
|
|
20
|
-
this.extendNote = noteable_1.extendNoteMethod;
|
|
21
19
|
}
|
|
22
20
|
// The `name is path` declaration constructor used to auto-resolve an output
|
|
23
21
|
// name collision for this kind of reference, or undefined if this reference
|
|
@@ -70,8 +68,8 @@ class FieldReference extends malloy_element_1.ListOf {
|
|
|
70
68
|
'to set the name explicitly and silence this warning.');
|
|
71
69
|
const renamedRef = new ExpressionFieldReference(this.list.map(n => new field_space_1.FieldName(n.refString)));
|
|
72
70
|
const decl = new declCtor(new expr_id_reference_1.ExprIdReference(renamedRef), autoName);
|
|
73
|
-
if (this.
|
|
74
|
-
decl.
|
|
71
|
+
if (this.ownAnnotation) {
|
|
72
|
+
decl.ownAnnotation = this.ownAnnotation;
|
|
75
73
|
}
|
|
76
74
|
// Attach under this reference so the synthetic nodes inherit its location
|
|
77
75
|
// and resolve back to the translator for logging.
|
|
@@ -320,7 +318,6 @@ class WildcardFieldReference extends malloy_element_1.MalloyElement {
|
|
|
320
318
|
this.joinPath = joinPath;
|
|
321
319
|
this.elementType = 'wildcardFieldReference';
|
|
322
320
|
this.isNoteableObj = true;
|
|
323
|
-
this.extendNote = noteable_1.extendNoteMethod;
|
|
324
321
|
this.except = new Set();
|
|
325
322
|
this.has({ joinPath });
|
|
326
323
|
}
|
|
@@ -13,6 +13,7 @@ class Aggregate extends definition_list_1.DefinitionList {
|
|
|
13
13
|
this.elementType = 'aggregateList';
|
|
14
14
|
this.queryRefinementStage = query_property_interface_1.LegalRefinementStage.Single;
|
|
15
15
|
this.forceQueryClass = query_property_interface_1.QueryClass.Grouping;
|
|
16
|
+
this.statement = 'aggregate:';
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
exports.Aggregate = Aggregate;
|
|
@@ -13,6 +13,7 @@ class GroupBy extends definition_list_1.DefinitionList {
|
|
|
13
13
|
this.elementType = 'groupBy';
|
|
14
14
|
this.queryRefinementStage = query_property_interface_1.LegalRefinementStage.Single;
|
|
15
15
|
this.forceQueryClass = query_property_interface_1.QueryClass.Grouping;
|
|
16
|
+
this.statement = 'group_by:';
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
exports.GroupBy = GroupBy;
|
|
@@ -8,6 +8,7 @@ export declare class Index extends MalloyElement implements QueryPropertyInterfa
|
|
|
8
8
|
elementType: string;
|
|
9
9
|
weightBy?: FieldName;
|
|
10
10
|
forceQueryClass: QueryClass;
|
|
11
|
+
statement: string;
|
|
11
12
|
queryRefinementStage: undefined;
|
|
12
13
|
constructor(fields: FieldReferences);
|
|
13
14
|
useWeight(fn: FieldName): void;
|
|
@@ -13,6 +13,7 @@ class Index extends malloy_element_1.MalloyElement {
|
|
|
13
13
|
this.fields = fields;
|
|
14
14
|
this.elementType = 'index';
|
|
15
15
|
this.forceQueryClass = query_property_interface_1.QueryClass.Index;
|
|
16
|
+
this.statement = 'index:';
|
|
16
17
|
this.queryRefinementStage = undefined;
|
|
17
18
|
}
|
|
18
19
|
useWeight(fn) {
|
|
@@ -8,6 +8,7 @@ export declare class NestFieldDeclaration extends ViewFieldDeclaration implement
|
|
|
8
8
|
elementType: string;
|
|
9
9
|
queryRefinementStage: LegalRefinementStage;
|
|
10
10
|
forceQueryClass: QueryClass;
|
|
11
|
+
statement: string;
|
|
11
12
|
turtleDef: model.TurtleDef | undefined;
|
|
12
13
|
queryExecute(executeFor: QueryBuilder): void;
|
|
13
14
|
getFieldDef(fs: FieldSpace): model.TurtleDef;
|
|
@@ -50,6 +50,7 @@ class NestFieldDeclaration extends view_field_declaration_1.ViewFieldDeclaration
|
|
|
50
50
|
this.elementType = 'nest-field-declaration';
|
|
51
51
|
this.queryRefinementStage = query_property_interface_1.LegalRefinementStage.Single;
|
|
52
52
|
this.forceQueryClass = query_property_interface_1.QueryClass.Grouping;
|
|
53
|
+
this.statement = 'nest:';
|
|
53
54
|
this.turtleDef = undefined;
|
|
54
55
|
}
|
|
55
56
|
queryExecute(executeFor) {
|
|
@@ -84,7 +85,7 @@ class NestFieldDeclaration extends view_field_declaration_1.ViewFieldDeclaration
|
|
|
84
85
|
name: this.name,
|
|
85
86
|
pipeline: pipelineWithDrillPaths,
|
|
86
87
|
annotations: {
|
|
87
|
-
...this.
|
|
88
|
+
...this.ownAnnotation,
|
|
88
89
|
inherits: annotations,
|
|
89
90
|
},
|
|
90
91
|
location: this.location,
|
|
@@ -13,6 +13,7 @@ class Nests extends definition_list_1.DefinitionList {
|
|
|
13
13
|
this.elementType = 'nestedQueries';
|
|
14
14
|
this.queryRefinementStage = query_property_interface_1.LegalRefinementStage.Single;
|
|
15
15
|
this.forceQueryClass = query_property_interface_1.QueryClass.Grouping;
|
|
16
|
+
this.statement = 'nest:';
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
exports.Nests = Nests;
|
|
@@ -6,6 +6,7 @@ import { LegalRefinementStage, QueryClass } from '../types/query-property-interf
|
|
|
6
6
|
export declare class ProjectStatement extends DefinitionList<FieldCollectionMember> implements QueryPropertyInterface {
|
|
7
7
|
elementType: string;
|
|
8
8
|
forceQueryClass: QueryClass;
|
|
9
|
+
statement: string;
|
|
9
10
|
queryRefinementStage: LegalRefinementStage;
|
|
10
11
|
queryExecute(executeFor: QueryBuilder): void;
|
|
11
12
|
}
|
|
@@ -12,6 +12,7 @@ class ProjectStatement extends definition_list_1.DefinitionList {
|
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.elementType = 'projectStatement';
|
|
14
14
|
this.forceQueryClass = query_property_interface_1.QueryClass.Project;
|
|
15
|
+
this.statement = 'select:';
|
|
15
16
|
this.queryRefinementStage = query_property_interface_1.LegalRefinementStage.Single;
|
|
16
17
|
}
|
|
17
18
|
queryExecute(executeFor) {
|
|
@@ -12,6 +12,11 @@ const malloy_element_1 = require("../types/malloy-element");
|
|
|
12
12
|
const query_property_interface_1 = require("../types/query-property-interface");
|
|
13
13
|
const partial_builder_1 = require("../query-builders/partial-builder");
|
|
14
14
|
const utils_1 = require("../../utils");
|
|
15
|
+
function queryContextName(queryClass) {
|
|
16
|
+
const className = (0, utils_1.modernizeTermsForUserText)(queryClass);
|
|
17
|
+
const article = className === 'index' ? 'an' : 'a';
|
|
18
|
+
return `${article} ${className} query`;
|
|
19
|
+
}
|
|
15
20
|
class QOpDesc extends malloy_element_1.ListOf {
|
|
16
21
|
constructor() {
|
|
17
22
|
super(...arguments);
|
|
@@ -36,7 +41,8 @@ class QOpDesc extends malloy_element_1.ListOf {
|
|
|
36
41
|
if (el.forceQueryClass) {
|
|
37
42
|
if (guessType) {
|
|
38
43
|
if (guessType !== el.forceQueryClass) {
|
|
39
|
-
|
|
44
|
+
const operationName = el.statement;
|
|
45
|
+
el.logError(`illegal-${guessType}-operation`, `Use of ${operationName} is not allowed in ${queryContextName(guessType)}`);
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
else {
|
|
@@ -70,6 +76,11 @@ class QOpDesc extends malloy_element_1.ListOf {
|
|
|
70
76
|
getOp(inputFS, isNestIn) {
|
|
71
77
|
const build = this.getBuilder(inputFS, isNestIn, this);
|
|
72
78
|
for (const qp of this.list) {
|
|
79
|
+
if (this.opClass &&
|
|
80
|
+
qp.forceQueryClass &&
|
|
81
|
+
qp.forceQueryClass !== this.opClass) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
73
84
|
build.execute(qp);
|
|
74
85
|
}
|
|
75
86
|
const segment = build.finalize(this.refineThis);
|
|
@@ -14,6 +14,7 @@ class SampleProperty extends malloy_element_1.MalloyElement {
|
|
|
14
14
|
this.elementType = 'sampleProperty';
|
|
15
15
|
this.queryRefinementStage = query_property_interface_1.LegalRefinementStage.Tail;
|
|
16
16
|
this.forceQueryClass = query_property_interface_1.QueryClass.Index;
|
|
17
|
+
this.statement = 'sample:';
|
|
17
18
|
}
|
|
18
19
|
sampling() {
|
|
19
20
|
return this.sample;
|
|
@@ -7,7 +7,6 @@ import type { FieldSpace } from '../types/field-space';
|
|
|
7
7
|
import type { ModelEntryReference } from '../types/malloy-element';
|
|
8
8
|
import { MalloyElement } from '../types/malloy-element';
|
|
9
9
|
import type { Noteable } from '../types/noteable';
|
|
10
|
-
import { extendNoteMethod } from '../types/noteable';
|
|
11
10
|
import type { MakeEntry } from '../types/space-entry';
|
|
12
11
|
import type { SourceQueryElement } from '../source-query-elements/source-query-element';
|
|
13
12
|
import type { ParameterSpace } from '../field-space/parameter-space';
|
|
@@ -18,9 +17,8 @@ export declare abstract class Join extends MalloyElement implements Noteable, Ma
|
|
|
18
17
|
abstract getStructDef(parameterSpace: ParameterSpace): JoinFieldDef;
|
|
19
18
|
abstract fixupJoinOn(outer: FieldSpace, inStruct: JoinFieldDef): void;
|
|
20
19
|
readonly isNoteableObj = true;
|
|
21
|
-
extendNote: typeof extendNoteMethod;
|
|
22
20
|
abstract sourceExpr: SourceQueryElement;
|
|
23
|
-
|
|
21
|
+
ownAnnotation?: AnnotationsDef;
|
|
24
22
|
makeEntry(fs: DynamicSpace): void;
|
|
25
23
|
getName(): string;
|
|
26
24
|
protected getStructDefFromExpr(parameterSpace: ParameterSpace): SourceDef;
|
|
@@ -9,7 +9,6 @@ const malloy_types_1 = require("../../../model/malloy_types");
|
|
|
9
9
|
const join_space_field_1 = require("../field-space/join-space-field");
|
|
10
10
|
const definition_list_1 = require("../types/definition-list");
|
|
11
11
|
const malloy_element_1 = require("../types/malloy-element");
|
|
12
|
-
const noteable_1 = require("../types/noteable");
|
|
13
12
|
const error_factory_1 = require("../error-factory");
|
|
14
13
|
const query_property_interface_1 = require("../types/query-property-interface");
|
|
15
14
|
const composite_source_utils_1 = require("../../composite-source-utils");
|
|
@@ -17,7 +16,6 @@ class Join extends malloy_element_1.MalloyElement {
|
|
|
17
16
|
constructor() {
|
|
18
17
|
super(...arguments);
|
|
19
18
|
this.isNoteableObj = true;
|
|
20
|
-
this.extendNote = noteable_1.extendNoteMethod;
|
|
21
19
|
}
|
|
22
20
|
makeEntry(fs) {
|
|
23
21
|
fs.newEntry(this.name.refString, this, new join_space_field_1.JoinSpaceField(fs.parameterSpace(), this, fs.dialectName(), fs.connectionName()));
|
|
@@ -56,8 +54,8 @@ class KeyJoin extends Join {
|
|
|
56
54
|
onExpression: { node: 'error', message: "('join fixup'='not done yet')" },
|
|
57
55
|
location: this.location,
|
|
58
56
|
};
|
|
59
|
-
if (this.
|
|
60
|
-
joinStruct.annotations = { ...this.
|
|
57
|
+
if (this.ownAnnotation) {
|
|
58
|
+
joinStruct.annotations = { ...this.ownAnnotation };
|
|
61
59
|
}
|
|
62
60
|
return joinStruct;
|
|
63
61
|
}
|
|
@@ -148,8 +146,8 @@ class ExpressionJoin extends Join {
|
|
|
148
146
|
matrixOperation,
|
|
149
147
|
location: this.location,
|
|
150
148
|
};
|
|
151
|
-
if (this.
|
|
152
|
-
joinStruct.annotations = { ...this.
|
|
149
|
+
if (this.ownAnnotation) {
|
|
150
|
+
joinStruct.annotations = { ...this.ownAnnotation };
|
|
153
151
|
}
|
|
154
152
|
return joinStruct;
|
|
155
153
|
}
|