@malloydata/malloy-tests 0.0.298 → 0.0.300

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.
@@ -22,28 +22,21 @@
22
22
  */
23
23
 
24
24
  import {test} from '@jest/globals';
25
- import * as malloy from '@malloydata/malloy';
26
- import type {Query} from '@malloydata/malloy';
25
+ import type * as malloy from '@malloydata/malloy';
27
26
  import {testModel} from '../../models/faa_model';
28
27
  import type {BigQueryTestConnection} from '../../runtimes';
29
28
  import {RuntimeList} from '../../runtimes';
30
- import {describeIfDatabaseAvailable, fStringEq, fToQF} from '../../util';
29
+ import {describeIfDatabaseAvailable} from '../../util';
31
30
  import '../../util/db-jest-matchers';
32
31
 
33
- const runtimeList = new RuntimeList(['bigquery']);
34
- const runtime = runtimeList.runtimeMap.get('bigquery');
32
+ const bigquery = 'bigquery';
33
+ const runtimeList = new RuntimeList([bigquery]);
34
+ const runtime = runtimeList.runtimeMap.get(bigquery);
35
35
  if (runtime === undefined) {
36
36
  throw new Error('BigQuery runtime not found');
37
37
  }
38
38
  const bq = runtime.connection as BigQueryTestConnection;
39
39
 
40
- function compileQueryFromQueryDef(
41
- model: malloy.ModelMaterializer,
42
- query: Query
43
- ) {
44
- return model._loadQueryFromQueryDef(query).getSQL();
45
- }
46
-
47
40
  async function compileQuery(model: malloy.ModelMaterializer, query: string) {
48
41
  return await model.loadQuery(query).getSQL();
49
42
  }
@@ -57,10 +50,10 @@ async function bqCompile(sql: string): Promise<boolean> {
57
50
  return true;
58
51
  }
59
52
 
60
- const [describe] = describeIfDatabaseAvailable(['bigquery']);
53
+ const [describe] = describeIfDatabaseAvailable([bigquery]);
61
54
 
62
55
  describe('BigQuery expression tests', () => {
63
- const faa = runtime._loadModelFromModelDef(testModel);
56
+ const faa = runtime.loadModel(testModel);
64
57
 
65
58
  // EXPLORE flights
66
59
  // ->{
@@ -75,170 +68,101 @@ describe('BigQuery expression tests', () => {
75
68
  // routes.route_flights,
76
69
  // flight_count / routes.route_flights as percent_of_carrier_flights
77
70
  it('turtle_requery', async () => {
78
- const sql = await compileQueryFromQueryDef(faa, {
79
- structRef: 'flights',
80
- pipeline: [
81
- // top 5 routes per carrier
82
- {
83
- type: 'reduce',
84
- queryFields: fToQF([
85
- 'carrier',
86
- 'flight_count',
87
- {
88
- type: 'turtle',
89
- name: 'routes',
90
- pipeline: [
91
- {
92
- type: 'reduce',
93
- queryFields: fToQF([
94
- 'origin_code',
95
- 'destination_code',
96
- 'flight_count',
97
- {
98
- type: 'number',
99
- name: 'route_flights',
100
- expressionType: 'aggregate',
101
- e: {node: 'aggregate', function: 'count', e: {node: ''}},
102
- },
103
- ]),
104
- },
105
- ],
106
- },
107
- ]),
108
- limit: 5,
109
- orderBy: [{dir: 'desc', field: 'carrier'}],
110
- },
111
- // carrier top routes
112
- {
113
- type: 'project',
114
- queryFields: fToQF([
115
- 'carrier',
116
- 'flight_count',
117
- 'routes.origin_code',
118
- 'routes.route_flights',
119
- ]),
120
- },
121
- ],
122
- });
123
- await bqCompile(sql);
71
+ const sql = await compileQuery(
72
+ faa,
73
+ `
74
+ run: flights -> {
75
+ group_by: carrier
76
+ aggregate: flight_count
77
+ nest: routes is {
78
+ group_by:
79
+ origin_code
80
+ destination_code
81
+ aggregate: flight_count
82
+ aggregate: route_flights is count()
83
+ }
84
+ limit: 5
85
+ order_by: carrier desc
86
+ } -> {
87
+ select:
88
+ carrier
89
+ flight_count
90
+ routes.origin_code
91
+ routes.route_flights
92
+ }
93
+ `
94
+ );
95
+ bqCompile(sql);
124
96
  });
125
97
 
126
98
  it('step_0', async () => {
127
- const sql = await compileQueryFromQueryDef(faa, {
128
- structRef: 'flights',
129
- pipeline: [
130
- {type: 'reduce', queryFields: fToQF(['carriers.name', 'flight_count'])},
131
- ],
132
- });
99
+ const sql = await compileQuery(
100
+ faa,
101
+ `
102
+ run: flights -> {
103
+ group_by: carriers.name
104
+ aggregate: flight_count
105
+ }
106
+ `
107
+ );
133
108
  await bqCompile(sql);
134
109
  });
135
110
 
136
111
  it('filtered_measures', async () => {
137
- const sql = await compileQueryFromQueryDef(faa, {
138
- structRef: 'flights',
139
- filterList: [
140
- fStringEq('origin.state', 'CA'),
141
- fStringEq('destination.state', 'NY'),
142
- ],
143
- pipeline: [
144
- {type: 'reduce', queryFields: fToQF(['carriers.name', 'flight_count'])},
145
- ],
146
- });
112
+ const sql = await compileQuery(
113
+ faa,
114
+ `
115
+ run: flights -> {
116
+ // TODO previously this filter list was just on the QUERY
117
+ // which can't even have a filter list; I assume it's meant that
118
+ // these should be applied to the aggregate...
119
+ where: origin.state = 'CA'
120
+ where: destination.state = 'NY'
121
+ group_by: carriers.name
122
+ aggregate: flight_count
123
+ }
124
+ `
125
+ );
147
126
  await bqCompile(sql);
148
127
  });
149
128
 
150
129
  it('timestamp', async () => {
151
- const sql = await compileQueryFromQueryDef(faa, {
152
- structRef: 'flights',
153
- pipeline: [
154
- {
155
- queryFields: [
156
- {
157
- as: 'dep_year',
158
- name: 'dep_time',
159
- timeframe: 'year',
160
- type: 'timestamp',
161
- },
162
- {
163
- as: 'dep_month',
164
- name: 'dep_time',
165
- timeframe: 'month',
166
- type: 'timestamp',
167
- },
168
- {
169
- as: 'dep_week',
170
- name: 'dep_time',
171
- timeframe: 'week',
172
- type: 'timestamp',
173
- },
174
- {
175
- as: 'dep_date',
176
- name: 'dep_time',
177
- timeframe: 'day',
178
- type: 'timestamp',
179
- },
180
- {
181
- as: 'dep_hour',
182
- name: 'dep_time',
183
- timeframe: 'hour',
184
- type: 'timestamp',
185
- },
186
- {
187
- as: 'dep_minute',
188
- name: 'dep_time',
189
- timeframe: 'minute',
190
- type: 'timestamp',
191
- },
192
- {
193
- as: 'dep_second',
194
- name: 'dep_time',
195
- timeframe: 'second',
196
- type: 'timestamp',
197
- },
198
- {
199
- type: 'number',
200
- name: 'total_distance_ca',
201
- expressionType: 'aggregate',
202
- e: {
203
- node: 'filteredExpr',
204
- kids: {
205
- filterList: [fStringEq('origin.state', 'CA')],
206
- e: {
207
- node: 'aggregate',
208
- function: 'sum',
209
- e: {node: 'field', path: ['distance']},
210
- },
211
- },
212
- },
213
- },
214
- ],
215
- limit: 20,
216
- type: 'reduce',
217
- },
218
- ],
219
- });
130
+ const sql = await compileQuery(
131
+ faa,
132
+ `
133
+ run: flights -> {
134
+ group_by:
135
+ dep_year is dep_time.year
136
+ dep_month is dep_time.month
137
+ dep_week is dep_time.week
138
+ dep_date is dep_time.day
139
+ dep_hour is dep_time.hour
140
+ dep_minute is dep_time.minute
141
+ dep_second is dep_time.second
142
+ aggregate: total_distance_ca is distance.sum() {
143
+ where: origin.state = 'CA'
144
+ }
145
+ limit: 20
146
+ }
147
+ `
148
+ );
220
149
  await bqCompile(sql);
221
150
  });
222
151
 
223
152
  it('bucket_test', async () => {
224
- const sql = await compileQueryFromQueryDef(faa, {
225
- pipeline: [
226
- {
227
- queryFields: fToQF([
228
- {
229
- bucketFilter: 'AA,WN,DL',
230
- bucketOther: 'Other Carrier',
231
- name: 'carrier',
232
- type: 'string',
233
- },
234
- 'flight_count',
235
- ]),
236
- orderBy: [{dir: 'asc', field: 2}],
237
- type: 'reduce',
238
- },
239
- ],
240
- structRef: 'flights',
241
- });
153
+ const sql = await compileQuery(
154
+ faa,
155
+ // TODO bucketFilter and bucketOther don't actually exist...
156
+ // bucketFilter: 'AA,WN,DL',
157
+ // bucketOther: 'Other Carrier',
158
+ `
159
+ run: flights -> {
160
+ group_by: carrier
161
+ aggregate: flight_count
162
+ order_by: 2 asc
163
+ }
164
+ `
165
+ );
242
166
  await bqCompile(sql);
243
167
  });
244
168
 
@@ -248,150 +172,81 @@ describe('BigQuery expression tests', () => {
248
172
  });
249
173
 
250
174
  it('simple_reduce', async () => {
251
- const sql = await compileQueryFromQueryDef(faa, {
252
- structRef: 'flights',
253
- pipeline: [
254
- {type: 'reduce', queryFields: fToQF(['carrier', 'flight_count'])},
255
- ],
256
- });
175
+ const sql = await compileQuery(
176
+ faa,
177
+ 'run: flights -> { group_by: carrier; aggregate: flight_count }'
178
+ );
257
179
  await bqCompile(sql);
258
180
  });
259
181
 
260
182
  it('two_sums', async () => {
261
- const sql = await compileQueryFromQueryDef(faa, {
262
- structRef: 'flights',
263
- pipeline: [
264
- {
265
- type: 'reduce',
266
- queryFields: fToQF([
267
- {
268
- type: 'number',
269
- expressionType: 'aggregate',
270
- name: 'total_distance',
271
- e: {
272
- node: 'aggregate',
273
- function: 'sum',
274
- e: {node: 'field', path: ['distance']},
275
- },
276
- },
277
- 'aircraft.aircraft_models.total_seats',
278
- ]),
279
- },
280
- ],
281
- });
183
+ const sql = await compileQuery(
184
+ faa,
185
+ `
186
+ run: flights -> {
187
+ aggregate: aircraft.aircraft_models.total_seats
188
+ aggregate: total_distance is distance.sum()
189
+ }
190
+ `
191
+ );
282
192
  await bqCompile(sql);
283
193
  });
284
194
 
285
195
  it('first_fragment', async () => {
286
- const sql = await compileQueryFromQueryDef(faa, {
287
- structRef: 'flights',
288
- pipeline: [
289
- {
290
- type: 'reduce',
291
- queryFields: fToQF([
292
- {
293
- type: 'string',
294
- name: 'carrier',
295
- e: malloy.composeSQLExpr([
296
- 'UPPER(',
297
- {node: 'field', path: ['carriers', 'nickname']},
298
- ')',
299
- ]),
300
- },
301
- 'flight_count',
302
- ]),
303
- },
304
- ],
305
- });
196
+ const sql = await compileQuery(
197
+ faa,
198
+ `
199
+ run: flights -> {
200
+ group_by: carrier is upper(carriers.nickname)
201
+ aggregate: flight_count
202
+ }
203
+ `
204
+ );
306
205
  await bqCompile(sql);
307
206
  });
308
207
 
309
208
  it('sum_in_expr', async () => {
310
- const sql = await compileQueryFromQueryDef(faa, {
311
- structRef: 'flights',
312
- pipeline: [
313
- {
314
- queryFields: fToQF([
315
- 'carriers.name',
316
- {
317
- type: 'number',
318
- expressionType: 'aggregate',
319
- name: 'total_distance',
320
- e: {
321
- node: 'aggregate',
322
- function: 'sum',
323
- e: {node: 'field', path: ['distance']},
324
- },
325
- },
326
- ]),
327
- type: 'reduce',
328
- },
329
- ],
330
- });
209
+ const sql = await compileQuery(
210
+ faa,
211
+ `
212
+ run: flights -> {
213
+ group_by: carriers.name
214
+ aggregate: total_distance is distance.sum()
215
+ }
216
+ `
217
+ );
331
218
  await bqCompile(sql);
332
219
  });
333
220
 
334
221
  it('filtered_sum_in_expr', async () => {
335
- const sql = await compileQueryFromQueryDef(faa, {
336
- structRef: 'flights',
337
- pipeline: [
338
- {
339
- type: 'reduce',
340
- queryFields: fToQF([
341
- 'aircraft.aircraft_models.manufacturer',
342
- {
343
- type: 'number',
344
- expressionType: 'aggregate',
345
- name: 'total_distance',
346
- e: {
347
- node: 'filteredExpr',
348
- kids: {
349
- filterList: [fStringEq('origin_code', 'SFO')],
350
- e: {
351
- node: 'aggregate',
352
- function: 'sum',
353
- e: {node: 'field', path: ['distance']},
354
- },
355
- },
356
- },
357
- },
358
- ]),
359
- },
360
- ],
361
- });
222
+ const sql = await compileQuery(
223
+ faa,
224
+ `
225
+ run: flights -> {
226
+ group_by: aircraft.aircraft_models.manufacturer
227
+ aggregate: total_distance is distance.sum() {
228
+ where: origin_code = 'SFO'
229
+ }
230
+ }
231
+ `
232
+ );
362
233
  await bqCompile(sql);
363
234
  });
364
235
 
365
236
  it('dynamic_measure', async () => {
366
- const sql = await compileQueryFromQueryDef(faa, {
367
- structRef: 'flights',
368
- pipeline: [
369
- {
370
- type: 'reduce',
371
- queryFields: fToQF([
372
- 'origin.state',
373
- 'flight_count',
374
- {
375
- type: 'number',
376
- expressionType: 'aggregate',
377
- name: 'total_distance',
378
- e: {
379
- node: 'filteredExpr',
380
- kids: {
381
- filterList: [fStringEq('origin_code', 'SFO')],
382
- e: {
383
- node: 'aggregate',
384
- function: 'sum',
385
- e: {node: 'field', path: ['distance']},
386
- },
387
- },
388
- },
389
- },
390
- ]),
391
- filterList: [fStringEq('carriers.code', 'WN')],
392
- },
393
- ],
394
- });
237
+ const sql = await compileQuery(
238
+ faa,
239
+ `
240
+ run: flights -> {
241
+ where: carriers.code = 'WN'
242
+ group_by: origin.state
243
+ aggregate: flight_count
244
+ aggregate: total_distance is distance.sum() {
245
+ where: origin_code = 'SFO'
246
+ }
247
+ }
248
+ `
249
+ );
395
250
  await bqCompile(sql);
396
251
  });
397
252
 
@@ -442,22 +297,20 @@ describe('BigQuery expression tests', () => {
442
297
  });
443
298
 
444
299
  it('lotsoturtles', async () => {
445
- const sql = await compileQueryFromQueryDef(faa, {
446
- structRef: 'flights',
447
- pipeline: [
448
- {
449
- queryFields: fToQF([
450
- 'origin.state',
451
- 'flight_count',
452
- 'flights_by_model',
453
- 'flights_by_carrier',
454
- 'measures_first',
455
- 'first_turtle',
456
- ]),
457
- type: 'reduce',
458
- },
459
- ],
460
- });
300
+ const sql = await compileQuery(
301
+ faa,
302
+ `
303
+ run: flights -> {
304
+ group_by: origin.state
305
+ aggregate: flight_count
306
+ nest:
307
+ flights_by_model
308
+ flights_by_carrier
309
+ measures_first
310
+ first_turtle
311
+ }
312
+ `
313
+ );
461
314
  await bqCompile(sql);
462
315
  });
463
316
 
@@ -576,19 +429,14 @@ describe('BigQuery expression tests', () => {
576
429
  });
577
430
 
578
431
  it('table_base_on_query', async () => {
579
- const result = await faa
580
- ._loadQueryFromQueryDef({
581
- structRef: 'medicare_state_facts',
582
- pipeline: [
583
- {
584
- type: 'reduce',
585
- queryFields: fToQF(['provider_state', 'num_providers']),
586
- orderBy: [{dir: 'desc', field: 2}],
587
- },
588
- ],
589
- })
590
- .run();
591
- expect(result.data.value[0]['num_providers']).toBe(296);
432
+ expect(`
433
+ run: medicare_state_facts -> {
434
+ group_by:
435
+ provider_state
436
+ num_providers
437
+ order_by: 2 desc
438
+ }
439
+ `).malloyResultMatches(faa, {num_providers: 296});
592
440
  });
593
441
  });
594
442
 
@@ -820,7 +668,7 @@ describe('airport_tests', () => {
820
668
  });
821
669
 
822
670
  describe('sql injection tests', () => {
823
- const model = runtime._loadModelFromModelDef(testModel);
671
+ const model = runtime.loadModel(testModel);
824
672
  jest.setTimeout(100000);
825
673
 
826
674
  test('string literal escapes quotes', async () => {