@malloydata/malloy-query-builder 0.0.237-dev250225144145

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.
@@ -0,0 +1,1776 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const flights_model_1 = require("./flights_model");
10
+ require("./expects");
11
+ function dedent(strs) {
12
+ const str = strs.join('');
13
+ let lines = str.split('\n');
14
+ const firstNonEmptyLine = lines.findIndex(l => l.trim().length > 0);
15
+ let lastNonEmptyLine = 0;
16
+ for (let i = lines.length - 1; i >= 0; i--) {
17
+ if (lines[i].trim().length > 0) {
18
+ lastNonEmptyLine = i;
19
+ break;
20
+ }
21
+ }
22
+ lines = lines.slice(firstNonEmptyLine, lastNonEmptyLine + 1);
23
+ let minIndent = undefined;
24
+ for (const line of lines) {
25
+ if (line.trim().length === 0)
26
+ continue;
27
+ const indent = line.length - line.trimStart().length;
28
+ if (minIndent === undefined || indent < minIndent)
29
+ minIndent = indent;
30
+ }
31
+ if (!minIndent)
32
+ return str;
33
+ return lines.map(l => l.slice(minIndent)).join('\n');
34
+ }
35
+ describe('query builder', () => {
36
+ test('add an order by', () => {
37
+ const from = {
38
+ definition: {
39
+ kind: 'arrow',
40
+ source_reference: { name: 'flights' },
41
+ view: {
42
+ kind: 'segment',
43
+ operations: [
44
+ {
45
+ kind: 'group_by',
46
+ field: {
47
+ expression: {
48
+ kind: 'field_reference',
49
+ name: 'carrier',
50
+ },
51
+ },
52
+ },
53
+ ],
54
+ },
55
+ },
56
+ };
57
+ expect((q) => {
58
+ q.getOrAddDefaultSegment().addOrderBy('carrier', 'asc');
59
+ }).toModifyQuery({
60
+ model: flights_model_1.flights_model,
61
+ from,
62
+ to: {
63
+ definition: {
64
+ kind: 'arrow',
65
+ source_reference: { name: 'flights' },
66
+ view: {
67
+ kind: 'segment',
68
+ operations: [
69
+ {
70
+ kind: 'group_by',
71
+ field: {
72
+ expression: {
73
+ kind: 'field_reference',
74
+ name: 'carrier',
75
+ },
76
+ },
77
+ },
78
+ {
79
+ kind: 'order_by',
80
+ field_reference: {
81
+ name: 'carrier',
82
+ },
83
+ direction: 'asc',
84
+ },
85
+ ],
86
+ },
87
+ },
88
+ },
89
+ malloy: `run: flights -> {
90
+ group_by: carrier
91
+ order_by: carrier asc
92
+ }`,
93
+ });
94
+ });
95
+ test('add a group by', () => {
96
+ const from = {
97
+ definition: {
98
+ kind: 'arrow',
99
+ source_reference: { name: 'flights' },
100
+ view: {
101
+ kind: 'segment',
102
+ operations: [],
103
+ },
104
+ },
105
+ };
106
+ expect((q) => {
107
+ q.getOrAddDefaultSegment().addGroupBy('carrier');
108
+ }).toModifyQuery({
109
+ model: flights_model_1.flights_model,
110
+ from,
111
+ to: {
112
+ definition: {
113
+ kind: 'arrow',
114
+ source_reference: { name: 'flights' },
115
+ view: {
116
+ kind: 'segment',
117
+ operations: [
118
+ {
119
+ kind: 'group_by',
120
+ field: {
121
+ expression: {
122
+ kind: 'field_reference',
123
+ name: 'carrier',
124
+ },
125
+ },
126
+ },
127
+ ],
128
+ },
129
+ },
130
+ },
131
+ malloy: 'run: flights -> { group_by: carrier }',
132
+ });
133
+ });
134
+ test('add a group by with a new name', () => {
135
+ const from = {
136
+ definition: {
137
+ kind: 'arrow',
138
+ source_reference: { name: 'flights' },
139
+ view: {
140
+ kind: 'segment',
141
+ operations: [],
142
+ },
143
+ },
144
+ };
145
+ expect((q) => {
146
+ q.getOrAddDefaultSegment().addGroupBy('carrier');
147
+ q.getOrAddDefaultSegment().addGroupBy('carrier', [], 'carrier_2');
148
+ }).toModifyQuery({
149
+ model: flights_model_1.flights_model,
150
+ from,
151
+ to: {
152
+ definition: {
153
+ kind: 'arrow',
154
+ source_reference: { name: 'flights' },
155
+ view: {
156
+ kind: 'segment',
157
+ operations: [
158
+ {
159
+ kind: 'group_by',
160
+ field: {
161
+ expression: {
162
+ kind: 'field_reference',
163
+ name: 'carrier',
164
+ },
165
+ },
166
+ },
167
+ {
168
+ kind: 'group_by',
169
+ name: 'carrier_2',
170
+ field: {
171
+ expression: {
172
+ kind: 'field_reference',
173
+ name: 'carrier',
174
+ },
175
+ },
176
+ },
177
+ ],
178
+ },
179
+ },
180
+ },
181
+ malloy: dedent `
182
+ run: flights -> {
183
+ group_by:
184
+ carrier
185
+ carrier_2 is carrier
186
+ }
187
+ `,
188
+ });
189
+ });
190
+ test('add a group by in a join', () => {
191
+ const from = {
192
+ definition: {
193
+ kind: 'arrow',
194
+ source_reference: { name: 'flights' },
195
+ view: {
196
+ kind: 'segment',
197
+ operations: [],
198
+ },
199
+ },
200
+ };
201
+ expect((q) => {
202
+ const segment = q.getOrAddDefaultSegment();
203
+ segment.addGroupBy('code', ['origin']);
204
+ segment.addOrderBy('code', 'asc');
205
+ }).toModifyQuery({
206
+ model: flights_model_1.flights_model,
207
+ from,
208
+ to: {
209
+ definition: {
210
+ kind: 'arrow',
211
+ source_reference: { name: 'flights' },
212
+ view: {
213
+ kind: 'segment',
214
+ operations: [
215
+ {
216
+ kind: 'group_by',
217
+ field: {
218
+ expression: {
219
+ kind: 'field_reference',
220
+ name: 'code',
221
+ path: ['origin'],
222
+ },
223
+ },
224
+ },
225
+ {
226
+ kind: 'order_by',
227
+ field_reference: { name: 'code' },
228
+ direction: 'asc',
229
+ },
230
+ ],
231
+ },
232
+ },
233
+ },
234
+ malloy: dedent `
235
+ run: flights -> {
236
+ group_by: origin.code
237
+ order_by: code asc
238
+ }
239
+ `,
240
+ });
241
+ });
242
+ test('add an aggregate with a where', () => {
243
+ const from = {
244
+ definition: {
245
+ kind: 'arrow',
246
+ source_reference: { name: 'flights' },
247
+ view: {
248
+ kind: 'segment',
249
+ operations: [],
250
+ },
251
+ },
252
+ };
253
+ expect((q) => {
254
+ q.getOrAddDefaultSegment()
255
+ .addAggregate('flight_count')
256
+ .addWhere('carrier', 'WN, AA');
257
+ }).toModifyQuery({
258
+ model: flights_model_1.flights_model,
259
+ from,
260
+ to: {
261
+ definition: {
262
+ kind: 'arrow',
263
+ source_reference: { name: 'flights' },
264
+ view: {
265
+ kind: 'segment',
266
+ operations: [
267
+ {
268
+ kind: 'aggregate',
269
+ field: {
270
+ expression: {
271
+ kind: 'filtered_field',
272
+ field_reference: { name: 'flight_count' },
273
+ where: [
274
+ {
275
+ filter: {
276
+ kind: 'filter_string',
277
+ field_reference: { name: 'carrier' },
278
+ filter: 'WN, AA',
279
+ },
280
+ },
281
+ ],
282
+ },
283
+ },
284
+ },
285
+ ],
286
+ },
287
+ },
288
+ },
289
+ malloy: 'run: flights -> { aggregate: flight_count { where: carrier ~ f`WN, AA` } }',
290
+ });
291
+ });
292
+ test('add a where', () => {
293
+ const from = {
294
+ definition: {
295
+ kind: 'arrow',
296
+ source_reference: { name: 'flights' },
297
+ view: {
298
+ kind: 'segment',
299
+ operations: [],
300
+ },
301
+ },
302
+ };
303
+ expect((q) => {
304
+ q.getOrAddDefaultSegment().addWhere('carrier', 'WN, AA');
305
+ }).toModifyQuery({
306
+ model: flights_model_1.flights_model,
307
+ from,
308
+ to: {
309
+ definition: {
310
+ kind: 'arrow',
311
+ source_reference: { name: 'flights' },
312
+ view: {
313
+ kind: 'segment',
314
+ operations: [
315
+ {
316
+ kind: 'where',
317
+ filter: {
318
+ kind: 'filter_string',
319
+ field_reference: { name: 'carrier' },
320
+ filter: 'WN, AA',
321
+ },
322
+ },
323
+ ],
324
+ },
325
+ },
326
+ },
327
+ malloy: 'run: flights -> { where: carrier ~ f`WN, AA` }',
328
+ });
329
+ });
330
+ test('add a parsed where', () => {
331
+ const from = {
332
+ definition: {
333
+ kind: 'arrow',
334
+ source_reference: { name: 'flights' },
335
+ view: {
336
+ kind: 'segment',
337
+ operations: [],
338
+ },
339
+ },
340
+ };
341
+ expect((q) => {
342
+ q.getOrAddDefaultSegment().addWhere('carrier', {
343
+ kind: 'string',
344
+ clauses: [{ operator: '=', values: ['WN', 'AA'] }],
345
+ });
346
+ }).toModifyQuery({
347
+ model: flights_model_1.flights_model,
348
+ from,
349
+ to: {
350
+ definition: {
351
+ kind: 'arrow',
352
+ source_reference: { name: 'flights' },
353
+ view: {
354
+ kind: 'segment',
355
+ operations: [
356
+ {
357
+ kind: 'where',
358
+ filter: {
359
+ kind: 'filter_string',
360
+ field_reference: { name: 'carrier' },
361
+ filter: 'WN, AA',
362
+ },
363
+ },
364
+ ],
365
+ },
366
+ },
367
+ },
368
+ malloy: 'run: flights -> { where: carrier ~ f`WN, AA` }',
369
+ });
370
+ });
371
+ test('add some parsed wheres with different quote requirements', () => {
372
+ const from = {
373
+ definition: {
374
+ kind: 'arrow',
375
+ source_reference: { name: 'flights' },
376
+ view: {
377
+ kind: 'segment',
378
+ operations: [],
379
+ },
380
+ },
381
+ };
382
+ expect((q) => {
383
+ const segment = q.getOrAddDefaultSegment();
384
+ function add(str) {
385
+ segment.addWhere('carrier', {
386
+ kind: 'string',
387
+ clauses: [{ operator: '=', values: [str] }],
388
+ });
389
+ }
390
+ add("'");
391
+ add('\'"');
392
+ add('`');
393
+ add("`'");
394
+ add('`\'"');
395
+ add("`'\"\"\"'''");
396
+ }).toModifyQuery({
397
+ model: flights_model_1.flights_model,
398
+ from,
399
+ to: {
400
+ definition: {
401
+ kind: 'arrow',
402
+ source_reference: { name: 'flights' },
403
+ view: {
404
+ kind: 'segment',
405
+ operations: [
406
+ {
407
+ kind: 'where',
408
+ filter: {
409
+ kind: 'filter_string',
410
+ field_reference: { name: 'carrier' },
411
+ filter: "'",
412
+ },
413
+ },
414
+ {
415
+ kind: 'where',
416
+ filter: {
417
+ kind: 'filter_string',
418
+ field_reference: { name: 'carrier' },
419
+ filter: '\'"',
420
+ },
421
+ },
422
+ {
423
+ kind: 'where',
424
+ filter: {
425
+ kind: 'filter_string',
426
+ field_reference: { name: 'carrier' },
427
+ filter: '`',
428
+ },
429
+ },
430
+ {
431
+ kind: 'where',
432
+ filter: {
433
+ kind: 'filter_string',
434
+ field_reference: { name: 'carrier' },
435
+ filter: "`'",
436
+ },
437
+ },
438
+ {
439
+ kind: 'where',
440
+ filter: {
441
+ kind: 'filter_string',
442
+ field_reference: { name: 'carrier' },
443
+ filter: '`\'"',
444
+ },
445
+ },
446
+ {
447
+ kind: 'where',
448
+ filter: {
449
+ kind: 'filter_string',
450
+ field_reference: { name: 'carrier' },
451
+ filter: "`'\"\"\"'''",
452
+ },
453
+ },
454
+ ],
455
+ },
456
+ },
457
+ },
458
+ malloy: dedent `
459
+ run: flights -> {
460
+ where:
461
+ carrier ~ f\`'\`
462
+ carrier ~ f\`'"\`
463
+ carrier ~ f'\`'
464
+ carrier ~ f"\`'"
465
+ carrier ~ f\`\\\`"\`
466
+ carrier ~ f\`\\\`"""'''\`
467
+ }`,
468
+ });
469
+ });
470
+ test('add a date group by', () => {
471
+ const from = {
472
+ definition: {
473
+ kind: 'arrow',
474
+ source_reference: { name: 'flights' },
475
+ view: {
476
+ kind: 'segment',
477
+ operations: [],
478
+ },
479
+ },
480
+ };
481
+ expect((q) => {
482
+ q.getOrAddDefaultSegment().addTimestampGroupBy('dep_time', 'month');
483
+ }).toModifyQuery({
484
+ model: flights_model_1.flights_model,
485
+ from,
486
+ to: {
487
+ definition: {
488
+ kind: 'arrow',
489
+ source_reference: { name: 'flights' },
490
+ view: {
491
+ kind: 'segment',
492
+ operations: [
493
+ {
494
+ kind: 'group_by',
495
+ field: {
496
+ expression: {
497
+ kind: 'time_truncation',
498
+ field_reference: { name: 'dep_time' },
499
+ truncation: 'month',
500
+ },
501
+ },
502
+ },
503
+ ],
504
+ },
505
+ },
506
+ },
507
+ malloy: 'run: flights -> { group_by: dep_time.month }',
508
+ });
509
+ });
510
+ test('add two group bys', () => {
511
+ const from = {
512
+ definition: {
513
+ kind: 'arrow',
514
+ source_reference: { name: 'flights' },
515
+ view: {
516
+ kind: 'segment',
517
+ operations: [],
518
+ },
519
+ },
520
+ };
521
+ expect((q) => {
522
+ const seg = q.getOrAddDefaultSegment();
523
+ seg.addGroupBy('carrier');
524
+ seg.addGroupBy('origin_code');
525
+ }).toModifyQuery({
526
+ model: flights_model_1.flights_model,
527
+ from,
528
+ to: {
529
+ definition: {
530
+ kind: 'arrow',
531
+ source_reference: { name: 'flights' },
532
+ view: {
533
+ kind: 'segment',
534
+ operations: [
535
+ {
536
+ kind: 'group_by',
537
+ field: {
538
+ expression: {
539
+ kind: 'field_reference',
540
+ name: 'carrier',
541
+ },
542
+ },
543
+ },
544
+ {
545
+ kind: 'group_by',
546
+ field: {
547
+ expression: {
548
+ kind: 'field_reference',
549
+ name: 'origin_code',
550
+ },
551
+ },
552
+ },
553
+ ],
554
+ },
555
+ },
556
+ },
557
+ malloy: dedent `
558
+ run: flights -> {
559
+ group_by:
560
+ carrier
561
+ origin_code
562
+ }`,
563
+ });
564
+ });
565
+ test('reorder fields', () => {
566
+ const from = {
567
+ definition: {
568
+ kind: 'arrow',
569
+ source_reference: { name: 'flights' },
570
+ view: {
571
+ kind: 'segment',
572
+ operations: [
573
+ {
574
+ kind: 'group_by',
575
+ field: {
576
+ expression: {
577
+ kind: 'field_reference',
578
+ name: 'carrier',
579
+ },
580
+ },
581
+ },
582
+ {
583
+ kind: 'group_by',
584
+ field: {
585
+ expression: {
586
+ kind: 'field_reference',
587
+ name: 'origin_code',
588
+ },
589
+ },
590
+ },
591
+ ],
592
+ },
593
+ },
594
+ };
595
+ expect((q) => {
596
+ const seg = q.getOrAddDefaultSegment();
597
+ seg.reorderFields(['origin_code', 'carrier']);
598
+ }).toModifyQuery({
599
+ model: flights_model_1.flights_model,
600
+ from,
601
+ to: {
602
+ definition: {
603
+ kind: 'arrow',
604
+ source_reference: { name: 'flights' },
605
+ view: {
606
+ kind: 'segment',
607
+ operations: [
608
+ {
609
+ kind: 'group_by',
610
+ field: {
611
+ expression: {
612
+ kind: 'field_reference',
613
+ name: 'origin_code',
614
+ },
615
+ },
616
+ },
617
+ {
618
+ kind: 'group_by',
619
+ field: {
620
+ expression: {
621
+ kind: 'field_reference',
622
+ name: 'carrier',
623
+ },
624
+ },
625
+ },
626
+ ],
627
+ },
628
+ },
629
+ },
630
+ malloy: dedent `
631
+ run: flights -> {
632
+ group_by:
633
+ origin_code
634
+ carrier
635
+ }`,
636
+ });
637
+ });
638
+ test('add a nest', () => {
639
+ const from = {
640
+ definition: {
641
+ kind: 'arrow',
642
+ source_reference: { name: 'flights' },
643
+ view: {
644
+ kind: 'segment',
645
+ operations: [],
646
+ },
647
+ },
648
+ };
649
+ expect((q) => {
650
+ const seg = q.getOrAddDefaultSegment();
651
+ const nest = seg.addEmptyNest('by_carrier');
652
+ const seg2 = nest.view.getOrAddDefaultSegment();
653
+ seg2.addGroupBy('carrier');
654
+ }).toModifyQuery({
655
+ model: flights_model_1.flights_model,
656
+ from,
657
+ to: {
658
+ definition: {
659
+ kind: 'arrow',
660
+ source_reference: { name: 'flights' },
661
+ view: {
662
+ kind: 'segment',
663
+ operations: [
664
+ {
665
+ kind: 'nest',
666
+ name: 'by_carrier',
667
+ view: {
668
+ definition: {
669
+ kind: 'segment',
670
+ operations: [
671
+ {
672
+ kind: 'group_by',
673
+ field: {
674
+ expression: {
675
+ kind: 'field_reference',
676
+ name: 'carrier',
677
+ },
678
+ },
679
+ },
680
+ ],
681
+ },
682
+ },
683
+ },
684
+ ],
685
+ },
686
+ },
687
+ },
688
+ malloy: 'run: flights -> { nest: by_carrier is { group_by: carrier } }',
689
+ });
690
+ });
691
+ test('nest via field reference', () => {
692
+ const from = {
693
+ definition: {
694
+ kind: 'arrow',
695
+ source_reference: { name: 'flights' },
696
+ view: {
697
+ kind: 'segment',
698
+ operations: [],
699
+ },
700
+ },
701
+ };
702
+ expect((q) => {
703
+ const seg = q.getOrAddDefaultSegment();
704
+ seg.addNest('by_month');
705
+ }).toModifyQuery({
706
+ model: flights_model_1.flights_model,
707
+ from,
708
+ to: {
709
+ definition: {
710
+ kind: 'arrow',
711
+ source_reference: { name: 'flights' },
712
+ view: {
713
+ kind: 'segment',
714
+ operations: [
715
+ {
716
+ kind: 'nest',
717
+ view: {
718
+ definition: {
719
+ kind: 'view_reference',
720
+ name: 'by_month',
721
+ },
722
+ },
723
+ },
724
+ ],
725
+ },
726
+ },
727
+ },
728
+ malloy: 'run: flights -> { nest: by_month }',
729
+ });
730
+ });
731
+ test('set view reference', () => {
732
+ const from = {
733
+ definition: {
734
+ kind: 'arrow',
735
+ source_reference: { name: 'flights' },
736
+ view: {
737
+ kind: 'segment',
738
+ operations: [],
739
+ },
740
+ },
741
+ };
742
+ expect((q) => {
743
+ q.setView('by_month');
744
+ }).toModifyQuery({
745
+ model: flights_model_1.flights_model,
746
+ from,
747
+ to: {
748
+ definition: {
749
+ kind: 'arrow',
750
+ source_reference: { name: 'flights' },
751
+ view: {
752
+ kind: 'view_reference',
753
+ name: 'by_month',
754
+ },
755
+ },
756
+ },
757
+ malloy: 'run: flights -> by_month',
758
+ });
759
+ });
760
+ test('reorder fields in a view reference', () => {
761
+ const from = {
762
+ definition: {
763
+ kind: 'arrow',
764
+ source_reference: { name: 'flights' },
765
+ view: {
766
+ kind: 'segment',
767
+ operations: [],
768
+ },
769
+ },
770
+ };
771
+ expect((q) => {
772
+ q.setView('by_month');
773
+ q.reorderFields(['flight_count', 'dep_month']);
774
+ }).toModifyQuery({
775
+ model: flights_model_1.flights_model,
776
+ from,
777
+ to: {
778
+ definition: {
779
+ kind: 'arrow',
780
+ source_reference: { name: 'flights' },
781
+ view: {
782
+ kind: 'view_reference',
783
+ name: 'by_month',
784
+ },
785
+ },
786
+ },
787
+ malloy: dedent `
788
+ # field_order = [flight_count, dep_month]
789
+ run: flights -> by_month
790
+ `,
791
+ });
792
+ });
793
+ test('set view with segment refinement', () => {
794
+ const from = {
795
+ definition: {
796
+ kind: 'arrow',
797
+ source_reference: { name: 'flights' },
798
+ view: {
799
+ kind: 'segment',
800
+ operations: [],
801
+ },
802
+ },
803
+ };
804
+ expect((q) => {
805
+ const view = q.setView('by_month');
806
+ const segment = view.addEmptyRefinement();
807
+ segment.setLimit(10);
808
+ }).toModifyQuery({
809
+ model: flights_model_1.flights_model,
810
+ from,
811
+ to: {
812
+ definition: {
813
+ kind: 'arrow',
814
+ source_reference: { name: 'flights' },
815
+ view: {
816
+ kind: 'refinement',
817
+ base: {
818
+ kind: 'view_reference',
819
+ name: 'by_month',
820
+ },
821
+ refinement: {
822
+ kind: 'segment',
823
+ operations: [
824
+ {
825
+ kind: 'limit',
826
+ limit: 10,
827
+ },
828
+ ],
829
+ },
830
+ },
831
+ },
832
+ },
833
+ malloy: 'run: flights -> by_month + { limit: 10 }',
834
+ });
835
+ });
836
+ test('add an order by in a refinement', () => {
837
+ const from = {
838
+ definition: {
839
+ kind: 'arrow',
840
+ source_reference: { name: 'flights' },
841
+ view: {
842
+ kind: 'view_reference',
843
+ name: 'by_month',
844
+ },
845
+ },
846
+ };
847
+ expect((q) => {
848
+ q.getOrAddDefaultSegment().addOrderBy('dep_month', 'asc');
849
+ }).toModifyQuery({
850
+ model: flights_model_1.flights_model,
851
+ from,
852
+ to: {
853
+ definition: {
854
+ kind: 'arrow',
855
+ source_reference: { name: 'flights' },
856
+ view: {
857
+ kind: 'refinement',
858
+ base: {
859
+ kind: 'view_reference',
860
+ name: 'by_month',
861
+ },
862
+ refinement: {
863
+ kind: 'segment',
864
+ operations: [
865
+ {
866
+ kind: 'order_by',
867
+ field_reference: { name: 'dep_month' },
868
+ direction: 'asc',
869
+ },
870
+ ],
871
+ },
872
+ },
873
+ },
874
+ },
875
+ malloy: 'run: flights -> by_month + { order_by: dep_month asc }',
876
+ });
877
+ });
878
+ test('do nothing', () => {
879
+ expect((_q) => { }).toModifyQuery({
880
+ model: flights_model_1.flights_model,
881
+ from: {
882
+ definition: {
883
+ kind: 'arrow',
884
+ source_reference: { name: 'flights' },
885
+ view: {
886
+ kind: 'segment',
887
+ operations: [],
888
+ },
889
+ },
890
+ },
891
+ to: {
892
+ definition: {
893
+ kind: 'arrow',
894
+ source_reference: { name: 'flights' },
895
+ view: {
896
+ kind: 'segment',
897
+ operations: [],
898
+ },
899
+ },
900
+ },
901
+ malloy: 'run: flights -> { }',
902
+ });
903
+ });
904
+ test('set view reference with named refinement', () => {
905
+ const from = {
906
+ definition: {
907
+ kind: 'arrow',
908
+ source_reference: { name: 'flights' },
909
+ view: {
910
+ kind: 'view_reference',
911
+ name: 'by_carrier',
912
+ },
913
+ },
914
+ };
915
+ expect((q) => {
916
+ q.definition
917
+ .asArrowQueryDefinition()
918
+ .view.addViewRefinement('cool_state_measures');
919
+ }).toModifyQuery({
920
+ source: {
921
+ name: 'flights',
922
+ schema: {
923
+ fields: [
924
+ {
925
+ kind: 'dimension',
926
+ name: 'carrier',
927
+ type: { kind: 'string_type' },
928
+ },
929
+ {
930
+ kind: 'measure',
931
+ name: 'flight_count',
932
+ type: { kind: 'number_type' },
933
+ },
934
+ {
935
+ kind: 'view',
936
+ name: 'by_carrier',
937
+ schema: {
938
+ fields: [
939
+ {
940
+ kind: 'dimension',
941
+ name: 'carrier',
942
+ type: { kind: 'string_type' },
943
+ },
944
+ {
945
+ kind: 'measure',
946
+ name: 'flight_count',
947
+ type: { kind: 'number_type' },
948
+ },
949
+ ],
950
+ },
951
+ },
952
+ {
953
+ kind: 'view',
954
+ name: 'cool_state_measures',
955
+ schema: {
956
+ fields: [
957
+ {
958
+ kind: 'measure',
959
+ name: 'il_flight_count',
960
+ type: { kind: 'number_type' },
961
+ },
962
+ {
963
+ kind: 'measure',
964
+ name: 'ca_flight_count',
965
+ type: { kind: 'number_type' },
966
+ },
967
+ ],
968
+ },
969
+ },
970
+ ],
971
+ },
972
+ },
973
+ from,
974
+ to: {
975
+ definition: {
976
+ kind: 'arrow',
977
+ source_reference: { name: 'flights' },
978
+ view: {
979
+ kind: 'refinement',
980
+ base: {
981
+ kind: 'view_reference',
982
+ name: 'by_carrier',
983
+ },
984
+ refinement: {
985
+ kind: 'view_reference',
986
+ name: 'cool_state_measures',
987
+ },
988
+ },
989
+ },
990
+ },
991
+ malloy: 'run: flights -> by_carrier + cool_state_measures',
992
+ });
993
+ });
994
+ test('add limit', () => {
995
+ const from = {
996
+ definition: {
997
+ kind: 'arrow',
998
+ source_reference: { name: 'flights' },
999
+ view: {
1000
+ kind: 'segment',
1001
+ operations: [],
1002
+ },
1003
+ },
1004
+ };
1005
+ expect((q) => {
1006
+ const seg = q.getOrAddDefaultSegment();
1007
+ seg.setLimit(10);
1008
+ }).toModifyQuery({
1009
+ model: flights_model_1.flights_model,
1010
+ from,
1011
+ to: {
1012
+ definition: {
1013
+ kind: 'arrow',
1014
+ source_reference: { name: 'flights' },
1015
+ view: {
1016
+ kind: 'segment',
1017
+ operations: [
1018
+ {
1019
+ kind: 'limit',
1020
+ limit: 10,
1021
+ },
1022
+ ],
1023
+ },
1024
+ },
1025
+ },
1026
+ malloy: 'run: flights -> { limit: 10 }',
1027
+ });
1028
+ });
1029
+ test('change limit', () => {
1030
+ const from = {
1031
+ definition: {
1032
+ kind: 'arrow',
1033
+ source_reference: { name: 'flights' },
1034
+ view: {
1035
+ kind: 'segment',
1036
+ operations: [
1037
+ {
1038
+ kind: 'limit',
1039
+ limit: 10,
1040
+ },
1041
+ ],
1042
+ },
1043
+ },
1044
+ };
1045
+ expect((q) => {
1046
+ const seg = q.getOrAddDefaultSegment();
1047
+ seg.setLimit(20);
1048
+ }).toModifyQuery({
1049
+ model: flights_model_1.flights_model,
1050
+ from,
1051
+ to: {
1052
+ definition: {
1053
+ kind: 'arrow',
1054
+ source_reference: { name: 'flights' },
1055
+ view: {
1056
+ kind: 'segment',
1057
+ operations: [
1058
+ {
1059
+ kind: 'limit',
1060
+ limit: 20,
1061
+ },
1062
+ ],
1063
+ },
1064
+ },
1065
+ },
1066
+ malloy: 'run: flights -> { limit: 20 }',
1067
+ });
1068
+ });
1069
+ describe('tags', () => {
1070
+ test('add a tag property to a group by', () => {
1071
+ const from = {
1072
+ definition: {
1073
+ kind: 'arrow',
1074
+ source_reference: { name: 'flights' },
1075
+ view: {
1076
+ kind: 'segment',
1077
+ operations: [],
1078
+ },
1079
+ },
1080
+ };
1081
+ expect((q) => {
1082
+ const gb = q.getOrAddDefaultSegment().addGroupBy('carrier');
1083
+ gb.setTagProperty(['a', 'b', 'c'], 10);
1084
+ }).toModifyQuery({
1085
+ model: flights_model_1.flights_model,
1086
+ from,
1087
+ to: {
1088
+ definition: {
1089
+ kind: 'arrow',
1090
+ source_reference: { name: 'flights' },
1091
+ view: {
1092
+ kind: 'segment',
1093
+ operations: [
1094
+ {
1095
+ kind: 'group_by',
1096
+ field: {
1097
+ annotations: [{ value: '# a.b.c = 10' }],
1098
+ expression: {
1099
+ kind: 'field_reference',
1100
+ name: 'carrier',
1101
+ },
1102
+ },
1103
+ },
1104
+ ],
1105
+ },
1106
+ },
1107
+ },
1108
+ malloy: dedent `
1109
+ run: flights -> {
1110
+ # a.b.c = 10
1111
+ group_by: carrier
1112
+ }`,
1113
+ });
1114
+ });
1115
+ test('add tag to query', () => {
1116
+ const from = {
1117
+ definition: {
1118
+ kind: 'arrow',
1119
+ source_reference: { name: 'flights' },
1120
+ view: {
1121
+ kind: 'segment',
1122
+ operations: [],
1123
+ },
1124
+ },
1125
+ };
1126
+ expect((q) => {
1127
+ q.setTagProperty(['a'], 'foo');
1128
+ }).toModifyQuery({
1129
+ model: flights_model_1.flights_model,
1130
+ from,
1131
+ to: {
1132
+ definition: {
1133
+ kind: 'arrow',
1134
+ source_reference: { name: 'flights' },
1135
+ view: {
1136
+ kind: 'segment',
1137
+ operations: [],
1138
+ },
1139
+ },
1140
+ annotations: [{ value: '# a = foo' }],
1141
+ },
1142
+ malloy: dedent `
1143
+ # a = foo
1144
+ run: flights -> { }
1145
+ `,
1146
+ });
1147
+ });
1148
+ test('clear an inherited tag', () => {
1149
+ const from = {
1150
+ definition: {
1151
+ kind: 'arrow',
1152
+ source_reference: { name: 'flights' },
1153
+ view: {
1154
+ kind: 'segment',
1155
+ operations: [],
1156
+ },
1157
+ },
1158
+ };
1159
+ expect((q) => {
1160
+ q.getOrAddDefaultSegment()
1161
+ .addGroupBy('carrier')
1162
+ .removeTagProperty(['a']);
1163
+ }).toModifyQuery({
1164
+ source: {
1165
+ name: 'flights',
1166
+ schema: {
1167
+ fields: [
1168
+ {
1169
+ kind: 'dimension',
1170
+ name: 'carrier',
1171
+ type: { kind: 'string_type' },
1172
+ annotations: [{ value: '# a' }],
1173
+ },
1174
+ ],
1175
+ },
1176
+ },
1177
+ from,
1178
+ to: {
1179
+ definition: {
1180
+ kind: 'arrow',
1181
+ source_reference: { name: 'flights' },
1182
+ view: {
1183
+ kind: 'segment',
1184
+ operations: [
1185
+ {
1186
+ kind: 'group_by',
1187
+ field: {
1188
+ annotations: [{ value: '# -a' }],
1189
+ expression: {
1190
+ kind: 'field_reference',
1191
+ name: 'carrier',
1192
+ },
1193
+ },
1194
+ },
1195
+ ],
1196
+ },
1197
+ },
1198
+ },
1199
+ malloy: dedent `
1200
+ run: flights -> {
1201
+ # -a
1202
+ group_by: carrier
1203
+ }`,
1204
+ });
1205
+ });
1206
+ });
1207
+ test('rename a group by', () => {
1208
+ const from = {
1209
+ definition: {
1210
+ kind: 'arrow',
1211
+ source_reference: { name: 'flights' },
1212
+ view: {
1213
+ kind: 'segment',
1214
+ operations: [
1215
+ {
1216
+ kind: 'group_by',
1217
+ field: {
1218
+ expression: {
1219
+ kind: 'field_reference',
1220
+ name: 'carrier',
1221
+ },
1222
+ },
1223
+ },
1224
+ {
1225
+ kind: 'order_by',
1226
+ field_reference: { name: 'carrier' },
1227
+ },
1228
+ ],
1229
+ },
1230
+ },
1231
+ };
1232
+ expect((q) => {
1233
+ q.getOrAddDefaultSegment().getGroupBy('carrier').rename('carrier_2');
1234
+ }).toModifyQuery({
1235
+ model: flights_model_1.flights_model,
1236
+ from,
1237
+ to: {
1238
+ definition: {
1239
+ kind: 'arrow',
1240
+ source_reference: { name: 'flights' },
1241
+ view: {
1242
+ kind: 'segment',
1243
+ operations: [
1244
+ {
1245
+ kind: 'group_by',
1246
+ name: 'carrier_2',
1247
+ field: {
1248
+ expression: {
1249
+ kind: 'field_reference',
1250
+ name: 'carrier',
1251
+ },
1252
+ },
1253
+ },
1254
+ {
1255
+ kind: 'order_by',
1256
+ field_reference: {
1257
+ name: 'carrier_2',
1258
+ },
1259
+ },
1260
+ ],
1261
+ },
1262
+ },
1263
+ },
1264
+ malloy: `run: flights -> {
1265
+ group_by: carrier_2 is carrier
1266
+ order_by: carrier_2
1267
+ }`,
1268
+ });
1269
+ });
1270
+ test('rename a group by should change order by in refinement', () => {
1271
+ const from = {
1272
+ definition: {
1273
+ kind: 'arrow',
1274
+ source_reference: { name: 'flights' },
1275
+ view: {
1276
+ kind: 'refinement',
1277
+ base: {
1278
+ kind: 'segment',
1279
+ operations: [
1280
+ {
1281
+ kind: 'group_by',
1282
+ field: {
1283
+ expression: {
1284
+ kind: 'field_reference',
1285
+ name: 'carrier',
1286
+ },
1287
+ },
1288
+ },
1289
+ ],
1290
+ },
1291
+ refinement: {
1292
+ kind: 'segment',
1293
+ operations: [
1294
+ {
1295
+ kind: 'order_by',
1296
+ field_reference: { name: 'carrier' },
1297
+ },
1298
+ ],
1299
+ },
1300
+ },
1301
+ },
1302
+ };
1303
+ expect((q) => {
1304
+ const segment = q.definition
1305
+ .asArrowQueryDefinition()
1306
+ .view.asRefinementViewDefinition()
1307
+ .base.asSegmentViewDefinition();
1308
+ segment.getGroupBy('carrier').rename('carrier_2');
1309
+ }).toModifyQuery({
1310
+ model: flights_model_1.flights_model,
1311
+ from,
1312
+ to: {
1313
+ definition: {
1314
+ kind: 'arrow',
1315
+ source_reference: { name: 'flights' },
1316
+ view: {
1317
+ kind: 'refinement',
1318
+ base: {
1319
+ kind: 'segment',
1320
+ operations: [
1321
+ {
1322
+ kind: 'group_by',
1323
+ name: 'carrier_2',
1324
+ field: {
1325
+ expression: {
1326
+ kind: 'field_reference',
1327
+ name: 'carrier',
1328
+ },
1329
+ },
1330
+ },
1331
+ ],
1332
+ },
1333
+ refinement: {
1334
+ kind: 'segment',
1335
+ operations: [
1336
+ {
1337
+ kind: 'order_by',
1338
+ field_reference: { name: 'carrier_2' },
1339
+ },
1340
+ ],
1341
+ },
1342
+ },
1343
+ },
1344
+ },
1345
+ malloy: 'run: flights -> { group_by: carrier_2 is carrier } + { order_by: carrier_2 }',
1346
+ });
1347
+ });
1348
+ test('deleting a group by should delete order by in refinement', () => {
1349
+ const from = {
1350
+ definition: {
1351
+ kind: 'arrow',
1352
+ source_reference: { name: 'flights' },
1353
+ view: {
1354
+ kind: 'refinement',
1355
+ base: {
1356
+ kind: 'segment',
1357
+ operations: [
1358
+ {
1359
+ kind: 'group_by',
1360
+ field: {
1361
+ expression: {
1362
+ kind: 'field_reference',
1363
+ name: 'carrier',
1364
+ },
1365
+ },
1366
+ },
1367
+ ],
1368
+ },
1369
+ refinement: {
1370
+ kind: 'segment',
1371
+ operations: [
1372
+ {
1373
+ kind: 'order_by',
1374
+ field_reference: { name: 'carrier' },
1375
+ },
1376
+ ],
1377
+ },
1378
+ },
1379
+ },
1380
+ };
1381
+ expect((q) => {
1382
+ const segment = q.definition
1383
+ .asArrowQueryDefinition()
1384
+ .view.asRefinementViewDefinition()
1385
+ .base.asSegmentViewDefinition();
1386
+ segment.getGroupBy('carrier').delete();
1387
+ }).toModifyQuery({
1388
+ model: flights_model_1.flights_model,
1389
+ from,
1390
+ to: {
1391
+ definition: {
1392
+ kind: 'arrow',
1393
+ source_reference: { name: 'flights' },
1394
+ view: {
1395
+ kind: 'refinement',
1396
+ base: {
1397
+ kind: 'segment',
1398
+ operations: [],
1399
+ },
1400
+ refinement: {
1401
+ kind: 'segment',
1402
+ operations: [],
1403
+ },
1404
+ },
1405
+ },
1406
+ },
1407
+ malloy: 'run: flights -> { } + { }',
1408
+ });
1409
+ });
1410
+ test.skip('deleting a group by should remove a group by in subsequent stage', () => {
1411
+ const from = {
1412
+ definition: {
1413
+ kind: 'arrow',
1414
+ source_reference: { name: 'flights' },
1415
+ view: {
1416
+ kind: 'arrow',
1417
+ source: {
1418
+ kind: 'segment',
1419
+ operations: [
1420
+ {
1421
+ kind: 'group_by',
1422
+ field: {
1423
+ expression: {
1424
+ kind: 'field_reference',
1425
+ name: 'carrier',
1426
+ },
1427
+ },
1428
+ },
1429
+ ],
1430
+ },
1431
+ view: {
1432
+ kind: 'segment',
1433
+ operations: [
1434
+ {
1435
+ kind: 'group_by',
1436
+ field: {
1437
+ expression: {
1438
+ kind: 'field_reference',
1439
+ name: 'carrier',
1440
+ },
1441
+ },
1442
+ },
1443
+ ],
1444
+ },
1445
+ },
1446
+ },
1447
+ };
1448
+ expect((q) => {
1449
+ const segment = q.definition
1450
+ .asArrowQueryDefinition()
1451
+ .view.asArrowViewDefinition()
1452
+ .source.asSegmentViewDefinition();
1453
+ segment.getGroupBy('carrier').delete();
1454
+ }).toModifyQuery({
1455
+ model: flights_model_1.flights_model,
1456
+ from,
1457
+ to: {
1458
+ definition: {
1459
+ kind: 'arrow',
1460
+ source_reference: { name: 'flights' },
1461
+ view: {
1462
+ kind: 'arrow',
1463
+ source: {
1464
+ kind: 'segment',
1465
+ operations: [],
1466
+ },
1467
+ view: {
1468
+ kind: 'segment',
1469
+ operations: [],
1470
+ },
1471
+ },
1472
+ },
1473
+ },
1474
+ malloy: 'run: flights -> { } -> { }',
1475
+ });
1476
+ });
1477
+ describe('getOrAddDefaultSegment', () => {
1478
+ test('on an arrow query with a segment', () => {
1479
+ expect((q) => {
1480
+ q.getOrAddDefaultSegment();
1481
+ }).toModifyQuery({
1482
+ model: flights_model_1.flights_model,
1483
+ from: {
1484
+ definition: {
1485
+ kind: 'arrow',
1486
+ source_reference: { name: 'flights' },
1487
+ view: {
1488
+ kind: 'segment',
1489
+ operations: [],
1490
+ },
1491
+ },
1492
+ },
1493
+ to: {
1494
+ definition: {
1495
+ kind: 'arrow',
1496
+ source_reference: { name: 'flights' },
1497
+ view: {
1498
+ kind: 'segment',
1499
+ operations: [],
1500
+ },
1501
+ },
1502
+ },
1503
+ malloy: 'run: flights -> { }',
1504
+ });
1505
+ });
1506
+ test('on an arrow query with a view reference', () => {
1507
+ expect((q) => {
1508
+ q.getOrAddDefaultSegment();
1509
+ }).toModifyQuery({
1510
+ model: flights_model_1.flights_model,
1511
+ from: {
1512
+ definition: {
1513
+ kind: 'arrow',
1514
+ source_reference: { name: 'flights' },
1515
+ view: {
1516
+ kind: 'view_reference',
1517
+ name: 'by_month',
1518
+ },
1519
+ },
1520
+ },
1521
+ to: {
1522
+ definition: {
1523
+ kind: 'arrow',
1524
+ source_reference: { name: 'flights' },
1525
+ view: {
1526
+ kind: 'refinement',
1527
+ base: {
1528
+ kind: 'view_reference',
1529
+ name: 'by_month',
1530
+ },
1531
+ refinement: {
1532
+ kind: 'segment',
1533
+ operations: [],
1534
+ },
1535
+ },
1536
+ },
1537
+ },
1538
+ malloy: 'run: flights -> by_month + { }',
1539
+ });
1540
+ });
1541
+ test('on an arrow query with a view reference that already has a segment refinement', () => {
1542
+ expect((q) => {
1543
+ q.getOrAddDefaultSegment();
1544
+ }).toModifyQuery({
1545
+ model: flights_model_1.flights_model,
1546
+ from: {
1547
+ definition: {
1548
+ kind: 'arrow',
1549
+ source_reference: { name: 'flights' },
1550
+ view: {
1551
+ kind: 'refinement',
1552
+ base: {
1553
+ kind: 'view_reference',
1554
+ name: 'by_month',
1555
+ },
1556
+ refinement: {
1557
+ kind: 'segment',
1558
+ operations: [],
1559
+ },
1560
+ },
1561
+ },
1562
+ },
1563
+ to: {
1564
+ definition: {
1565
+ kind: 'arrow',
1566
+ source_reference: { name: 'flights' },
1567
+ view: {
1568
+ kind: 'refinement',
1569
+ base: {
1570
+ kind: 'view_reference',
1571
+ name: 'by_month',
1572
+ },
1573
+ refinement: {
1574
+ kind: 'segment',
1575
+ operations: [],
1576
+ },
1577
+ },
1578
+ },
1579
+ },
1580
+ malloy: 'run: flights -> by_month + { }',
1581
+ });
1582
+ });
1583
+ test('on a query reference', () => {
1584
+ expect((q) => {
1585
+ q.getOrAddDefaultSegment();
1586
+ }).toModifyQuery({
1587
+ model: flights_model_1.flights_model,
1588
+ from: {
1589
+ definition: {
1590
+ kind: 'query_reference',
1591
+ name: 'flights_by_carrier',
1592
+ },
1593
+ },
1594
+ to: {
1595
+ definition: {
1596
+ kind: 'refinement',
1597
+ query_reference: { name: 'flights_by_carrier' },
1598
+ refinement: {
1599
+ kind: 'segment',
1600
+ operations: [],
1601
+ },
1602
+ },
1603
+ },
1604
+ malloy: 'run: flights_by_carrier + { }',
1605
+ });
1606
+ });
1607
+ });
1608
+ test('on an arrow query with a view reference that already has a reference refinement', () => {
1609
+ expect((q) => {
1610
+ q.getOrAddDefaultSegment();
1611
+ }).toModifyQuery({
1612
+ model: flights_model_1.flights_model,
1613
+ from: {
1614
+ definition: {
1615
+ kind: 'arrow',
1616
+ source_reference: { name: 'flights' },
1617
+ view: {
1618
+ kind: 'refinement',
1619
+ base: {
1620
+ kind: 'view_reference',
1621
+ name: 'by_month',
1622
+ },
1623
+ refinement: {
1624
+ kind: 'view_reference',
1625
+ name: 'top10',
1626
+ },
1627
+ },
1628
+ },
1629
+ },
1630
+ to: {
1631
+ definition: {
1632
+ kind: 'arrow',
1633
+ source_reference: { name: 'flights' },
1634
+ view: {
1635
+ kind: 'refinement',
1636
+ base: {
1637
+ kind: 'view_reference',
1638
+ name: 'by_month',
1639
+ },
1640
+ refinement: {
1641
+ kind: 'refinement',
1642
+ base: {
1643
+ kind: 'view_reference',
1644
+ name: 'top10',
1645
+ },
1646
+ refinement: {
1647
+ kind: 'segment',
1648
+ operations: [],
1649
+ },
1650
+ },
1651
+ },
1652
+ },
1653
+ },
1654
+ malloy: 'run: flights -> by_month + top10 + { }',
1655
+ });
1656
+ });
1657
+ describe('parameters', () => {
1658
+ test('add parameters of different types', () => {
1659
+ const from = {
1660
+ definition: {
1661
+ kind: 'arrow',
1662
+ source_reference: { name: 'foo' },
1663
+ view: {
1664
+ kind: 'segment',
1665
+ operations: [],
1666
+ },
1667
+ },
1668
+ };
1669
+ expect((q) => {
1670
+ const source = q.definition.asArrowQueryDefinition().sourceReference;
1671
+ source.setParameter('string_param', 'COOL');
1672
+ source.setParameter('number_param', 7);
1673
+ source.setParameter('boolean_param', true);
1674
+ source.setParameter('date_param', {
1675
+ // TODO what am I supposed to do about timezones?
1676
+ date: new Date('2020-01-01 10:00:00+00:00'),
1677
+ granularity: 'month',
1678
+ });
1679
+ source.setParameter('timestamp_param', {
1680
+ date: new Date('2020-01-01 10:00:00+00:00'),
1681
+ granularity: 'minute',
1682
+ });
1683
+ source.setParameter('null_param', null);
1684
+ }).toModifyQuery({
1685
+ source: {
1686
+ name: 'foo',
1687
+ schema: { fields: [] },
1688
+ parameters: [
1689
+ {
1690
+ name: 'string_param',
1691
+ type: { kind: 'string_type' },
1692
+ },
1693
+ {
1694
+ name: 'number_param',
1695
+ type: { kind: 'number_type' },
1696
+ },
1697
+ {
1698
+ name: 'boolean_param',
1699
+ type: { kind: 'boolean_type' },
1700
+ },
1701
+ {
1702
+ name: 'date_param',
1703
+ type: { kind: 'date_type' },
1704
+ },
1705
+ {
1706
+ name: 'timestamp_param',
1707
+ type: { kind: 'timestamp_type' },
1708
+ },
1709
+ {
1710
+ name: 'null_param',
1711
+ type: { kind: 'string_type' },
1712
+ },
1713
+ ],
1714
+ },
1715
+ from,
1716
+ to: {
1717
+ definition: {
1718
+ kind: 'arrow',
1719
+ source_reference: {
1720
+ name: 'foo',
1721
+ parameters: [
1722
+ {
1723
+ name: 'string_param',
1724
+ value: { kind: 'string_literal', string_value: 'COOL' },
1725
+ },
1726
+ {
1727
+ name: 'number_param',
1728
+ value: { kind: 'number_literal', number_value: 7 },
1729
+ },
1730
+ {
1731
+ name: 'boolean_param',
1732
+ value: { kind: 'boolean_literal', boolean_value: true },
1733
+ },
1734
+ {
1735
+ name: 'date_param',
1736
+ value: {
1737
+ kind: 'date_literal',
1738
+ date_value: '2020-01-01 10:00:00',
1739
+ granularity: 'month',
1740
+ },
1741
+ },
1742
+ {
1743
+ name: 'timestamp_param',
1744
+ value: {
1745
+ kind: 'timestamp_literal',
1746
+ timestamp_value: '2020-01-01 10:00:00',
1747
+ granularity: 'minute',
1748
+ },
1749
+ },
1750
+ {
1751
+ name: 'null_param',
1752
+ value: { kind: 'null_literal' },
1753
+ },
1754
+ ],
1755
+ },
1756
+ view: {
1757
+ kind: 'segment',
1758
+ operations: [],
1759
+ },
1760
+ },
1761
+ },
1762
+ malloy: dedent `
1763
+ run: foo(
1764
+ string_param is "COOL",
1765
+ number_param is 7,
1766
+ boolean_param is true,
1767
+ date_param is @2020-01,
1768
+ timestamp_param is @2020-01-01 18:00,
1769
+ null_param is null
1770
+ ) -> { }
1771
+ `,
1772
+ });
1773
+ });
1774
+ });
1775
+ });
1776
+ //# sourceMappingURL=query-ast.spec.js.map