@malloydata/malloy-query-builder 0.0.240-dev250311202829 → 0.0.240-dev250311213218

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.
package/src/query-ast.ts CHANGED
@@ -76,9 +76,9 @@ abstract class ASTNode<T> {
76
76
  if (node instanceof ASTReference) return node;
77
77
  throw new Error('Not an ASTReference');
78
78
  },
79
- SourceReference(): ASTSourceReference {
80
- if (node instanceof ASTSourceReference) return node;
81
- throw new Error('Not an ASTSourceReference');
79
+ ReferenceQueryArrowSource(): ASTReferenceQueryArrowSource {
80
+ if (node instanceof ASTReferenceQueryArrowSource) return node;
81
+ throw new Error('Not an ASTReferenceQueryArrowSource');
82
82
  },
83
83
  ParameterValueList(): ASTParameterValueList {
84
84
  if (node instanceof ASTParameterValueList) return node;
@@ -189,8 +189,8 @@ abstract class ASTNode<T> {
189
189
  Reference(path: Path): ASTReference {
190
190
  return node.findAny(path).as.Reference();
191
191
  },
192
- SourceReference(path: Path): ASTSourceReference {
193
- return node.findAny(path).as.SourceReference();
192
+ ReferenceQueryArrowSource(path: Path): ASTReferenceQueryArrowSource {
193
+ return node.findAny(path).as.ReferenceQueryArrowSource();
194
194
  },
195
195
  ParameterValueList(path: Path): ASTParameterValueList {
196
196
  return node.findAny(path).as.ParameterValueList();
@@ -601,8 +601,11 @@ export class ASTQuery
601
601
  }
602
602
  if (options.query) {
603
603
  const definition = options.query.definition;
604
- if (definition.kind === 'arrow') {
605
- const name = definition.source_reference.name;
604
+ if (
605
+ definition.kind === 'arrow' &&
606
+ definition.source.kind === 'source_reference'
607
+ ) {
608
+ const name = definition.source.name;
606
609
  chosenSource = options.model.entries.find(e => e.name === name);
607
610
  if (chosenSource === undefined) {
608
611
  throw new Error(
@@ -622,7 +625,8 @@ export class ASTQuery
622
625
  const query = options.query ?? {
623
626
  definition: {
624
627
  kind: 'arrow',
625
- source_reference: {
628
+ source: {
629
+ kind: 'source_reference',
626
630
  name: source.name,
627
631
  },
628
632
  view: {
@@ -699,7 +703,7 @@ export class ASTQuery
699
703
  }
700
704
  this.definition = new ASTArrowQueryDefinition({
701
705
  kind: 'arrow',
702
- source_reference: this.definition.sourceReference.build(),
706
+ source: this.definition.source.build(),
703
707
  view: {
704
708
  kind: 'segment',
705
709
  operations: [],
@@ -712,6 +716,14 @@ export class ASTQuery
712
716
  return this.definition.isRunnable();
713
717
  }
714
718
 
719
+ isEmpty() {
720
+ return (
721
+ this.definition instanceof ASTArrowQueryDefinition &&
722
+ this.definition.view instanceof ASTSegmentViewDefinition &&
723
+ this.definition.view.operations.length === 0
724
+ );
725
+ }
726
+
715
727
  /**
716
728
  * Gets an {@link ASTSegmentViewDefinition} for the "default" place to add query
717
729
  * operations, or creates one if it doesn't exist.
@@ -755,7 +767,10 @@ export class ASTQuery
755
767
  */
756
768
  public setSource(name: string) {
757
769
  if (this.definition instanceof ASTArrowQueryDefinition) {
758
- if (this.definition.sourceReference.name === name) {
770
+ if (
771
+ this.definition.source instanceof ASTReferenceQueryArrowSource &&
772
+ this.definition.source.name === name
773
+ ) {
759
774
  return;
760
775
  }
761
776
  }
@@ -765,7 +780,10 @@ export class ASTQuery
765
780
  }
766
781
  this.definition = new ASTArrowQueryDefinition({
767
782
  kind: 'arrow',
768
- source_reference: {name},
783
+ source: {
784
+ kind: 'source_reference',
785
+ name,
786
+ },
769
787
  view:
770
788
  this.definition instanceof ASTArrowQueryDefinition
771
789
  ? this.definition.view.build()
@@ -862,7 +880,7 @@ export class ASTQuery
862
880
  }
863
881
  this.definition = new ASTArrowQueryDefinition({
864
882
  kind: 'arrow',
865
- source_reference: this.definition.sourceReference.build(),
883
+ source: this.definition.source.build(),
866
884
  view: {
867
885
  kind: 'view_reference',
868
886
  name,
@@ -871,18 +889,23 @@ export class ASTQuery
871
889
  return this.definition.view.as.ReferenceViewDefinition();
872
890
  }
873
891
 
874
- getInheritedAnnotations(): Malloy.Annotation[] {
875
- if (this.definition instanceof ASTReferenceQueryDefinition) {
876
- const query = this.getQueryInfo(this.definition.name);
892
+ private _getInheritedAnnotations(
893
+ definition: ASTQueryDefinition
894
+ ): Malloy.Annotation[] {
895
+ if (definition instanceof ASTReferenceQueryDefinition) {
896
+ const query = this.getQueryInfo(definition.name);
877
897
  return query.annotations ?? [];
878
- } else if (this.definition instanceof ASTRefinementQueryDefinition) {
879
- const query = this.getQueryInfo(this.definition.queryReference.name);
880
- return query.annotations ?? [];
881
- } else if (this.definition instanceof ASTArrowQueryDefinition) {
882
- return this.definition.view.getInheritedAnnotations();
898
+ } else if (definition instanceof ASTRefinementQueryDefinition) {
899
+ return this._getInheritedAnnotations(definition.base);
900
+ } else if (definition instanceof ASTArrowQueryDefinition) {
901
+ return definition.view.getInheritedAnnotations();
883
902
  }
884
903
  return [];
885
904
  }
905
+
906
+ getInheritedAnnotations(): Malloy.Annotation[] {
907
+ return this._getInheritedAnnotations(this.definition);
908
+ }
886
909
  }
887
910
 
888
911
  export type RawLiteralValue =
@@ -1050,44 +1073,6 @@ export class ASTFieldReference extends ASTReference {
1050
1073
  }
1051
1074
  }
1052
1075
 
1053
- export class ASTSourceReference extends ASTReference {
1054
- /**
1055
- * @internal
1056
- */
1057
- get query(): ASTQuery {
1058
- return this.parent.parent.as.Query();
1059
- }
1060
-
1061
- /**
1062
- * Gets the `Malloy.SourceInfo` for the referenced source
1063
- *
1064
- * @returns The source information for the referenced source
1065
- */
1066
- public getSourceInfo(): Malloy.SourceInfo {
1067
- const info = this.query.model.entries.find(e => e.name === this.name);
1068
- if (info === undefined) {
1069
- throw new Error('No source info found');
1070
- }
1071
- return info;
1072
- }
1073
-
1074
- public getSourceParameters(): Malloy.ParameterInfo[] {
1075
- return this.getSourceInfo().parameters ?? [];
1076
- }
1077
-
1078
- areRequiredParametersSet() {
1079
- const sourceParameters = this.getSourceParameters();
1080
- for (const parameterInfo of sourceParameters) {
1081
- if (parameterInfo.default_value !== undefined) continue;
1082
- const parameter = this.tryGetParameter(parameterInfo.name);
1083
- if (parameter === undefined) {
1084
- return false;
1085
- }
1086
- }
1087
- return true;
1088
- }
1089
- }
1090
-
1091
1076
  export class ASTParameterValueList extends ASTListNode<
1092
1077
  Malloy.ParameterValue,
1093
1078
  ASTParameterValue
@@ -1339,12 +1324,26 @@ export interface IASTQueryDefinition extends IASTQueryOrViewDefinition {
1339
1324
  isRunnable(): boolean;
1340
1325
  }
1341
1326
 
1327
+ export type ASTQueryArrowSource =
1328
+ | ASTReferenceQueryArrowSource
1329
+ | ASTRefinementQueryDefinition;
1330
+ export const ASTQueryArrowSource = {
1331
+ from(definition: Malloy.QueryArrowSource) {
1332
+ switch (definition.kind) {
1333
+ case 'refinement':
1334
+ return new ASTRefinementQueryDefinition(definition);
1335
+ case 'source_reference':
1336
+ return new ASTReferenceQueryArrowSource(definition);
1337
+ }
1338
+ },
1339
+ };
1340
+
1342
1341
  export type ASTQueryDefinition =
1343
1342
  | ASTReferenceQueryDefinition
1344
1343
  | ASTArrowQueryDefinition
1345
1344
  | ASTRefinementQueryDefinition;
1346
1345
  export const ASTQueryDefinition = {
1347
- from: (definition: Malloy.QueryDefinition) => {
1346
+ from(definition: Malloy.QueryDefinition) {
1348
1347
  switch (definition.kind) {
1349
1348
  case 'arrow':
1350
1349
  return new ASTArrowQueryDefinition(definition);
@@ -1361,7 +1360,7 @@ export class ASTArrowQueryDefinition
1361
1360
  Malloy.QueryDefinitionWithArrow,
1362
1361
  {
1363
1362
  kind: 'arrow';
1364
- source_reference: ASTSourceReference;
1363
+ source: ASTQueryArrowSource;
1365
1364
  view: ASTViewDefinition;
1366
1365
  }
1367
1366
  >
@@ -1370,7 +1369,7 @@ export class ASTArrowQueryDefinition
1370
1369
  constructor(public node: Malloy.QueryDefinitionWithArrow) {
1371
1370
  super(node, {
1372
1371
  kind: 'arrow',
1373
- source_reference: new ASTSourceReference(node.source_reference),
1372
+ source: ASTQueryArrowSource.from(node.source),
1374
1373
  view: ASTViewDefinition.from(node.view),
1375
1374
  });
1376
1375
  }
@@ -1385,8 +1384,13 @@ export class ASTArrowQueryDefinition
1385
1384
  view.parent = this;
1386
1385
  }
1387
1386
 
1388
- get sourceReference() {
1389
- return this.children.source_reference;
1387
+ get source() {
1388
+ return this.children.source;
1389
+ }
1390
+
1391
+ set source(source: ASTQueryArrowSource) {
1392
+ this.edit();
1393
+ this.children.source = source;
1390
1394
  }
1391
1395
 
1392
1396
  getOrAddDefaultSegment(): ASTSegmentViewDefinition {
@@ -1394,7 +1398,7 @@ export class ASTArrowQueryDefinition
1394
1398
  }
1395
1399
 
1396
1400
  getSourceInfo() {
1397
- return this.sourceReference.getSourceInfo();
1401
+ return this.source.getSourceInfo();
1398
1402
  }
1399
1403
 
1400
1404
  getOutputSchema() {
@@ -1402,9 +1406,7 @@ export class ASTArrowQueryDefinition
1402
1406
  }
1403
1407
 
1404
1408
  isRunnable(): boolean {
1405
- return (
1406
- this.view.isRunnable() && this.sourceReference.areRequiredParametersSet()
1407
- );
1409
+ return this.view.isRunnable() && this.source.isRunnable();
1408
1410
  }
1409
1411
 
1410
1412
  /**
@@ -1443,7 +1445,7 @@ export class ASTRefinementQueryDefinition
1443
1445
  Malloy.QueryDefinitionWithRefinement,
1444
1446
  {
1445
1447
  kind: 'refinement';
1446
- query_reference: ASTReference;
1448
+ base: ASTQueryDefinition;
1447
1449
  refinement: ASTViewDefinition;
1448
1450
  }
1449
1451
  >
@@ -1452,13 +1454,13 @@ export class ASTRefinementQueryDefinition
1452
1454
  constructor(public node: Malloy.QueryDefinitionWithRefinement) {
1453
1455
  super(node, {
1454
1456
  kind: 'refinement',
1455
- query_reference: new ASTReference(node.query_reference),
1457
+ base: ASTQueryDefinition.from(node.base),
1456
1458
  refinement: ASTViewDefinition.from(node.refinement),
1457
1459
  });
1458
1460
  }
1459
1461
 
1460
- get queryReference() {
1461
- return this.children.query_reference;
1462
+ get base() {
1463
+ return this.children.base;
1462
1464
  }
1463
1465
 
1464
1466
  get refinement() {
@@ -1487,12 +1489,7 @@ export class ASTRefinementQueryDefinition
1487
1489
  }
1488
1490
 
1489
1491
  getOutputSchema() {
1490
- const model = this.query.model;
1491
- const query = model.entries.find(e => e.name === this.queryReference.name);
1492
- if (query === undefined) {
1493
- throw new Error(`Query not found with name ${this.queryReference.name}`);
1494
- }
1495
- const base = query.schema;
1492
+ const base = this.base.getOutputSchema();
1496
1493
  const refinement = this.refinement.getRefinementSchema();
1497
1494
  return ASTQuery.schemaMerge(base, refinement);
1498
1495
  }
@@ -1515,6 +1512,10 @@ export class ASTRefinementQueryDefinition
1515
1512
  reorderFields(names: string[]): void {
1516
1513
  this.query.getOrAddAnnotations().setTagProperty(['field_order'], names);
1517
1514
  }
1515
+
1516
+ getSourceInfo() {
1517
+ return this.base.getSourceInfo();
1518
+ }
1518
1519
  }
1519
1520
 
1520
1521
  export class ASTReferenceQueryDefinition
@@ -1566,11 +1567,7 @@ export class ASTReferenceQueryDefinition
1566
1567
  getOrAddDefaultSegment(): ASTSegmentViewDefinition {
1567
1568
  const newQuery = new ASTRefinementQueryDefinition({
1568
1569
  kind: 'refinement',
1569
- query_reference: {
1570
- name: this.name,
1571
- path: this.path,
1572
- parameters: this.parameters?.build(),
1573
- },
1570
+ base: this.build(),
1574
1571
  refinement: {
1575
1572
  kind: 'segment',
1576
1573
  operations: [],
@@ -1609,6 +1606,149 @@ export class ASTReferenceQueryDefinition
1609
1606
  public tryGetParameter(name: string): ASTParameterValue | undefined {
1610
1607
  return ASTReference.tryGetParameter(this, name);
1611
1608
  }
1609
+
1610
+ public getOutputSchema() {
1611
+ return this.getSourceInfo().schema;
1612
+ }
1613
+
1614
+ getSourceInfo() {
1615
+ const model = this.query.model;
1616
+ const query = model.entries.find(e => e.name === this.name);
1617
+ if (query === undefined) {
1618
+ throw new Error(`Query not found with name ${this.name}`);
1619
+ }
1620
+ return query;
1621
+ }
1622
+ }
1623
+
1624
+ export class ASTReferenceQueryArrowSource
1625
+ extends ASTObjectNode<
1626
+ Malloy.QueryArrowSourceWithSourceReference,
1627
+ {
1628
+ kind: 'source_reference';
1629
+ name: string;
1630
+ path?: string[];
1631
+ parameters?: ASTParameterValueList;
1632
+ }
1633
+ >
1634
+ implements IASTReference
1635
+ {
1636
+ constructor(public node: Malloy.QueryArrowSourceWithSourceReference) {
1637
+ super(node, {
1638
+ kind: 'source_reference',
1639
+ name: node.name,
1640
+ path: node.path,
1641
+ parameters: node.parameters && new ASTParameterValueList(node.parameters),
1642
+ });
1643
+ }
1644
+
1645
+ isRunnable(): boolean {
1646
+ return this.areRequiredParametersSet();
1647
+ }
1648
+
1649
+ get name() {
1650
+ return this.children.name;
1651
+ }
1652
+
1653
+ get arrow() {
1654
+ return this.parent.as.ArrowQueryDefinition();
1655
+ }
1656
+
1657
+ get parameters() {
1658
+ return this.children.parameters;
1659
+ }
1660
+
1661
+ set parameters(parameters: ASTParameterValueList | undefined) {
1662
+ this.edit();
1663
+ this.children.parameters = parameters;
1664
+ }
1665
+
1666
+ get path() {
1667
+ return this.children.path;
1668
+ }
1669
+
1670
+ getSourceInfo() {
1671
+ const entry = this.arrow.query.model.entries.find(
1672
+ entry => entry.name === this.name
1673
+ );
1674
+ if (entry === undefined) {
1675
+ throw new Error(`No query or source named ${this.name}`);
1676
+ }
1677
+ return entry;
1678
+ }
1679
+
1680
+ getOrAddDefaultSegment(): ASTSegmentViewDefinition {
1681
+ const entry = this.getSourceInfo();
1682
+ if (entry.kind !== 'query') {
1683
+ throw new Error(`Cannot refine source ${this.name}`);
1684
+ }
1685
+ const newQuery = new ASTRefinementQueryDefinition({
1686
+ kind: 'refinement',
1687
+ base: {
1688
+ ...this.build(),
1689
+ kind: 'query_reference',
1690
+ },
1691
+ refinement: {
1692
+ kind: 'segment',
1693
+ operations: [],
1694
+ },
1695
+ });
1696
+ this.arrow.source = newQuery;
1697
+ return newQuery.refinement.as.SegmentViewDefinition();
1698
+ }
1699
+
1700
+ /**
1701
+ * @internal
1702
+ */
1703
+ propagateUp(_f: PropagationFunction): void {
1704
+ return;
1705
+ }
1706
+
1707
+ /**
1708
+ * @internal
1709
+ */
1710
+ propagateDown(_f: PropagationFunction): void {
1711
+ return;
1712
+ }
1713
+
1714
+ public getOrAddParameters() {
1715
+ return ASTReference.getOrAddParameters(this);
1716
+ }
1717
+
1718
+ public setParameter(name: string, value: RawLiteralValue) {
1719
+ return ASTReference.setParameter(this, name, value);
1720
+ }
1721
+
1722
+ public tryGetParameter(name: string): ASTParameterValue | undefined {
1723
+ return ASTReference.tryGetParameter(this, name);
1724
+ }
1725
+
1726
+ /**
1727
+ * @internal
1728
+ */
1729
+ get query(): ASTQuery {
1730
+ return this.parent.parent.as.Query();
1731
+ }
1732
+
1733
+ public getSourceParameters(): Malloy.ParameterInfo[] {
1734
+ const sourceInfo = this.getSourceInfo();
1735
+ if (sourceInfo.kind === 'query') {
1736
+ return [];
1737
+ }
1738
+ return sourceInfo.parameters ?? [];
1739
+ }
1740
+
1741
+ areRequiredParametersSet() {
1742
+ const sourceParameters = this.getSourceParameters();
1743
+ for (const parameterInfo of sourceParameters) {
1744
+ if (parameterInfo.default_value !== undefined) continue;
1745
+ const parameter = this.tryGetParameter(parameterInfo.name);
1746
+ if (parameter === undefined) {
1747
+ return false;
1748
+ }
1749
+ }
1750
+ return true;
1751
+ }
1612
1752
  }
1613
1753
 
1614
1754
  export interface IASTViewDefinition extends IASTQueryOrViewDefinition {