@malloydata/malloy 0.0.15 → 0.0.16-dev221214152428

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.
@@ -1658,6 +1658,9 @@ class QueryQuery extends QueryField {
1658
1658
  let structSQL = qs.structSourceSQL(stageWriter);
1659
1659
  if ((0, malloy_types_1.isIndexSegment)(this.firstSegment)) {
1660
1660
  structSQL = this.parent.dialect.sqlSampleTable(structSQL, this.firstSegment.sample);
1661
+ if (this.firstSegment.sample) {
1662
+ structSQL = stageWriter.addStage(`SELECT * from ${structSQL} as x limit 100000 `);
1663
+ }
1661
1664
  }
1662
1665
  const structRelationship = qs.fieldDef.structRelationship;
1663
1666
  if (structRelationship.type === "basetable") {
@@ -2211,23 +2214,13 @@ class QueryQueryReduce extends QueryQuery {
2211
2214
  }
2212
2215
  class QueryQueryProject extends QueryQuery {
2213
2216
  }
2214
- class QueryQueryIndex extends QueryQuery {
2217
+ // generates a single stage query for the index.
2218
+ // wildcards have been expanded
2219
+ // nested repeated fields are safe to use.
2220
+ class QueryQueryIndexStage extends QueryQuery {
2215
2221
  constructor(fieldDef, parent, stageWriter) {
2216
2222
  super(fieldDef, parent, stageWriter);
2217
- this.fanPrefixes = [];
2218
2223
  this.fieldDef = fieldDef;
2219
- this.findFanPrefexes(parent);
2220
- }
2221
- // we want to generate a different query for each
2222
- // nested structure so we don't do a crazy cross product.
2223
- findFanPrefexes(qs) {
2224
- for (const [_name, f] of qs.nameMap) {
2225
- if (f instanceof QueryStruct &&
2226
- (f.fieldDef.structRelationship.type === "many" ||
2227
- f.fieldDef.structRelationship.type === "nested")) {
2228
- this.fanPrefixes.push(f.getFullOutputName());
2229
- }
2230
- }
2231
2224
  }
2232
2225
  // get a field ref and expand it.
2233
2226
  expandField(f) {
@@ -2238,13 +2231,7 @@ class QueryQueryIndex extends QueryQuery {
2238
2231
  let resultIndex = 1;
2239
2232
  const groupIndex = resultStruct.groupSet;
2240
2233
  this.maxGroupSet = groupIndex;
2241
- // if no fields were specified, look in the parent struct for strings.
2242
- let fieldNames = this.firstSegment.fields || [];
2243
- if (fieldNames.length === 0) {
2244
- fieldNames.push("**");
2245
- }
2246
- fieldNames = this.expandWildCards(fieldNames, (qf) => ["string", "number", "timestamp", "date"].indexOf(qf.fieldDef.type) !==
2247
- -1);
2234
+ const fieldNames = this.firstSegment.fields || [];
2248
2235
  for (const f of fieldNames) {
2249
2236
  const { as, field } = this.expandField(f);
2250
2237
  resultStruct.addField(as, field, {
@@ -2343,6 +2330,110 @@ class QueryQueryIndex extends QueryQuery {
2343
2330
  FROM ${resultStage}\n`);
2344
2331
  return this.resultStage;
2345
2332
  }
2333
+ }
2334
+ class QueryQueryIndex extends QueryQuery {
2335
+ constructor(fieldDef, parent, stageWriter) {
2336
+ super(fieldDef, parent, stageWriter);
2337
+ this.rootFields = [];
2338
+ this.fanPrefixMap = {};
2339
+ this.fieldDef = fieldDef;
2340
+ this.findFanPrefexes(parent);
2341
+ }
2342
+ // we want to generate a different query for each
2343
+ // nested structure so we don't do a crazy cross product.
2344
+ findFanPrefexes(qs) {
2345
+ for (const [_name, f] of qs.nameMap) {
2346
+ if (f instanceof QueryStruct &&
2347
+ (f.fieldDef.structRelationship.type === "many" ||
2348
+ f.fieldDef.structRelationship.type === "nested") &&
2349
+ f.fieldDef.fields.length > 1 && // leave arrays in parent.
2350
+ this.parent.dialect.dontUnionIndex === false) {
2351
+ this.fanPrefixMap[f.getFullOutputName()] = [];
2352
+ this.findFanPrefexes(f);
2353
+ }
2354
+ }
2355
+ }
2356
+ expandIndexWildCards() {
2357
+ // if no fields were specified, look in the parent struct for strings.
2358
+ let fieldNames = this.firstSegment.fields || [];
2359
+ if (fieldNames.length === 0) {
2360
+ fieldNames.push("**");
2361
+ }
2362
+ fieldNames = this.expandWildCards(fieldNames, (qf) => ["string", "number", "timestamp", "date"].indexOf(qf.fieldDef.type) !==
2363
+ -1);
2364
+ return fieldNames;
2365
+ }
2366
+ // return the number of stages it is going to take to generate this index.
2367
+ getStageFields() {
2368
+ const s = [];
2369
+ if (this.rootFields.length > 0) {
2370
+ s.push(this.rootFields);
2371
+ }
2372
+ for (const fieldList of Object.values(this.fanPrefixMap)) {
2373
+ if (fieldList.length > 0) {
2374
+ s.push(fieldList);
2375
+ }
2376
+ }
2377
+ return s;
2378
+ }
2379
+ // Map fields into stages based on their level of repeated nesting
2380
+ //
2381
+ mapFieldsIntoStages(fieldNames) {
2382
+ // find all the fanned prefixes, longest ones first.
2383
+ const fannedPrefixes = Object.keys(this.fanPrefixMap).sort((k1, k2) => {
2384
+ if (k1.length < k2.length) {
2385
+ return 1;
2386
+ }
2387
+ if (k1.length > k2.length) {
2388
+ return -1;
2389
+ }
2390
+ return 0;
2391
+ });
2392
+ // Find the deepest fanned prefix
2393
+ for (const fn of fieldNames) {
2394
+ let found = false;
2395
+ for (const prefix of fannedPrefixes) {
2396
+ if (fn.startsWith(prefix)) {
2397
+ this.fanPrefixMap[prefix].push(fn);
2398
+ found = true;
2399
+ }
2400
+ }
2401
+ if (!found) {
2402
+ this.rootFields.push(fn);
2403
+ }
2404
+ }
2405
+ }
2406
+ expandFields(_resultStruct) {
2407
+ const fieldNames = this.expandIndexWildCards();
2408
+ this.mapFieldsIntoStages(fieldNames);
2409
+ }
2410
+ generateSQL(stageWriter) {
2411
+ const stages = this.getStageFields();
2412
+ const outputStageNames = [];
2413
+ for (const fields of stages) {
2414
+ const q = new QueryQueryIndexStage({
2415
+ ...this.fieldDef,
2416
+ pipeline: [
2417
+ {
2418
+ ...this.fieldDef.pipeline[0],
2419
+ fields: fields,
2420
+ },
2421
+ ],
2422
+ }, this.parent, stageWriter);
2423
+ q.prepare(stageWriter);
2424
+ const lastStageName = q.generateSQL(stageWriter);
2425
+ outputStageNames.push(lastStageName);
2426
+ }
2427
+ if (outputStageNames.length === 1) {
2428
+ this.resultStage = outputStageNames[0];
2429
+ }
2430
+ else {
2431
+ this.resultStage = stageWriter.addStage(outputStageNames
2432
+ .map((n) => `SELECT * FROM ${n}\n`)
2433
+ .join(" UNION ALL \n"));
2434
+ }
2435
+ return this.resultStage;
2436
+ }
2346
2437
  /** All Indexes have the same output schema */
2347
2438
  getResultStructDef() {
2348
2439
  return {
@@ -2499,7 +2590,7 @@ class QueryStruct extends QueryNode {
2499
2590
  }
2500
2591
  // if this is an inline object, include the parents alias.
2501
2592
  if (this.fieldDef.structRelationship.type === "inline" && this.parent) {
2502
- return this.parent.getIdentifier() + "." + super.getIdentifier();
2593
+ return this.parent.getSQLIdentifier() + "." + super.getIdentifier();
2503
2594
  }
2504
2595
  // we are somewhere in the join tree. Make sure the alias is unique.
2505
2596
  return this.getAliasIdentifier();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.15",
3
+ "version": "0.0.16-dev221214152428",
4
4
  "license": "GPL-2.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",