@malloydata/malloy 0.0.104 → 0.0.105-dev231124203430
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.
|
@@ -230,8 +230,9 @@ declare class QueryQuery extends QueryField {
|
|
|
230
230
|
rootResult: FieldInstanceResultRoot;
|
|
231
231
|
resultStage: string | undefined;
|
|
232
232
|
stageWriter: StageWriter | undefined;
|
|
233
|
-
|
|
234
|
-
|
|
233
|
+
isJoinedSubquery: boolean;
|
|
234
|
+
constructor(fieldDef: TurtleDef, parent: QueryStruct, stageWriter: StageWriter | undefined, isJoinedSubquery: boolean);
|
|
235
|
+
static makeQuery(fieldDef: TurtleDef, parentStruct: QueryStruct, stageWriter: StageWriter | undefined, isJoinedSubquery: boolean): QueryQuery;
|
|
235
236
|
inNestedPipeline(): boolean;
|
|
236
237
|
getFieldList(): QueryFieldDef[];
|
|
237
238
|
expandField(f: QueryFieldDef): {
|
|
@@ -355,7 +356,7 @@ export declare class QueryModel {
|
|
|
355
356
|
};
|
|
356
357
|
getStructByName(name: string): QueryStruct;
|
|
357
358
|
getStructFromRef(structRef: StructRef): QueryStruct;
|
|
358
|
-
loadQuery(query: Query, stageWriter: StageWriter | undefined, emitFinalStage?: boolean): QueryResults;
|
|
359
|
+
loadQuery(query: Query, stageWriter: StageWriter | undefined, emitFinalStage?: boolean, isJoinedSubquery?: boolean): QueryResults;
|
|
359
360
|
compileQuery(query: Query, finalize?: boolean): CompiledQuery;
|
|
360
361
|
exploreSearchSQLMap: Map<any, any>;
|
|
361
362
|
searchIndex(connection: Connection, explore: string, searchValue: string, limit?: number, searchField?: string | undefined): Promise<SearchIndexResult[] | undefined>;
|
|
@@ -1262,15 +1262,15 @@ class Segment {
|
|
|
1262
1262
|
name: 'ignoreme',
|
|
1263
1263
|
pipeline: [segment],
|
|
1264
1264
|
};
|
|
1265
|
-
const queryQueryQuery = QueryQuery.makeQuery(turtleDef, qs, new StageWriter(true, undefined) // stage write indicates we want to get a result.
|
|
1266
|
-
);
|
|
1265
|
+
const queryQueryQuery = QueryQuery.makeQuery(turtleDef, qs, new StageWriter(true, undefined), // stage write indicates we want to get a result.
|
|
1266
|
+
false);
|
|
1267
1267
|
return queryQueryQuery.getResultStructDef();
|
|
1268
1268
|
}
|
|
1269
1269
|
}
|
|
1270
1270
|
exports.Segment = Segment;
|
|
1271
1271
|
/** Query builder object. */
|
|
1272
1272
|
class QueryQuery extends QueryField {
|
|
1273
|
-
constructor(fieldDef, parent, stageWriter) {
|
|
1273
|
+
constructor(fieldDef, parent, stageWriter, isJoinedSubquery) {
|
|
1274
1274
|
super(fieldDef, parent);
|
|
1275
1275
|
this.prepared = false;
|
|
1276
1276
|
this.maxDepth = 0;
|
|
@@ -1280,8 +1280,9 @@ class QueryQuery extends QueryField {
|
|
|
1280
1280
|
this.stageWriter = stageWriter;
|
|
1281
1281
|
// do some magic here to get the first segment.
|
|
1282
1282
|
this.firstSegment = fieldDef.pipeline[0];
|
|
1283
|
+
this.isJoinedSubquery = isJoinedSubquery;
|
|
1283
1284
|
}
|
|
1284
|
-
static makeQuery(fieldDef, parentStruct, stageWriter = undefined) {
|
|
1285
|
+
static makeQuery(fieldDef, parentStruct, stageWriter = undefined, isJoinedSubquery) {
|
|
1285
1286
|
let flatTurtleDef = parentStruct.flattenTurtleDef(fieldDef);
|
|
1286
1287
|
let parent = parentStruct;
|
|
1287
1288
|
const firstStage = flatTurtleDef.pipeline[0];
|
|
@@ -1315,11 +1316,11 @@ class QueryQuery extends QueryField {
|
|
|
1315
1316
|
}
|
|
1316
1317
|
switch (firstStage.type) {
|
|
1317
1318
|
case 'reduce':
|
|
1318
|
-
return new QueryQueryReduce(flatTurtleDef, parent, stageWriter);
|
|
1319
|
+
return new QueryQueryReduce(flatTurtleDef, parent, stageWriter, isJoinedSubquery);
|
|
1319
1320
|
case 'project':
|
|
1320
|
-
return new QueryQueryProject(flatTurtleDef, parent, stageWriter);
|
|
1321
|
+
return new QueryQueryProject(flatTurtleDef, parent, stageWriter, isJoinedSubquery);
|
|
1321
1322
|
case 'index':
|
|
1322
|
-
return new QueryQueryIndex(flatTurtleDef, parent, stageWriter);
|
|
1323
|
+
return new QueryQueryIndex(flatTurtleDef, parent, stageWriter, isJoinedSubquery);
|
|
1323
1324
|
case 'partial':
|
|
1324
1325
|
throw new Error('Attempt to make query out of partial stage');
|
|
1325
1326
|
}
|
|
@@ -1370,7 +1371,7 @@ class QueryQuery extends QueryField {
|
|
|
1370
1371
|
const newFieldDef = (0, cloneDeep_1.default)(field.fieldDef);
|
|
1371
1372
|
newFieldDef.as = f.name;
|
|
1372
1373
|
newFieldDef.filterList = f.filterList;
|
|
1373
|
-
field = QueryQuery.makeQuery(newFieldDef, this.parent);
|
|
1374
|
+
field = QueryQuery.makeQuery(newFieldDef, this.parent, undefined, this.isJoinedSubquery);
|
|
1374
1375
|
}
|
|
1375
1376
|
else if (!(field instanceof QueryFieldTimestamp ||
|
|
1376
1377
|
field instanceof QueryFieldDate)) {
|
|
@@ -1984,6 +1985,22 @@ class QueryQuery extends QueryField {
|
|
|
1984
1985
|
if (this.firstSegment.type === 'project' && !queryDef.orderBy) {
|
|
1985
1986
|
return ''; // No default ordering for project.
|
|
1986
1987
|
}
|
|
1988
|
+
// Intermediate results (in a pipeline or join) that have no limit, don't need an orderby
|
|
1989
|
+
// Some database don't have this optimization.
|
|
1990
|
+
if (this.fieldDef.pipeline.length > 1 && queryDef.limit === undefined) {
|
|
1991
|
+
return '';
|
|
1992
|
+
}
|
|
1993
|
+
// ignore orderby if all aggregates.
|
|
1994
|
+
if (resultStruct.getRepeatedResultType() === 'inline_all_numbers') {
|
|
1995
|
+
return '';
|
|
1996
|
+
}
|
|
1997
|
+
// if we are in the last stage of a query and the query is a subquery
|
|
1998
|
+
// and has no limit, ORDER BY is superfluous
|
|
1999
|
+
if (this.isJoinedSubquery &&
|
|
2000
|
+
this.fieldDef.pipeline.length === 1 &&
|
|
2001
|
+
queryDef.limit === undefined) {
|
|
2002
|
+
return '';
|
|
2003
|
+
}
|
|
1987
2004
|
const orderBy = queryDef.orderBy || resultStruct.calculateDefaultOrderBy();
|
|
1988
2005
|
const o = [];
|
|
1989
2006
|
for (const f of orderBy) {
|
|
@@ -2439,7 +2456,7 @@ class QueryQuery extends QueryField {
|
|
|
2439
2456
|
const qs = new QueryStruct(structDef, {
|
|
2440
2457
|
model: this.parent.getModel(),
|
|
2441
2458
|
});
|
|
2442
|
-
const q = QueryQuery.makeQuery(newTurtle, qs, stageWriter);
|
|
2459
|
+
const q = QueryQuery.makeQuery(newTurtle, qs, stageWriter, this.isJoinedSubquery);
|
|
2443
2460
|
pipeOut = q.generateSQLFromPipeline(stageWriter);
|
|
2444
2461
|
// console.log(stageWriter.generateSQLStages());
|
|
2445
2462
|
structDef = pipeOut.outputStruct;
|
|
@@ -2497,7 +2514,7 @@ class QueryQuery extends QueryField {
|
|
|
2497
2514
|
const s = new QueryStruct(structDef, {
|
|
2498
2515
|
model: this.parent.getModel(),
|
|
2499
2516
|
});
|
|
2500
|
-
const q = QueryQuery.makeQuery({ type: 'turtle', name: 'ignoreme', pipeline: [transform] }, s, stageWriter);
|
|
2517
|
+
const q = QueryQuery.makeQuery({ type: 'turtle', name: 'ignoreme', pipeline: [transform] }, s, stageWriter, this.isJoinedSubquery);
|
|
2501
2518
|
q.prepare(stageWriter);
|
|
2502
2519
|
lastStageName = q.generateSQL(stageWriter);
|
|
2503
2520
|
outputStruct = q.getResultStructDef();
|
|
@@ -2518,8 +2535,8 @@ class QueryQueryProject extends QueryQuery {
|
|
|
2518
2535
|
// wildcards have been expanded
|
|
2519
2536
|
// nested repeated fields are safe to use.
|
|
2520
2537
|
class QueryQueryIndexStage extends QueryQuery {
|
|
2521
|
-
constructor(fieldDef, parent, stageWriter) {
|
|
2522
|
-
super(fieldDef, parent, stageWriter);
|
|
2538
|
+
constructor(fieldDef, parent, stageWriter, isJoinedSubquery) {
|
|
2539
|
+
super(fieldDef, parent, stageWriter, isJoinedSubquery);
|
|
2523
2540
|
this.fieldDef = fieldDef;
|
|
2524
2541
|
}
|
|
2525
2542
|
// get a field ref and expand it.
|
|
@@ -2632,8 +2649,8 @@ FROM ${resultStage}\n`);
|
|
|
2632
2649
|
}
|
|
2633
2650
|
}
|
|
2634
2651
|
class QueryQueryIndex extends QueryQuery {
|
|
2635
|
-
constructor(fieldDef, parent, stageWriter) {
|
|
2636
|
-
super(fieldDef, parent, stageWriter);
|
|
2652
|
+
constructor(fieldDef, parent, stageWriter, isJoinedSubquery) {
|
|
2653
|
+
super(fieldDef, parent, stageWriter, isJoinedSubquery);
|
|
2637
2654
|
this.rootFields = [];
|
|
2638
2655
|
this.fanPrefixMap = {};
|
|
2639
2656
|
this.fieldDef = fieldDef;
|
|
@@ -2720,7 +2737,7 @@ class QueryQueryIndex extends QueryQuery {
|
|
|
2720
2737
|
fields: fields,
|
|
2721
2738
|
},
|
|
2722
2739
|
],
|
|
2723
|
-
}, this.parent, stageWriter);
|
|
2740
|
+
}, this.parent, stageWriter, this.isJoinedSubquery);
|
|
2724
2741
|
q.prepare(stageWriter);
|
|
2725
2742
|
const lastStageName = q.generateSQL(stageWriter);
|
|
2726
2743
|
outputStageNames.push(lastStageName);
|
|
@@ -2799,7 +2816,7 @@ class QueryStruct extends QueryNode {
|
|
|
2799
2816
|
// case "reduce" || "project" || "index": {
|
|
2800
2817
|
case 'turtle': {
|
|
2801
2818
|
// not sure why we need to cast here...
|
|
2802
|
-
this.addFieldToNameMap(as, QueryQuery.makeQuery(field, this));
|
|
2819
|
+
this.addFieldToNameMap(as, QueryQuery.makeQuery(field, this, undefined, false));
|
|
2803
2820
|
break;
|
|
2804
2821
|
}
|
|
2805
2822
|
default: {
|
|
@@ -3077,12 +3094,13 @@ class QueryStruct extends QueryNode {
|
|
|
3077
3094
|
// should be cached.
|
|
3078
3095
|
if (name.includes('cache')) {
|
|
3079
3096
|
const dtStageWriter = new StageWriter(true, stageWriter);
|
|
3080
|
-
this.model.loadQuery(this.fieldDef.structSource.query, dtStageWriter);
|
|
3097
|
+
this.model.loadQuery(this.fieldDef.structSource.query, dtStageWriter, false, false);
|
|
3081
3098
|
return dtStageWriter.addPDT(name, this.dialect);
|
|
3082
3099
|
}
|
|
3083
3100
|
else {
|
|
3084
3101
|
// returns the stage name.
|
|
3085
|
-
return this.model.loadQuery(this.fieldDef.structSource.query, stageWriter
|
|
3102
|
+
return this.model.loadQuery(this.fieldDef.structSource.query, stageWriter, false, true // this is an intermediate stage.
|
|
3103
|
+
).lastStageName;
|
|
3086
3104
|
}
|
|
3087
3105
|
}
|
|
3088
3106
|
default:
|
|
@@ -3269,7 +3287,7 @@ class QueryModel {
|
|
|
3269
3287
|
}
|
|
3270
3288
|
return new QueryStruct(structDef, { model: this });
|
|
3271
3289
|
}
|
|
3272
|
-
loadQuery(query, stageWriter, emitFinalStage = false) {
|
|
3290
|
+
loadQuery(query, stageWriter, emitFinalStage = false, isJoinedSubquery = false) {
|
|
3273
3291
|
const malloy = '';
|
|
3274
3292
|
if (!stageWriter) {
|
|
3275
3293
|
stageWriter = new StageWriter(true, undefined);
|
|
@@ -3281,7 +3299,7 @@ class QueryModel {
|
|
|
3281
3299
|
pipeline: query.pipeline,
|
|
3282
3300
|
filterList: query.filterList,
|
|
3283
3301
|
};
|
|
3284
|
-
const q = QueryQuery.makeQuery(turtleDef, this.getStructFromRef(query.structRef), stageWriter);
|
|
3302
|
+
const q = QueryQuery.makeQuery(turtleDef, this.getStructFromRef(query.structRef), stageWriter, isJoinedSubquery);
|
|
3285
3303
|
const ret = q.generateSQLFromPipeline(stageWriter);
|
|
3286
3304
|
if (emitFinalStage && q.parent.dialect.hasFinalStage) {
|
|
3287
3305
|
// const fieldNames: string[] = [];
|
|
@@ -3302,7 +3320,7 @@ class QueryModel {
|
|
|
3302
3320
|
compileQuery(query, finalize = true) {
|
|
3303
3321
|
let newModel;
|
|
3304
3322
|
const m = newModel || this;
|
|
3305
|
-
const ret = m.loadQuery(query, undefined, finalize);
|
|
3323
|
+
const ret = m.loadQuery(query, undefined, finalize, false);
|
|
3306
3324
|
const sourceExplore = typeof query.structRef === 'string'
|
|
3307
3325
|
? query.structRef
|
|
3308
3326
|
: // LTNOTE: the parser needs to capture the query before the |. This will work
|