@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,3633 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.ASTAnnotation = exports.ASTAnnotationList = exports.ASTLimitViewOperation = exports.ASTView = exports.ASTFilterWithFilterString = exports.ASTFilter = exports.ASTWhereViewOperation = exports.ASTNestViewOperation = exports.ASTFilteredFieldExpression = exports.ASTWhereList = exports.ASTWhere = exports.ASTTimeTruncationExpression = exports.ASTReferenceExpression = exports.ASTExpression = exports.ASTField = exports.ASTAggregateViewOperation = exports.ASTGroupByViewOperation = exports.ASTOrderByViewOperation = exports.ASTViewOperation = exports.ASTViewOperationList = exports.ASTSegmentViewDefinition = exports.ASTRefinementViewDefinition = exports.ASTArrowViewDefinition = exports.ASTReferenceViewDefinition = exports.ASTReferenceQueryDefinition = exports.ASTRefinementQueryDefinition = exports.ASTArrowQueryDefinition = exports.ASTQueryDefinition = exports.ASTUnimplemented = exports.ASTTimestampLiteralValue = exports.ASTDateLiteralValue = exports.ASTBooleanLiteralValue = exports.ASTNumberLiteralValue = exports.ASTNullLiteralValue = exports.ASTStringLiteralValue = exports.LiteralValueAST = exports.ASTParameterValue = exports.ASTParameterValueList = exports.ASTSourceReference = exports.ASTFieldReference = exports.ASTReference = exports.ASTQuery = void 0;
27
+ /*
28
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
29
+ *
30
+ * This source code is licensed under the MIT license found in the
31
+ * LICENSE file in the root directory of this source tree.
32
+ */
33
+ const Malloy = __importStar(require("@malloydata/malloy-interfaces"));
34
+ const malloy_tag_1 = require("@malloydata/malloy-tag");
35
+ const Filter = __importStar(require("@malloydata/malloy-filter"));
36
+ class ASTNode {
37
+ constructor() {
38
+ /**
39
+ * @internal
40
+ */
41
+ this.edited = false;
42
+ }
43
+ /**
44
+ * @internal
45
+ */
46
+ edit() {
47
+ this.edited = true;
48
+ if (this._parent)
49
+ this._parent.edit();
50
+ return this;
51
+ }
52
+ /**
53
+ * Returns this node as an `ASTQuery`. Throws if it is not an `ASTQuery`.
54
+ *
55
+ * There are variants of this method for _all_ ASTXYZ nodes `asXYZ`, but they
56
+ * are not shown here so the docs aren't crazy big.
57
+ *
58
+ * @returns Returns this node as an `ASTQuery`.
59
+ */
60
+ asQuery() {
61
+ if (this instanceof ASTQuery)
62
+ return this;
63
+ throw new Error('Not an ASTQuery');
64
+ }
65
+ /**
66
+ * Finds the AST node at the given `path`. Throws if it is not an `ASTQuery`.
67
+ *
68
+ * There are variants of this method for _all_ ASTXYZ nodes `findXYZ`, but they
69
+ * are not shown here so the docs aren't crazy big.
70
+ *
71
+ * @param path Path to the desired ASTNode, e.g. `['source', 'parameters', 0]`
72
+ * @returns Returns this node as an `ASTQuery`.
73
+ */
74
+ findQuery(path) {
75
+ return this.find(path).asQuery();
76
+ }
77
+ /**
78
+ * @hidden
79
+ */
80
+ asReference() {
81
+ if (this instanceof ASTReference)
82
+ return this;
83
+ throw new Error('Not an ASTReference');
84
+ }
85
+ /**
86
+ * @hidden
87
+ */
88
+ findReference(path) {
89
+ return this.find(path).asReference();
90
+ }
91
+ /**
92
+ * @hidden
93
+ */
94
+ asSourceReference() {
95
+ if (this instanceof ASTSourceReference)
96
+ return this;
97
+ throw new Error('Not an ASTSourceReference');
98
+ }
99
+ /**
100
+ * @hidden
101
+ */
102
+ findSourceReference(path) {
103
+ return this.find(path).asSourceReference();
104
+ }
105
+ /**
106
+ * @hidden
107
+ */
108
+ asParameterValueList() {
109
+ if (this instanceof ASTParameterValueList)
110
+ return this;
111
+ throw new Error('Not an ASTParameterValueList');
112
+ }
113
+ /**
114
+ * @hidden
115
+ */
116
+ findParameterValueList(path) {
117
+ return this.find(path).asParameterValueList();
118
+ }
119
+ /**
120
+ * @hidden
121
+ */
122
+ asWhere() {
123
+ if (this instanceof ASTWhere)
124
+ return this;
125
+ throw new Error('Not an ASTWhere');
126
+ }
127
+ /**
128
+ * @hidden
129
+ */
130
+ findWhere(path) {
131
+ return this.find(path).asWhere();
132
+ }
133
+ /**
134
+ * @hidden
135
+ */
136
+ asWhereList() {
137
+ if (this instanceof ASTWhereList)
138
+ return this;
139
+ throw new Error('Not an ASTWhereList');
140
+ }
141
+ /**
142
+ * @hidden
143
+ */
144
+ findWhereList(path) {
145
+ return this.find(path).asWhereList();
146
+ }
147
+ /**
148
+ * @hidden
149
+ */
150
+ asParameterValue() {
151
+ if (this instanceof ASTParameterValue)
152
+ return this;
153
+ throw new Error('Not an ASTParameterValue');
154
+ }
155
+ /**
156
+ * @hidden
157
+ */
158
+ findParameterValue(path) {
159
+ return this.find(path).asParameterValue();
160
+ }
161
+ /**
162
+ * @hidden
163
+ */
164
+ asStringLiteralValue() {
165
+ if (this instanceof ASTStringLiteralValue)
166
+ return this;
167
+ throw new Error('Not an ASTStringLiteralValue');
168
+ }
169
+ /**
170
+ * @hidden
171
+ */
172
+ findStringLiteralValue(path) {
173
+ return this.find(path).asStringLiteralValue();
174
+ }
175
+ /**
176
+ * @hidden
177
+ */
178
+ asNumberLiteralValue() {
179
+ if (this instanceof ASTNumberLiteralValue)
180
+ return this;
181
+ throw new Error('Not an ASTNumberLiteralValue');
182
+ }
183
+ /**
184
+ * @hidden
185
+ */
186
+ findNumberLiteralValue(path) {
187
+ return this.find(path).asNumberLiteralValue();
188
+ }
189
+ /**
190
+ * @hidden
191
+ */
192
+ asViewOperationList() {
193
+ if (this instanceof ASTViewOperationList)
194
+ return this;
195
+ throw new Error('Not an ASTViewOperationList');
196
+ }
197
+ /**
198
+ * @hidden
199
+ */
200
+ findViewOperationList(path) {
201
+ return this.find(path).asViewOperationList();
202
+ }
203
+ /**
204
+ * @hidden
205
+ */
206
+ asGroupByViewOperation() {
207
+ if (this instanceof ASTGroupByViewOperation)
208
+ return this;
209
+ throw new Error('Not an ASTGroupByViewOperation');
210
+ }
211
+ /**
212
+ * @hidden
213
+ */
214
+ findGroupByViewOperation(path) {
215
+ return this.find(path).asGroupByViewOperation();
216
+ }
217
+ /**
218
+ * @hidden
219
+ */
220
+ asAggregateViewOperation() {
221
+ if (this instanceof ASTAggregateViewOperation)
222
+ return this;
223
+ throw new Error('Not an ASTAggregateViewOperation');
224
+ }
225
+ /**
226
+ * @hidden
227
+ */
228
+ findAggregateViewOperation(path) {
229
+ return this.find(path).asAggregateViewOperation();
230
+ }
231
+ /**
232
+ * @hidden
233
+ */
234
+ asOrderByViewOperation() {
235
+ if (this instanceof ASTOrderByViewOperation)
236
+ return this;
237
+ throw new Error('Not an ASTOrderByViewOperation');
238
+ }
239
+ /**
240
+ * @hidden
241
+ */
242
+ findOrderByViewOperation(path) {
243
+ return this.find(path).asOrderByViewOperation();
244
+ }
245
+ /**
246
+ * @hidden
247
+ */
248
+ asField() {
249
+ if (this instanceof ASTField)
250
+ return this;
251
+ throw new Error('Not an ASTField');
252
+ }
253
+ /**
254
+ * @hidden
255
+ */
256
+ findField(path) {
257
+ return this.find(path).asField();
258
+ }
259
+ /**
260
+ * @hidden
261
+ */
262
+ asReferenceExpression() {
263
+ if (this instanceof ASTReferenceExpression)
264
+ return this;
265
+ throw new Error('Not an ASTReferenceExpression');
266
+ }
267
+ /**
268
+ * @hidden
269
+ */
270
+ findReferenceExpression(path) {
271
+ return this.find(path).asReferenceExpression();
272
+ }
273
+ /**
274
+ * @hidden
275
+ */
276
+ asReferenceViewDefinition() {
277
+ if (this instanceof ASTReferenceViewDefinition)
278
+ return this;
279
+ throw new Error('Not an ASTReferenceViewDefinition');
280
+ }
281
+ /**
282
+ * @hidden
283
+ */
284
+ findReferenceViewDefinition(path) {
285
+ return this.find(path).asReferenceViewDefinition();
286
+ }
287
+ /**
288
+ * @hidden
289
+ */
290
+ asArrowQueryDefinition() {
291
+ if (this instanceof ASTArrowQueryDefinition)
292
+ return this;
293
+ throw new Error('Not an ASTArrowQueryDefinition');
294
+ }
295
+ /**
296
+ * @hidden
297
+ */
298
+ findArrowQueryDefinition(path) {
299
+ return this.find(path).asArrowQueryDefinition();
300
+ }
301
+ /**
302
+ * @hidden
303
+ */
304
+ asArrowViewDefinition() {
305
+ if (this instanceof ASTArrowViewDefinition)
306
+ return this;
307
+ throw new Error('Not an ASTArrowViewDefinition');
308
+ }
309
+ /**
310
+ * @hidden
311
+ */
312
+ findArrowViewDefinition(path) {
313
+ return this.find(path).asArrowViewDefinition();
314
+ }
315
+ /**
316
+ * @hidden
317
+ */
318
+ asRefinementViewDefinition() {
319
+ if (this instanceof ASTRefinementViewDefinition)
320
+ return this;
321
+ throw new Error('Not an ASTRefinementViewDefinition');
322
+ }
323
+ /**
324
+ * @hidden
325
+ */
326
+ findRefinementViewDefinition(path) {
327
+ return this.find(path).asRefinementViewDefinition();
328
+ }
329
+ /**
330
+ * @hidden
331
+ */
332
+ asTimeTruncationExpression() {
333
+ if (this instanceof ASTTimeTruncationExpression)
334
+ return this;
335
+ throw new Error('Not an ASTTimeTruncationExpression');
336
+ }
337
+ /**
338
+ * @hidden
339
+ */
340
+ findTimeTruncationExpression(path) {
341
+ return this.find(path).asTimeTruncationExpression();
342
+ }
343
+ /**
344
+ * @hidden
345
+ */
346
+ asFilteredFieldExpression() {
347
+ if (this instanceof ASTFilteredFieldExpression)
348
+ return this;
349
+ throw new Error('Not an ASTFilteredFieldExpression');
350
+ }
351
+ /**
352
+ * @hidden
353
+ */
354
+ findFilteredFieldExpression(path) {
355
+ return this.find(path).asFilteredFieldExpression();
356
+ }
357
+ /**
358
+ * @hidden
359
+ */
360
+ asNestViewOperation() {
361
+ if (this instanceof ASTNestViewOperation)
362
+ return this;
363
+ throw new Error('Not an ASTNestViewOperation');
364
+ }
365
+ /**
366
+ * @hidden
367
+ */
368
+ findNestViewOperation(path) {
369
+ return this.find(path).asNestViewOperation();
370
+ }
371
+ /**
372
+ * @hidden
373
+ */
374
+ asView() {
375
+ if (this instanceof ASTView)
376
+ return this;
377
+ throw new Error('Not an ASTView');
378
+ }
379
+ /**
380
+ * @hidden
381
+ */
382
+ findView(path) {
383
+ return this.find(path).asView();
384
+ }
385
+ /**
386
+ * @hidden
387
+ */
388
+ asSegmentViewDefinition() {
389
+ if (this instanceof ASTSegmentViewDefinition)
390
+ return this;
391
+ throw new Error('Not an ASTSegmentViewDefinition');
392
+ }
393
+ /**
394
+ * @hidden
395
+ */
396
+ findSegmentViewDefinition(path) {
397
+ return this.find(path).asSegmentViewDefinition();
398
+ }
399
+ /**
400
+ * @hidden
401
+ */
402
+ asLimitViewOperation() {
403
+ if (this instanceof ASTLimitViewOperation)
404
+ return this;
405
+ throw new Error('Not an ASTLimitViewOperation');
406
+ }
407
+ /**
408
+ * @hidden
409
+ */
410
+ findLimitViewOperation(path) {
411
+ return this.find(path).asLimitViewOperation();
412
+ }
413
+ /**
414
+ * @hidden
415
+ */
416
+ asAnnotationList() {
417
+ if (this instanceof ASTAnnotationList)
418
+ return this;
419
+ throw new Error('Not an ASTAnnotationList');
420
+ }
421
+ /**
422
+ * @hidden
423
+ */
424
+ findAnnotationList(path) {
425
+ return this.find(path).asAnnotationList();
426
+ }
427
+ /**
428
+ * @hidden
429
+ */
430
+ asAnnotation() {
431
+ if (this instanceof ASTAnnotation)
432
+ return this;
433
+ throw new Error('Not an ASTAnnotation');
434
+ }
435
+ /**
436
+ * @hidden
437
+ */
438
+ findAnnotation(path) {
439
+ return this.find(path).asAnnotation();
440
+ }
441
+ /**
442
+ * @internal
443
+ */
444
+ get parent() {
445
+ if (this._parent === undefined) {
446
+ throw new Error('This node does not have a parent');
447
+ }
448
+ return this._parent;
449
+ }
450
+ /**
451
+ * @internal
452
+ */
453
+ set parent(parent) {
454
+ this._parent = parent;
455
+ }
456
+ /**
457
+ * @internal
458
+ */
459
+ static schemaTryGet(schema, name, path) {
460
+ let current = schema;
461
+ for (const part of path !== null && path !== void 0 ? path : []) {
462
+ const field = current.fields.find(f => f.name === part);
463
+ if (field === undefined) {
464
+ throw new Error(`${part} not found`);
465
+ }
466
+ if (field.kind !== 'join') {
467
+ throw new Error(`${part} is not a join`);
468
+ }
469
+ current = field.schema;
470
+ }
471
+ const field = current.fields.find(f => f.name === name);
472
+ return field;
473
+ }
474
+ /**
475
+ * @internal
476
+ */
477
+ static schemaGet(schema, name, path) {
478
+ const field = ASTNode.schemaTryGet(schema, name, path);
479
+ if (field === undefined) {
480
+ throw new Error(`${name} not found`);
481
+ }
482
+ return field;
483
+ }
484
+ /**
485
+ * @internal
486
+ */
487
+ static schemaMerge(a, b) {
488
+ return {
489
+ fields: [...a.fields, ...b.fields],
490
+ };
491
+ }
492
+ }
493
+ function isBasic(t) {
494
+ return (Array.isArray(t) ||
495
+ typeof t === 'string' ||
496
+ typeof t === 'number' ||
497
+ typeof t === 'boolean');
498
+ }
499
+ class ASTListNode extends ASTNode {
500
+ constructor(node, children) {
501
+ super();
502
+ this.node = node;
503
+ this.children = children;
504
+ this.originalChildren = [...children];
505
+ children.forEach(c => (c.parent = this));
506
+ }
507
+ *iter() {
508
+ for (let i = 0; i < this.length; i++) {
509
+ yield this.index(i);
510
+ }
511
+ }
512
+ get length() {
513
+ return this.children.length;
514
+ }
515
+ get last() {
516
+ return this.children[this.children.length - 1];
517
+ }
518
+ /**
519
+ * Get the `i`th element of this list
520
+ *
521
+ * @param i The index of the list to get
522
+ * @returns The item at index `i` in this list
523
+ */
524
+ index(i) {
525
+ return this.children[i];
526
+ }
527
+ /**
528
+ * @internal
529
+ */
530
+ insert(n, index) {
531
+ this.edit();
532
+ this.children.splice(index, 0, n);
533
+ n.parent = this;
534
+ }
535
+ /**
536
+ * @internal
537
+ */
538
+ add(n) {
539
+ this.edit();
540
+ this.children.push(n);
541
+ n.parent = this;
542
+ }
543
+ /**
544
+ * @internal
545
+ */
546
+ remove(n) {
547
+ const idx = this.children.findIndex(o => o === n);
548
+ if (idx === -1)
549
+ return this;
550
+ this.edit();
551
+ this.children.splice(idx, 1);
552
+ }
553
+ /**
554
+ * @internal
555
+ */
556
+ build() {
557
+ if (!this.edited)
558
+ return this.node;
559
+ const ret = this.children.map(c => c.build());
560
+ this.edited = false;
561
+ this.originalChildren = [...this.children];
562
+ this.node = ret;
563
+ return ret;
564
+ }
565
+ /**
566
+ * @internal
567
+ */
568
+ find(path) {
569
+ if (path.length === 0) {
570
+ return this;
571
+ }
572
+ const [head, ...rest] = path;
573
+ if (typeof head !== 'number') {
574
+ throw new Error(`${this.constructor.name} is a ASTListNode and thus cannot contain a ${head}`);
575
+ }
576
+ const child = this.children[head];
577
+ return child.find(rest);
578
+ }
579
+ /**
580
+ * @internal
581
+ */
582
+ findIndex(predicate) {
583
+ return this.children.findIndex(predicate);
584
+ }
585
+ /**
586
+ * @internal
587
+ */
588
+ indexOf(n) {
589
+ return this.children.indexOf(n);
590
+ }
591
+ }
592
+ class ASTObjectNode extends ASTNode {
593
+ constructor(node, children) {
594
+ super();
595
+ this.node = node;
596
+ this.children = children;
597
+ for (const key in children) {
598
+ const child = children[key];
599
+ if (child && !isBasic(child)) {
600
+ child.parent = this;
601
+ }
602
+ }
603
+ }
604
+ /**
605
+ * @internal
606
+ */
607
+ build() {
608
+ if (!this.edited)
609
+ return this.node;
610
+ let ret = this.node;
611
+ for (const key in this.children) {
612
+ const child = this.children[key];
613
+ if (child === undefined) {
614
+ ret = { ...ret, [key]: undefined };
615
+ }
616
+ else if (isBasic(child)) {
617
+ if (this.edited) {
618
+ ret = { ...ret, [key]: child };
619
+ }
620
+ }
621
+ else {
622
+ ret = { ...ret, [key]: child.build() };
623
+ }
624
+ }
625
+ this.node = ret;
626
+ this.edited = false;
627
+ return ret;
628
+ }
629
+ /**
630
+ * @internal
631
+ */
632
+ find(path) {
633
+ if (path.length === 0) {
634
+ return this;
635
+ }
636
+ const [head, ...rest] = path;
637
+ if (typeof head !== 'string') {
638
+ throw new Error(`${this.constructor.name} is a ASTListNode and thus cannot contain a ${head}`);
639
+ }
640
+ const child = this.children[head];
641
+ if (isBasic(child)) {
642
+ throw new Error(`${this.constructor.name}.${head} refers to a basic type, not an ASTNode`);
643
+ }
644
+ return child.find(rest);
645
+ }
646
+ }
647
+ /**
648
+ * AST Object to represent the whole query AST.
649
+ *
650
+ * ```ts
651
+ * const q = new ASTQuery({
652
+ * source: flightsSourceInfo,
653
+ * });
654
+ * const segment = q.getOrAddDefaultSegment();
655
+ * segment.addGroupBy("carrier");
656
+ * segment.addOrderBy("carrier", Malloy.OrderByDirection.DESC);
657
+ * const malloy = q.toMalloy();
658
+ * const query = q.build();
659
+ * ```
660
+ */
661
+ class ASTQuery extends ASTObjectNode {
662
+ constructor(options) {
663
+ var _a, _b;
664
+ let chosenSource = options.source;
665
+ if (chosenSource === undefined) {
666
+ if (options.model === undefined) {
667
+ throw new Error('Need a model or source');
668
+ }
669
+ if (options.query) {
670
+ const definition = options.query.definition;
671
+ if (definition.kind === 'arrow') {
672
+ const name = definition.source_reference.name;
673
+ chosenSource = options.model.entries.find(e => e.name === name);
674
+ if (chosenSource === undefined) {
675
+ throw new Error(`Model does not contain source or query named ${name}`);
676
+ }
677
+ }
678
+ }
679
+ if (chosenSource === undefined) {
680
+ chosenSource = options.model.entries[0];
681
+ }
682
+ if (chosenSource === undefined) {
683
+ throw new Error('Model does not contain any sources or queries');
684
+ }
685
+ }
686
+ const source = sourceOrQueryToModelEntry(chosenSource);
687
+ const query = (_a = options.query) !== null && _a !== void 0 ? _a : {
688
+ definition: {
689
+ kind: 'arrow',
690
+ source_reference: {
691
+ name: source.name,
692
+ },
693
+ view: {
694
+ kind: 'segment',
695
+ operations: [],
696
+ },
697
+ },
698
+ };
699
+ const model = (_b = options.model) !== null && _b !== void 0 ? _b : {
700
+ entries: [source],
701
+ anonymous_queries: [],
702
+ };
703
+ super(query, {
704
+ definition: exports.ASTQueryDefinition.from(query.definition),
705
+ annotations: query.annotations && new ASTAnnotationList(query.annotations),
706
+ });
707
+ this.model = model;
708
+ if (options.source) {
709
+ this.setSource(options.source.name);
710
+ }
711
+ }
712
+ get definition() {
713
+ return this.children.definition;
714
+ }
715
+ set definition(definition) {
716
+ this.edit();
717
+ this.children.definition = definition;
718
+ definition.parent = this;
719
+ }
720
+ get annotations() {
721
+ return this.children.annotations;
722
+ }
723
+ reorderFields(names) {
724
+ this.definition.reorderFields(names);
725
+ }
726
+ getOrAddAnnotations() {
727
+ if (this.annotations)
728
+ return this.annotations;
729
+ this.edit();
730
+ const annotations = new ASTAnnotationList([]);
731
+ this.children.annotations = annotations;
732
+ return annotations;
733
+ }
734
+ getInheritedTag(prefix = '# ') {
735
+ return tagFromAnnotations(prefix, this.getInheritedAnnotations());
736
+ }
737
+ getIntrinsicTag(prefix = '# ') {
738
+ var _a, _b;
739
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getIntrinsicTag(prefix)) !== null && _b !== void 0 ? _b : new malloy_tag_1.Tag();
740
+ }
741
+ getTag(prefix = '# ') {
742
+ var _a, _b;
743
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getTag(prefix)) !== null && _b !== void 0 ? _b : this.getInheritedTag(prefix);
744
+ }
745
+ setTagProperty(path, value = null, prefix = '# ') {
746
+ this.getOrAddAnnotations().setTagProperty(path, value, prefix);
747
+ }
748
+ removeTagProperty(path, prefix = '# ') {
749
+ if (!this.getTag().has(...path))
750
+ return;
751
+ this.getOrAddAnnotations().removeTagProperty(path, prefix);
752
+ }
753
+ setViewToEmptySegment() {
754
+ if (!(this.definition instanceof ASTArrowQueryDefinition)) {
755
+ throw new Error('Must set source before setting view');
756
+ }
757
+ this.definition = new ASTArrowQueryDefinition({
758
+ kind: 'arrow',
759
+ source_reference: this.definition.sourceReference.build(),
760
+ view: {
761
+ kind: 'segment',
762
+ operations: [],
763
+ },
764
+ });
765
+ return this.definition.view.asSegmentViewDefinition();
766
+ }
767
+ isRunnable() {
768
+ return this.definition.isRunnable();
769
+ }
770
+ /**
771
+ * Gets an {@link ASTSegmentViewDefinition} for the "default" place to add query
772
+ * operations, or creates one if it doesn't exist.
773
+ *
774
+ * ```
775
+ * run: flights ->
776
+ * ```
777
+ * ```ts
778
+ * q.getOrAddDefaultSegment();
779
+ * ```
780
+ * ```
781
+ * run: flights -> { }
782
+ * ```
783
+ *
784
+ * If there is a view at the head, it will refine it:
785
+ * ```
786
+ * run: flights -> by_carrier
787
+ * ```
788
+ * ```ts
789
+ * q.getOrAddDefaultSegment();
790
+ * ```
791
+ * ```
792
+ * run: flights -> by_carrier + { }
793
+ * ```
794
+ */
795
+ getOrAddDefaultSegment() {
796
+ return this.definition.getOrAddDefaultSegment();
797
+ }
798
+ /**
799
+ * Sets the source of this query to be a reference to a source in the model.
800
+ *
801
+ * ```ts
802
+ * q.setSource('flights')
803
+ * ```
804
+ * ```
805
+ * run: flights -> { }
806
+ * ```
807
+ *
808
+ * @param name The name of the source in the model to reference.
809
+ */
810
+ setSource(name) {
811
+ if (this.definition instanceof ASTArrowQueryDefinition) {
812
+ if (this.definition.sourceReference.name === name) {
813
+ return;
814
+ }
815
+ }
816
+ const source = this.model.entries.find(e => e.name === name);
817
+ if (source === undefined) {
818
+ throw new Error(`Source ${name} is not defined in model`);
819
+ }
820
+ this.definition = new ASTArrowQueryDefinition({
821
+ kind: 'arrow',
822
+ source_reference: { name },
823
+ view: this.definition instanceof ASTArrowQueryDefinition
824
+ ? this.definition.view.build()
825
+ : {
826
+ kind: 'segment',
827
+ operations: [],
828
+ },
829
+ });
830
+ }
831
+ /**
832
+ * Sets the head of this query to be a reference to a top level query.
833
+ *
834
+ * ```ts
835
+ * q.setQueryHead('flights_by_carrier')
836
+ * ```
837
+ * ```
838
+ * run: flights_by_carrier
839
+ * ```
840
+ *
841
+ * @param name The name of the query in the model to reference.
842
+ */
843
+ setQueryHead(name) {
844
+ const query = this.model.entries.find(e => e.name === name);
845
+ if (query === undefined || query.kind !== 'query') {
846
+ throw new Error(`No query named ${name} in the model`);
847
+ }
848
+ this.definition = new ASTReferenceQueryDefinition({
849
+ kind: 'query_reference',
850
+ name,
851
+ });
852
+ }
853
+ /**
854
+ * @internal
855
+ */
856
+ getQueryInfo(name) {
857
+ const query = this.model.entries.find(e => e.name === name);
858
+ if (query === undefined) {
859
+ throw new Error(`Query ${name} is not defined in model`);
860
+ }
861
+ if (query.kind !== 'query') {
862
+ throw new Error(`Model entry ${name} is not a query`);
863
+ }
864
+ return query;
865
+ }
866
+ /**
867
+ * Emits the current query object as Malloy code
868
+ *
869
+ * ```ts
870
+ * q.setSource('flights')
871
+ * q.setView('by_carrier')
872
+ * q.toMalloy();
873
+ * ```
874
+ * ```
875
+ * run: flights -> by_carrier
876
+ * ```
877
+ *
878
+ * @returns Malloy code for the query
879
+ */
880
+ toMalloy() {
881
+ return Malloy.queryToMalloy(this.build());
882
+ }
883
+ /**
884
+ * Build the query into its `Malloy.Query` object form. New JS objects will be
885
+ * created for any subtree which has edits.
886
+ *
887
+ * @returns A `Malloy.Query` representing the current query
888
+ */
889
+ build() {
890
+ return super.build();
891
+ }
892
+ /**
893
+ * Set the view of this query; overwrites any other query operations.
894
+ *
895
+ * ```
896
+ * run: flights ->
897
+ * ```
898
+ * ```ts
899
+ * q.setView('by_carrier')
900
+ * ```
901
+ * ```
902
+ * run: flights -> by_carrier
903
+ * ```
904
+ *
905
+ * @param name The name of the view to set as the head of the query pipeline
906
+ */
907
+ setView(name) {
908
+ if (!(this.definition instanceof ASTArrowQueryDefinition)) {
909
+ throw new Error('Must set source before setting view');
910
+ }
911
+ this.definition = new ASTArrowQueryDefinition({
912
+ kind: 'arrow',
913
+ source_reference: this.definition.sourceReference.build(),
914
+ view: {
915
+ kind: 'view_reference',
916
+ name,
917
+ },
918
+ });
919
+ return this.definition.view.asReferenceViewDefinition();
920
+ }
921
+ getInheritedAnnotations() {
922
+ var _a, _b;
923
+ if (this.definition instanceof ASTReferenceQueryDefinition) {
924
+ const query = this.getQueryInfo(this.definition.name);
925
+ return (_a = query.annotations) !== null && _a !== void 0 ? _a : [];
926
+ }
927
+ else if (this.definition instanceof ASTRefinementQueryDefinition) {
928
+ const query = this.getQueryInfo(this.definition.queryReference.name);
929
+ return (_b = query.annotations) !== null && _b !== void 0 ? _b : [];
930
+ }
931
+ else if (this.definition instanceof ASTArrowQueryDefinition) {
932
+ return this.definition.view.getInheritedAnnotations();
933
+ }
934
+ return [];
935
+ }
936
+ }
937
+ exports.ASTQuery = ASTQuery;
938
+ class ASTReference extends ASTObjectNode {
939
+ constructor(reference) {
940
+ super(reference, {
941
+ name: reference.name,
942
+ path: reference.path,
943
+ parameters: reference.parameters && new ASTParameterValueList(reference.parameters),
944
+ });
945
+ this.reference = reference;
946
+ }
947
+ get name() {
948
+ return this.children.name;
949
+ }
950
+ set name(value) {
951
+ this.edit();
952
+ this.children.name = value;
953
+ }
954
+ get parameters() {
955
+ return this.children.parameters;
956
+ }
957
+ set parameters(parameters) {
958
+ this.edit();
959
+ this.children.parameters = parameters;
960
+ }
961
+ get path() {
962
+ return this.children.path;
963
+ }
964
+ /**
965
+ * @internal
966
+ */
967
+ static getOrAddParameters(reference) {
968
+ if (reference.parameters) {
969
+ return reference.parameters;
970
+ }
971
+ reference.edit();
972
+ const parameters = new ASTParameterValueList([]);
973
+ reference.parameters = parameters;
974
+ return parameters;
975
+ }
976
+ /**
977
+ * @internal
978
+ */
979
+ static setParameter(reference, name, value) {
980
+ return reference.getOrAddParameters().addParameter(name, value);
981
+ }
982
+ /**
983
+ * @internal
984
+ */
985
+ static tryGetParameter(reference, name) {
986
+ if (reference.parameters === undefined)
987
+ return undefined;
988
+ for (const parameter of reference.parameters.iter()) {
989
+ if (parameter.name === name) {
990
+ return parameter;
991
+ }
992
+ }
993
+ }
994
+ getOrAddParameters() {
995
+ return ASTReference.getOrAddParameters(this);
996
+ }
997
+ setParameter(name, value) {
998
+ return ASTReference.setParameter(this, name, value);
999
+ }
1000
+ tryGetParameter(name) {
1001
+ return ASTReference.tryGetParameter(this, name);
1002
+ }
1003
+ }
1004
+ exports.ASTReference = ASTReference;
1005
+ class ASTFieldReference extends ASTReference {
1006
+ /**
1007
+ * @internal
1008
+ */
1009
+ get segment() {
1010
+ const parent = this.parent;
1011
+ if (parent instanceof ASTFilteredFieldExpression ||
1012
+ parent instanceof ASTTimeTruncationExpression) {
1013
+ return parent.field.segment;
1014
+ }
1015
+ else if (parent instanceof ASTFilterWithFilterString) {
1016
+ const grand = parent.parent;
1017
+ if (grand instanceof ASTWhere) {
1018
+ return grand.list.expression.field.segment;
1019
+ }
1020
+ else {
1021
+ return grand.list.segment;
1022
+ }
1023
+ }
1024
+ else {
1025
+ return parent.list.segment;
1026
+ }
1027
+ }
1028
+ getFieldInfo() {
1029
+ const schema = this.segment.getInputSchema();
1030
+ return ASTNode.schemaGet(schema, this.name, this.path);
1031
+ }
1032
+ }
1033
+ exports.ASTFieldReference = ASTFieldReference;
1034
+ class ASTSourceReference extends ASTReference {
1035
+ /**
1036
+ * @internal
1037
+ */
1038
+ get query() {
1039
+ return this.parent.parent.asQuery();
1040
+ }
1041
+ /**
1042
+ * Gets the `Malloy.SourceInfo` for the referenced source
1043
+ *
1044
+ * @returns The source information for the referenced source
1045
+ */
1046
+ getSourceInfo() {
1047
+ const info = this.query.model.entries.find(e => e.name === this.name);
1048
+ if (info === undefined) {
1049
+ throw new Error('No source info found');
1050
+ }
1051
+ return info;
1052
+ }
1053
+ getSourceParameters() {
1054
+ var _a;
1055
+ return (_a = this.getSourceInfo().parameters) !== null && _a !== void 0 ? _a : [];
1056
+ }
1057
+ areRequiredParametersSet() {
1058
+ const sourceParameters = this.getSourceParameters();
1059
+ for (const parameterInfo of sourceParameters) {
1060
+ if (parameterInfo.default_value !== undefined)
1061
+ continue;
1062
+ const parameter = this.tryGetParameter(parameterInfo.name);
1063
+ if (parameter === undefined) {
1064
+ return false;
1065
+ }
1066
+ }
1067
+ return true;
1068
+ }
1069
+ }
1070
+ exports.ASTSourceReference = ASTSourceReference;
1071
+ class ASTParameterValueList extends ASTListNode {
1072
+ constructor(parameters) {
1073
+ super(parameters, parameters.map(p => new ASTParameterValue(p)));
1074
+ }
1075
+ get parameters() {
1076
+ return this.children;
1077
+ }
1078
+ addParameter(name, value) {
1079
+ // TODO validate that the parameter is valid (name and type)
1080
+ this.add(new ASTParameterValue({
1081
+ name,
1082
+ value: exports.LiteralValueAST.makeLiteral(value),
1083
+ }));
1084
+ }
1085
+ }
1086
+ exports.ASTParameterValueList = ASTParameterValueList;
1087
+ class ASTParameterValue extends ASTObjectNode {
1088
+ constructor(parameter) {
1089
+ super(parameter, {
1090
+ name: parameter.name,
1091
+ value: exports.LiteralValueAST.from(parameter.value),
1092
+ });
1093
+ this.parameter = parameter;
1094
+ }
1095
+ get name() {
1096
+ return this.children.name;
1097
+ }
1098
+ }
1099
+ exports.ASTParameterValue = ASTParameterValue;
1100
+ exports.LiteralValueAST = {
1101
+ from(value) {
1102
+ switch (value.kind) {
1103
+ case 'string_literal':
1104
+ return new ASTStringLiteralValue(value);
1105
+ case 'number_literal':
1106
+ return new ASTNumberLiteralValue(value);
1107
+ case 'boolean_literal':
1108
+ return new ASTBooleanLiteralValue(value);
1109
+ case 'date_literal':
1110
+ return new ASTDateLiteralValue(value);
1111
+ case 'timestamp_literal':
1112
+ return new ASTTimestampLiteralValue(value);
1113
+ case 'null_literal':
1114
+ return new ASTNullLiteralValue(value);
1115
+ }
1116
+ },
1117
+ makeLiteral(value) {
1118
+ if (typeof value === 'string') {
1119
+ return {
1120
+ kind: 'string_literal',
1121
+ string_value: value,
1122
+ };
1123
+ }
1124
+ else if (typeof value === 'boolean') {
1125
+ return {
1126
+ kind: 'boolean_literal',
1127
+ boolean_value: value,
1128
+ };
1129
+ }
1130
+ else if (typeof value === 'number') {
1131
+ return {
1132
+ kind: 'number_literal',
1133
+ number_value: value,
1134
+ };
1135
+ }
1136
+ else if (value === null) {
1137
+ return {
1138
+ kind: 'null_literal',
1139
+ };
1140
+ }
1141
+ else if ('date' in value) {
1142
+ const granularity = value.granularity;
1143
+ const serialized = serializeDateAsLiteral(value.date);
1144
+ if (isDateTimeframe(granularity)) {
1145
+ return {
1146
+ kind: 'date_literal',
1147
+ date_value: serialized,
1148
+ granularity: granularity,
1149
+ };
1150
+ }
1151
+ return {
1152
+ kind: 'timestamp_literal',
1153
+ timestamp_value: serialized,
1154
+ granularity: granularity,
1155
+ };
1156
+ }
1157
+ throw new Error('Unknown literal type');
1158
+ },
1159
+ };
1160
+ class ASTStringLiteralValue extends ASTObjectNode {
1161
+ constructor(node) {
1162
+ super(node, {
1163
+ kind: node.kind,
1164
+ string_value: node.string_value,
1165
+ });
1166
+ this.node = node;
1167
+ this.kind = 'string_literal';
1168
+ }
1169
+ }
1170
+ exports.ASTStringLiteralValue = ASTStringLiteralValue;
1171
+ class ASTNullLiteralValue extends ASTObjectNode {
1172
+ constructor(node) {
1173
+ super(node, {
1174
+ kind: node.kind,
1175
+ });
1176
+ this.node = node;
1177
+ this.kind = 'null_literal';
1178
+ }
1179
+ }
1180
+ exports.ASTNullLiteralValue = ASTNullLiteralValue;
1181
+ class ASTNumberLiteralValue extends ASTObjectNode {
1182
+ constructor(node) {
1183
+ super(node, {
1184
+ kind: node.kind,
1185
+ number_value: node.number_value,
1186
+ });
1187
+ this.node = node;
1188
+ this.kind = 'number_literal';
1189
+ }
1190
+ }
1191
+ exports.ASTNumberLiteralValue = ASTNumberLiteralValue;
1192
+ class ASTBooleanLiteralValue extends ASTObjectNode {
1193
+ constructor(node) {
1194
+ super(node, {
1195
+ kind: node.kind,
1196
+ boolean_value: node.boolean_value,
1197
+ });
1198
+ this.node = node;
1199
+ this.kind = 'boolean_literal';
1200
+ }
1201
+ }
1202
+ exports.ASTBooleanLiteralValue = ASTBooleanLiteralValue;
1203
+ class ASTDateLiteralValue extends ASTObjectNode {
1204
+ constructor(node) {
1205
+ super(node, {
1206
+ kind: node.kind,
1207
+ date_value: node.date_value,
1208
+ granularity: node.granularity,
1209
+ });
1210
+ this.node = node;
1211
+ this.kind = 'date_literal';
1212
+ }
1213
+ }
1214
+ exports.ASTDateLiteralValue = ASTDateLiteralValue;
1215
+ class ASTTimestampLiteralValue extends ASTObjectNode {
1216
+ constructor(node) {
1217
+ super(node, {
1218
+ kind: node.kind,
1219
+ timestamp_value: node.timestamp_value,
1220
+ granularity: node.granularity,
1221
+ });
1222
+ this.node = node;
1223
+ this.kind = 'timestamp_literal';
1224
+ }
1225
+ }
1226
+ exports.ASTTimestampLiteralValue = ASTTimestampLiteralValue;
1227
+ class ASTUnimplemented extends ASTNode {
1228
+ constructor(node) {
1229
+ super();
1230
+ this.node = node;
1231
+ }
1232
+ get treeEdited() {
1233
+ return false;
1234
+ }
1235
+ build() {
1236
+ return this.node;
1237
+ }
1238
+ find() {
1239
+ throw new Error('Tried to find a node from an unimplemented node type');
1240
+ }
1241
+ }
1242
+ exports.ASTUnimplemented = ASTUnimplemented;
1243
+ exports.ASTQueryDefinition = {
1244
+ from: (definition) => {
1245
+ switch (definition.kind) {
1246
+ case 'arrow':
1247
+ return new ASTArrowQueryDefinition(definition);
1248
+ case 'query_reference':
1249
+ return new ASTReferenceQueryDefinition(definition);
1250
+ case 'refinement':
1251
+ return new ASTRefinementQueryDefinition(definition);
1252
+ }
1253
+ },
1254
+ };
1255
+ class ASTArrowQueryDefinition extends ASTObjectNode {
1256
+ constructor(node) {
1257
+ super(node, {
1258
+ kind: 'arrow',
1259
+ source_reference: new ASTSourceReference(node.source_reference),
1260
+ view: ASTViewDefinition.from(node.view),
1261
+ });
1262
+ this.node = node;
1263
+ }
1264
+ get view() {
1265
+ return this.children.view;
1266
+ }
1267
+ set view(view) {
1268
+ this.edit();
1269
+ this.children.view = view;
1270
+ view.parent = this;
1271
+ }
1272
+ get sourceReference() {
1273
+ return this.children.source_reference;
1274
+ }
1275
+ getOrAddDefaultSegment() {
1276
+ return this.view.getOrAddDefaultSegment();
1277
+ }
1278
+ getSourceInfo() {
1279
+ return this.sourceReference.getSourceInfo();
1280
+ }
1281
+ getOutputSchema() {
1282
+ return this.view.getRefinementSchema();
1283
+ }
1284
+ isRunnable() {
1285
+ return (this.view.isRunnable() && this.sourceReference.areRequiredParametersSet());
1286
+ }
1287
+ /**
1288
+ * @internal
1289
+ */
1290
+ get query() {
1291
+ return this.parent.asQuery();
1292
+ }
1293
+ /**
1294
+ * @internal
1295
+ */
1296
+ propagateUp(f) {
1297
+ this.propagateDown(f);
1298
+ }
1299
+ /**
1300
+ * @internal
1301
+ */
1302
+ propagateDown(f) {
1303
+ f(this.view);
1304
+ this.view.propagateDown(f);
1305
+ }
1306
+ reorderFields(names) {
1307
+ if (this.view instanceof ASTSegmentViewDefinition) {
1308
+ this.view.reorderFields(names);
1309
+ }
1310
+ else {
1311
+ this.query.getOrAddAnnotations().setTagProperty(['field_order'], names);
1312
+ }
1313
+ }
1314
+ }
1315
+ exports.ASTArrowQueryDefinition = ASTArrowQueryDefinition;
1316
+ class ASTRefinementQueryDefinition extends ASTObjectNode {
1317
+ constructor(node) {
1318
+ super(node, {
1319
+ kind: 'refinement',
1320
+ query_reference: new ASTReference(node.query_reference),
1321
+ refinement: ASTViewDefinition.from(node.refinement),
1322
+ });
1323
+ this.node = node;
1324
+ }
1325
+ get queryReference() {
1326
+ return this.children.query_reference;
1327
+ }
1328
+ get refinement() {
1329
+ return this.children.refinement;
1330
+ }
1331
+ set refinement(refinement) {
1332
+ this.edit();
1333
+ this.children.refinement = refinement;
1334
+ refinement.parent = this;
1335
+ }
1336
+ isRunnable() {
1337
+ return this.refinement.isRunnable();
1338
+ }
1339
+ /**
1340
+ * @internal
1341
+ */
1342
+ get query() {
1343
+ return this.parent.asQuery();
1344
+ }
1345
+ getOrAddDefaultSegment() {
1346
+ return this.refinement.getOrAddDefaultSegment();
1347
+ }
1348
+ getOutputSchema() {
1349
+ const model = this.query.model;
1350
+ const query = model.entries.find(e => e.name === this.queryReference.name);
1351
+ if (query === undefined) {
1352
+ throw new Error(`Query not found with name ${this.queryReference.name}`);
1353
+ }
1354
+ const base = query.schema;
1355
+ const refinement = this.refinement.getRefinementSchema();
1356
+ return ASTQuery.schemaMerge(base, refinement);
1357
+ }
1358
+ /**
1359
+ * @internal
1360
+ */
1361
+ propagateUp(f) {
1362
+ this.propagateDown(f);
1363
+ }
1364
+ /**
1365
+ * @internal
1366
+ */
1367
+ propagateDown(f) {
1368
+ f(this.refinement);
1369
+ this.refinement.propagateDown(f);
1370
+ }
1371
+ reorderFields(names) {
1372
+ this.query.getOrAddAnnotations().setTagProperty(['field_order'], names);
1373
+ }
1374
+ }
1375
+ exports.ASTRefinementQueryDefinition = ASTRefinementQueryDefinition;
1376
+ class ASTReferenceQueryDefinition extends ASTObjectNode {
1377
+ constructor(node) {
1378
+ super(node, {
1379
+ kind: 'query_reference',
1380
+ name: node.name,
1381
+ path: node.path,
1382
+ parameters: node.parameters && new ASTParameterValueList(node.parameters),
1383
+ });
1384
+ this.node = node;
1385
+ }
1386
+ isRunnable() {
1387
+ return true;
1388
+ }
1389
+ get name() {
1390
+ return this.children.name;
1391
+ }
1392
+ get query() {
1393
+ return this.parent.asQuery();
1394
+ }
1395
+ get parameters() {
1396
+ return this.children.parameters;
1397
+ }
1398
+ set parameters(parameters) {
1399
+ this.edit();
1400
+ this.children.parameters = parameters;
1401
+ }
1402
+ get path() {
1403
+ return this.children.path;
1404
+ }
1405
+ getOrAddDefaultSegment() {
1406
+ var _a;
1407
+ const newQuery = new ASTRefinementQueryDefinition({
1408
+ kind: 'refinement',
1409
+ query_reference: {
1410
+ name: this.name,
1411
+ path: this.path,
1412
+ parameters: (_a = this.parameters) === null || _a === void 0 ? void 0 : _a.build(),
1413
+ },
1414
+ refinement: {
1415
+ kind: 'segment',
1416
+ operations: [],
1417
+ },
1418
+ });
1419
+ this.query.definition = newQuery;
1420
+ return newQuery.refinement.asSegmentViewDefinition();
1421
+ }
1422
+ /**
1423
+ * @internal
1424
+ */
1425
+ propagateUp(_f) {
1426
+ return;
1427
+ }
1428
+ /**
1429
+ * @internal
1430
+ */
1431
+ propagateDown(_f) {
1432
+ return;
1433
+ }
1434
+ reorderFields(names) {
1435
+ this.query.getOrAddAnnotations().setTagProperty(['field_order'], names);
1436
+ }
1437
+ getOrAddParameters() {
1438
+ return ASTReference.getOrAddParameters(this);
1439
+ }
1440
+ setParameter(name, value) {
1441
+ return ASTReference.setParameter(this, name, value);
1442
+ }
1443
+ tryGetParameter(name) {
1444
+ return ASTReference.tryGetParameter(this, name);
1445
+ }
1446
+ }
1447
+ exports.ASTReferenceQueryDefinition = ASTReferenceQueryDefinition;
1448
+ const ASTViewDefinition = {
1449
+ from(definition) {
1450
+ switch (definition.kind) {
1451
+ case 'arrow':
1452
+ return new ASTArrowViewDefinition(definition);
1453
+ case 'view_reference':
1454
+ return new ASTReferenceViewDefinition(definition);
1455
+ case 'segment':
1456
+ return new ASTSegmentViewDefinition(definition);
1457
+ case 'refinement':
1458
+ return new ASTRefinementViewDefinition(definition);
1459
+ }
1460
+ },
1461
+ };
1462
+ function swapViewInParent(node, view) {
1463
+ const parent = node.parent;
1464
+ if (parent instanceof ASTArrowQueryDefinition) {
1465
+ parent.view = view;
1466
+ }
1467
+ else if (parent instanceof ASTRefinementQueryDefinition) {
1468
+ parent.refinement = view;
1469
+ }
1470
+ else if (parent instanceof ASTView) {
1471
+ parent.definition = view;
1472
+ }
1473
+ else if (parent instanceof ASTArrowViewDefinition) {
1474
+ if (parent.source === node) {
1475
+ parent.source = view;
1476
+ }
1477
+ else {
1478
+ parent.view = view;
1479
+ }
1480
+ }
1481
+ else {
1482
+ if (parent.base === node) {
1483
+ parent.base = view;
1484
+ }
1485
+ else {
1486
+ parent.refinement = view;
1487
+ }
1488
+ }
1489
+ }
1490
+ function isValidViewRefinement(view, name, path = []) {
1491
+ const schema = view.getInputSchema();
1492
+ const field = ASTQuery.schemaGet(schema, name, path);
1493
+ if (field === undefined) {
1494
+ return { isValidViewRefinement: false, error: `${name} is not defined` };
1495
+ }
1496
+ else if (field.kind !== 'view') {
1497
+ // TODO scalar refinements
1498
+ return { isValidViewRefinement: false, error: `${name} is not a view` };
1499
+ }
1500
+ const prevOutput = view.getOutputSchema();
1501
+ for (const refinementField of field.schema.fields) {
1502
+ if (ASTQuery.schemaTryGet(prevOutput, refinementField.name, [])) {
1503
+ return {
1504
+ isValidViewRefinement: false,
1505
+ error: `Cannot refine with ${name} because stage already has an output field named ${refinementField.name}`,
1506
+ };
1507
+ }
1508
+ }
1509
+ return { isValidViewRefinement: true };
1510
+ }
1511
+ class ASTReferenceViewDefinition extends ASTObjectNode {
1512
+ constructor(node) {
1513
+ super(node, {
1514
+ kind: 'view_reference',
1515
+ name: node.name,
1516
+ path: node.path,
1517
+ parameters: node.parameters && new ASTParameterValueList(node.parameters),
1518
+ });
1519
+ this.node = node;
1520
+ }
1521
+ isRunnable() {
1522
+ return true;
1523
+ }
1524
+ get name() {
1525
+ return this.children.name;
1526
+ }
1527
+ get path() {
1528
+ return this.children.path;
1529
+ }
1530
+ get parameters() {
1531
+ return this.children.parameters;
1532
+ }
1533
+ set parameters(parameters) {
1534
+ this.edit();
1535
+ this.children.parameters = parameters;
1536
+ }
1537
+ getOrAddDefaultSegment() {
1538
+ return this.addEmptyRefinement();
1539
+ }
1540
+ addEmptyRefinement() {
1541
+ const newView = ASTRefinementViewDefinition.segmentRefinementOf(this.build());
1542
+ swapViewInParent(this, newView);
1543
+ return newView.refinement.asSegmentViewDefinition();
1544
+ }
1545
+ addViewRefinement(name, path) {
1546
+ const { error } = this.isValidViewRefinement(name, path);
1547
+ if (error) {
1548
+ throw new Error(error);
1549
+ }
1550
+ const newView = ASTRefinementViewDefinition.viewRefinementOf(this.build(), name, path);
1551
+ swapViewInParent(this, newView);
1552
+ return newView.refinement.asReferenceViewDefinition();
1553
+ }
1554
+ isValidViewRefinement(name, path) {
1555
+ return isValidViewRefinement(this, name, path);
1556
+ }
1557
+ getInputSchema() {
1558
+ return getInputSchemaFromViewParent(this.parent);
1559
+ }
1560
+ getOutputSchema() {
1561
+ const parent = this.parent;
1562
+ return parent.getOutputSchema();
1563
+ }
1564
+ getImplicitName() {
1565
+ return this.name;
1566
+ }
1567
+ getViewInfo() {
1568
+ const schema = this.getInputSchema();
1569
+ const view = ASTNode.schemaGet(schema, this.name, this.path);
1570
+ if (view.kind !== 'view') {
1571
+ throw new Error('Not a view');
1572
+ }
1573
+ return view;
1574
+ }
1575
+ getRefinementSchema() {
1576
+ const view = this.getViewInfo();
1577
+ return view.schema;
1578
+ }
1579
+ /**
1580
+ * @internal
1581
+ */
1582
+ propagateUp(f) {
1583
+ this.parent.propagateUp(f);
1584
+ }
1585
+ /**
1586
+ * @internal
1587
+ */
1588
+ propagateDown(_f) {
1589
+ return;
1590
+ }
1591
+ getInheritedAnnotations() {
1592
+ var _a;
1593
+ const view = this.getViewInfo();
1594
+ return (_a = view.annotations) !== null && _a !== void 0 ? _a : [];
1595
+ }
1596
+ getOrAddParameters() {
1597
+ return ASTReference.getOrAddParameters(this);
1598
+ }
1599
+ setParameter(name, value) {
1600
+ return ASTReference.setParameter(this, name, value);
1601
+ }
1602
+ tryGetParameter(name) {
1603
+ return ASTReference.tryGetParameter(this, name);
1604
+ }
1605
+ }
1606
+ exports.ASTReferenceViewDefinition = ASTReferenceViewDefinition;
1607
+ class ASTArrowViewDefinition extends ASTObjectNode {
1608
+ constructor(node) {
1609
+ super(node, {
1610
+ kind: 'arrow',
1611
+ source: ASTViewDefinition.from(node.source),
1612
+ view: ASTViewDefinition.from(node.view),
1613
+ });
1614
+ this.node = node;
1615
+ }
1616
+ isRunnable() {
1617
+ return this.source.isRunnable() && this.view.isRunnable();
1618
+ }
1619
+ get source() {
1620
+ return this.children.source;
1621
+ }
1622
+ set source(source) {
1623
+ this.edit();
1624
+ this.children.source = source;
1625
+ }
1626
+ get view() {
1627
+ return this.children.view;
1628
+ }
1629
+ set view(view) {
1630
+ this.edit();
1631
+ this.children.view = view;
1632
+ view.parent = this;
1633
+ }
1634
+ getOrAddDefaultSegment() {
1635
+ return this.view.getOrAddDefaultSegment();
1636
+ }
1637
+ addEmptyRefinement() {
1638
+ return this.view.addEmptyRefinement();
1639
+ }
1640
+ addViewRefinement(name, path) {
1641
+ return this.view.addViewRefinement(name, path);
1642
+ }
1643
+ getInputSchema() {
1644
+ return this.source.getOutputSchema();
1645
+ }
1646
+ getOutputSchema() {
1647
+ return this.view.getRefinementSchema();
1648
+ }
1649
+ getImplicitName() {
1650
+ return this.view.getImplicitName();
1651
+ }
1652
+ getRefinementSchema() {
1653
+ throw new Error('An arrow is not a valid refinement');
1654
+ }
1655
+ isValidViewRefinement(name, path) {
1656
+ return isValidViewRefinement(this, name, path);
1657
+ }
1658
+ /**
1659
+ * @internal
1660
+ */
1661
+ propagateUp(f) {
1662
+ this.propagateDown(f);
1663
+ }
1664
+ /**
1665
+ * @internal
1666
+ */
1667
+ propagateDown(f) {
1668
+ f(this.view);
1669
+ this.view.propagateDown(f);
1670
+ }
1671
+ getInheritedAnnotations() {
1672
+ return [];
1673
+ }
1674
+ }
1675
+ exports.ASTArrowViewDefinition = ASTArrowViewDefinition;
1676
+ class ASTRefinementViewDefinition extends ASTObjectNode {
1677
+ constructor(node) {
1678
+ super(node, {
1679
+ kind: 'refinement',
1680
+ base: ASTViewDefinition.from(node.base),
1681
+ refinement: ASTViewDefinition.from(node.refinement),
1682
+ });
1683
+ this.node = node;
1684
+ }
1685
+ isRunnable() {
1686
+ return this.base.isRunnable() && this.refinement.isRunnable();
1687
+ }
1688
+ get refinement() {
1689
+ return this.children.refinement;
1690
+ }
1691
+ set refinement(refinement) {
1692
+ this.edit();
1693
+ this.children.refinement = refinement;
1694
+ refinement.parent = this;
1695
+ }
1696
+ get base() {
1697
+ return this.children.base;
1698
+ }
1699
+ set base(base) {
1700
+ this.edit();
1701
+ this.children.base = base;
1702
+ }
1703
+ getOrAddDefaultSegment() {
1704
+ return this.refinement.getOrAddDefaultSegment();
1705
+ }
1706
+ addEmptyRefinement() {
1707
+ return this.refinement.addEmptyRefinement();
1708
+ }
1709
+ addViewRefinement(name, path) {
1710
+ return this.refinement.addViewRefinement(name, path);
1711
+ }
1712
+ getInputSchema() {
1713
+ return getInputSchemaFromViewParent(this.parent);
1714
+ }
1715
+ getOutputSchema() {
1716
+ const parent = this.parent;
1717
+ return parent.getOutputSchema();
1718
+ }
1719
+ getRefinementSchema() {
1720
+ return ASTNode.schemaMerge(this.base.getRefinementSchema(), this.refinement.getRefinementSchema());
1721
+ }
1722
+ getImplicitName() {
1723
+ return this.base.getImplicitName();
1724
+ }
1725
+ isValidViewRefinement(name, path) {
1726
+ return isValidViewRefinement(this, name, path);
1727
+ }
1728
+ /**
1729
+ * @internal
1730
+ */
1731
+ propagateUp(f) {
1732
+ this.parent.propagateUp(f);
1733
+ }
1734
+ /**
1735
+ * @internal
1736
+ */
1737
+ propagateDown(f) {
1738
+ f(this.base);
1739
+ f(this.refinement);
1740
+ this.base.propagateDown(f);
1741
+ this.refinement.propagateDown(f);
1742
+ }
1743
+ getInheritedAnnotations() {
1744
+ return this.base.getInheritedAnnotations();
1745
+ }
1746
+ /**
1747
+ * @internal
1748
+ */
1749
+ static viewRefinementOf(view, name, path) {
1750
+ return new ASTRefinementViewDefinition({
1751
+ kind: 'refinement',
1752
+ base: view,
1753
+ refinement: {
1754
+ kind: 'view_reference',
1755
+ name,
1756
+ path,
1757
+ },
1758
+ });
1759
+ }
1760
+ /**
1761
+ * @internal
1762
+ */
1763
+ static segmentRefinementOf(view) {
1764
+ return new ASTRefinementViewDefinition({
1765
+ kind: 'refinement',
1766
+ base: view,
1767
+ refinement: {
1768
+ kind: 'segment',
1769
+ operations: [],
1770
+ },
1771
+ });
1772
+ }
1773
+ }
1774
+ exports.ASTRefinementViewDefinition = ASTRefinementViewDefinition;
1775
+ class ASTSegmentViewDefinition extends ASTObjectNode {
1776
+ constructor(node) {
1777
+ super(node, {
1778
+ kind: 'segment',
1779
+ operations: new ASTViewOperationList(node.operations),
1780
+ });
1781
+ this.node = node;
1782
+ this.DEFAULT_INSERTION_ORDER = [
1783
+ 'where',
1784
+ 'group_by',
1785
+ 'aggregate',
1786
+ 'nest',
1787
+ 'order_by',
1788
+ ];
1789
+ }
1790
+ isRunnable() {
1791
+ for (const operation of this.operations.iter()) {
1792
+ if (operation instanceof ASTAggregateViewOperation ||
1793
+ operation instanceof ASTGroupByViewOperation ||
1794
+ operation instanceof ASTNestViewOperation) {
1795
+ return true;
1796
+ }
1797
+ }
1798
+ return false;
1799
+ }
1800
+ get operations() {
1801
+ return this.children.operations;
1802
+ }
1803
+ /**
1804
+ * @internal
1805
+ */
1806
+ renameOrderBys(oldName, newName) {
1807
+ for (const operation of this.operations.iter()) {
1808
+ if (operation instanceof ASTOrderByViewOperation) {
1809
+ if (operation.name === oldName) {
1810
+ operation.setField(newName);
1811
+ }
1812
+ }
1813
+ }
1814
+ }
1815
+ /**
1816
+ * @internal
1817
+ */
1818
+ propagateUp(f) {
1819
+ this.parent.propagateUp(f);
1820
+ }
1821
+ /**
1822
+ * @internal
1823
+ */
1824
+ propagateDown(_f) {
1825
+ return;
1826
+ }
1827
+ /**
1828
+ * @internal
1829
+ */
1830
+ removeOrderBys(name) {
1831
+ for (const operation of this.operations.iter()) {
1832
+ if (operation instanceof ASTOrderByViewOperation) {
1833
+ if (operation.name === name) {
1834
+ operation.delete();
1835
+ }
1836
+ }
1837
+ }
1838
+ }
1839
+ reorderFields(names) {
1840
+ const leadingOperations = [];
1841
+ const trailingOperations = [];
1842
+ const opsByName = {};
1843
+ let seenAnyNamed = false;
1844
+ for (const operation of this.operations.iter()) {
1845
+ if (operation instanceof ASTAggregateViewOperation ||
1846
+ operation instanceof ASTGroupByViewOperation ||
1847
+ operation instanceof ASTNestViewOperation) {
1848
+ if (names.includes(operation.name)) {
1849
+ opsByName[operation.name] = operation;
1850
+ seenAnyNamed = true;
1851
+ continue;
1852
+ }
1853
+ }
1854
+ if (seenAnyNamed) {
1855
+ trailingOperations.push(operation);
1856
+ }
1857
+ else {
1858
+ leadingOperations.push(operation);
1859
+ }
1860
+ }
1861
+ const middleOperations = [];
1862
+ for (const name of names) {
1863
+ const operation = opsByName[name];
1864
+ if (operation === undefined) {
1865
+ throw new Error(`No field named ${name}`);
1866
+ }
1867
+ middleOperations.push(operation);
1868
+ }
1869
+ const operations = [
1870
+ ...leadingOperations,
1871
+ ...middleOperations,
1872
+ ...trailingOperations,
1873
+ ];
1874
+ this.operations.items = operations;
1875
+ }
1876
+ renameField(field, name) {
1877
+ if (field.name === name)
1878
+ return;
1879
+ const output = this.getOutputSchema();
1880
+ if (ASTNode.schemaTryGet(output, name, [])) {
1881
+ throw new Error(`Output already has a field named ${name}`);
1882
+ }
1883
+ const oldName = field.name;
1884
+ field.name = name;
1885
+ this.propagateUp(v => {
1886
+ if (v instanceof ASTSegmentViewDefinition) {
1887
+ v.renameOrderBys(oldName, name);
1888
+ }
1889
+ });
1890
+ }
1891
+ /**
1892
+ * Adds an order by to the segment. Will override the direction of an existing order by
1893
+ * if one is present for the same field.
1894
+ *
1895
+ * ```
1896
+ * run: flights -> { group_by: carrier }
1897
+ * ```
1898
+ * ```ts
1899
+ * q.getOrAddDefaultSegment().addOrderBy("carrier", Malloy.OrderByDirection.DESC);
1900
+ * ```
1901
+ * ```
1902
+ * run: flights -> {
1903
+ * group_by: carrier
1904
+ * order_by: carrier desc
1905
+ * }
1906
+ * ```
1907
+ *
1908
+ * The order by item is added after an existing order by operation if one is present,
1909
+ * or to a new order by operation at the end of the query.
1910
+ *
1911
+ * @param name The name of the field to order by.
1912
+ * @param direction The order by direction (ascending or descending).
1913
+ */
1914
+ addOrderBy(name, direction) {
1915
+ // Ensure output schema has a field with this name
1916
+ const outputSchema = this.getOutputSchema();
1917
+ try {
1918
+ ASTNode.schemaGet(outputSchema, name, []);
1919
+ }
1920
+ catch {
1921
+ throw new Error(`No such field ${name} in stage output`);
1922
+ }
1923
+ // first see if there is already an order by for this field
1924
+ for (const operation of this.operations.iter()) {
1925
+ if (operation instanceof ASTOrderByViewOperation) {
1926
+ if (operation.name === name) {
1927
+ operation.direction = direction;
1928
+ return;
1929
+ }
1930
+ }
1931
+ }
1932
+ // add a new order by operation
1933
+ this.addOperation(new ASTOrderByViewOperation({
1934
+ kind: 'order_by',
1935
+ field_reference: { name },
1936
+ direction,
1937
+ }));
1938
+ }
1939
+ /**
1940
+ * Adds an empty nest to this segment, with the given name.
1941
+ * @param name The name of the new nest.
1942
+ *
1943
+ * The new nest is always added to the end of the query in a new nest block.
1944
+ *
1945
+ * ```
1946
+ * run: flights -> { group_by: carrier }
1947
+ * ```
1948
+ * ```ts
1949
+ * q.getOrAddDefaultSegment().addEmptyNest("by_origin");
1950
+ * ```
1951
+ * ```
1952
+ * run: flights -> {
1953
+ * group_by: carrier
1954
+ * nest: by_origin is { }
1955
+ * }
1956
+ * ```
1957
+ *
1958
+ * @returns The {@link ASTNestViewOperation} that was created.
1959
+ *
1960
+ */
1961
+ addEmptyNest(name) {
1962
+ const nest = new ASTNestViewOperation({
1963
+ kind: 'nest',
1964
+ name,
1965
+ view: {
1966
+ definition: {
1967
+ kind: 'segment',
1968
+ operations: [],
1969
+ },
1970
+ },
1971
+ });
1972
+ this.addOperation(nest);
1973
+ return nest;
1974
+ }
1975
+ firstIndexOfOperationType(type) {
1976
+ return this.operations.findIndex(o => o.kind === type);
1977
+ }
1978
+ findInsertionPoint(kind) {
1979
+ const firstOfType = this.firstIndexOfOperationType(kind);
1980
+ if (firstOfType > -1) {
1981
+ let i = firstOfType;
1982
+ while (this.operations.index(i) && this.operations.index(i).kind === kind)
1983
+ i++;
1984
+ return i;
1985
+ }
1986
+ const indexInOrder = this.DEFAULT_INSERTION_ORDER.indexOf(kind);
1987
+ if (indexInOrder === -1) {
1988
+ throw new Error(`Operation ${kind} is not supported for \`findInsertionPoint\``);
1989
+ }
1990
+ const laterOperations = this.DEFAULT_INSERTION_ORDER.slice(indexInOrder + 1);
1991
+ for (const laterType of laterOperations) {
1992
+ const firstOfType = this.firstIndexOfOperationType(laterType);
1993
+ return firstOfType;
1994
+ }
1995
+ return this.operations.length;
1996
+ }
1997
+ getFieldNamed(name) {
1998
+ const field = this.tryGetFieldNamed(name);
1999
+ if (field === undefined)
2000
+ throw new Error('No such field');
2001
+ return field;
2002
+ }
2003
+ hasFieldNamed(name) {
2004
+ return this.tryGetFieldNamed(name) !== undefined;
2005
+ }
2006
+ hasField(name, path) {
2007
+ return this.tryGetField(name, path) !== undefined;
2008
+ }
2009
+ getField(name, path) {
2010
+ const field = this.tryGetField(name, path);
2011
+ if (field === undefined) {
2012
+ throw new Error('No such field');
2013
+ }
2014
+ return field;
2015
+ }
2016
+ // TODO what constitutes "having a field" -- does "dep_time.month" count as dep_time?
2017
+ // does flight_count {where: carrier = 'CA' } count as flight_count?
2018
+ tryGetField(name, path) {
2019
+ for (const operation of this.operations.iter()) {
2020
+ if (operation instanceof ASTGroupByViewOperation ||
2021
+ operation instanceof ASTAggregateViewOperation) {
2022
+ const reference = operation.field.getReference();
2023
+ if (reference.name === name && pathsMatch(reference.path, path)) {
2024
+ return operation;
2025
+ }
2026
+ }
2027
+ else if (operation instanceof ASTNestViewOperation) {
2028
+ if (operation.view instanceof ASTReferenceViewDefinition) {
2029
+ return operation;
2030
+ }
2031
+ }
2032
+ }
2033
+ return undefined;
2034
+ }
2035
+ tryGetFieldNamed(name) {
2036
+ for (const operation of this.operations.iter()) {
2037
+ if (operation instanceof ASTGroupByViewOperation ||
2038
+ operation instanceof ASTAggregateViewOperation ||
2039
+ operation instanceof ASTNestViewOperation) {
2040
+ if (operation.name === name) {
2041
+ return operation;
2042
+ }
2043
+ }
2044
+ }
2045
+ return undefined;
2046
+ }
2047
+ getGroupBy(name) {
2048
+ for (const operation of this.operations.iter()) {
2049
+ if (operation instanceof ASTGroupByViewOperation) {
2050
+ if (operation.name === name) {
2051
+ return operation;
2052
+ }
2053
+ }
2054
+ }
2055
+ }
2056
+ removeGroupBy(name) {
2057
+ var _a;
2058
+ (_a = this.getGroupBy(name)) === null || _a === void 0 ? void 0 : _a.delete();
2059
+ return this;
2060
+ }
2061
+ /**
2062
+ * Adds a group by field with the given name to this segment.
2063
+ *
2064
+ * ```
2065
+ * run: flights -> { }
2066
+ * ```
2067
+ * ```ts
2068
+ * q.getOrAddDefaultSegment().addGroupBy("carrier");
2069
+ * ```
2070
+ * ```
2071
+ * run: flights -> { group_by: carrier }
2072
+ * ```
2073
+ *
2074
+ * If there is already a group by clause, the new field will be added
2075
+ * to that clause (or the first one if there are multiple).
2076
+ *
2077
+ * ```
2078
+ * run: flights -> { group_by: carrier }
2079
+ * ```
2080
+ * ```ts
2081
+ * q.getOrAddDefaultSegment().addGroupBy("origin_code");
2082
+ * ```
2083
+ * ```
2084
+ * run: flights -> {
2085
+ * group_by:
2086
+ * carrier
2087
+ * origin_code
2088
+ * }
2089
+ * ```
2090
+ *
2091
+ * If there is no group by clause, it will be added
2092
+ * 1) before the first aggregate clause if there is one, or
2093
+ * 2) before the first nest clause if there is one, or
2094
+ * 3) before the first order by clause if ther is one, or
2095
+ * 4) at the end of the query
2096
+ *
2097
+ * ```
2098
+ * run: flights -> {
2099
+ * order_by: flight_count
2100
+ * aggregate: flight_count
2101
+ * }
2102
+ * ```
2103
+ * ```ts
2104
+ * q.getOrAddDefaultSegment().addGroupBy("carrier");
2105
+ * ```
2106
+ * ```
2107
+ * run: flights -> {
2108
+ * order_by: flight_count
2109
+ * group_by: carrier
2110
+ * aggregate: flight_count
2111
+ * }
2112
+ * ```
2113
+ *
2114
+ * @param name The name of the dimension to group by.
2115
+ * @param path Join path for this dimension.
2116
+ */
2117
+ addGroupBy(name, path = [], rename) {
2118
+ const item = this.makeField(name, path, rename, 'dimension');
2119
+ this.addOperation(item);
2120
+ return item;
2121
+ }
2122
+ addWhere(name, arg2, arg3) {
2123
+ const path = Array.isArray(arg2) ? arg2 : [];
2124
+ const filter = arg3 === undefined ? arg2 : arg3;
2125
+ const filterString = typeof filter === 'string' ? filter : serializeFilter(filter);
2126
+ const schema = this.getInputSchema();
2127
+ // Validate name
2128
+ const field = ASTQuery.schemaGet(schema, name, path);
2129
+ // Validate filter
2130
+ validateFilter(field, filter);
2131
+ const item = new ASTWhereViewOperation({
2132
+ kind: 'where',
2133
+ filter: {
2134
+ kind: 'filter_string',
2135
+ field_reference: { name },
2136
+ filter: filterString,
2137
+ },
2138
+ });
2139
+ this.addOperation(item);
2140
+ return item;
2141
+ }
2142
+ addTimeGroupBy(name, path, timeframe, type) {
2143
+ const schema = this.getInputSchema();
2144
+ const fieldInfo = ASTNode.schemaGet(schema, name, path);
2145
+ if (fieldInfo === undefined) {
2146
+ throw new Error(`No such field ${name}`);
2147
+ }
2148
+ if (fieldInfo.kind !== 'dimension') {
2149
+ throw new Error(`Cannot group by non-dimension ${name}`);
2150
+ }
2151
+ if (fieldInfo.type.kind !== type) {
2152
+ throw new Error(`${name} is not a ${type}`);
2153
+ }
2154
+ const item = new ASTGroupByViewOperation({
2155
+ kind: 'group_by',
2156
+ field: {
2157
+ expression: {
2158
+ kind: 'time_truncation',
2159
+ field_reference: { name, path },
2160
+ truncation: timeframe,
2161
+ },
2162
+ },
2163
+ });
2164
+ this.addOperation(item);
2165
+ return item;
2166
+ }
2167
+ addDateGroupBy(name, arg2, arg3) {
2168
+ const timeframe = arg3 === undefined ? arg2 : arg3;
2169
+ const path = arg3 === undefined ? [] : arg2;
2170
+ return this.addTimeGroupBy(name, path, timeframe, 'date_type');
2171
+ }
2172
+ addTimestampGroupBy(name, arg2, arg3) {
2173
+ const timeframe = arg3 === undefined ? arg2 : arg3;
2174
+ const path = arg3 === undefined ? [] : arg2;
2175
+ return this.addTimeGroupBy(name, path, timeframe, 'timestamp_type');
2176
+ }
2177
+ /**
2178
+ * Adds an aggregate item with the given name to this segment.
2179
+ *
2180
+ * ```
2181
+ * run: flights -> { }
2182
+ * ```
2183
+ * ```ts
2184
+ * q.getOrAddDefaultSegment().addAggregate("flight_count");
2185
+ * ```
2186
+ * ```
2187
+ * run: flights -> { aggregate: flight_count }
2188
+ * ```
2189
+ *
2190
+ * Added
2191
+ * 1) at the end of an existing aggregate clause if ther is one, or
2192
+ * 2) before the first nest clause if there is one, or
2193
+ * 3) before the first order by clause if ther is one, or
2194
+ * 4) at the end of the query
2195
+ *
2196
+ * @param name The name of the measure to aggregate.
2197
+ * @param path The join path of the measure to aggregate.
2198
+ * @param rename A new name for this measure
2199
+ */
2200
+ addAggregate(name, path = [], rename) {
2201
+ const item = this.makeField(name, path, rename, 'measure');
2202
+ this.addOperation(item);
2203
+ return item;
2204
+ }
2205
+ /**
2206
+ * Adds a nest item with the given name to this segment.
2207
+ *
2208
+ * ```
2209
+ * run: flights -> { }
2210
+ * ```
2211
+ * ```ts
2212
+ * q.getOrAddDefaultSegment().addNest("by_carrier");
2213
+ * ```
2214
+ * ```
2215
+ * run: flights -> { nest: by_carrier }
2216
+ * ```
2217
+ *
2218
+ * Added
2219
+ * 1) at the end of an existing nest clause if there is one, or
2220
+ * 2) before the first order by clause if ther is one, or
2221
+ * 3) at the end of the query
2222
+ *
2223
+ * @param name The name of the view to nest.
2224
+ * @param rename A new name for this view in the query
2225
+ */
2226
+ addNest(name, rename) {
2227
+ const item = this.makeField(name, [], rename, 'view');
2228
+ this.addOperation(item);
2229
+ return item;
2230
+ }
2231
+ makeField(name, path, rename, type) {
2232
+ const schema = this.getInputSchema();
2233
+ const fieldInfo = ASTNode.schemaGet(schema, name, path);
2234
+ if (fieldInfo === undefined) {
2235
+ throw new Error(`No such field ${name}`);
2236
+ }
2237
+ if (fieldInfo.kind !== type) {
2238
+ const action = fieldTypeToAction(type);
2239
+ const typeName = fieldTypeName(type);
2240
+ throw new Error(`Cannot ${action} non-${typeName} ${name}`);
2241
+ }
2242
+ if (type === 'dimension') {
2243
+ return ASTGroupByViewOperation.fromReference(name, path, rename);
2244
+ }
2245
+ else if (type === 'measure') {
2246
+ return ASTAggregateViewOperation.fromReference(name, path, rename);
2247
+ }
2248
+ else {
2249
+ return ASTNestViewOperation.fromReference(name, path, rename);
2250
+ }
2251
+ }
2252
+ addOperation(item) {
2253
+ if (item instanceof ASTGroupByViewOperation ||
2254
+ item instanceof ASTAggregateViewOperation ||
2255
+ item instanceof ASTNestViewOperation) {
2256
+ if (this.hasFieldNamed(item.name)) {
2257
+ throw new Error(`Query already has a field named ${item.name}`);
2258
+ }
2259
+ }
2260
+ const whereToInsert = this.findInsertionPoint(item.kind);
2261
+ this.operations.insert(item, whereToInsert);
2262
+ return item;
2263
+ }
2264
+ /**
2265
+ * @internal
2266
+ */
2267
+ getRefinementSchema() {
2268
+ const fields = [];
2269
+ for (const operation of this.operations.iter()) {
2270
+ if (operation instanceof ASTGroupByViewOperation ||
2271
+ operation instanceof ASTAggregateViewOperation ||
2272
+ operation instanceof ASTNestViewOperation) {
2273
+ // TODO convert measures into dimensions for output
2274
+ fields.push(operation.getFieldInfo());
2275
+ }
2276
+ }
2277
+ return { fields };
2278
+ }
2279
+ /**
2280
+ * Sets the limit for this segment. Overrides an existing limit.
2281
+ *
2282
+ * ```
2283
+ * run: flights -> { group_by: carrier }
2284
+ * ```
2285
+ * ```ts
2286
+ * q.getOrAddDefaultSegment().setLimit(10);
2287
+ * ```
2288
+ * ```
2289
+ * run: flights -> {
2290
+ * group_by: carrier
2291
+ * limit: 10
2292
+ * }
2293
+ * ```
2294
+ *
2295
+ * @param limit The limit to set. Must be an integer.
2296
+ */
2297
+ setLimit(limit) {
2298
+ ASTLimitViewOperation.validateLimit(limit);
2299
+ const limitOp = [
2300
+ ...this.operations.iter(),
2301
+ ].find(exports.ASTViewOperation.isLimit);
2302
+ if (limitOp) {
2303
+ limitOp.limit = limit;
2304
+ }
2305
+ else {
2306
+ this.operations.add(new ASTLimitViewOperation({
2307
+ kind: 'limit',
2308
+ limit,
2309
+ }));
2310
+ }
2311
+ }
2312
+ getOrAddDefaultSegment() {
2313
+ return this;
2314
+ }
2315
+ addEmptyRefinement() {
2316
+ const view = ASTRefinementViewDefinition.segmentRefinementOf(this.build());
2317
+ swapViewInParent(this, view);
2318
+ return view.refinement.asSegmentViewDefinition();
2319
+ }
2320
+ addViewRefinement(name, path) {
2321
+ const { error } = this.isValidViewRefinement(name, path);
2322
+ if (error) {
2323
+ throw new Error(error);
2324
+ }
2325
+ const view = ASTRefinementViewDefinition.viewRefinementOf(this.build(), name, path);
2326
+ swapViewInParent(this, view);
2327
+ return view.refinement.asReferenceViewDefinition();
2328
+ }
2329
+ getInputSchema() {
2330
+ return getInputSchemaFromViewParent(this.parent);
2331
+ }
2332
+ getOutputSchema() {
2333
+ const parent = this.parent;
2334
+ return parent.getOutputSchema();
2335
+ }
2336
+ getImplicitName() {
2337
+ return undefined;
2338
+ }
2339
+ isValidViewRefinement(name, path) {
2340
+ return isValidViewRefinement(this, name, path);
2341
+ }
2342
+ getInheritedAnnotations() {
2343
+ return [];
2344
+ }
2345
+ }
2346
+ exports.ASTSegmentViewDefinition = ASTSegmentViewDefinition;
2347
+ class ASTViewOperationList extends ASTListNode {
2348
+ constructor(operations) {
2349
+ super(operations, operations.map(p => exports.ASTViewOperation.from(p)));
2350
+ }
2351
+ get items() {
2352
+ return this.children;
2353
+ }
2354
+ /**
2355
+ * @internal
2356
+ */
2357
+ set items(operations) {
2358
+ this.edit();
2359
+ this.children = operations;
2360
+ }
2361
+ /**
2362
+ * @internal
2363
+ */
2364
+ get segment() {
2365
+ return this.parent.asSegmentViewDefinition();
2366
+ }
2367
+ }
2368
+ exports.ASTViewOperationList = ASTViewOperationList;
2369
+ exports.ASTViewOperation = {
2370
+ from(value) {
2371
+ switch (value.kind) {
2372
+ case 'group_by':
2373
+ return new ASTGroupByViewOperation(value);
2374
+ case 'aggregate':
2375
+ return new ASTAggregateViewOperation(value);
2376
+ case 'order_by':
2377
+ return new ASTOrderByViewOperation(value);
2378
+ case 'nest':
2379
+ return new ASTNestViewOperation(value);
2380
+ case 'limit':
2381
+ return new ASTLimitViewOperation(value);
2382
+ case 'where':
2383
+ return new ASTWhereViewOperation(value);
2384
+ }
2385
+ },
2386
+ isLimit(x) {
2387
+ return x instanceof ASTLimitViewOperation;
2388
+ },
2389
+ };
2390
+ class ASTOrderByViewOperation extends ASTObjectNode {
2391
+ constructor(node) {
2392
+ super(node, {
2393
+ kind: 'order_by',
2394
+ field_reference: new ASTFieldReference(node.field_reference),
2395
+ direction: node.direction,
2396
+ });
2397
+ this.node = node;
2398
+ this.kind = 'order_by';
2399
+ }
2400
+ get fieldReference() {
2401
+ return this.children.field_reference;
2402
+ }
2403
+ get name() {
2404
+ return this.fieldReference.name;
2405
+ }
2406
+ get direction() {
2407
+ return this.children.direction;
2408
+ }
2409
+ set direction(direction) {
2410
+ if (this.direction === direction)
2411
+ return;
2412
+ this.edit();
2413
+ this.children.direction = direction;
2414
+ }
2415
+ get list() {
2416
+ return this.parent.asViewOperationList();
2417
+ }
2418
+ delete() {
2419
+ const list = this.list;
2420
+ list.remove(this);
2421
+ }
2422
+ setField(name) {
2423
+ const schema = this.list.segment.getOutputSchema();
2424
+ ASTNode.schemaGet(schema, name, []);
2425
+ this.edit();
2426
+ this.children.field_reference = new ASTFieldReference({ name });
2427
+ }
2428
+ setDirection(direction) {
2429
+ this.direction = direction;
2430
+ }
2431
+ }
2432
+ exports.ASTOrderByViewOperation = ASTOrderByViewOperation;
2433
+ class ASTGroupByViewOperation extends ASTObjectNode {
2434
+ constructor(node) {
2435
+ super(node, {
2436
+ kind: 'group_by',
2437
+ name: node.name,
2438
+ field: new ASTField(node.field),
2439
+ });
2440
+ this.node = node;
2441
+ this.kind = 'group_by';
2442
+ }
2443
+ get field() {
2444
+ return this.children.field;
2445
+ }
2446
+ get name() {
2447
+ var _a;
2448
+ return (_a = this.children.name) !== null && _a !== void 0 ? _a : this.field.name;
2449
+ }
2450
+ set name(name) {
2451
+ if (this.name === name)
2452
+ return;
2453
+ this.edit();
2454
+ if (this.field.name === name) {
2455
+ this.children.name = undefined;
2456
+ }
2457
+ else {
2458
+ this.children.name = name;
2459
+ }
2460
+ }
2461
+ /**
2462
+ * @internal
2463
+ */
2464
+ get list() {
2465
+ return this.parent.asViewOperationList();
2466
+ }
2467
+ /**
2468
+ * Renames the group by item. If the field's name matches the given name,
2469
+ * removes the `name is` part.
2470
+ *
2471
+ * ```
2472
+ * run: flights -> { group_by: carrier }
2473
+ * ```
2474
+ * ```ts
2475
+ * groupBy.rename("carrier_2");
2476
+ * ```
2477
+ * ```
2478
+ * run: flights -> { group_by: carrier2 is carrier }
2479
+ * ```
2480
+ *
2481
+ * ```
2482
+ * run: flights -> { group_by: renamed is carrier }
2483
+ * ```
2484
+ * ```ts
2485
+ * groupBy.rename("carrier");
2486
+ * ```
2487
+ * ```
2488
+ * run: flights -> { group_by: carrier }
2489
+ * ```
2490
+ *
2491
+ *
2492
+ * @param name The new name
2493
+ */
2494
+ rename(name) {
2495
+ this.list.segment.renameField(this, name);
2496
+ }
2497
+ /**
2498
+ * Delete this group by item.
2499
+ *
2500
+ * Possible side effects:
2501
+ * - If this was the last item in the group by operation, the whole
2502
+ * operation is removed.
2503
+ * - Any order by that references this group by item will be removed.
2504
+ *
2505
+ * ```
2506
+ * run: flights -> {
2507
+ * group_by: carrier
2508
+ * aggregate: flight_count
2509
+ * order by:
2510
+ * flight_count desc
2511
+ * carrier asc
2512
+ * }
2513
+ * ```
2514
+ * ```ts
2515
+ * groupBy.delete();
2516
+ * ```
2517
+ * ```
2518
+ * run: flights -> {
2519
+ * aggregate: flight_count
2520
+ * order by: flight_count desc
2521
+ * }
2522
+ * ```
2523
+ *
2524
+ */
2525
+ delete() {
2526
+ this.list.remove(this);
2527
+ this.list.segment.propagateUp(v => {
2528
+ if (v instanceof ASTSegmentViewDefinition) {
2529
+ v.removeOrderBys(this.name);
2530
+ }
2531
+ });
2532
+ }
2533
+ getFieldInfo() {
2534
+ return {
2535
+ kind: 'dimension',
2536
+ name: this.name,
2537
+ type: this.field.type,
2538
+ };
2539
+ }
2540
+ get annotations() {
2541
+ return this.field.annotations;
2542
+ }
2543
+ set annotations(annotations) {
2544
+ this.edit();
2545
+ this.field.annotations = annotations;
2546
+ }
2547
+ getOrAddAnnotations() {
2548
+ return this.field.getOrAddAnnotations();
2549
+ }
2550
+ getInheritedTag(prefix = '# ') {
2551
+ return tagFromAnnotations(prefix, this.field.getInheritedAnnotations());
2552
+ }
2553
+ getIntrinsicTag(prefix = '# ') {
2554
+ var _a, _b;
2555
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getIntrinsicTag(prefix)) !== null && _b !== void 0 ? _b : new malloy_tag_1.Tag();
2556
+ }
2557
+ getTag(prefix = '# ') {
2558
+ var _a, _b;
2559
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getTag(prefix)) !== null && _b !== void 0 ? _b : this.getInheritedTag(prefix);
2560
+ }
2561
+ setTagProperty(path, value = null, prefix = '# ') {
2562
+ this.getOrAddAnnotations().setTagProperty(path, value, prefix);
2563
+ }
2564
+ removeTagProperty(path, prefix = '# ') {
2565
+ if (!this.getTag().has(...path))
2566
+ return;
2567
+ this.getOrAddAnnotations().removeTagProperty(path, prefix);
2568
+ }
2569
+ /**
2570
+ * @internal
2571
+ */
2572
+ static fromReference(name, path, rename) {
2573
+ return new ASTGroupByViewOperation({
2574
+ kind: 'group_by',
2575
+ name: rename,
2576
+ field: {
2577
+ expression: {
2578
+ kind: 'field_reference',
2579
+ name,
2580
+ path,
2581
+ },
2582
+ },
2583
+ });
2584
+ }
2585
+ }
2586
+ exports.ASTGroupByViewOperation = ASTGroupByViewOperation;
2587
+ class ASTAggregateViewOperation extends ASTObjectNode {
2588
+ constructor(node) {
2589
+ super(node, {
2590
+ kind: 'aggregate',
2591
+ name: node.name,
2592
+ field: new ASTField(node.field),
2593
+ });
2594
+ this.node = node;
2595
+ this.kind = 'aggregate';
2596
+ }
2597
+ get field() {
2598
+ return this.children.field;
2599
+ }
2600
+ get name() {
2601
+ var _a;
2602
+ return (_a = this.children.name) !== null && _a !== void 0 ? _a : this.field.name;
2603
+ }
2604
+ set name(name) {
2605
+ if (this.name === name)
2606
+ return;
2607
+ this.edit();
2608
+ if (this.field.name === name) {
2609
+ this.children.name = undefined;
2610
+ }
2611
+ else {
2612
+ this.children.name = name;
2613
+ }
2614
+ }
2615
+ get annotations() {
2616
+ return this.field.annotations;
2617
+ }
2618
+ /**
2619
+ * Renames the aggregate item. If the field's name matches the given name,
2620
+ * removes the `name is` part.
2621
+ *
2622
+ * ```
2623
+ * run: flights -> { aggregate: flight_count }
2624
+ * ```
2625
+ * ```ts
2626
+ * aggregate.rename("flight_count_2");
2627
+ * ```
2628
+ * ```
2629
+ * run: flights -> { aggregate: flight_count2 is flight_count }
2630
+ * ```
2631
+ *
2632
+ * ```
2633
+ * run: flights -> { aggregate: renamed is flight_count }
2634
+ * ```
2635
+ * ```ts
2636
+ * aggregate.rename("flight_count");
2637
+ * ```
2638
+ * ```
2639
+ * run: flights -> { aggregate: flight_count }
2640
+ * ```
2641
+ *
2642
+ *
2643
+ * @param name The new name
2644
+ */
2645
+ rename(name) {
2646
+ this.list.segment.renameField(this, name);
2647
+ }
2648
+ /**
2649
+ * @internal
2650
+ */
2651
+ get list() {
2652
+ return this.parent.asViewOperationList();
2653
+ }
2654
+ delete() {
2655
+ this.list.remove(this);
2656
+ this.list.segment.propagateUp(v => {
2657
+ if (v instanceof ASTSegmentViewDefinition) {
2658
+ v.removeOrderBys(this.name);
2659
+ }
2660
+ });
2661
+ }
2662
+ getFieldInfo() {
2663
+ return {
2664
+ kind: 'dimension',
2665
+ name: this.name,
2666
+ type: this.field.type,
2667
+ };
2668
+ }
2669
+ getOrAddAnnotations() {
2670
+ return this.field.getOrAddAnnotations();
2671
+ }
2672
+ getInheritedTag(prefix = '# ') {
2673
+ return tagFromAnnotations(prefix, this.field.getInheritedAnnotations());
2674
+ }
2675
+ getIntrinsicTag(prefix = '# ') {
2676
+ var _a, _b;
2677
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getIntrinsicTag(prefix)) !== null && _b !== void 0 ? _b : new malloy_tag_1.Tag();
2678
+ }
2679
+ getTag(prefix = '# ') {
2680
+ var _a, _b;
2681
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getTag(prefix)) !== null && _b !== void 0 ? _b : this.getInheritedTag(prefix);
2682
+ }
2683
+ setTagProperty(path, value = null, prefix = '# ') {
2684
+ this.getOrAddAnnotations().setTagProperty(path, value, prefix);
2685
+ }
2686
+ removeTagProperty(path, prefix = '# ') {
2687
+ if (!this.getTag().has(...path))
2688
+ return;
2689
+ this.getOrAddAnnotations().removeTagProperty(path, prefix);
2690
+ }
2691
+ addWhere(name, arg2, arg3) {
2692
+ const path = Array.isArray(arg2) ? arg2 : [];
2693
+ const filter = arg3 === undefined ? arg2 : arg3;
2694
+ const filterString = typeof filter === 'string' ? filter : serializeFilter(filter);
2695
+ const schema = this.list.segment.getInputSchema();
2696
+ const field = ASTQuery.schemaGet(schema, name, path);
2697
+ // Validate filter
2698
+ validateFilter(field, filter);
2699
+ const where = {
2700
+ filter: {
2701
+ kind: 'filter_string',
2702
+ field_reference: { name },
2703
+ filter: filterString,
2704
+ },
2705
+ };
2706
+ if (this.field.expression instanceof ASTFilteredFieldExpression) {
2707
+ this.field.expression.where.add(new ASTWhere(where));
2708
+ return this.field.expression;
2709
+ }
2710
+ else if (this.field.expression instanceof ASTReferenceExpression) {
2711
+ const existing = this.field.expression.build();
2712
+ this.field.expression = new ASTFilteredFieldExpression({
2713
+ kind: 'filtered_field',
2714
+ field_reference: {
2715
+ name: existing.name,
2716
+ path: existing.path,
2717
+ parameters: existing.parameters,
2718
+ },
2719
+ where: [where],
2720
+ });
2721
+ return this.field.expression;
2722
+ }
2723
+ else {
2724
+ throw new Error('This kind of expression does not support addWhere');
2725
+ }
2726
+ }
2727
+ /**
2728
+ * @internal
2729
+ */
2730
+ static fromReference(name, path, rename) {
2731
+ return new ASTAggregateViewOperation({
2732
+ kind: 'aggregate',
2733
+ name: rename,
2734
+ field: {
2735
+ expression: {
2736
+ kind: 'field_reference',
2737
+ name,
2738
+ path,
2739
+ },
2740
+ },
2741
+ });
2742
+ }
2743
+ }
2744
+ exports.ASTAggregateViewOperation = ASTAggregateViewOperation;
2745
+ class ASTField extends ASTObjectNode {
2746
+ constructor(node) {
2747
+ super(node, {
2748
+ expression: exports.ASTExpression.from(node.expression),
2749
+ annotations: node.annotations && new ASTAnnotationList(node.annotations),
2750
+ });
2751
+ this.node = node;
2752
+ }
2753
+ get expression() {
2754
+ return this.children.expression;
2755
+ }
2756
+ set expression(expression) {
2757
+ this.edit();
2758
+ this.children.expression = expression;
2759
+ expression.parent = this;
2760
+ }
2761
+ get name() {
2762
+ return this.expression.name;
2763
+ }
2764
+ get type() {
2765
+ return this.expression.fieldType;
2766
+ }
2767
+ get annotations() {
2768
+ return this.children.annotations;
2769
+ }
2770
+ set annotations(annotations) {
2771
+ this.edit();
2772
+ this.children.annotations = annotations;
2773
+ }
2774
+ // Returns a Malloy reference that this field points to
2775
+ getReference() {
2776
+ return this.expression.getReference();
2777
+ }
2778
+ getOrAddAnnotations() {
2779
+ if (this.annotations)
2780
+ return this.annotations;
2781
+ this.edit();
2782
+ const annotations = new ASTAnnotationList([]);
2783
+ this.children.annotations = annotations;
2784
+ return annotations;
2785
+ }
2786
+ getInheritedTag(prefix = '# ') {
2787
+ return tagFromAnnotations(prefix, this.getInheritedAnnotations());
2788
+ }
2789
+ getIntrinsicTag(prefix = '# ') {
2790
+ var _a, _b;
2791
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getIntrinsicTag(prefix)) !== null && _b !== void 0 ? _b : new malloy_tag_1.Tag();
2792
+ }
2793
+ getTag(prefix = '# ') {
2794
+ var _a, _b;
2795
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getTag(prefix)) !== null && _b !== void 0 ? _b : this.getInheritedTag(prefix);
2796
+ }
2797
+ setTagProperty(path, value = null, prefix = '# ') {
2798
+ this.getOrAddAnnotations().setTagProperty(path, value, prefix);
2799
+ }
2800
+ removeTagProperty(path, prefix = '# ') {
2801
+ if (!this.getTag().has(...path))
2802
+ return;
2803
+ this.getOrAddAnnotations().removeTagProperty(path, prefix);
2804
+ }
2805
+ /**
2806
+ * @internal
2807
+ */
2808
+ get segment() {
2809
+ const groupByOrAggregate = this.parent;
2810
+ const operationList = groupByOrAggregate.list;
2811
+ return operationList.segment;
2812
+ }
2813
+ getInheritedAnnotations() {
2814
+ return this.expression.getInheritedAnnotations();
2815
+ }
2816
+ }
2817
+ exports.ASTField = ASTField;
2818
+ exports.ASTExpression = {
2819
+ from(value) {
2820
+ switch (value.kind) {
2821
+ case 'field_reference':
2822
+ return new ASTReferenceExpression(value);
2823
+ case 'filtered_field':
2824
+ return new ASTFilteredFieldExpression(value);
2825
+ case 'time_truncation':
2826
+ return new ASTTimeTruncationExpression(value);
2827
+ }
2828
+ },
2829
+ };
2830
+ // TODO would be nice for this to extend ASTFieldReference?
2831
+ class ASTReferenceExpression extends ASTObjectNode {
2832
+ constructor(node) {
2833
+ super(node, {
2834
+ kind: node.kind,
2835
+ name: node.name,
2836
+ path: node.path,
2837
+ parameters: node.parameters && new ASTParameterValueList(node.parameters),
2838
+ });
2839
+ this.node = node;
2840
+ this.kind = 'field_reference';
2841
+ }
2842
+ get name() {
2843
+ return this.children.name;
2844
+ }
2845
+ get parameters() {
2846
+ return this.children.parameters;
2847
+ }
2848
+ set parameters(parameters) {
2849
+ this.edit();
2850
+ this.children.parameters = parameters;
2851
+ }
2852
+ /**
2853
+ * @internal
2854
+ */
2855
+ get field() {
2856
+ return this.parent.asField();
2857
+ }
2858
+ get path() {
2859
+ return this.children.path;
2860
+ }
2861
+ getReference() {
2862
+ return this.build();
2863
+ }
2864
+ getFieldInfo() {
2865
+ const schema = this.field.segment.getInputSchema();
2866
+ const def = ASTNode.schemaGet(schema, this.name, this.path);
2867
+ if (def.kind !== 'dimension' && def.kind !== 'measure') {
2868
+ throw new Error('Invalid field for ASTReferenceExpression');
2869
+ }
2870
+ return def;
2871
+ }
2872
+ get fieldType() {
2873
+ return this.getFieldInfo().type;
2874
+ }
2875
+ getInheritedAnnotations() {
2876
+ var _a;
2877
+ const field = this.getFieldInfo();
2878
+ return (_a = field.annotations) !== null && _a !== void 0 ? _a : [];
2879
+ }
2880
+ getOrAddParameters() {
2881
+ return ASTReference.getOrAddParameters(this);
2882
+ }
2883
+ setParameter(name, value) {
2884
+ return ASTReference.setParameter(this, name, value);
2885
+ }
2886
+ tryGetParameter(name) {
2887
+ return ASTReference.tryGetParameter(this, name);
2888
+ }
2889
+ }
2890
+ exports.ASTReferenceExpression = ASTReferenceExpression;
2891
+ class ASTTimeTruncationExpression extends ASTObjectNode {
2892
+ constructor(node) {
2893
+ super(node, {
2894
+ kind: node.kind,
2895
+ field_reference: new ASTFieldReference(node.field_reference),
2896
+ truncation: node.truncation,
2897
+ });
2898
+ this.node = node;
2899
+ this.kind = 'time_truncation';
2900
+ }
2901
+ getReference() {
2902
+ return this.fieldReference.build();
2903
+ }
2904
+ get fieldReference() {
2905
+ return this.children.field_reference;
2906
+ }
2907
+ get truncation() {
2908
+ return this.children.truncation;
2909
+ }
2910
+ get name() {
2911
+ return this.fieldReference.name;
2912
+ }
2913
+ /**
2914
+ * @internal
2915
+ */
2916
+ get field() {
2917
+ return this.parent.asField();
2918
+ }
2919
+ getFieldInfo() {
2920
+ const schema = this.field.segment.getInputSchema();
2921
+ const def = ASTNode.schemaGet(schema, this.name, this.fieldReference.path);
2922
+ if (def.kind !== 'dimension' && def.kind !== 'measure') {
2923
+ throw new Error('Invalid field for ASTReferenceExpression');
2924
+ }
2925
+ return def;
2926
+ }
2927
+ get fieldType() {
2928
+ const def = this.getFieldInfo();
2929
+ if (def.type.kind === 'date_type') {
2930
+ return {
2931
+ ...def.type,
2932
+ timeframe: timestampTimeframeToDateTimeframe(this.truncation),
2933
+ };
2934
+ }
2935
+ else if (def.type.kind === 'timestamp_type') {
2936
+ return { ...def.type, timeframe: this.truncation };
2937
+ }
2938
+ throw new Error('This type of field cannot have a time truncation');
2939
+ }
2940
+ getInheritedAnnotations() {
2941
+ var _a;
2942
+ const field = this.getFieldInfo();
2943
+ return (_a = field.annotations) !== null && _a !== void 0 ? _a : [];
2944
+ }
2945
+ }
2946
+ exports.ASTTimeTruncationExpression = ASTTimeTruncationExpression;
2947
+ class ASTWhere extends ASTObjectNode {
2948
+ constructor(node) {
2949
+ super(node, {
2950
+ filter: exports.ASTFilter.from(node.filter),
2951
+ });
2952
+ }
2953
+ get filter() {
2954
+ return this.children.filter;
2955
+ }
2956
+ get list() {
2957
+ return this.parent.asWhereList();
2958
+ }
2959
+ delete() {
2960
+ this.list.remove(this);
2961
+ }
2962
+ }
2963
+ exports.ASTWhere = ASTWhere;
2964
+ class ASTWhereList extends ASTListNode {
2965
+ constructor(wheres) {
2966
+ super(wheres, wheres.map(p => new ASTWhere(p)));
2967
+ }
2968
+ get expression() {
2969
+ return this.parent.asFilteredFieldExpression();
2970
+ }
2971
+ }
2972
+ exports.ASTWhereList = ASTWhereList;
2973
+ class ASTFilteredFieldExpression extends ASTObjectNode {
2974
+ constructor(node) {
2975
+ super(node, {
2976
+ kind: node.kind,
2977
+ field_reference: new ASTFieldReference(node.field_reference),
2978
+ where: new ASTWhereList(node.where),
2979
+ });
2980
+ this.node = node;
2981
+ this.kind = 'filtered_field';
2982
+ }
2983
+ getReference() {
2984
+ return this.fieldReference.build();
2985
+ }
2986
+ get fieldReference() {
2987
+ return this.children.field_reference;
2988
+ }
2989
+ get name() {
2990
+ return this.fieldReference.name;
2991
+ }
2992
+ get where() {
2993
+ return this.children.where;
2994
+ }
2995
+ /**
2996
+ * @internal
2997
+ */
2998
+ get field() {
2999
+ return this.parent.asField();
3000
+ }
3001
+ getFieldInfo() {
3002
+ const schema = this.field.segment.getInputSchema();
3003
+ const def = ASTNode.schemaGet(schema, this.name, this.fieldReference.path);
3004
+ if (def.kind !== 'measure') {
3005
+ throw new Error('Invalid field for ASTFilteredFieldExpression');
3006
+ }
3007
+ return def;
3008
+ }
3009
+ get fieldType() {
3010
+ return this.getFieldInfo().type;
3011
+ }
3012
+ getInheritedAnnotations() {
3013
+ var _a;
3014
+ const field = this.getFieldInfo();
3015
+ return (_a = field.annotations) !== null && _a !== void 0 ? _a : [];
3016
+ }
3017
+ }
3018
+ exports.ASTFilteredFieldExpression = ASTFilteredFieldExpression;
3019
+ function timestampTimeframeToDateTimeframe(timeframe) {
3020
+ switch (timeframe) {
3021
+ case 'day':
3022
+ case 'week':
3023
+ case 'month':
3024
+ case 'year':
3025
+ case 'quarter':
3026
+ return timeframe;
3027
+ default:
3028
+ throw new Error('Invalid date timeframe');
3029
+ }
3030
+ }
3031
+ class ASTNestViewOperation extends ASTObjectNode {
3032
+ constructor(node) {
3033
+ super(node, {
3034
+ kind: 'nest',
3035
+ name: node.name,
3036
+ view: new ASTView(node.view),
3037
+ });
3038
+ this.node = node;
3039
+ this.kind = 'nest';
3040
+ }
3041
+ get view() {
3042
+ return this.children.view;
3043
+ }
3044
+ get annotations() {
3045
+ return this.view.annotations;
3046
+ }
3047
+ get name() {
3048
+ var _a;
3049
+ const name = (_a = this.children.name) !== null && _a !== void 0 ? _a : this.view.name;
3050
+ if (name === undefined) {
3051
+ throw new Error('Nest does not have a name');
3052
+ }
3053
+ return name;
3054
+ }
3055
+ set name(name) {
3056
+ if (this.name === name)
3057
+ return;
3058
+ this.edit();
3059
+ if (this.view.name === name) {
3060
+ this.children.name = undefined;
3061
+ }
3062
+ else {
3063
+ this.children.name = name;
3064
+ }
3065
+ }
3066
+ /**
3067
+ * @internal
3068
+ */
3069
+ get list() {
3070
+ return this.parent.asViewOperationList();
3071
+ }
3072
+ getOrAddAnnotations() {
3073
+ return this.view.getOrAddAnnotations();
3074
+ }
3075
+ getInheritedTag(prefix = '# ') {
3076
+ return tagFromAnnotations(prefix, this.view.getInheritedAnnotations());
3077
+ }
3078
+ getIntrinsicTag(prefix = '# ') {
3079
+ var _a, _b;
3080
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getIntrinsicTag(prefix)) !== null && _b !== void 0 ? _b : new malloy_tag_1.Tag();
3081
+ }
3082
+ getTag(prefix = '# ') {
3083
+ var _a, _b;
3084
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getTag(prefix)) !== null && _b !== void 0 ? _b : this.getInheritedTag(prefix);
3085
+ }
3086
+ setTagProperty(path, value = null, prefix = '# ') {
3087
+ this.getOrAddAnnotations().setTagProperty(path, value, prefix);
3088
+ }
3089
+ removeTagProperty(path, prefix = '# ') {
3090
+ if (!this.getTag().has(...path))
3091
+ return;
3092
+ this.getOrAddAnnotations().removeTagProperty(path, prefix);
3093
+ }
3094
+ delete() {
3095
+ this.list.remove(this);
3096
+ }
3097
+ /**
3098
+ * Renames the nest item. If the view's name matches the given name,
3099
+ * removes the `name is` part.
3100
+ *
3101
+ * ```
3102
+ * run: flights -> { nest: by_carrier }
3103
+ * ```
3104
+ * ```ts
3105
+ * nest.rename("by_carrier_2");
3106
+ * ```
3107
+ * ```
3108
+ * run: flights -> { nest: by_carrier_2 is by_carrier }
3109
+ * ```
3110
+ *
3111
+ * ```
3112
+ * run: flights -> { nest: by_carrier_2 is by_carrier }
3113
+ * ```
3114
+ * ```ts
3115
+ * nest.rename("by_carrier");
3116
+ * ```
3117
+ * ```
3118
+ * run: flights -> { nest: by_carrier }
3119
+ * ```
3120
+ *
3121
+ * ```
3122
+ * run: flights -> {
3123
+ * nest: by_carrier is {
3124
+ * group_by: carrier
3125
+ * }
3126
+ * }
3127
+ * ```
3128
+ * ```ts
3129
+ * nest.rename("by_carrier_2");
3130
+ * ```
3131
+ * ```
3132
+ * run: flights -> {
3133
+ * nest: by_carrier_2 is {
3134
+ * group_by: carrier
3135
+ * }
3136
+ * }
3137
+ * ```
3138
+ *
3139
+ * @param name The new name
3140
+ */
3141
+ rename(name) {
3142
+ this.list.segment.renameField(this, name);
3143
+ }
3144
+ getFieldInfo() {
3145
+ return {
3146
+ kind: 'view',
3147
+ name: this.name,
3148
+ definition: this.view.build(),
3149
+ schema: this.view.getOutputSchema(),
3150
+ };
3151
+ }
3152
+ /**
3153
+ * @internal
3154
+ */
3155
+ static fromReference(name, path, rename) {
3156
+ return new ASTNestViewOperation({
3157
+ kind: 'nest',
3158
+ name: rename,
3159
+ view: {
3160
+ definition: {
3161
+ kind: 'view_reference',
3162
+ name,
3163
+ path,
3164
+ },
3165
+ },
3166
+ });
3167
+ }
3168
+ }
3169
+ exports.ASTNestViewOperation = ASTNestViewOperation;
3170
+ class ASTWhereViewOperation extends ASTObjectNode {
3171
+ constructor(node) {
3172
+ super(node, {
3173
+ kind: 'where',
3174
+ filter: exports.ASTFilter.from(node.filter),
3175
+ });
3176
+ this.node = node;
3177
+ this.kind = 'nest';
3178
+ }
3179
+ get filter() {
3180
+ return this.children.filter;
3181
+ }
3182
+ /**
3183
+ * @internal
3184
+ */
3185
+ get list() {
3186
+ return this.parent.asViewOperationList();
3187
+ }
3188
+ delete() {
3189
+ this.list.remove(this);
3190
+ }
3191
+ }
3192
+ exports.ASTWhereViewOperation = ASTWhereViewOperation;
3193
+ exports.ASTFilter = {
3194
+ from(filter) {
3195
+ return new ASTFilterWithFilterString(filter);
3196
+ },
3197
+ };
3198
+ class ASTFilterWithFilterString extends ASTObjectNode {
3199
+ constructor(node) {
3200
+ super(node, {
3201
+ kind: 'filter_string',
3202
+ field_reference: new ASTFieldReference(node.field_reference),
3203
+ filter: node.filter,
3204
+ });
3205
+ this.node = node;
3206
+ this.kind = 'filter_string';
3207
+ }
3208
+ get fieldReference() {
3209
+ return this.children.field_reference;
3210
+ }
3211
+ get filterString() {
3212
+ return this.children.filter;
3213
+ }
3214
+ set filterString(filter) {
3215
+ this.edit();
3216
+ this.children.filter = filter;
3217
+ }
3218
+ setFilterString(filterString) {
3219
+ const kind = this.getFilterType();
3220
+ parseFilter(this.filterString, kind);
3221
+ this.filterString = filterString;
3222
+ }
3223
+ getFieldInfo() {
3224
+ const field = this.fieldReference.getFieldInfo();
3225
+ if (field.kind !== 'dimension' && field.kind !== 'measure') {
3226
+ throw new Error('Invalid field type for filter with filter string');
3227
+ }
3228
+ return field;
3229
+ }
3230
+ getFilterType() {
3231
+ const fieldInfo = this.getFieldInfo();
3232
+ return getFilterType(fieldInfo);
3233
+ }
3234
+ setFilter(filter) {
3235
+ const kind = this.getFilterType();
3236
+ if (kind !== filter.kind) {
3237
+ throw new Error(`Invalid filter: expected type ${kind}, got ${filter.kind}`);
3238
+ }
3239
+ this.filterString = serializeFilter(filter);
3240
+ }
3241
+ getFilter() {
3242
+ const kind = this.getFilterType();
3243
+ return parseFilter(this.filterString, kind);
3244
+ }
3245
+ }
3246
+ exports.ASTFilterWithFilterString = ASTFilterWithFilterString;
3247
+ class ASTView extends ASTObjectNode {
3248
+ constructor(node) {
3249
+ super(node, {
3250
+ definition: ASTViewDefinition.from(node.definition),
3251
+ annotations: node.annotations && new ASTAnnotationList(node.annotations),
3252
+ });
3253
+ this.node = node;
3254
+ }
3255
+ get definition() {
3256
+ return this.children.definition;
3257
+ }
3258
+ set definition(definition) {
3259
+ this.edit();
3260
+ this.children.definition = definition;
3261
+ definition.parent = this;
3262
+ }
3263
+ get name() {
3264
+ return this.definition.getImplicitName();
3265
+ }
3266
+ getOrAddDefaultSegment() {
3267
+ return this.definition.getOrAddDefaultSegment();
3268
+ }
3269
+ /**
3270
+ * @internal
3271
+ */
3272
+ get nest() {
3273
+ return this.parent.asNestViewOperation();
3274
+ }
3275
+ getInputSchema() {
3276
+ return this.nest.list.segment.getInputSchema();
3277
+ }
3278
+ getOutputSchema() {
3279
+ return this.definition.getOutputSchema();
3280
+ }
3281
+ /**
3282
+ * @internal
3283
+ */
3284
+ propagateUp(f) {
3285
+ this.propagateDown(f);
3286
+ }
3287
+ /**
3288
+ * @internal
3289
+ */
3290
+ propagateDown(f) {
3291
+ f(this.definition);
3292
+ this.definition.propagateDown(f);
3293
+ }
3294
+ reorderFields(names) {
3295
+ if (this.definition instanceof ASTSegmentViewDefinition) {
3296
+ this.definition.reorderFields(names);
3297
+ }
3298
+ else {
3299
+ this.getOrAddAnnotations().setTagProperty(['field_order'], names);
3300
+ }
3301
+ }
3302
+ get annotations() {
3303
+ return this.children.annotations;
3304
+ }
3305
+ getOrAddAnnotations() {
3306
+ if (this.annotations)
3307
+ return this.annotations;
3308
+ this.edit();
3309
+ const annotations = new ASTAnnotationList([]);
3310
+ this.children.annotations = annotations;
3311
+ return annotations;
3312
+ }
3313
+ getInheritedAnnotations() {
3314
+ return this.definition.getInheritedAnnotations();
3315
+ }
3316
+ getInheritedTag(prefix = '# ') {
3317
+ return tagFromAnnotations(prefix, this.getInheritedAnnotations());
3318
+ }
3319
+ getIntrinsicTag(prefix = '# ') {
3320
+ var _a, _b;
3321
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getIntrinsicTag(prefix)) !== null && _b !== void 0 ? _b : new malloy_tag_1.Tag();
3322
+ }
3323
+ getTag(prefix = '# ') {
3324
+ var _a, _b;
3325
+ return (_b = (_a = this.annotations) === null || _a === void 0 ? void 0 : _a.getTag(prefix)) !== null && _b !== void 0 ? _b : this.getInheritedTag(prefix);
3326
+ }
3327
+ setTagProperty(path, value = null, prefix = '# ') {
3328
+ this.getOrAddAnnotations().setTagProperty(path, value, prefix);
3329
+ }
3330
+ removeTagProperty(path, prefix = '# ') {
3331
+ if (!this.getTag().has(...path))
3332
+ return;
3333
+ this.getOrAddAnnotations().removeTagProperty(path, prefix);
3334
+ }
3335
+ }
3336
+ exports.ASTView = ASTView;
3337
+ class ASTLimitViewOperation extends ASTObjectNode {
3338
+ get limit() {
3339
+ return this.children.limit;
3340
+ }
3341
+ set limit(limit) {
3342
+ ASTLimitViewOperation.validateLimit(limit);
3343
+ this.edit();
3344
+ this.children.limit = limit;
3345
+ }
3346
+ constructor(node) {
3347
+ super(node, {
3348
+ kind: node.kind,
3349
+ limit: node.limit,
3350
+ });
3351
+ this.node = node;
3352
+ this.kind = 'limit';
3353
+ }
3354
+ /**
3355
+ * @internal
3356
+ */
3357
+ get list() {
3358
+ return this.parent.asViewOperationList();
3359
+ }
3360
+ delete() {
3361
+ this.list.remove(this);
3362
+ }
3363
+ /**
3364
+ * @internal
3365
+ */
3366
+ static validateLimit(limit) {
3367
+ if (!Number.isInteger(limit)) {
3368
+ throw new Error('Limit must be an integer');
3369
+ }
3370
+ }
3371
+ }
3372
+ exports.ASTLimitViewOperation = ASTLimitViewOperation;
3373
+ function fieldTypeToAction(type) {
3374
+ switch (type) {
3375
+ case 'dimension':
3376
+ return 'group by';
3377
+ case 'measure':
3378
+ return 'aggregate';
3379
+ case 'view':
3380
+ return 'nest';
3381
+ case 'join':
3382
+ return 'join';
3383
+ }
3384
+ }
3385
+ function fieldTypeName(type) {
3386
+ return type;
3387
+ }
3388
+ class ASTAnnotationList extends ASTListNode {
3389
+ constructor(annotations) {
3390
+ super(annotations, annotations.map(p => new ASTAnnotation(p)));
3391
+ }
3392
+ get items() {
3393
+ return this.children;
3394
+ }
3395
+ getInheritedAnnotations() {
3396
+ const parent = this.parent;
3397
+ return parent.getInheritedAnnotations();
3398
+ }
3399
+ getIntrinsicTag(prefix = '# ') {
3400
+ return tagFromAnnotations(prefix, this.items);
3401
+ }
3402
+ getTag(prefix = '# ') {
3403
+ const extending = malloy_tag_1.Tag.fromTagLines(this.getInheritedAnnotations().map(a => a.value)).tag;
3404
+ return tagFromAnnotations(prefix, this.items, extending);
3405
+ }
3406
+ get annotations() {
3407
+ return this.children.map(astAnnotation => astAnnotation.node);
3408
+ }
3409
+ setTagProperty(path, value = null, prefix = '# ') {
3410
+ let firstMatch = undefined;
3411
+ for (let i = this.items.length - 1; i >= 0; i--) {
3412
+ const annotation = this.index(i);
3413
+ if (!annotation.hasPrefix(prefix))
3414
+ continue;
3415
+ firstMatch = annotation;
3416
+ if (annotation.hasIntrinsicTagProperty(path)) {
3417
+ annotation.setTagProperty(path, value);
3418
+ return;
3419
+ }
3420
+ }
3421
+ if (firstMatch) {
3422
+ firstMatch.setTagProperty(path, value);
3423
+ }
3424
+ else {
3425
+ this.add(new ASTAnnotation({
3426
+ value: new malloy_tag_1.Tag({ prefix }).set(path, value).toString(),
3427
+ }));
3428
+ }
3429
+ }
3430
+ removeTagProperty(path, prefix = '# ') {
3431
+ let firstMatch = undefined;
3432
+ for (let i = this.items.length - 1; i >= 0; i--) {
3433
+ const annotation = this.index(i);
3434
+ if (!annotation.hasPrefix(prefix))
3435
+ continue;
3436
+ firstMatch = annotation;
3437
+ if (annotation.hasIntrinsicTagProperty(path)) {
3438
+ annotation.removeTagProperty(path);
3439
+ return;
3440
+ }
3441
+ }
3442
+ if (firstMatch) {
3443
+ firstMatch.removeTagProperty(path);
3444
+ }
3445
+ else {
3446
+ this.add(new ASTAnnotation({ value: new malloy_tag_1.Tag({ prefix }).unset(...path).toString() }));
3447
+ }
3448
+ }
3449
+ }
3450
+ exports.ASTAnnotationList = ASTAnnotationList;
3451
+ class ASTAnnotation extends ASTObjectNode {
3452
+ get value() {
3453
+ return this.children.value;
3454
+ }
3455
+ set value(value) {
3456
+ this.edit();
3457
+ this.children.value = value;
3458
+ }
3459
+ constructor(node) {
3460
+ super(node, {
3461
+ value: node.value,
3462
+ });
3463
+ this.node = node;
3464
+ this.kind = 'limit';
3465
+ }
3466
+ /**
3467
+ * @internal
3468
+ */
3469
+ get list() {
3470
+ return this.parent.asAnnotationList();
3471
+ }
3472
+ get index() {
3473
+ return this.list.indexOf(this);
3474
+ }
3475
+ delete() {
3476
+ this.list.remove(this);
3477
+ }
3478
+ getIntrinsicTag() {
3479
+ var _a;
3480
+ return (_a = malloy_tag_1.Tag.fromTagLines([this.value]).tag) !== null && _a !== void 0 ? _a : new malloy_tag_1.Tag();
3481
+ }
3482
+ getTag() {
3483
+ var _a, _b;
3484
+ const extending = this.index === 0
3485
+ ? (_a = malloy_tag_1.Tag.fromTagLines(this.list.getInheritedAnnotations().map(a => a.value)).tag) !== null && _a !== void 0 ? _a : new malloy_tag_1.Tag()
3486
+ : this.list.index(this.index - 1).getTag();
3487
+ return (_b = malloy_tag_1.Tag.fromTagLines([this.value], extending).tag) !== null && _b !== void 0 ? _b : new malloy_tag_1.Tag();
3488
+ }
3489
+ hasPrefix(prefix) {
3490
+ return this.value.startsWith(prefix);
3491
+ }
3492
+ hasIntrinsicTagProperty(path) {
3493
+ return this.getIntrinsicTag().has(...path);
3494
+ }
3495
+ setTagProperty(path, value) {
3496
+ this.value = this.getTag().set(path, value).toString();
3497
+ }
3498
+ removeTagProperty(path) {
3499
+ this.value = this.getTag()
3500
+ .unset(...path)
3501
+ .toString();
3502
+ }
3503
+ }
3504
+ exports.ASTAnnotation = ASTAnnotation;
3505
+ function tagFromAnnotations(prefix, annotations = [], inherited) {
3506
+ var _a;
3507
+ const lines = annotations.map(a => a.value);
3508
+ const filteredLines = lines.filter(l => typeof prefix === 'string' ? l.startsWith(prefix) : l.match(prefix));
3509
+ return (_a = malloy_tag_1.Tag.fromTagLines(filteredLines, inherited).tag) !== null && _a !== void 0 ? _a : new malloy_tag_1.Tag();
3510
+ }
3511
+ function serializeFilter(filter) {
3512
+ switch (filter.kind) {
3513
+ case 'string':
3514
+ return new Filter.StringSerializer(filter.clauses).serialize();
3515
+ case 'number':
3516
+ return new Filter.NumberSerializer(filter.clauses).serialize();
3517
+ case 'boolean':
3518
+ return new Filter.BooleanSerializer(filter.clauses).serialize();
3519
+ case 'date':
3520
+ return new Filter.DateSerializer(filter.clauses).serialize();
3521
+ }
3522
+ }
3523
+ function parseFilter(filterString, kind) {
3524
+ function handleError(logs) {
3525
+ const errors = logs.filter(l => l.severity === 'error');
3526
+ if (errors.length === 0)
3527
+ return;
3528
+ throw new Error(`Invalid Malloy filter string: ${errors[0].message}`);
3529
+ }
3530
+ switch (kind) {
3531
+ case 'string': {
3532
+ const result = new Filter.StringParser(filterString).parse();
3533
+ handleError(result.logs);
3534
+ return { kind, clauses: result.clauses };
3535
+ }
3536
+ case 'number': {
3537
+ const result = new Filter.NumberParser(filterString).parse();
3538
+ handleError(result.logs);
3539
+ return { kind, clauses: result.clauses };
3540
+ }
3541
+ case 'boolean': {
3542
+ const result = new Filter.BooleanParser(filterString).parse();
3543
+ handleError(result.logs);
3544
+ return { kind, clauses: result.clauses };
3545
+ }
3546
+ case 'date': {
3547
+ const result = new Filter.DateParser(filterString).parse();
3548
+ handleError(result.logs);
3549
+ return { kind, clauses: result.clauses };
3550
+ }
3551
+ case 'other':
3552
+ throw new Error('Not implemented');
3553
+ }
3554
+ }
3555
+ function sourceOrQueryToModelEntry(entry) {
3556
+ if ('kind' in entry) {
3557
+ return entry;
3558
+ }
3559
+ else {
3560
+ return { ...entry, kind: 'source' };
3561
+ }
3562
+ }
3563
+ function isDateTimeframe(timeframe) {
3564
+ switch (timeframe) {
3565
+ case 'year':
3566
+ case 'quarter':
3567
+ case 'month':
3568
+ case 'week':
3569
+ case 'day':
3570
+ return true;
3571
+ default:
3572
+ return false;
3573
+ }
3574
+ }
3575
+ function digits(value, digits) {
3576
+ return value.toString().padStart(digits, '0');
3577
+ }
3578
+ function serializeDateAsLiteral(date) {
3579
+ const year = digits(date.getUTCFullYear(), 2);
3580
+ const month = digits(date.getUTCMonth() + 1, 2);
3581
+ const day = digits(date.getUTCDate(), 2);
3582
+ const hour = digits(date.getUTCHours(), 2);
3583
+ const minute = digits(date.getUTCMinutes(), 2);
3584
+ const second = digits(date.getUTCSeconds(), 2);
3585
+ return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
3586
+ }
3587
+ function pathsMatch(a, b) {
3588
+ const aOrEmpty = a !== null && a !== void 0 ? a : [];
3589
+ const bOrEmpty = b !== null && b !== void 0 ? b : [];
3590
+ return (aOrEmpty.length === bOrEmpty.length &&
3591
+ aOrEmpty.every((s, i) => s === bOrEmpty[i]));
3592
+ }
3593
+ function getFilterType(fieldInfo) {
3594
+ switch (fieldInfo.type.kind) {
3595
+ case 'string_type':
3596
+ return 'string';
3597
+ case 'boolean_type':
3598
+ return 'boolean';
3599
+ case 'number_type':
3600
+ return 'number';
3601
+ case 'date_type':
3602
+ case 'timestamp_type':
3603
+ return 'date';
3604
+ default:
3605
+ return 'other';
3606
+ }
3607
+ }
3608
+ function validateFilter(field, filter) {
3609
+ if (field.kind !== 'dimension' && field.kind !== 'measure') {
3610
+ throw new Error(`Cannot filter by field of type ${field.kind}`);
3611
+ }
3612
+ const type = getFilterType(field);
3613
+ if (typeof filter === 'string') {
3614
+ parseFilter(filter, type);
3615
+ }
3616
+ else {
3617
+ if (filter.kind !== type) {
3618
+ throw new Error(`Invalid filter for field ${field.name}; expected type ${type}, but got ${filter.kind}`);
3619
+ }
3620
+ }
3621
+ }
3622
+ function getInputSchemaFromViewParent(parent) {
3623
+ if (parent instanceof ASTArrowQueryDefinition) {
3624
+ return parent.getSourceInfo().schema;
3625
+ }
3626
+ else if (parent instanceof ASTRefinementQueryDefinition) {
3627
+ throw new Error('unimplemented');
3628
+ }
3629
+ else {
3630
+ return parent.getInputSchema();
3631
+ }
3632
+ }
3633
+ //# sourceMappingURL=query-ast.js.map