@malloydata/malloy-tests 0.0.68-dev230808000650 → 0.0.68

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.
Files changed (81) hide show
  1. package/dist/databases/all/db_index.spec.d.ts +1 -0
  2. package/dist/databases/all/db_index.spec.js +36 -0
  3. package/dist/databases/all/db_index.spec.js.map +1 -0
  4. package/dist/databases/all/expr.spec.d.ts +0 -2
  5. package/dist/databases/all/expr.spec.js +2 -547
  6. package/dist/databases/all/expr.spec.js.map +1 -1
  7. package/dist/databases/all/functions.spec.d.ts +1 -2
  8. package/dist/databases/all/functions.spec.js +2 -751
  9. package/dist/databases/all/functions.spec.js.map +1 -1
  10. package/dist/databases/all/join.spec.d.ts +1 -2
  11. package/dist/databases/all/join.spec.js +2 -276
  12. package/dist/databases/all/join.spec.js.map +1 -1
  13. package/dist/databases/all/nomodel.spec.d.ts +1 -2
  14. package/dist/databases/all/nomodel.spec.js +2 -923
  15. package/dist/databases/all/nomodel.spec.js.map +1 -1
  16. package/dist/databases/all/orderby.spec.d.ts +1 -2
  17. package/dist/databases/all/orderby.spec.js +2 -191
  18. package/dist/databases/all/orderby.spec.js.map +1 -1
  19. package/dist/databases/all/problems.spec.d.ts +1 -2
  20. package/dist/databases/all/problems.spec.js +2 -80
  21. package/dist/databases/all/problems.spec.js.map +1 -1
  22. package/dist/databases/all/sql_expressions.spec.d.ts +1 -2
  23. package/dist/databases/all/sql_expressions.spec.js +2 -62
  24. package/dist/databases/all/sql_expressions.spec.js.map +1 -1
  25. package/dist/databases/all/time.spec.d.ts +1 -3
  26. package/dist/databases/all/time.spec.js +2 -615
  27. package/dist/databases/all/time.spec.js.map +1 -1
  28. package/dist/databases/{all/index.spec.d.ts → shared/db_index.d.ts} +1 -0
  29. package/dist/databases/{all/index.spec.js → shared/db_index.js} +2 -33
  30. package/dist/databases/shared/db_index.js.map +1 -0
  31. package/dist/databases/shared/expr.d.ts +3 -0
  32. package/dist/databases/shared/expr.js +551 -0
  33. package/dist/databases/shared/expr.js.map +1 -0
  34. package/dist/databases/shared/functions.d.ts +3 -0
  35. package/dist/databases/shared/functions.js +754 -0
  36. package/dist/databases/shared/functions.js.map +1 -0
  37. package/dist/databases/shared/join.d.ts +3 -0
  38. package/dist/databases/shared/join.js +302 -0
  39. package/dist/databases/shared/join.js.map +1 -0
  40. package/dist/databases/shared/nomodel.d.ts +3 -0
  41. package/dist/databases/shared/nomodel.js +950 -0
  42. package/dist/databases/shared/nomodel.js.map +1 -0
  43. package/dist/databases/shared/orderby.d.ts +3 -0
  44. package/dist/databases/shared/orderby.js +217 -0
  45. package/dist/databases/shared/orderby.js.map +1 -0
  46. package/dist/databases/shared/problems.d.ts +3 -0
  47. package/dist/databases/shared/problems.js +106 -0
  48. package/dist/databases/shared/problems.js.map +1 -0
  49. package/dist/databases/shared/sql_expressions.d.ts +3 -0
  50. package/dist/databases/shared/sql_expressions.js +88 -0
  51. package/dist/databases/shared/sql_expressions.js.map +1 -0
  52. package/dist/databases/shared/test_list.js +18 -18
  53. package/dist/databases/shared/test_list.js.map +1 -1
  54. package/dist/databases/shared/time.d.ts +3 -0
  55. package/dist/databases/shared/time.js +640 -0
  56. package/dist/databases/shared/time.js.map +1 -0
  57. package/dist/index.d.ts +9 -10
  58. package/dist/index.js +19 -21
  59. package/dist/index.js.map +1 -1
  60. package/package.json +6 -6
  61. package/src/databases/all/db_index.spec.ts +37 -0
  62. package/src/databases/all/expr.spec.ts +2 -670
  63. package/src/databases/all/functions.spec.ts +1 -1101
  64. package/src/databases/all/join.spec.ts +1 -315
  65. package/src/databases/all/nomodel.spec.ts +2 -1124
  66. package/src/databases/all/orderby.spec.ts +1 -234
  67. package/src/databases/all/problems.spec.ts +1 -87
  68. package/src/databases/all/sql_expressions.spec.ts +1 -71
  69. package/src/databases/all/time.spec.ts +1 -761
  70. package/src/databases/{all/index.spec.ts → shared/db_index.ts} +2 -13
  71. package/src/databases/shared/expr.ts +695 -0
  72. package/src/databases/shared/functions.ts +1126 -0
  73. package/src/databases/shared/join.ts +340 -0
  74. package/src/databases/shared/nomodel.ts +1150 -0
  75. package/src/databases/shared/orderby.ts +260 -0
  76. package/src/databases/shared/problems.ts +113 -0
  77. package/src/databases/shared/sql_expressions.ts +96 -0
  78. package/src/databases/shared/test_list.ts +9 -9
  79. package/src/databases/shared/time.ts +786 -0
  80. package/src/index.ts +10 -11
  81. package/dist/databases/all/index.spec.js.map +0 -1
@@ -25,1130 +25,8 @@
25
25
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
26
 
27
27
  import {RuntimeList, allDatabases} from '../../runtimes';
28
- import {databasesFromEnvironmentOr, testIf} from '../../util';
29
-
30
- // No prebuilt shared model, each test is complete. Makes debugging easier.
31
- export const noModelSharedTests = (
32
- runtimes: RuntimeList,
33
- splitFunction?: (column: string, splitChar: string) => string
34
- ) => {
35
- function rootDbPath(databaseName: string) {
36
- return databaseName === 'bigquery' ? 'malloy-data.' : '';
37
- }
38
-
39
- // TODO: Figure out how to generalize this.
40
- function getSplitFunction(db: string) {
41
- return (
42
- splitFunction ??
43
- {
44
- 'bigquery': (column: string, splitChar: string) =>
45
- `split(${column}, '${splitChar}')`,
46
- 'postgres': (column: string, splitChar: string) =>
47
- `string_to_array(${column}, '${splitChar}')`,
48
- 'duckdb': (column: string, splitChar: string) =>
49
- `string_to_array(${column}, '${splitChar}')`,
50
- 'duckdb_wasm': (column: string, splitChar: string) =>
51
- `string_to_array(${column}, '${splitChar}')`,
52
- }[db]
53
- );
54
- }
55
-
56
- afterAll(async () => {
57
- await runtimes.closeAll();
58
- });
59
-
60
- runtimes.runtimeMap.forEach((runtime, databaseName) => {
61
- // Issue: #151
62
- it(`unknown dialect - ${databaseName}`, async () => {
63
- const result = await runtime
64
- .loadQuery(
65
- `
66
- query: q is table('malloytest.aircraft')->{
67
- where: state != null
68
- group_by: state
69
- }
70
-
71
- source: r is from(->q){
72
- query: foo is {
73
- order_by: 1 desc
74
- group_by: state
75
- }
76
- }
77
-
78
- query: r->foo
79
- `
80
- )
81
- .run();
82
- // console.log(result.data.toObject());
83
- expect(result.data.path(0, 'state').value).toBe('WY');
84
- });
85
-
86
- // Issue #149
87
- it(`refine query from query - ${databaseName}`, async () => {
88
- const result = await runtime
89
- .loadQuery(
90
- `
91
- query: from(
92
- table('malloytest.state_facts')->{group_by: state; order_by: 1 desc; limit: 1}
93
- )
94
- {
95
- dimension: lower_state is lower(state)
96
- }
97
- -> {project: lower_state}
98
- `
99
- )
100
- .run();
101
- // console.log(result.data.toObject());
102
- expect(result.data.path(0, 'lower_state').value).toBe('wy');
103
- });
104
-
105
- // issue #157
106
- it(`source- not -found - ${databaseName}`, async () => {
107
- // console.log(result.data.toObject());
108
- let error;
109
- try {
110
- await runtime
111
- .loadQuery(
112
- `
113
- source: foo is table('malloytest.state_facts'){primary_key: state}
114
- query: foox->{aggregate: c is count()}
115
- `
116
- )
117
- .run();
118
- } catch (e) {
119
- error = e;
120
- }
121
- expect(error.toString()).not.toContain('Unknown Dialect');
122
- });
123
-
124
- it(`join_many - ${databaseName}`, async () => {
125
- const result = await runtime
126
- .loadQuery(
127
- `
128
- source: a is table('malloytest.aircraft'){
129
- measure: avg_year is floor(avg(year_built))
130
- }
131
- source: m is table('malloytest.aircraft_models'){
132
- join_many: a on a.aircraft_model_code=aircraft_model_code
133
- measure: avg_seats is floor(avg(seats))
134
- }
135
- query: m->{aggregate: avg_seats, a.avg_year}
136
- `
137
- )
138
- .run();
139
- expect(result.data.value[0]['avg_year']).toBe(1969);
140
- expect(result.data.value[0]['avg_seats']).toBe(7);
141
- });
142
-
143
- it(`join_many condition no primary key - ${databaseName}`, async () => {
144
- const result = await runtime
145
- .loadQuery(
146
- `
147
- source: a is table('malloytest.airports'){}
148
- source: b is table('malloytest.state_facts') {
149
- join_many: a on state=a.state
150
- }
151
- query: b->{aggregate: c is airport_count.sum()}
152
- `
153
- )
154
- .run();
155
- expect(result.data.value[0]['c']).toBe(19701);
156
- });
157
-
158
- it(`join_many filter multiple values - ${databaseName}`, async () => {
159
- const result = await runtime
160
- .loadQuery(
161
- `
162
- source: a is table('malloytest.airports'){
163
- where: state = 'NH' | 'CA'
164
- }
165
- source: b is table('malloytest.state_facts') {
166
- join_many: a on state=a.state
167
- }
168
- query: b->{
169
- aggregate: c is airport_count.sum()
170
- group_by: a.state
171
- }
172
- `
173
- )
174
- .run();
175
- expect(result.data.value[0]['c']).toBe(18605);
176
- expect(result.data.value[0]['state']).toBeNull();
177
- expect(result.data.value[1]['c']).toBe(984);
178
- expect(result.data.value[1]['state']).toBe('CA');
179
- expect(result.data.value[2]['c']).toBe(112);
180
- expect(result.data.value[2]['state']).toBe('NH');
181
- });
182
-
183
- it(`join_one condition no primary key - ${databaseName}`, async () => {
184
- const result = await runtime
185
- .loadQuery(
186
- `
187
- source: a is table('malloytest.state_facts'){}
188
- source: b is table('malloytest.airports') {
189
- join_one: a on state=a.state
190
- }
191
- query: b->{aggregate: c is a.airport_count.sum()}
192
-
193
- `
194
- )
195
- .run();
196
- expect(result.data.value[0]['c']).toBe(19701);
197
- });
198
-
199
- it(`join_one filter multiple values - ${databaseName}`, async () => {
200
- const result = await runtime
201
- .loadQuery(
202
- `
203
- source: a is table('malloytest.state_facts'){
204
- where: state = 'TX' | 'LA'
205
- }
206
- source: b is table('malloytest.airports') {
207
- join_one: a on state=a.state
208
- }
209
- query: b->{
210
- aggregate: c is a.airport_count.sum()
211
- group_by: a.state
212
- }
213
- `
214
- )
215
- .run();
216
- // https://github.com/malloydata/malloy/pull/501#discussion_r861022857
217
- expect(result.data.value).toHaveLength(3);
218
- expect(result.data.value).toContainEqual({c: 1845, state: 'TX'});
219
- expect(result.data.value).toContainEqual({c: 500, state: 'LA'});
220
- expect(result.data.value).toContainEqual({c: 0, state: null});
221
- });
222
-
223
- it(`join_many cross from - ${databaseName}`, async () => {
224
- // a cross join produces a Many to Many result.
225
- // symmetric aggregate are needed on both sides of the join
226
- // Check the row count and that sums on each side work properly.
227
- const result = await runtime
228
- .loadQuery(
229
- `
230
- source: a is table('malloytest.state_facts')
231
- source: f is a{
232
- join_cross: a
233
- }
234
- query: f->{
235
- aggregate:
236
- row_count is count(distinct concat(state,a.state))
237
- left_count is count()
238
- right_count is a.count()
239
- left_sum is airport_count.sum()
240
- right_sum is a.airport_count.sum()
241
- }
242
- `
243
- )
244
- .run();
245
- expect(result.data.value[0]['row_count']).toBe(51 * 51);
246
- expect(result.data.value[0]['left_sum']).toBe(19701);
247
- expect(result.data.value[0]['right_sum']).toBe(19701);
248
- });
249
-
250
- it(`join_one only - ${databaseName}`, async () => {
251
- // a cross join produces a Many to Many result.
252
- // symmetric aggregate are needed on both sides of the join
253
- // Check the row count and that sums on each side work properly.
254
- const result = await runtime
255
- .loadQuery(
256
- `
257
- query: q is table('malloytest.state_facts')->{
258
- aggregate: r is airport_count.sum()
259
- }
260
- source: f is table('malloytest.state_facts'){
261
- join_one: a is from(->q)
262
- }
263
- query: f->{
264
- aggregate:
265
- row_count is count(distinct concat(state,a.r))
266
- left_sum is airport_count.sum()
267
- right_sum is a.r.sum()
268
- sum_sum is sum(airport_count + a.r)
269
- }
270
- `
271
- )
272
- .run();
273
- expect(result.data.value[0]['row_count']).toBe(51);
274
- expect(result.data.value[0]['left_sum']).toBe(19701);
275
- expect(result.data.value[0]['right_sum']).toBe(19701);
276
- expect(result.data.value[0]['sum_sum']).toBe(19701 + 51 * 19701);
277
- });
278
-
279
- it(`join_many cross ON - ${databaseName}`, async () => {
280
- // a cross join produces a Many to Many result.
281
- // symmetric aggregate are needed on both sides of the join
282
- // Check the row count and that sums on each side work properly.
283
- const result = await runtime
284
- .loadQuery(
285
- `
286
- source: a is table('malloytest.state_facts')
287
- source: f is a{
288
- join_cross: a on a.state = 'CA' | 'NY'
289
- }
290
- query: f->{
291
- aggregate:
292
- row_count is count(distinct concat(state,a.state))
293
- left_sum is airport_count.sum()
294
- right_sum is a.airport_count.sum()
295
- }
296
- `
297
- )
298
- .run();
299
- expect(result.data.value[0]['row_count']).toBe(51 * 2);
300
- expect(result.data.value[0]['left_sum']).toBe(19701);
301
- expect(result.data.value[0]['right_sum']).toBe(1560);
302
- });
303
-
304
- it(`limit - provided - ${databaseName}`, async () => {
305
- // a cross join produces a Many to Many result.
306
- // symmetric aggregate are needed on both sides of the join
307
- // Check the row count and that sums on each side work properly.
308
- const result = await runtime
309
- .loadQuery(
310
- `
311
- query: table('malloytest.state_facts') -> {
312
- group_by: state
313
- aggregate: c is count()
314
- limit: 3
315
- }
316
- `
317
- )
318
- .run();
319
- expect(result.resultExplore.limit).toBe(3);
320
- });
321
-
322
- testIf(runtime.supportsNesting)(
323
- `number as null- ${databaseName}`,
324
- async () => {
325
- // a cross join produces a Many to Many result.
326
- // symmetric aggregate are needed on both sides of the join
327
- // Check the row count and that sums on each side work properly.
328
- const result = await runtime
329
- .loadQuery(
330
- `
331
- source: s is table('malloytest.state_facts') + {
332
- }
333
- query: s-> {
334
- group_by: state
335
- nest: ugly is {
336
- group_by: popular_name
337
- aggregate: foo is NULLIF(sum(airport_count)*0,0)+1
338
- }
339
- }
340
- `
341
- )
342
- .run();
343
- expect(result.data.path(0, 'ugly', 0, 'foo').value).toBe(null);
344
- }
345
- );
346
-
347
- // average should only include non-null values in the denominator
348
- it(`avg ignore null- ${databaseName}`, async () => {
349
- const result = await runtime
350
- .loadQuery(
351
- `
352
- sql: one is { select: """
353
- SELECT 2 as a
354
- UNION ALL SELECT 4
355
- UNION ALL SELECT null
356
- """}
357
-
358
- query: from_sql(one) -> {
359
- join_cross: b is from_sql(one)
360
- aggregate:
361
- avg_a is a.avg()
362
- avg_b is b.a.avg()
363
- }
364
- `
365
- )
366
- .run();
367
- expect(result.data.value[0]['avg_a']).toBe(3);
368
- });
369
-
370
- it(`limit - not provided - ${databaseName}`, async () => {
371
- // a cross join produces a Many to Many result.
372
- // symmetric aggregate are needed on both sides of the join
373
- // Check the row count and that sums on each side work properly.
374
- const result = await runtime
375
- .loadQuery(
376
- `
377
- query: table('malloytest.state_facts') -> {
378
- group_by: state
379
- aggregate: c is count()
380
- }
381
- `
382
- )
383
- .run();
384
- expect(result.resultExplore.limit).toBe(undefined);
385
- });
386
-
387
- it(`limit pipeline - provided - ${databaseName}`, async () => {
388
- // a cross join produces a Many to Many result.
389
- // symmetric aggregate are needed on both sides of the join
390
- // Check the row count and that sums on each side work properly.
391
- const result = await runtime
392
- .loadQuery(
393
- `
394
- query: table('malloytest.state_facts') -> {
395
- project: state
396
- limit: 10
397
- }
398
- -> {
399
- project: state
400
- limit: 3
401
- }
402
- `
403
- )
404
- .run();
405
- expect(result.resultExplore.limit).toBe(3);
406
- });
407
-
408
- it(`ungrouped top level - ${databaseName}`, async () => {
409
- const result = await runtime
410
- .loadQuery(
411
- `
412
- source: s is table('malloytest.state_facts') + {
413
- measure: total_births is births.sum()
414
- measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
415
- }
416
-
417
- query:s-> {
418
- group_by: state
419
- aggregate: births_per_100k
420
- }
421
- `
422
- )
423
- .run();
424
- // console.log(result.sql);
425
- expect(result.data.path(0, 'births_per_100k').value).toBe(9742);
426
- });
427
-
428
- testIf(runtime.supportsNesting)(
429
- `ungrouped top level with nested - ${databaseName}`,
430
- async () => {
431
- const result = await runtime
432
- .loadQuery(
433
- `
434
- source: s is table('malloytest.state_facts') + {
435
- measure: total_births is births.sum()
436
- measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
437
- }
438
-
439
- query:s-> {
440
- group_by: state
441
- aggregate: births_per_100k
442
- nest: by_name is {
443
- group_by: popular_name
444
- aggregate: total_births
445
- }
446
- limit: 1000
447
- }
448
- `
449
- )
450
- .run();
451
- // console.log(result.sql);
452
- expect(result.data.path(0, 'births_per_100k').value).toBe(9742);
453
- }
454
- );
455
-
456
- it(`ungrouped - eliminate rows - ${databaseName}`, async () => {
457
- const result = await runtime
458
- .loadQuery(
459
- `
460
- source: s is table('malloytest.state_facts') + {
461
- measure: m is all(births.sum())
462
- where: state='CA' | 'NY'
463
- }
464
-
465
- query:s-> {
466
- group_by: state
467
- aggregate: m
468
- }
469
- `
470
- )
471
- .run();
472
- // console.log(result.sql);
473
- expect(result.data.toObject().length).toBe(2);
474
- });
475
-
476
- testIf(runtime.supportsNesting)(
477
- `ungrouped nested with no grouping above - ${databaseName}`,
478
- async () => {
479
- const result = await runtime
480
- .loadQuery(
481
- `
482
- source: s is table('malloytest.state_facts') + {
483
- measure: total_births is births.sum()
484
- measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
485
- }
486
-
487
- query: s-> {
488
- aggregate: total_births
489
- nest: by_name is {
490
- group_by: popular_name
491
- aggregate: births_per_100k
492
- }
493
- }
494
-
495
- `
496
- )
497
- .run();
498
- // console.log(result.sql);
499
- expect(result.data.path(0, 'by_name', 0, 'births_per_100k').value).toBe(
500
- 66703
501
- );
502
- }
503
- );
504
-
505
- testIf(runtime.supportsNesting)(
506
- `ungrouped - partial grouping - ${databaseName}`,
507
- async () => {
508
- const result = await runtime
509
- .loadQuery(
510
- `
511
- source: airports is table('malloytest.airports') {
512
- measure: c is count()
513
- }
514
-
515
-
516
- query: airports -> {
517
- where: state = 'TX' | 'NY'
518
- group_by:
519
- faa_region
520
- state
521
- aggregate:
522
- c
523
- all_ is all(c)
524
- airport_count is c {? fac_type = 'AIRPORT'}
525
- nest: fac_type is {
526
- group_by: fac_type
527
- aggregate:
528
- c
529
- all_ is all(c)
530
- all_state_region is exclude(c,fac_type)
531
- all_of_this_type is exclude(c, state, faa_region)
532
- all_top is exclude(c, state, faa_region, fac_type)
533
- }
534
- }
535
-
536
- `
537
- )
538
- .run();
539
- // console.log(result.sql);
540
- expect(result.data.path(0, 'fac_type', 0, 'all_').value).toBe(1845);
541
- expect(
542
- result.data.path(0, 'fac_type', 0, 'all_state_region').value
543
- ).toBe(1845);
544
- expect(
545
- result.data.path(0, 'fac_type', 0, 'all_of_this_type').value
546
- ).toBe(1782);
547
- expect(result.data.path(0, 'fac_type', 0, 'all_top').value).toBe(2421);
548
- }
549
- );
550
-
551
- testIf(runtime.supportsNesting)(
552
- `ungrouped - all nested - ${databaseName}`,
553
- async () => {
554
- const result = await runtime
555
- .loadQuery(
556
- `
557
- source: airports is table('malloytest.airports') {
558
- measure: c is count()
559
- }
560
-
561
-
562
- query: airports -> {
563
- where: state = 'TX' | 'NY'
564
- group_by:
565
- state
566
- aggregate:
567
- c
568
- all_ is all(c)
569
- airport_count is c {? fac_type = 'AIRPORT'}
570
- nest: fac_type is {
571
- group_by: fac_type, major
572
- aggregate:
573
- c
574
- all_ is all(c)
575
- all_major is all(c,major)
576
- }
577
- }
578
-
579
-
580
- `
581
- )
582
- .run();
583
- // console.log(result.sql);
584
- expect(result.data.path(0, 'fac_type', 0, 'all_').value).toBe(1845);
585
- expect(result.data.path(0, 'fac_type', 0, 'all_major').value).toBe(
586
- 1819
587
- );
588
- }
589
- );
590
-
591
- testIf(runtime.supportsNesting)(
592
- `ungrouped nested - ${databaseName}`,
593
- async () => {
594
- const result = await runtime
595
- .loadQuery(
596
- `
597
- source: s is table('malloytest.state_facts') + {
598
- measure: total_births is births.sum()
599
- measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
600
- }
601
-
602
- query:s -> {
603
- group_by: popular_name
604
- nest: by_state is {
605
- group_by: state
606
- aggregate: births_per_100k
607
- }
608
- }
609
-
610
- `
611
- )
612
- .run();
613
- // console.log(result.sql);
614
- expect(
615
- result.data.path(0, 'by_state', 0, 'births_per_100k').value
616
- ).toBe(36593);
617
- }
618
- );
619
-
620
- testIf(runtime.supportsNesting)(
621
- `ungrouped nested expression - ${databaseName}`,
622
- async () => {
623
- const result = await runtime
624
- .loadQuery(
625
- `
626
- source: s is table('malloytest.state_facts') + {
627
- measure: total_births is births.sum()
628
- measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
629
- }
630
-
631
- query:s -> {
632
- group_by: upper_name is upper(popular_name)
633
- nest: by_state is {
634
- group_by: state
635
- aggregate: births_per_100k
636
- }
637
- }
638
-
639
- `
640
- )
641
- .run();
642
- // console.log(result.sql);
643
- expect(
644
- result.data.path(0, 'by_state', 0, 'births_per_100k').value
645
- ).toBe(36593);
646
- }
647
- );
648
-
649
- testIf(runtime.supportsNesting)(
650
- `ungrouped nested group by float - ${databaseName}`,
651
- async () => {
652
- const result = await runtime
653
- .loadQuery(
654
- `
655
- source: s is table('malloytest.state_facts') + {
656
- measure: total_births is births.sum()
657
- measure: ug is all(total_births)
658
- }
659
-
660
- query:s -> {
661
- group_by: f is floor(airport_count/300.0)
662
- nest: by_state is {
663
- group_by: state
664
- aggregate: ug
665
- }
666
- }
667
-
668
- `
669
- )
670
- .run();
671
- // console.log(result.sql);
672
- // console.log(JSON.stringify(result.data.toObject(), null, 2));
673
- expect(result.data.path(0, 'by_state', 0, 'ug').value).toBe(62742230);
674
- }
675
- );
676
-
677
- it(`all with parameters - basic - ${databaseName}`, async () => {
678
- const result = await runtime
679
- .loadQuery(
680
- `
681
- source: s is table('malloytest.state_facts') + {
682
- measure: total_births is births.sum()
683
- }
684
-
685
- query: s -> {
686
- group_by: popular_name, state
687
- aggregate:
688
- total_births
689
- all_births is all(total_births)
690
- all_name is exclude(total_births, state)
691
- }
692
-
693
- `
694
- )
695
- .run();
696
- // console.log(result.sql);
697
- // console.log(JSON.stringify(result.data.toObject(), null, 2));
698
- expect(result.data.path(0, 'all_births').value).toBe(295727065);
699
- expect(result.data.path(0, 'all_name').value).toBe(197260594);
700
- });
701
-
702
- testIf(runtime.supportsNesting)(
703
- `all with parameters - nest - ${databaseName}`,
704
- async () => {
705
- const result = await runtime
706
- .loadQuery(
707
- `
708
- source: s is table('malloytest.state_facts') + {
709
- measure: total_births is births.sum()
710
- dimension: abc is floor(airport_count/300)
711
- }
712
-
713
- query: s -> {
714
- group_by: abc
715
- aggregate: total_births
716
- nest: by_stuff is {
717
- group_by: popular_name, state
718
- aggregate:
719
- total_births
720
- all_births is all(total_births)
721
- all_name is exclude(total_births, state)
722
- }
723
- }
724
-
725
- `
726
- )
727
- .run();
728
- // console.log(result.sql);
729
- // console.log(JSON.stringify(result.data.toObject(), null, 2));
730
- expect(result.data.path(0, 'by_stuff', 0, 'all_births').value).toBe(
731
- 119809719
732
- );
733
- expect(result.data.path(0, 'by_stuff', 0, 'all_name').value).toBe(
734
- 61091215
735
- );
736
- }
737
- );
738
-
739
- testIf(runtime.supportsNesting)(
740
- `single value to udf - ${databaseName}`,
741
- async () => {
742
- const result = await runtime
743
- .loadQuery(
744
- `
745
- source: f is table('malloytest.state_facts') {
746
- query: fun is {
747
- aggregate: t is count()
748
- }
749
- -> {
750
- project: t1 is t+1
751
- }
752
- }
753
- query: f-> {
754
- nest: fun
755
- }
756
- `
757
- )
758
- .run();
759
- // console.log(result.sql);
760
- expect(result.data.path(0, 'fun', 0, 't1').value).toBe(52);
761
- }
762
- );
763
-
764
- testIf(runtime.supportsNesting)(
765
- `Multi value to udf - ${databaseName}`,
766
- async () => {
767
- const result = await runtime
768
- .loadQuery(
769
- `
770
- source: f is table('malloytest.state_facts') {
771
- query: fun is {
772
- group_by: one is 1
773
- aggregate: t is count()
774
- }
775
- -> {
776
- project: t1 is t+1
777
- }
778
- }
779
- query: f-> {
780
- nest: fun
781
- }
782
- `
783
- )
784
- .run();
785
- // console.log(result.sql);
786
- // console.log(result.data.toObject());
787
- expect(result.data.path(0, 'fun', 0, 't1').value).toBe(52);
788
- }
789
- );
790
-
791
- testIf(runtime.supportsNesting)(
792
- `Multi value to udf group by - ${databaseName}`,
793
- async () => {
794
- const result = await runtime
795
- .loadQuery(
796
- `
797
- source: f is table('malloytest.state_facts') {
798
- query: fun is {
799
- group_by: one is 1
800
- aggregate: t is count()
801
- }
802
- -> {
803
- group_by: t1 is t+1
804
- }
805
- }
806
- query: f-> {
807
- nest: fun
808
- }
809
- `
810
- )
811
- .run();
812
- // console.log(result.sql);
813
- // console.log(result.data.toObject());
814
- expect(result.data.path(0, 'fun', 0, 't1').value).toBe(52);
815
- }
816
- );
817
-
818
- const sql1234 = `
819
- sql: one is {select: """
820
- SELECT 1 as a, 2 as b
821
- UNION ALL SELECT 3, 4
822
- """}`;
823
-
824
- it(`sql_block - ${databaseName}`, async () => {
825
- const result = await runtime
826
- .loadQuery(
827
- `
828
- ${sql1234}
829
- source: eone is from_sql(one) {}
830
-
831
- query: eone -> { project: a }
832
- `
833
- )
834
- .run();
835
- expect(result.data.value[0]['a']).toBe(1);
836
- });
837
-
838
- it(`sql_block no explore- ${databaseName}`, async () => {
839
- const result = await runtime
840
- .loadQuery(
841
- `
842
- ${sql1234}
843
- query: from_sql(one) -> { project: a }
844
- `
845
- )
846
- .run();
847
- expect(result.data.value[0]['a']).toBe(1);
848
- });
849
-
850
- it(`sql_block with turducken- ${databaseName}`, async () => {
851
- if (databaseName !== 'postgres') {
852
- const turduckenQuery = `
853
- sql: state_as_sql is {
854
- select: """
855
- SELECT
856
- ROW_NUMBER() OVER (ORDER BY state_count) as row_number,
857
- *
858
- FROM (%{
859
- table('malloytest.state_facts')
860
- -> {
861
- group_by: popular_name
862
- aggregate: state_count is count()
863
- }
864
- }%)
865
- """
866
- }
867
- query: from_sql(state_as_sql) -> {
868
- project: *; where: popular_name = 'Emma'
869
- }`;
870
- const result = await runtime.loadQuery(turduckenQuery).run();
871
- expect(result.data.value[0]['state_count']).toBe(6);
872
- }
873
- });
874
-
875
- // it(`sql_block version- ${databaseName}`, async () => {
876
- // const result = await runtime
877
- // .loadQuery(
878
- // `
879
- // sql: one is ||
880
- // select version() as version
881
- // ;;
882
-
883
- // query: from_sql(one) -> { project: version }
884
- // `
885
- // )
886
- // .run();
887
- // expect(result.data.value[0].version).toBe("something");
888
- // });
889
-
890
- // local declarations
891
- it(`local declarations external query - ${databaseName}`, async () => {
892
- const result = await runtime
893
- .loadQuery(
894
- `
895
- ${sql1234}
896
- query: from_sql(one) -> {
897
- declare: c is a + 1
898
- project: c
899
- }
900
- `
901
- )
902
- .run();
903
- expect(result.data.value[0]['c']).toBe(2);
904
- });
905
-
906
- it(`local declarations named query - ${databaseName}`, async () => {
907
- const result = await runtime
908
- .loadQuery(
909
- `
910
- ${sql1234}
911
- source: foo is from_sql(one) + {
912
- query: bar is {
913
- declare: c is a + 1
914
- project: c
915
- }
916
- }
917
-
918
- query: foo-> bar
919
- `
920
- )
921
- .run();
922
- expect(result.data.value[0]['c']).toBe(2);
923
- });
924
-
925
- it(`local declarations refined named query - ${databaseName}`, async () => {
926
- const result = await runtime
927
- .loadQuery(
928
- `
929
- ${sql1234}
930
- source: foo is from_sql(one) + {
931
- query: bar is {
932
- declare: c is a + 1
933
- project: c
934
- }
935
-
936
- query: baz is bar + {
937
- declare: d is c + 1
938
- project: d
939
- }
940
- }
941
-
942
- query: foo-> baz
943
- `
944
- )
945
- .run();
946
- expect(result.data.value[0]['d']).toBe(3);
947
- });
948
-
949
- it(`regexp match- ${databaseName}`, async () => {
950
- const result = await runtime
951
- .loadQuery(
952
- `
953
- sql: one is { select: """
954
- SELECT 'hello mom' as a, 'cheese tastes good' as b
955
- UNION ALL SELECT 'lloyd is a bozo', 'michael likes poetry'
956
- """}
957
-
958
- query: from_sql(one) -> {
959
- aggregate: llo is count() {? a ~ r'llo'}
960
- aggregate: m2 is count() {? a !~ r'bozo'}
961
- }
962
- `
963
- )
964
- .run();
965
- expect(result.data.value[0]['llo']).toBe(2);
966
- expect(result.data.value[0]['m2']).toBe(1);
967
- });
968
-
969
- it(`substitution precidence- ${databaseName}`, async () => {
970
- const result = await runtime
971
- .loadQuery(
972
- `
973
- sql: one is {select: """
974
- SELECT 5 as a, 2 as b
975
- UNION ALL SELECT 3, 4
976
- """}
977
-
978
- query: from_sql(one) -> {
979
- declare: c is b + 4
980
- project: x is a * c
981
- }
982
- `
983
- )
984
- .run();
985
- expect(result.data.value[0]['x']).toBe(30);
986
- });
987
-
988
- it(`array unnest - ${databaseName}`, async () => {
989
- const result = await runtime
990
- .loadQuery(
991
- `
992
- sql: atitle is {select:"""
993
- SELECT
994
- city,
995
- ${getSplitFunction(databaseName)!('city', ' ')} as words
996
- FROM ${rootDbPath(databaseName)}malloytest.aircraft
997
- """}
998
-
999
- source: title is from_sql(atitle){}
1000
-
1001
- query: title -> {
1002
- where: words.value != null
1003
- group_by: words.value
1004
- aggregate: c is count()
1005
- }
1006
- `
1007
- )
1008
- .run();
1009
- expect(result.data.value[0]['c']).toBe(145);
1010
- });
1011
-
1012
- // make sure we can count the total number of elements when fanning out.
1013
- it(`array unnest x 2 - ${databaseName}`, async () => {
1014
- const result = await runtime
1015
- .loadQuery(
1016
- `
1017
- sql: atitle is {select: """
1018
- SELECT
1019
- city,
1020
- ${getSplitFunction(databaseName)!('city', ' ')} as words,
1021
- ${getSplitFunction(databaseName)!('city', 'A')} as abreak
1022
- FROM ${rootDbPath(databaseName)}malloytest.aircraft
1023
- where city IS NOT null
1024
- """}
1025
-
1026
- source: title is from_sql(atitle){}
1027
-
1028
- query: title -> {
1029
- aggregate:
1030
- b is count()
1031
- c is words.count()
1032
- a is abreak.count()
1033
- }
1034
- `
1035
- )
1036
- .run();
1037
- expect(result.data.value[0]['b']).toBe(3552);
1038
- expect(result.data.value[0]['c']).toBe(4586);
1039
- expect(result.data.value[0]['a']).toBe(6601);
1040
- });
1041
-
1042
- testIf(runtime.supportsNesting)(`nest null - ${databaseName}`, async () => {
1043
- const result = await runtime
1044
- .loadQuery(
1045
- `
1046
- query: table('malloytest.airports') -> {
1047
- where: faa_region = null
1048
- group_by: faa_region
1049
- aggregate: airport_count is count()
1050
- nest: by_state is {
1051
- where: state != null
1052
- group_by: state
1053
- aggregate: airport_count is count()
1054
- }
1055
- nest: by_state1 is {
1056
- where: state != null
1057
- group_by: state
1058
- aggregate: airport_count is count()
1059
- limit: 1
1060
- }
1061
- }
1062
- `
1063
- )
1064
- .run();
1065
-
1066
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1067
- const d: any = result.data.toObject();
1068
- expect(d[0]['by_state']).not.toBe(null);
1069
- expect(d[0]['by_state1']).not.toBe(null);
1070
- });
1071
-
1072
- testIf(runtime.supportsNesting)(
1073
- `number as null- ${databaseName}`,
1074
- async () => {
1075
- const result = await runtime
1076
- .loadQuery(
1077
- `
1078
- source: s is table('malloytest.state_facts') + {
1079
- }
1080
- query: s-> {
1081
- group_by: state
1082
- nest: ugly is {
1083
- group_by: popular_name
1084
- aggregate: foo is NULLIF(sum(airport_count)*0,0)+1
1085
- }
1086
- }
1087
- `
1088
- )
1089
- .run();
1090
- expect(result.data.path(0, 'ugly', 0, 'foo').value).toBe(null);
1091
- }
1092
- );
1093
-
1094
- describe('quoting and strings', () => {
1095
- const tick = "'";
1096
- const back = '\\';
1097
- test('backslash quote', async () => {
1098
- const result = await runtime
1099
- .loadQuery(
1100
- `
1101
- query: table('malloytest.state_facts') -> {
1102
- project: tick is '${back}${tick}'
1103
- }
1104
- `
1105
- )
1106
- .run();
1107
- expect(result.data.value[0]['tick']).toBe(tick);
1108
- });
1109
- test('backslash backslash', async () => {
1110
- const result = await runtime
1111
- .loadQuery(
1112
- `
1113
- query: table('malloytest.state_facts') -> {
1114
- project: back is '${back}${back}'
1115
- }
1116
- `
1117
- )
1118
- .run();
1119
- expect(result.data.value[0]['back']).toBe(back);
1120
- });
1121
-
1122
- testIf(runtime.supportsNesting)('spaces in names', async () => {
1123
- const result = await runtime
1124
- .loadQuery(
1125
- `
1126
- source: \`space race\` is table('malloytest.state_facts') {
1127
- join_one: \`j space\` is table('malloytest.state_facts') on \`j space\`.state=state
1128
- query: \`q u e r y\` is {
1129
- group_by:
1130
- \`P O P\` is popular_name
1131
- \`J P O P\` is \`j space\`.popular_name
1132
- aggregate: \`c o u n t\` is count()
1133
- calculate:
1134
- \`R O W\` is row_number()
1135
- \`l a g\` is lag(\`P O P\`, 1)
1136
- nest: \`by state\` is {
1137
- group_by: \`J S\` is \`j space\`.state
1138
- aggregate: \`c o u n t\` is count()
1139
- }
1140
- }
1141
- }
1142
-
1143
- query: \`space race\` -> \`q u e r y\`
1144
- `
1145
- )
1146
- .run();
1147
- expect(result.data.value[0]['c o u n t']).toBe(24);
1148
- });
1149
- });
1150
- });
1151
- };
28
+ import {databasesFromEnvironmentOr} from '../../util';
29
+ import {noModelSharedTests} from '../shared/nomodel';
1152
30
 
1153
31
  const runtimes = new RuntimeList(databasesFromEnvironmentOr(allDatabases));
1154
32