@malloydata/malloy 0.0.222-dev241212154316 → 0.0.222-dev241212190052
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/dialect/duckdb/duckdb.js +1 -1
- package/dist/dialect/functions/util.d.ts +8 -1
- package/dist/dialect/functions/util.js +55 -0
- package/dist/dialect/trino/dialect_functions.js +6 -0
- package/dist/lang/ast/expressions/expr-record-literal.js +1 -1
- package/dist/lang/ast/field-space/dynamic-space.js +1 -1
- package/dist/lang/ast/field-space/join-space-field.d.ts +1 -1
- package/dist/lang/ast/field-space/join-space-field.js +2 -2
- package/dist/lang/ast/field-space/reference-field.js +1 -1
- package/dist/lang/ast/field-space/static-space.d.ts +5 -4
- package/dist/lang/ast/field-space/static-space.js +16 -12
- package/dist/lang/ast/query-elements/query-arrow.js +2 -2
- package/dist/lang/ast/query-elements/query-refine.js +1 -1
- package/dist/lang/ast/query-items/field-declaration.js +1 -1
- package/dist/lang/ast/source-elements/named-source.js +2 -1
- package/dist/lang/ast/source-properties/join.js +1 -1
- package/dist/lang/ast/view-elements/view-arrow.js +1 -1
- package/dist/lang/test/field-symbols.spec.js +10 -12
- package/dist/lang/test/test-translator.js +1 -3
- package/dist/malloy.js +3 -0
- package/dist/model/malloy_query.d.ts +1 -0
- package/dist/model/malloy_query.js +12 -3
- package/dist/model/malloy_types.d.ts +4 -4
- package/dist/model/malloy_types.js +6 -8
- package/package.json +1 -1
|
@@ -423,7 +423,7 @@ class DuckDBTypeParser extends tiny_parser_1.TinyParser {
|
|
|
423
423
|
fieldName.type === 'qdouble' ||
|
|
424
424
|
fieldName.type === 'id') {
|
|
425
425
|
const fieldType = this.typeDef();
|
|
426
|
-
baseType.fields.push((0, malloy_types_1.mkFieldDef)(fieldType, this.unquoteName(fieldName)
|
|
426
|
+
baseType.fields.push((0, malloy_types_1.mkFieldDef)(fieldType, this.unquoteName(fieldName)));
|
|
427
427
|
}
|
|
428
428
|
else {
|
|
429
429
|
if (fieldName.type !== ')') {
|
|
@@ -48,7 +48,14 @@ export declare function overload(returnType: TypeDesc, params: FunctionParameter
|
|
|
48
48
|
defaultOrderByArgIndex?: number;
|
|
49
49
|
supportsOrderBy?: boolean | 'only_default';
|
|
50
50
|
}): DialectFunctionOverloadDef;
|
|
51
|
-
export
|
|
51
|
+
export interface ArrayBlueprint {
|
|
52
|
+
array: TypeDescElementBlueprint;
|
|
53
|
+
}
|
|
54
|
+
export interface RecordBlueprint {
|
|
55
|
+
record: Record<string, TypeDescElementBlueprint>;
|
|
56
|
+
}
|
|
57
|
+
export type TypeDescElementBlueprint = LeafExpressionType | ArrayBlueprint | RecordBlueprint;
|
|
58
|
+
export type TypeDescBlueprint = TypeDescElementBlueprint | {
|
|
52
59
|
generic: string;
|
|
53
60
|
} | {
|
|
54
61
|
literal: LeafExpressionType | {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.expandOverrideMapFromBase = exports.expandBlueprintMap = exports.overload = exports.minAnalytic = exports.minAggregate = exports.minScalar = exports.maxAnalytic = exports.maxUngroupedAggregate = exports.anyExprType = exports.maxAggregate = exports.maxScalar = exports.makeParam = exports.param = exports.variadicParam = exports.literal = exports.output = exports.constant = exports.sql = exports.spread = exports.arg = void 0;
|
|
26
26
|
const composite_source_utils_1 = require("../../model/composite_source_utils");
|
|
27
|
+
const malloy_types_1 = require("../../model/malloy_types");
|
|
27
28
|
function arg(name) {
|
|
28
29
|
return { node: 'function_parameter', name };
|
|
29
30
|
}
|
|
@@ -116,6 +117,10 @@ function anyExprType(type) {
|
|
|
116
117
|
return { type, expressionType: undefined, evalSpace: 'input' };
|
|
117
118
|
}
|
|
118
119
|
exports.anyExprType = anyExprType;
|
|
120
|
+
function anyExprTypeBP(type, generic) {
|
|
121
|
+
const typeDesc = expandReturnTypeBlueprint(type, generic);
|
|
122
|
+
return { ...typeDesc, expressionType: undefined, evalSpace: 'input' };
|
|
123
|
+
}
|
|
119
124
|
function maxUngroupedAggregate(type) {
|
|
120
125
|
return { type, expressionType: 'ungrouped_aggregate', evalSpace: 'input' };
|
|
121
126
|
}
|
|
@@ -165,6 +170,48 @@ function expandReturnTypeBlueprint(blueprint, generic) {
|
|
|
165
170
|
if (typeof blueprint === 'string') {
|
|
166
171
|
base = minScalar(blueprint);
|
|
167
172
|
}
|
|
173
|
+
else if ('array' in blueprint) {
|
|
174
|
+
const innerType = expandReturnTypeBlueprint(blueprint.array, generic);
|
|
175
|
+
const { expressionType, evalSpace } = innerType;
|
|
176
|
+
if (malloy_types_1.TD.isAtomic(innerType)) {
|
|
177
|
+
if (innerType.type !== 'record') {
|
|
178
|
+
base = {
|
|
179
|
+
type: 'array',
|
|
180
|
+
elementTypeDef: innerType,
|
|
181
|
+
expressionType,
|
|
182
|
+
evalSpace,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
base = {
|
|
187
|
+
type: 'array',
|
|
188
|
+
elementTypeDef: { type: 'record_element' },
|
|
189
|
+
fields: innerType.fields,
|
|
190
|
+
expressionType,
|
|
191
|
+
evalSpace,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// mtoy todo fix by doing "exapndElementBlueprint" ...
|
|
197
|
+
throw new Error(`TypeDescElementBlueprint should never allow ${blueprint.array}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else if ('record' in blueprint) {
|
|
201
|
+
const fields = [];
|
|
202
|
+
for (const [fieldName, fieldBlueprint] of Object.entries(blueprint.record)) {
|
|
203
|
+
const fieldDesc = expandReturnTypeBlueprint(fieldBlueprint, generic);
|
|
204
|
+
if (malloy_types_1.TD.isAtomic(fieldDesc)) {
|
|
205
|
+
fields.push((0, malloy_types_1.mkFieldDef)(fieldDesc, fieldName));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
base = {
|
|
209
|
+
type: 'record',
|
|
210
|
+
fields,
|
|
211
|
+
evalSpace: 'input',
|
|
212
|
+
expressionType: 'scalar',
|
|
213
|
+
};
|
|
214
|
+
}
|
|
168
215
|
else if ('generic' in blueprint) {
|
|
169
216
|
base = minScalar(removeGeneric(blueprint, generic));
|
|
170
217
|
}
|
|
@@ -191,6 +238,8 @@ function expandReturnTypeBlueprint(blueprint, generic) {
|
|
|
191
238
|
}
|
|
192
239
|
function isTypeDescBlueprint(blueprint) {
|
|
193
240
|
return (typeof blueprint === 'string' ||
|
|
241
|
+
'array' in blueprint ||
|
|
242
|
+
'record' in blueprint ||
|
|
194
243
|
'generic' in blueprint ||
|
|
195
244
|
'literal' in blueprint ||
|
|
196
245
|
'constant' in blueprint ||
|
|
@@ -231,6 +280,12 @@ function expandParamTypeBlueprint(blueprint, generic) {
|
|
|
231
280
|
else if ('measure' in blueprint) {
|
|
232
281
|
return maxAggregate(removeGeneric(blueprint.measure, generic));
|
|
233
282
|
}
|
|
283
|
+
else if ('array' in blueprint) {
|
|
284
|
+
return anyExprTypeBP(blueprint, generic);
|
|
285
|
+
}
|
|
286
|
+
else if ('record' in blueprint) {
|
|
287
|
+
return anyExprTypeBP(blueprint, generic);
|
|
288
|
+
}
|
|
234
289
|
else {
|
|
235
290
|
return maxAnalytic(removeGeneric(blueprint.calculation, generic));
|
|
236
291
|
}
|
|
@@ -239,6 +239,11 @@ const url_extract_query = {
|
|
|
239
239
|
returns: 'string',
|
|
240
240
|
impl: { function: 'URL_EXTRACT_QUERY' },
|
|
241
241
|
};
|
|
242
|
+
const split = {
|
|
243
|
+
takes: { 'src': 'string', 'splitChar': 'string' },
|
|
244
|
+
returns: { array: 'string' },
|
|
245
|
+
impl: { function: 'SPLIT' },
|
|
246
|
+
};
|
|
242
247
|
exports.TRINO_DIALECT_FUNCTIONS = {
|
|
243
248
|
// aggregate functions
|
|
244
249
|
approx_percentile,
|
|
@@ -274,5 +279,6 @@ exports.TRINO_DIALECT_FUNCTIONS = {
|
|
|
274
279
|
url_extract_query,
|
|
275
280
|
// window functions
|
|
276
281
|
percent_rank,
|
|
282
|
+
split,
|
|
277
283
|
};
|
|
278
284
|
//# sourceMappingURL=dialect_functions.js.map
|
|
@@ -67,7 +67,7 @@ class RecordLiteral extends expression_def_1.ExpressionDef {
|
|
|
67
67
|
if (model_1.TD.isAtomic(xVal)) {
|
|
68
68
|
dependents.push(xVal);
|
|
69
69
|
recLit.kids[el.key] = xVal.value;
|
|
70
|
-
recLit.typeDef.fields.push((0, model_1.mkFieldDef)(TDU.atomicDef(xVal), el.key
|
|
70
|
+
recLit.typeDef.fields.push((0, model_1.mkFieldDef)(TDU.atomicDef(xVal), el.key));
|
|
71
71
|
}
|
|
72
72
|
else {
|
|
73
73
|
this.logError('illegal-record-property-type', `Record property '${el.key} is type '${xVal.type}', which is not a legal property value type`);
|
|
@@ -58,7 +58,7 @@ const struct_space_field_base_1 = require("./struct-space-field-base");
|
|
|
58
58
|
const parameter_space_1 = require("./parameter-space");
|
|
59
59
|
class DynamicSpace extends static_space_1.StaticSpace {
|
|
60
60
|
constructor(extending) {
|
|
61
|
-
super(structuredClone(extending));
|
|
61
|
+
super(structuredClone(extending), extending.dialect);
|
|
62
62
|
this.complete = false;
|
|
63
63
|
this.parameters = [];
|
|
64
64
|
this.fromSource = extending;
|
|
@@ -4,5 +4,5 @@ import { StructSpaceField } from './static-space';
|
|
|
4
4
|
export declare class JoinSpaceField extends StructSpaceField {
|
|
5
5
|
readonly parameterSpace: ParameterSpace;
|
|
6
6
|
readonly join: Join;
|
|
7
|
-
constructor(parameterSpace: ParameterSpace, join: Join);
|
|
7
|
+
constructor(parameterSpace: ParameterSpace, join: Join, forDialect: string);
|
|
8
8
|
}
|
|
@@ -25,8 +25,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.JoinSpaceField = void 0;
|
|
26
26
|
const static_space_1 = require("./static-space");
|
|
27
27
|
class JoinSpaceField extends static_space_1.StructSpaceField {
|
|
28
|
-
constructor(parameterSpace, join) {
|
|
29
|
-
super(join.structDef(parameterSpace));
|
|
28
|
+
constructor(parameterSpace, join, forDialect) {
|
|
29
|
+
super(join.structDef(parameterSpace), forDialect);
|
|
30
30
|
this.parameterSpace = parameterSpace;
|
|
31
31
|
this.join = join;
|
|
32
32
|
}
|
|
@@ -78,7 +78,7 @@ class ReferenceField extends space_field_1.SpaceField {
|
|
|
78
78
|
const foundType = check.found.typeDesc();
|
|
79
79
|
if (malloy_types_1.TD.isAtomic(foundType)) {
|
|
80
80
|
this.queryFieldDef = {
|
|
81
|
-
...(0, malloy_types_1.mkFieldDef)(TDU.atomicDef(foundType), path[0]
|
|
81
|
+
...(0, malloy_types_1.mkFieldDef)(TDU.atomicDef(foundType), path[0]),
|
|
82
82
|
e: { node: 'parameter', path },
|
|
83
83
|
};
|
|
84
84
|
}
|
|
@@ -6,11 +6,11 @@ import { FieldName, FieldSpace, QueryFieldSpace, SourceFieldSpace } from '../typ
|
|
|
6
6
|
import { SpaceField } from '../types/space-field';
|
|
7
7
|
import { StructSpaceFieldBase } from './struct-space-field-base';
|
|
8
8
|
export declare class StaticSpace implements FieldSpace {
|
|
9
|
-
protected fromStruct: StructDef;
|
|
10
9
|
readonly type = "fieldSpace";
|
|
11
10
|
private memoMap?;
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
protected fromStruct: StructDef;
|
|
12
|
+
protected structDialect: string;
|
|
13
|
+
constructor(struct: StructDef, dialect_name: string);
|
|
14
14
|
dialectName(): string;
|
|
15
15
|
dialectObj(): Dialect | undefined;
|
|
16
16
|
defToSpaceField(from: FieldDef): SpaceField;
|
|
@@ -26,7 +26,8 @@ export declare class StaticSpace implements FieldSpace {
|
|
|
26
26
|
isQueryFieldSpace(): this is QueryFieldSpace;
|
|
27
27
|
}
|
|
28
28
|
export declare class StructSpaceField extends StructSpaceFieldBase {
|
|
29
|
-
|
|
29
|
+
private forDialect;
|
|
30
|
+
constructor(def: JoinFieldDef, forDialect: string);
|
|
30
31
|
get fieldSpace(): FieldSpace;
|
|
31
32
|
}
|
|
32
33
|
export declare class StaticSourceSpace extends StaticSpace implements SourceFieldSpace {
|
|
@@ -31,19 +31,17 @@ const struct_space_field_base_1 = require("./struct-space-field-base");
|
|
|
31
31
|
const column_space_field_1 = require("./column-space-field");
|
|
32
32
|
const ir_view_field_1 = require("./ir-view-field");
|
|
33
33
|
class StaticSpace {
|
|
34
|
-
|
|
35
|
-
return this.fromStruct.dialect;
|
|
36
|
-
}
|
|
37
|
-
constructor(fromStruct) {
|
|
38
|
-
this.fromStruct = fromStruct;
|
|
34
|
+
constructor(struct, dialect_name) {
|
|
39
35
|
this.type = 'fieldSpace';
|
|
36
|
+
this.fromStruct = struct;
|
|
37
|
+
this.structDialect = dialect_name;
|
|
40
38
|
}
|
|
41
39
|
dialectName() {
|
|
42
|
-
return this.
|
|
40
|
+
return this.structDialect;
|
|
43
41
|
}
|
|
44
42
|
dialectObj() {
|
|
45
43
|
try {
|
|
46
|
-
return (0, dialect_map_1.getDialect)(this.
|
|
44
|
+
return (0, dialect_map_1.getDialect)(this.structDialect);
|
|
47
45
|
}
|
|
48
46
|
catch {
|
|
49
47
|
return undefined;
|
|
@@ -51,7 +49,7 @@ class StaticSpace {
|
|
|
51
49
|
}
|
|
52
50
|
defToSpaceField(from) {
|
|
53
51
|
if ((0, malloy_types_1.isJoined)(from)) {
|
|
54
|
-
return new StructSpaceField(from);
|
|
52
|
+
return new StructSpaceField(from, this.structDialect);
|
|
55
53
|
}
|
|
56
54
|
else if ((0, malloy_types_1.isTurtle)(from)) {
|
|
57
55
|
return new ir_view_field_1.IRViewField(this, from);
|
|
@@ -125,7 +123,7 @@ class StaticSpace {
|
|
|
125
123
|
// because it is someting like "dimension: joinedArray is arrayComputation"
|
|
126
124
|
// which wasn't known to be a join when the fieldspace was constructed.
|
|
127
125
|
// TODO don't make one of these every time you do a lookup
|
|
128
|
-
found = new StructSpaceField(definition);
|
|
126
|
+
found = new StructSpaceField(definition, this.structDialect);
|
|
129
127
|
}
|
|
130
128
|
// cswenson review todo I don't know how to count the reference properly now
|
|
131
129
|
// i tried only writing it as a join reference if there was more in the path
|
|
@@ -173,17 +171,23 @@ class StaticSpace {
|
|
|
173
171
|
}
|
|
174
172
|
exports.StaticSpace = StaticSpace;
|
|
175
173
|
class StructSpaceField extends struct_space_field_base_1.StructSpaceFieldBase {
|
|
176
|
-
constructor(def) {
|
|
174
|
+
constructor(def, forDialect) {
|
|
177
175
|
super(def);
|
|
176
|
+
this.forDialect = forDialect;
|
|
178
177
|
}
|
|
179
178
|
get fieldSpace() {
|
|
180
|
-
|
|
179
|
+
if ((0, malloy_types_1.isSourceDef)(this.structDef)) {
|
|
180
|
+
return new StaticSourceSpace(this.structDef);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return new StaticSpace(this.structDef, this.forDialect);
|
|
184
|
+
}
|
|
181
185
|
}
|
|
182
186
|
}
|
|
183
187
|
exports.StructSpaceField = StructSpaceField;
|
|
184
188
|
class StaticSourceSpace extends StaticSpace {
|
|
185
189
|
constructor(source) {
|
|
186
|
-
super(source);
|
|
190
|
+
super(source, source.dialect);
|
|
187
191
|
this.source = source;
|
|
188
192
|
}
|
|
189
193
|
structDef() {
|
|
@@ -58,14 +58,14 @@ class QueryArrow extends query_base_1.QueryBase {
|
|
|
58
58
|
inputStruct = (0, malloy_types_1.refIsStructDef)(invoked.structRef)
|
|
59
59
|
? invoked.structRef
|
|
60
60
|
: this.source.getSourceDef(undefined);
|
|
61
|
-
fieldSpace = new static_space_1.
|
|
61
|
+
fieldSpace = new static_space_1.StaticSourceSpace(inputStruct);
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
64
64
|
// We are adding a second stage to the given "source" query; we get the query and add a segment
|
|
65
65
|
const lhsQuery = this.source.queryComp(isRefOk);
|
|
66
66
|
queryBase = lhsQuery.query;
|
|
67
67
|
inputStruct = lhsQuery.outputStruct;
|
|
68
|
-
fieldSpace = new static_space_1.
|
|
68
|
+
fieldSpace = new static_space_1.StaticSourceSpace(lhsQuery.outputStruct);
|
|
69
69
|
}
|
|
70
70
|
const { pipeline, annotation, outputStruct, name } = this.view.pipelineComp(fieldSpace);
|
|
71
71
|
return {
|
|
@@ -40,7 +40,7 @@ class QueryRefine extends query_base_1.QueryBase {
|
|
|
40
40
|
}
|
|
41
41
|
queryComp(isRefOk) {
|
|
42
42
|
const q = this.base.queryComp(isRefOk);
|
|
43
|
-
const inputFS = new static_space_1.
|
|
43
|
+
const inputFS = new static_space_1.StaticSourceSpace(q.inputStruct);
|
|
44
44
|
const resultPipe = this.refinement.refine(inputFS, q.query.pipeline, undefined);
|
|
45
45
|
return {
|
|
46
46
|
query: {
|
|
@@ -109,7 +109,7 @@ class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
|
|
|
109
109
|
}
|
|
110
110
|
if ((0, malloy_types_1.isAtomicFieldType)(exprValue.type) && exprValue.type !== 'error') {
|
|
111
111
|
this.typecheckExprValue(exprValue);
|
|
112
|
-
const ret = (0, malloy_types_1.mkFieldDef)(TDU.atomicDef(exprValue), exprName
|
|
112
|
+
const ret = (0, malloy_types_1.mkFieldDef)(TDU.atomicDef(exprValue), exprName);
|
|
113
113
|
if ((ret.type === 'date' || ret.type === 'timestamp') &&
|
|
114
114
|
(0, granular_result_1.isGranularResult)(exprValue)) {
|
|
115
115
|
ret.timeframe = exprValue.timeframe;
|
|
@@ -104,7 +104,8 @@ class NamedSource extends source_1.Source {
|
|
|
104
104
|
return { ...entry };
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
-
|
|
107
|
+
// I think this is now a never
|
|
108
|
+
this.logError('invalid-source-source', 'Cannot construct a source from a never type');
|
|
108
109
|
}
|
|
109
110
|
evaluateArgumentsForRef(parameterSpace) {
|
|
110
111
|
const base = this.modelStruct();
|
|
@@ -37,7 +37,7 @@ class Join extends malloy_element_1.MalloyElement {
|
|
|
37
37
|
this.extendNote = noteable_1.extendNoteMethod;
|
|
38
38
|
}
|
|
39
39
|
makeEntry(fs) {
|
|
40
|
-
fs.newEntry(this.name.refString, this, new join_space_field_1.JoinSpaceField(fs.parameterSpace(), this));
|
|
40
|
+
fs.newEntry(this.name.refString, this, new join_space_field_1.JoinSpaceField(fs.parameterSpace(), this, fs.dialectName()));
|
|
41
41
|
}
|
|
42
42
|
getStructDefFromExpr(parameterSpace) {
|
|
43
43
|
const source = this.sourceExpr.getSource();
|
|
@@ -40,7 +40,7 @@ class ViewArrow extends view_1.View {
|
|
|
40
40
|
}
|
|
41
41
|
pipelineComp(fs) {
|
|
42
42
|
const baseComp = this.base.pipelineComp(fs);
|
|
43
|
-
const nextFS = new static_space_1.
|
|
43
|
+
const nextFS = new static_space_1.StaticSourceSpace(baseComp.outputStruct);
|
|
44
44
|
const finalComp = this.operation.pipelineComp(nextFS);
|
|
45
45
|
return {
|
|
46
46
|
pipeline: [...baseComp.pipeline, ...finalComp.pipeline],
|
|
@@ -51,7 +51,7 @@ describe('structdef comprehension', () => {
|
|
|
51
51
|
type: 'string',
|
|
52
52
|
};
|
|
53
53
|
const struct = mkStructDef(field);
|
|
54
|
-
const space = new static_space_1.
|
|
54
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
55
55
|
expect(space.lookup(fieldRef('t')).found).toBeInstanceOf(column_space_field_1.ColumnSpaceField);
|
|
56
56
|
const oField = space.structDef().fields[0];
|
|
57
57
|
expect(oField).toEqual(field);
|
|
@@ -63,7 +63,7 @@ describe('structdef comprehension', () => {
|
|
|
63
63
|
numberType: 'float',
|
|
64
64
|
};
|
|
65
65
|
const struct = mkStructDef(field);
|
|
66
|
-
const space = new static_space_1.
|
|
66
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
67
67
|
expect(space.lookup(fieldRef('t')).found).toBeInstanceOf(column_space_field_1.ColumnSpaceField);
|
|
68
68
|
const oField = space.structDef().fields[0];
|
|
69
69
|
expect(oField).toEqual(field);
|
|
@@ -75,7 +75,7 @@ describe('structdef comprehension', () => {
|
|
|
75
75
|
numberType: 'integer',
|
|
76
76
|
};
|
|
77
77
|
const struct = mkStructDef(field);
|
|
78
|
-
const space = new static_space_1.
|
|
78
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
79
79
|
expect(space.lookup(fieldRef('t')).found).toBeInstanceOf(column_space_field_1.ColumnSpaceField);
|
|
80
80
|
const oField = space.structDef().fields[0];
|
|
81
81
|
expect(oField).toEqual(field);
|
|
@@ -86,7 +86,7 @@ describe('structdef comprehension', () => {
|
|
|
86
86
|
type: 'boolean',
|
|
87
87
|
};
|
|
88
88
|
const struct = mkStructDef(field);
|
|
89
|
-
const space = new static_space_1.
|
|
89
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
90
90
|
expect(space.lookup(fieldRef('t')).found).toBeInstanceOf(column_space_field_1.ColumnSpaceField);
|
|
91
91
|
const oField = space.structDef().fields[0];
|
|
92
92
|
expect(oField).toEqual(field);
|
|
@@ -97,7 +97,7 @@ describe('structdef comprehension', () => {
|
|
|
97
97
|
type: 'sql native',
|
|
98
98
|
};
|
|
99
99
|
const struct = mkStructDef(field);
|
|
100
|
-
const space = new static_space_1.
|
|
100
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
101
101
|
expect(space.lookup(fieldRef('t')).found).toBeInstanceOf(column_space_field_1.ColumnSpaceField);
|
|
102
102
|
const oField = space.structDef().fields[0];
|
|
103
103
|
expect(oField).toEqual(field);
|
|
@@ -106,14 +106,13 @@ describe('structdef comprehension', () => {
|
|
|
106
106
|
const field = {
|
|
107
107
|
name: 't',
|
|
108
108
|
type: 'array',
|
|
109
|
-
dialect: 'standardsql',
|
|
110
109
|
elementTypeDef: { type: 'string' },
|
|
111
110
|
join: 'many',
|
|
112
111
|
matrixOperation: 'left',
|
|
113
112
|
fields: [{ type: 'string', name: 'b' }],
|
|
114
113
|
};
|
|
115
114
|
const struct = mkStructDef(field);
|
|
116
|
-
const space = new static_space_1.
|
|
115
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
117
116
|
expect(space.lookup(fieldRef('t.b')).found).toBeInstanceOf(column_space_field_1.ColumnSpaceField);
|
|
118
117
|
const oField = space.structDef().fields[0];
|
|
119
118
|
expect(oField).toEqual(field);
|
|
@@ -122,13 +121,12 @@ describe('structdef comprehension', () => {
|
|
|
122
121
|
const field = {
|
|
123
122
|
name: 't',
|
|
124
123
|
type: 'record',
|
|
125
|
-
dialect: 'standardsql',
|
|
126
124
|
join: 'one',
|
|
127
125
|
matrixOperation: 'left',
|
|
128
126
|
fields: [{ type: 'string', name: 'a' }],
|
|
129
127
|
};
|
|
130
128
|
const struct = mkStructDef(field);
|
|
131
|
-
const space = new static_space_1.
|
|
129
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
132
130
|
expect(space.lookup(fieldRef('t.a')).found).toBeInstanceOf(column_space_field_1.ColumnSpaceField);
|
|
133
131
|
const oField = space.structDef().fields[0];
|
|
134
132
|
expect(oField).toEqual(field);
|
|
@@ -152,7 +150,7 @@ describe('structdef comprehension', () => {
|
|
|
152
150
|
fields: [{ type: 'string', name: 'a' }],
|
|
153
151
|
};
|
|
154
152
|
const struct = mkStructDef(field);
|
|
155
|
-
const space = new static_space_1.
|
|
153
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
156
154
|
expect(space.lookup(fieldRef('t.a')).found).toBeInstanceOf(column_space_field_1.ColumnSpaceField);
|
|
157
155
|
const oField = space.structDef().fields[0];
|
|
158
156
|
expect(oField).toEqual(field);
|
|
@@ -169,7 +167,7 @@ describe('structdef comprehension', () => {
|
|
|
169
167
|
],
|
|
170
168
|
};
|
|
171
169
|
const struct = mkStructDef(field);
|
|
172
|
-
const space = new static_space_1.
|
|
170
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
173
171
|
expect(space.lookup(fieldRef('t')).found).toBeInstanceOf(ir_view_field_1.IRViewField);
|
|
174
172
|
const oField = space.structDef().fields[0];
|
|
175
173
|
expect(oField).toEqual(field);
|
|
@@ -188,7 +186,7 @@ describe('structdef comprehension', () => {
|
|
|
188
186
|
value: { node: 'stringLiteral', literal: 'value' },
|
|
189
187
|
},
|
|
190
188
|
};
|
|
191
|
-
const space = new static_space_1.
|
|
189
|
+
const space = new static_space_1.StaticSourceSpace(struct);
|
|
192
190
|
expect(space.lookup(fieldRef('cReqStr')).found).toBeInstanceOf(space_param_1.DefinedParameter);
|
|
193
191
|
expect(space.lookup(fieldRef('cOptStr')).found).toBeInstanceOf(space_param_1.DefinedParameter);
|
|
194
192
|
});
|
|
@@ -64,7 +64,6 @@ const mockSchema = {
|
|
|
64
64
|
numberType: 'integer',
|
|
65
65
|
},
|
|
66
66
|
],
|
|
67
|
-
dialect: 'standardsql',
|
|
68
67
|
},
|
|
69
68
|
{
|
|
70
69
|
type: 'record',
|
|
@@ -72,9 +71,8 @@ const mockSchema = {
|
|
|
72
71
|
fields: [{ ...intType, name: 'column' }],
|
|
73
72
|
join: 'one',
|
|
74
73
|
matrixOperation: 'left',
|
|
75
|
-
dialect: 'standardsql',
|
|
76
74
|
},
|
|
77
|
-
(0, malloy_types_1.mkArrayDef)(intType, 'ais'
|
|
75
|
+
(0, malloy_types_1.mkArrayDef)(intType, 'ais'),
|
|
78
76
|
],
|
|
79
77
|
},
|
|
80
78
|
'malloytest.carriers': {
|
package/dist/malloy.js
CHANGED
|
@@ -1025,6 +1025,9 @@ class Explore extends Entity {
|
|
|
1025
1025
|
return new PreparedQuery(internalQuery, this.modelDef, [], name);
|
|
1026
1026
|
}
|
|
1027
1027
|
get modelDef() {
|
|
1028
|
+
if (!(0, model_1.isSourceDef)(this.structDef)) {
|
|
1029
|
+
throw new Error(`Cannot create pseudo model for struct type ${this.structDef.type}`);
|
|
1030
|
+
}
|
|
1028
1031
|
return {
|
|
1029
1032
|
name: 'generated_model',
|
|
1030
1033
|
exports: [],
|
|
@@ -307,6 +307,7 @@ declare class QueryStruct {
|
|
|
307
307
|
connectionName: string;
|
|
308
308
|
recordAlias?: string;
|
|
309
309
|
constructor(structDef: StructDef, sourceArguments: Record<string, Argument> | undefined, parent: ParentQueryStruct | ParentQueryModel, prepareResultOptions: PrepareResultOptions);
|
|
310
|
+
protected findFirstDialect(): string;
|
|
310
311
|
informOfAliasValue(av: string): void;
|
|
311
312
|
maybeEmitParameterizedSourceUsage(): void;
|
|
312
313
|
private resolveParentParameterReferences;
|
|
@@ -2020,7 +2020,7 @@ class QueryQuery extends QueryField {
|
|
|
2020
2020
|
type: 'query_result',
|
|
2021
2021
|
name: this.resultStage || 'result',
|
|
2022
2022
|
fields,
|
|
2023
|
-
dialect: this.parent.
|
|
2023
|
+
dialect: this.parent.dialect.name,
|
|
2024
2024
|
primaryKey,
|
|
2025
2025
|
connection: this.parent.connectionName,
|
|
2026
2026
|
resultMetadata: this.getResultMetadata(this.rootResult),
|
|
@@ -3008,7 +3008,7 @@ class QueryQueryIndex extends QueryQuery {
|
|
|
3008
3008
|
const ret = {
|
|
3009
3009
|
type: 'query_result',
|
|
3010
3010
|
name: this.resultStage || 'result',
|
|
3011
|
-
dialect: this.parent.
|
|
3011
|
+
dialect: this.parent.dialect.name,
|
|
3012
3012
|
fields: [
|
|
3013
3013
|
{ type: 'string', name: 'fieldName' },
|
|
3014
3014
|
{ type: 'string', name: 'fieldPath' },
|
|
@@ -3078,9 +3078,18 @@ class QueryStruct {
|
|
|
3078
3078
|
this.pathAliasMap = this.root().pathAliasMap;
|
|
3079
3079
|
this.connectionName = this.root().connectionName;
|
|
3080
3080
|
}
|
|
3081
|
-
this.dialect = (0, dialect_1.getDialect)(
|
|
3081
|
+
this.dialect = (0, dialect_1.getDialect)(this.findFirstDialect());
|
|
3082
3082
|
this.addFieldsFromFieldList(structDef.fields);
|
|
3083
3083
|
}
|
|
3084
|
+
findFirstDialect() {
|
|
3085
|
+
if ((0, malloy_types_1.isSourceDef)(this.structDef)) {
|
|
3086
|
+
return this.structDef.dialect;
|
|
3087
|
+
}
|
|
3088
|
+
if (this.parent) {
|
|
3089
|
+
return this.parent.findFirstDialect();
|
|
3090
|
+
}
|
|
3091
|
+
throw new Error('Cannot create QueryStruct from record with model parent');
|
|
3092
|
+
}
|
|
3084
3093
|
informOfAliasValue(av) {
|
|
3085
3094
|
this.recordAlias = av;
|
|
3086
3095
|
}
|
|
@@ -389,8 +389,8 @@ export interface ScalarArrayDef extends ScalarArrayTypeDef, StructDefBase, JoinB
|
|
|
389
389
|
type: 'array';
|
|
390
390
|
join: 'many';
|
|
391
391
|
}
|
|
392
|
-
export declare function mkFieldDef(atd: AtomicTypeDef, name: string
|
|
393
|
-
export declare function mkArrayDef(ofType: AtomicTypeDef, name: string
|
|
392
|
+
export declare function mkFieldDef(atd: AtomicTypeDef, name: string): AtomicFieldDef;
|
|
393
|
+
export declare function mkArrayDef(ofType: AtomicTypeDef, name: string): ArrayDef;
|
|
394
394
|
export interface RecordTypeDef {
|
|
395
395
|
type: 'record';
|
|
396
396
|
fields: FieldDef[];
|
|
@@ -572,7 +572,6 @@ interface StructDefBase extends HasLocation, NamedObject {
|
|
|
572
572
|
annotation?: Annotation;
|
|
573
573
|
modelAnnotation?: ModelAnnotation;
|
|
574
574
|
fields: FieldDef[];
|
|
575
|
-
dialect: string;
|
|
576
575
|
}
|
|
577
576
|
interface SourceDefBase extends StructDefBase, Filtered, ResultStructMetadata {
|
|
578
577
|
arguments?: Record<string, Argument>;
|
|
@@ -580,6 +579,7 @@ interface SourceDefBase extends StructDefBase, Filtered, ResultStructMetadata {
|
|
|
580
579
|
queryTimezone?: string;
|
|
581
580
|
connection: string;
|
|
582
581
|
primaryKey?: PrimaryKeyRef;
|
|
582
|
+
dialect: string;
|
|
583
583
|
}
|
|
584
584
|
/** which field is the primary key in this struct */
|
|
585
585
|
export type PrimaryKeyRef = string;
|
|
@@ -695,7 +695,7 @@ export type QueryFieldDef = AtomicFieldDef | TurtleDef | RefToField;
|
|
|
695
695
|
export type TypedDef = AtomicTypeDef | JoinFieldDef | TurtleDef | RefToField | StructDef;
|
|
696
696
|
/** Get the output name for a NamedObject */
|
|
697
697
|
export declare function getIdentifier(n: AliasedName): string;
|
|
698
|
-
export type NamedModelObject =
|
|
698
|
+
export type NamedModelObject = SourceDef | NamedQuery | FunctionDef | ConnectionDef;
|
|
699
699
|
/** Result of parsing a model file */
|
|
700
700
|
export interface ModelDef {
|
|
701
701
|
name: string;
|
|
@@ -179,38 +179,36 @@ function fieldIsIntrinsic(f) {
|
|
|
179
179
|
return isAtomicFieldType(f.type) && !hasExpression(f);
|
|
180
180
|
}
|
|
181
181
|
exports.fieldIsIntrinsic = fieldIsIntrinsic;
|
|
182
|
-
function mkFieldDef(atd, name
|
|
182
|
+
function mkFieldDef(atd, name) {
|
|
183
183
|
if (isScalarArray(atd)) {
|
|
184
|
-
return mkArrayDef(atd.elementTypeDef, name
|
|
184
|
+
return mkArrayDef(atd.elementTypeDef, name);
|
|
185
185
|
}
|
|
186
186
|
if (isRepeatedRecord(atd)) {
|
|
187
187
|
const { type, fields, elementTypeDef } = atd;
|
|
188
|
-
return { type, fields, elementTypeDef, join: 'many', name
|
|
188
|
+
return { type, fields, elementTypeDef, join: 'many', name };
|
|
189
189
|
}
|
|
190
190
|
if (atd.type === 'record') {
|
|
191
191
|
const { type, fields } = atd;
|
|
192
|
-
return { type, fields, join: 'one',
|
|
192
|
+
return { type, fields, join: 'one', name };
|
|
193
193
|
}
|
|
194
194
|
return { ...atd, name };
|
|
195
195
|
}
|
|
196
196
|
exports.mkFieldDef = mkFieldDef;
|
|
197
|
-
function mkArrayDef(ofType, name
|
|
197
|
+
function mkArrayDef(ofType, name) {
|
|
198
198
|
if (ofType.type === 'record') {
|
|
199
199
|
return {
|
|
200
200
|
type: 'array',
|
|
201
201
|
join: 'many',
|
|
202
202
|
name,
|
|
203
|
-
dialect,
|
|
204
203
|
elementTypeDef: { type: 'record_element' },
|
|
205
204
|
fields: ofType.fields,
|
|
206
205
|
};
|
|
207
206
|
}
|
|
208
|
-
const valueEnt = mkFieldDef(ofType, 'value'
|
|
207
|
+
const valueEnt = mkFieldDef(ofType, 'value');
|
|
209
208
|
return {
|
|
210
209
|
type: 'array',
|
|
211
210
|
join: 'many',
|
|
212
211
|
name,
|
|
213
|
-
dialect,
|
|
214
212
|
elementTypeDef: ofType,
|
|
215
213
|
fields: [
|
|
216
214
|
valueEnt,
|