@malloydata/malloy 0.0.120-dev240131220408 → 0.0.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/dialect/dialect_map.js +12 -2
  2. package/dist/dialect/functions/all_functions.js +3 -0
  3. package/dist/dialect/functions/string_agg.d.ts +3 -0
  4. package/dist/dialect/functions/string_agg.js +47 -0
  5. package/dist/dialect/functions/util.d.ts +5 -0
  6. package/dist/dialect/functions/util.js +3 -0
  7. package/dist/dialect/postgres/functions/postgres_functions.js +3 -0
  8. package/dist/dialect/postgres/functions/string_agg.d.ts +3 -0
  9. package/dist/dialect/postgres/functions/string_agg.js +47 -0
  10. package/dist/dialect/standardsql/functions/standardsql_functions.js +3 -0
  11. package/dist/dialect/standardsql/functions/string_agg.d.ts +3 -0
  12. package/dist/dialect/standardsql/functions/string_agg.js +49 -0
  13. package/dist/index.d.ts +2 -2
  14. package/dist/lang/ast/expressions/expr-func.d.ts +11 -0
  15. package/dist/lang/ast/expressions/expr-func.js +69 -10
  16. package/dist/lang/ast/expressions/{expr-filter.d.ts → expr-props.d.ts} +5 -4
  17. package/dist/lang/ast/expressions/expr-props.js +122 -0
  18. package/dist/lang/ast/expressions/function-ordering.d.ts +18 -0
  19. package/dist/lang/ast/expressions/function-ordering.js +75 -0
  20. package/dist/lang/ast/expressions/partition_by.d.ts +7 -0
  21. package/dist/lang/ast/expressions/partition_by.js +35 -0
  22. package/dist/lang/ast/index.d.ts +4 -1
  23. package/dist/lang/ast/index.js +4 -1
  24. package/dist/lang/ast/query-items/field-references.d.ts +4 -0
  25. package/dist/lang/ast/query-items/field-references.js +12 -1
  26. package/dist/lang/ast/types/expression-def.d.ts +4 -0
  27. package/dist/lang/ast/types/expression-def.js +12 -0
  28. package/dist/lang/ast/types/field-prop-statement.d.ts +7 -0
  29. package/dist/lang/ast/types/field-prop-statement.js +37 -0
  30. package/dist/lang/lib/Malloy/MalloyLexer.d.ts +136 -135
  31. package/dist/lang/lib/Malloy/MalloyLexer.js +1186 -1174
  32. package/dist/lang/lib/Malloy/MalloyParser.d.ts +278 -213
  33. package/dist/lang/lib/Malloy/MalloyParser.js +2200 -1683
  34. package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +76 -36
  35. package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +48 -22
  36. package/dist/lang/malloy-to-ast.d.ts +6 -2
  37. package/dist/lang/malloy-to-ast.js +33 -9
  38. package/dist/lang/test/expressions.spec.js +132 -9
  39. package/dist/model/malloy_query.d.ts +2 -2
  40. package/dist/model/malloy_query.js +59 -25
  41. package/dist/model/malloy_types.d.ts +20 -2
  42. package/dist/model/malloy_types.js +5 -1
  43. package/dist/run_sql_options.d.ts +1 -0
  44. package/dist/runtime_types.d.ts +4 -1
  45. package/package.json +1 -1
  46. package/dist/lang/ast/expressions/expr-filter.js +0 -66
@@ -22,7 +22,7 @@ import { TableMethodContext } from "./MalloyParser";
22
22
  import { NestExistingContext } from "./MalloyParser";
23
23
  import { NestDefContext } from "./MalloyParser";
24
24
  import { ExprFieldPathContext } from "./MalloyParser";
25
- import { ExprFilterContext } from "./MalloyParser";
25
+ import { ExprFieldPropsContext } from "./MalloyParser";
26
26
  import { ExprLiteralContext } from "./MalloyParser";
27
27
  import { ExprDurationContext } from "./MalloyParser";
28
28
  import { ExprTimeTruncContext } from "./MalloyParser";
@@ -68,8 +68,6 @@ import { DefExploreQueryContext } from "./MalloyParser";
68
68
  import { DefExploreTimezoneContext } from "./MalloyParser";
69
69
  import { DefExploreAnnotationContext } from "./MalloyParser";
70
70
  import { DefIgnoreModel_stubContext } from "./MalloyParser";
71
- import { FilterByShortcutContext } from "./MalloyParser";
72
- import { FilterByWhereContext } from "./MalloyParser";
73
71
  import { JoinWithContext } from "./MalloyParser";
74
72
  import { JoinOnContext } from "./MalloyParser";
75
73
  import { SQIDContext } from "./MalloyParser";
@@ -139,7 +137,12 @@ import { MatrixOperationContext } from "./MalloyParser";
139
137
  import { JoinDefContext } from "./MalloyParser";
140
138
  import { JoinExpressionContext } from "./MalloyParser";
141
139
  import { FilterStatementContext } from "./MalloyParser";
142
- import { FilteredByContext } from "./MalloyParser";
140
+ import { FieldPropertiesContext } from "./MalloyParser";
141
+ import { AggregateOrderingContext } from "./MalloyParser";
142
+ import { AggregateOrderBySpecContext } from "./MalloyParser";
143
+ import { AggregateOrderByStatementContext } from "./MalloyParser";
144
+ import { FieldPropertyLimitStatementContext } from "./MalloyParser";
145
+ import { FieldPropertyStatementContext } from "./MalloyParser";
143
146
  import { FilterClauseListContext } from "./MalloyParser";
144
147
  import { WhereStatementContext } from "./MalloyParser";
145
148
  import { HavingStatementContext } from "./MalloyParser";
@@ -157,6 +160,7 @@ import { NestEntryContext } from "./MalloyParser";
157
160
  import { AggregateStatementContext } from "./MalloyParser";
158
161
  import { CalculateStatementContext } from "./MalloyParser";
159
162
  import { ProjectStatementContext } from "./MalloyParser";
163
+ import { PartitionByStatementContext } from "./MalloyParser";
160
164
  import { OrderByStatementContext } from "./MalloyParser";
161
165
  import { OrderingContext } from "./MalloyParser";
162
166
  import { OrderBySpecContext } from "./MalloyParser";
@@ -486,17 +490,17 @@ export interface MalloyParserListener extends ParseTreeListener {
486
490
  */
487
491
  exitExprFieldPath?: (ctx: ExprFieldPathContext) => void;
488
492
  /**
489
- * Enter a parse tree produced by the `exprFilter`
493
+ * Enter a parse tree produced by the `exprFieldProps`
490
494
  * labeled alternative in `MalloyParser.fieldExpr`.
491
495
  * @param ctx the parse tree
492
496
  */
493
- enterExprFilter?: (ctx: ExprFilterContext) => void;
497
+ enterExprFieldProps?: (ctx: ExprFieldPropsContext) => void;
494
498
  /**
495
- * Exit a parse tree produced by the `exprFilter`
499
+ * Exit a parse tree produced by the `exprFieldProps`
496
500
  * labeled alternative in `MalloyParser.fieldExpr`.
497
501
  * @param ctx the parse tree
498
502
  */
499
- exitExprFilter?: (ctx: ExprFilterContext) => void;
503
+ exitExprFieldProps?: (ctx: ExprFieldPropsContext) => void;
500
504
  /**
501
505
  * Enter a parse tree produced by the `exprLiteral`
502
506
  * labeled alternative in `MalloyParser.fieldExpr`.
@@ -1037,30 +1041,6 @@ export interface MalloyParserListener extends ParseTreeListener {
1037
1041
  * @param ctx the parse tree
1038
1042
  */
1039
1043
  exitDefIgnoreModel_stub?: (ctx: DefIgnoreModel_stubContext) => void;
1040
- /**
1041
- * Enter a parse tree produced by the `filterByShortcut`
1042
- * labeled alternative in `MalloyParser.filteredBy`.
1043
- * @param ctx the parse tree
1044
- */
1045
- enterFilterByShortcut?: (ctx: FilterByShortcutContext) => void;
1046
- /**
1047
- * Exit a parse tree produced by the `filterByShortcut`
1048
- * labeled alternative in `MalloyParser.filteredBy`.
1049
- * @param ctx the parse tree
1050
- */
1051
- exitFilterByShortcut?: (ctx: FilterByShortcutContext) => void;
1052
- /**
1053
- * Enter a parse tree produced by the `filterByWhere`
1054
- * labeled alternative in `MalloyParser.filteredBy`.
1055
- * @param ctx the parse tree
1056
- */
1057
- enterFilterByWhere?: (ctx: FilterByWhereContext) => void;
1058
- /**
1059
- * Exit a parse tree produced by the `filterByWhere`
1060
- * labeled alternative in `MalloyParser.filteredBy`.
1061
- * @param ctx the parse tree
1062
- */
1063
- exitFilterByWhere?: (ctx: FilterByWhereContext) => void;
1064
1044
  /**
1065
1045
  * Enter a parse tree produced by the `joinWith`
1066
1046
  * labeled alternative in `MalloyParser.joinDef`.
@@ -1770,15 +1750,65 @@ export interface MalloyParserListener extends ParseTreeListener {
1770
1750
  */
1771
1751
  exitFilterStatement?: (ctx: FilterStatementContext) => void;
1772
1752
  /**
1773
- * Enter a parse tree produced by `MalloyParser.filteredBy`.
1753
+ * Enter a parse tree produced by `MalloyParser.fieldProperties`.
1754
+ * @param ctx the parse tree
1755
+ */
1756
+ enterFieldProperties?: (ctx: FieldPropertiesContext) => void;
1757
+ /**
1758
+ * Exit a parse tree produced by `MalloyParser.fieldProperties`.
1759
+ * @param ctx the parse tree
1760
+ */
1761
+ exitFieldProperties?: (ctx: FieldPropertiesContext) => void;
1762
+ /**
1763
+ * Enter a parse tree produced by `MalloyParser.aggregateOrdering`.
1764
+ * @param ctx the parse tree
1765
+ */
1766
+ enterAggregateOrdering?: (ctx: AggregateOrderingContext) => void;
1767
+ /**
1768
+ * Exit a parse tree produced by `MalloyParser.aggregateOrdering`.
1769
+ * @param ctx the parse tree
1770
+ */
1771
+ exitAggregateOrdering?: (ctx: AggregateOrderingContext) => void;
1772
+ /**
1773
+ * Enter a parse tree produced by `MalloyParser.aggregateOrderBySpec`.
1774
1774
  * @param ctx the parse tree
1775
1775
  */
1776
- enterFilteredBy?: (ctx: FilteredByContext) => void;
1776
+ enterAggregateOrderBySpec?: (ctx: AggregateOrderBySpecContext) => void;
1777
1777
  /**
1778
- * Exit a parse tree produced by `MalloyParser.filteredBy`.
1778
+ * Exit a parse tree produced by `MalloyParser.aggregateOrderBySpec`.
1779
1779
  * @param ctx the parse tree
1780
1780
  */
1781
- exitFilteredBy?: (ctx: FilteredByContext) => void;
1781
+ exitAggregateOrderBySpec?: (ctx: AggregateOrderBySpecContext) => void;
1782
+ /**
1783
+ * Enter a parse tree produced by `MalloyParser.aggregateOrderByStatement`.
1784
+ * @param ctx the parse tree
1785
+ */
1786
+ enterAggregateOrderByStatement?: (ctx: AggregateOrderByStatementContext) => void;
1787
+ /**
1788
+ * Exit a parse tree produced by `MalloyParser.aggregateOrderByStatement`.
1789
+ * @param ctx the parse tree
1790
+ */
1791
+ exitAggregateOrderByStatement?: (ctx: AggregateOrderByStatementContext) => void;
1792
+ /**
1793
+ * Enter a parse tree produced by `MalloyParser.fieldPropertyLimitStatement`.
1794
+ * @param ctx the parse tree
1795
+ */
1796
+ enterFieldPropertyLimitStatement?: (ctx: FieldPropertyLimitStatementContext) => void;
1797
+ /**
1798
+ * Exit a parse tree produced by `MalloyParser.fieldPropertyLimitStatement`.
1799
+ * @param ctx the parse tree
1800
+ */
1801
+ exitFieldPropertyLimitStatement?: (ctx: FieldPropertyLimitStatementContext) => void;
1802
+ /**
1803
+ * Enter a parse tree produced by `MalloyParser.fieldPropertyStatement`.
1804
+ * @param ctx the parse tree
1805
+ */
1806
+ enterFieldPropertyStatement?: (ctx: FieldPropertyStatementContext) => void;
1807
+ /**
1808
+ * Exit a parse tree produced by `MalloyParser.fieldPropertyStatement`.
1809
+ * @param ctx the parse tree
1810
+ */
1811
+ exitFieldPropertyStatement?: (ctx: FieldPropertyStatementContext) => void;
1782
1812
  /**
1783
1813
  * Enter a parse tree produced by `MalloyParser.filterClauseList`.
1784
1814
  * @param ctx the parse tree
@@ -1949,6 +1979,16 @@ export interface MalloyParserListener extends ParseTreeListener {
1949
1979
  * @param ctx the parse tree
1950
1980
  */
1951
1981
  exitProjectStatement?: (ctx: ProjectStatementContext) => void;
1982
+ /**
1983
+ * Enter a parse tree produced by `MalloyParser.partitionByStatement`.
1984
+ * @param ctx the parse tree
1985
+ */
1986
+ enterPartitionByStatement?: (ctx: PartitionByStatementContext) => void;
1987
+ /**
1988
+ * Exit a parse tree produced by `MalloyParser.partitionByStatement`.
1989
+ * @param ctx the parse tree
1990
+ */
1991
+ exitPartitionByStatement?: (ctx: PartitionByStatementContext) => void;
1952
1992
  /**
1953
1993
  * Enter a parse tree produced by `MalloyParser.orderByStatement`.
1954
1994
  * @param ctx the parse tree
@@ -22,7 +22,7 @@ import { TableMethodContext } from "./MalloyParser";
22
22
  import { NestExistingContext } from "./MalloyParser";
23
23
  import { NestDefContext } from "./MalloyParser";
24
24
  import { ExprFieldPathContext } from "./MalloyParser";
25
- import { ExprFilterContext } from "./MalloyParser";
25
+ import { ExprFieldPropsContext } from "./MalloyParser";
26
26
  import { ExprLiteralContext } from "./MalloyParser";
27
27
  import { ExprDurationContext } from "./MalloyParser";
28
28
  import { ExprTimeTruncContext } from "./MalloyParser";
@@ -68,8 +68,6 @@ import { DefExploreQueryContext } from "./MalloyParser";
68
68
  import { DefExploreTimezoneContext } from "./MalloyParser";
69
69
  import { DefExploreAnnotationContext } from "./MalloyParser";
70
70
  import { DefIgnoreModel_stubContext } from "./MalloyParser";
71
- import { FilterByShortcutContext } from "./MalloyParser";
72
- import { FilterByWhereContext } from "./MalloyParser";
73
71
  import { JoinWithContext } from "./MalloyParser";
74
72
  import { JoinOnContext } from "./MalloyParser";
75
73
  import { SQIDContext } from "./MalloyParser";
@@ -139,7 +137,12 @@ import { MatrixOperationContext } from "./MalloyParser";
139
137
  import { JoinDefContext } from "./MalloyParser";
140
138
  import { JoinExpressionContext } from "./MalloyParser";
141
139
  import { FilterStatementContext } from "./MalloyParser";
142
- import { FilteredByContext } from "./MalloyParser";
140
+ import { FieldPropertiesContext } from "./MalloyParser";
141
+ import { AggregateOrderingContext } from "./MalloyParser";
142
+ import { AggregateOrderBySpecContext } from "./MalloyParser";
143
+ import { AggregateOrderByStatementContext } from "./MalloyParser";
144
+ import { FieldPropertyLimitStatementContext } from "./MalloyParser";
145
+ import { FieldPropertyStatementContext } from "./MalloyParser";
143
146
  import { FilterClauseListContext } from "./MalloyParser";
144
147
  import { WhereStatementContext } from "./MalloyParser";
145
148
  import { HavingStatementContext } from "./MalloyParser";
@@ -157,6 +160,7 @@ import { NestEntryContext } from "./MalloyParser";
157
160
  import { AggregateStatementContext } from "./MalloyParser";
158
161
  import { CalculateStatementContext } from "./MalloyParser";
159
162
  import { ProjectStatementContext } from "./MalloyParser";
163
+ import { PartitionByStatementContext } from "./MalloyParser";
160
164
  import { OrderByStatementContext } from "./MalloyParser";
161
165
  import { OrderingContext } from "./MalloyParser";
162
166
  import { OrderBySpecContext } from "./MalloyParser";
@@ -374,12 +378,12 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
374
378
  */
375
379
  visitExprFieldPath?: (ctx: ExprFieldPathContext) => Result;
376
380
  /**
377
- * Visit a parse tree produced by the `exprFilter`
381
+ * Visit a parse tree produced by the `exprFieldProps`
378
382
  * labeled alternative in `MalloyParser.fieldExpr`.
379
383
  * @param ctx the parse tree
380
384
  * @return the visitor result
381
385
  */
382
- visitExprFilter?: (ctx: ExprFilterContext) => Result;
386
+ visitExprFieldProps?: (ctx: ExprFieldPropsContext) => Result;
383
387
  /**
384
388
  * Visit a parse tree produced by the `exprLiteral`
385
389
  * labeled alternative in `MalloyParser.fieldExpr`.
@@ -695,20 +699,6 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
695
699
  * @return the visitor result
696
700
  */
697
701
  visitDefIgnoreModel_stub?: (ctx: DefIgnoreModel_stubContext) => Result;
698
- /**
699
- * Visit a parse tree produced by the `filterByShortcut`
700
- * labeled alternative in `MalloyParser.filteredBy`.
701
- * @param ctx the parse tree
702
- * @return the visitor result
703
- */
704
- visitFilterByShortcut?: (ctx: FilterByShortcutContext) => Result;
705
- /**
706
- * Visit a parse tree produced by the `filterByWhere`
707
- * labeled alternative in `MalloyParser.filteredBy`.
708
- * @param ctx the parse tree
709
- * @return the visitor result
710
- */
711
- visitFilterByWhere?: (ctx: FilterByWhereContext) => Result;
712
702
  /**
713
703
  * Visit a parse tree produced by the `joinWith`
714
704
  * labeled alternative in `MalloyParser.joinDef`.
@@ -1133,11 +1123,41 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
1133
1123
  */
1134
1124
  visitFilterStatement?: (ctx: FilterStatementContext) => Result;
1135
1125
  /**
1136
- * Visit a parse tree produced by `MalloyParser.filteredBy`.
1126
+ * Visit a parse tree produced by `MalloyParser.fieldProperties`.
1127
+ * @param ctx the parse tree
1128
+ * @return the visitor result
1129
+ */
1130
+ visitFieldProperties?: (ctx: FieldPropertiesContext) => Result;
1131
+ /**
1132
+ * Visit a parse tree produced by `MalloyParser.aggregateOrdering`.
1133
+ * @param ctx the parse tree
1134
+ * @return the visitor result
1135
+ */
1136
+ visitAggregateOrdering?: (ctx: AggregateOrderingContext) => Result;
1137
+ /**
1138
+ * Visit a parse tree produced by `MalloyParser.aggregateOrderBySpec`.
1137
1139
  * @param ctx the parse tree
1138
1140
  * @return the visitor result
1139
1141
  */
1140
- visitFilteredBy?: (ctx: FilteredByContext) => Result;
1142
+ visitAggregateOrderBySpec?: (ctx: AggregateOrderBySpecContext) => Result;
1143
+ /**
1144
+ * Visit a parse tree produced by `MalloyParser.aggregateOrderByStatement`.
1145
+ * @param ctx the parse tree
1146
+ * @return the visitor result
1147
+ */
1148
+ visitAggregateOrderByStatement?: (ctx: AggregateOrderByStatementContext) => Result;
1149
+ /**
1150
+ * Visit a parse tree produced by `MalloyParser.fieldPropertyLimitStatement`.
1151
+ * @param ctx the parse tree
1152
+ * @return the visitor result
1153
+ */
1154
+ visitFieldPropertyLimitStatement?: (ctx: FieldPropertyLimitStatementContext) => Result;
1155
+ /**
1156
+ * Visit a parse tree produced by `MalloyParser.fieldPropertyStatement`.
1157
+ * @param ctx the parse tree
1158
+ * @return the visitor result
1159
+ */
1160
+ visitFieldPropertyStatement?: (ctx: FieldPropertyStatementContext) => Result;
1141
1161
  /**
1142
1162
  * Visit a parse tree produced by `MalloyParser.filterClauseList`.
1143
1163
  * @param ctx the parse tree
@@ -1240,6 +1260,12 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
1240
1260
  * @return the visitor result
1241
1261
  */
1242
1262
  visitProjectStatement?: (ctx: ProjectStatementContext) => Result;
1263
+ /**
1264
+ * Visit a parse tree produced by `MalloyParser.partitionByStatement`.
1265
+ * @param ctx the parse tree
1266
+ * @return the visitor result
1267
+ */
1268
+ visitPartitionByStatement?: (ctx: PartitionByStatementContext) => Result;
1243
1269
  /**
1244
1270
  * Visit a parse tree produced by `MalloyParser.orderByStatement`.
1245
1271
  * @param ctx the parse tree
@@ -105,7 +105,6 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
105
105
  visitExploreRenameDef(pcx: parse.ExploreRenameDefContext): ast.RenameField;
106
106
  visitDefExploreRename(pcx: parse.DefExploreRenameContext): ast.Renames;
107
107
  visitFilterClauseList(pcx: parse.FilterClauseListContext): ast.Filter;
108
- visitFilterByShortcut(pcx: parse.FilterByShortcutContext): ast.Filter;
109
108
  visitWhereStatement(pcx: parse.WhereStatementContext): ast.Filter;
110
109
  visitHavingStatement(pcx: parse.HavingStatementContext): ast.Filter;
111
110
  visitSubQueryDefList(pcx: parse.SubQueryDefListContext): ast.Views;
@@ -130,7 +129,11 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
130
129
  visitCollectionWildCard(pcx: parse.CollectionWildCardContext): ast.FieldReferenceElement;
131
130
  visitIndexFields(pcx: parse.IndexFieldsContext): ast.FieldReferences;
132
131
  visitIndexStatement(pcx: parse.IndexStatementContext): ast.Index;
132
+ visitFieldPropertyLimitStatement(pcx: parse.FieldPropertyLimitStatementContext): ast.Limit;
133
133
  visitLimitStatement(pcx: parse.LimitStatementContext): ast.Limit;
134
+ visitAggregateOrderBySpec(pcx: parse.AggregateOrderBySpecContext): ast.FunctionOrderBy;
135
+ visitAggregateOrderByStatement(pcx: parse.AggregateOrderByStatementContext): ast.FunctionOrdering;
136
+ visitAggregateOrdering(pcx: parse.AggregateOrderingContext): ast.FunctionOrdering;
134
137
  visitOrderBySpec(pcx: parse.OrderBySpecContext): ast.OrderBy;
135
138
  visitOrdering(pcx: parse.OrderingContext): ast.Ordering;
136
139
  visitTopStatement(pcx: parse.TopStatementContext): ast.Top;
@@ -184,7 +187,8 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
184
187
  visitExprFunc(pcx: parse.ExprFuncContext): ast.ExpressionDef;
185
188
  visitExprDuration(pcx: parse.ExprDurationContext): ast.ExprDuration;
186
189
  visitPickStatement(pcx: parse.PickStatementContext): ast.Pick;
187
- visitExprFilter(pcx: parse.ExprFilterContext): ast.ExprFilter;
190
+ visitExprFieldProps(pcx: parse.ExprFieldPropsContext): ast.ExprProps;
191
+ visitPartitionByStatement(pcx: parse.PartitionByStatementContext): ast.PartitionBy;
188
192
  visitLiteralTimestamp(pcx: parse.LiteralTimestampContext): ast.ExpressionDef;
189
193
  visitLiteralHour(pcx: parse.LiteralHourContext): ast.ExpressionDef;
190
194
  visitLiteralDay(pcx: parse.LiteralDayContext): ast.ExpressionDef;
@@ -489,12 +489,6 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
489
489
  visitFilterClauseList(pcx) {
490
490
  return new ast.Filter(pcx.fieldExpr().map(f => this.getFilterElement(f)));
491
491
  }
492
- visitFilterByShortcut(pcx) {
493
- const el = this.getFilterElement(pcx.fieldExpr());
494
- const res = this.astAt(new ast.Filter([el]), pcx);
495
- this.m4advisory(pcx, 'Filter shortcut `{? condition }` is deprecated; use `{ where: condition } instead');
496
- return res;
497
- }
498
492
  visitWhereStatement(pcx) {
499
493
  const where = this.visitFilterClauseList(pcx.filterClauseList());
500
494
  where.having = false;
@@ -691,9 +685,28 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
691
685
  }
692
686
  return this.astAt(indexStmt, pcx);
693
687
  }
688
+ visitFieldPropertyLimitStatement(pcx) {
689
+ this.inExperiment('aggregate_limit', pcx);
690
+ return this.visitLimitStatement(pcx.limitStatement());
691
+ }
694
692
  visitLimitStatement(pcx) {
695
693
  return new ast.Limit(this.getNumber(pcx.INTEGER_LITERAL()));
696
694
  }
695
+ visitAggregateOrderBySpec(pcx) {
696
+ const dir = pcx.ASC() ? 'asc' : pcx.DESC() ? 'desc' : undefined;
697
+ const f = this.getFieldExpr(pcx.fieldExpr());
698
+ return this.astAt(new ast.FunctionOrderBy(f, dir), pcx);
699
+ }
700
+ visitAggregateOrderByStatement(pcx) {
701
+ this.inExperiment('function_order_by', pcx);
702
+ return this.visitAggregateOrdering(pcx.aggregateOrdering());
703
+ }
704
+ visitAggregateOrdering(pcx) {
705
+ const orderList = pcx
706
+ .aggregateOrderBySpec()
707
+ .map(o => this.visitAggregateOrderBySpec(o));
708
+ return this.astAt(new ast.FunctionOrdering(orderList), pcx);
709
+ }
697
710
  visitOrderBySpec(pcx) {
698
711
  const dir = pcx.ASC() ? 'asc' : pcx.DESC() ? 'desc' : undefined;
699
712
  const ncx = pcx.INTEGER_LITERAL();
@@ -1104,9 +1117,20 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
1104
1117
  }
1105
1118
  return new ast.Pick(picks);
1106
1119
  }
1107
- visitExprFilter(pcx) {
1108
- const filters = this.visit(pcx.filteredBy());
1109
- return new ast.ExprFilter(this.getFieldExpr(pcx.fieldExpr()), filters);
1120
+ visitExprFieldProps(pcx) {
1121
+ const statements = this.only(pcx
1122
+ .fieldProperties()
1123
+ .fieldPropertyStatement()
1124
+ .map(scx => this.visit(scx)), x => ast.isFieldPropStatement(x) && x, 'field property statement');
1125
+ return new ast.ExprProps(this.getFieldExpr(pcx.fieldExpr()), statements);
1126
+ }
1127
+ visitPartitionByStatement(pcx) {
1128
+ this.inExperiment('partition_by', pcx);
1129
+ return this.astAt(new ast.PartitionBy(pcx
1130
+ .id()
1131
+ .map(idCx => this.astAt(new ast.PartitionByFieldReference([
1132
+ this.astAt(new ast.FieldName((0, parse_utils_1.idToStr)(idCx)), idCx),
1133
+ ]), idCx))), pcx);
1110
1134
  }
1111
1135
  visitLiteralTimestamp(pcx) {
1112
1136
  return this.parseTime(pcx, ast.LiteralTimestamp.parse);
@@ -150,15 +150,6 @@ describe('expressions', () => {
150
150
  }
151
151
  `).toTranslate();
152
152
  });
153
- test('shortcut filtered measure m4warning', () => {
154
- expect(`
155
- ##! m4warnings=warn
156
- run: a -> {
157
- group_by: ai
158
- aggregate: x is avg(ai) {? astr = 'why?' }
159
- }
160
- `).toTranslateWithWarnings('Filter shortcut `{? condition }` is deprecated; use `{ where: condition } instead');
161
- });
162
153
  test('correctly flags filtered scalar', () => {
163
154
  const e = new test_translator_1.BetaExpression('ai { where: true }');
164
155
  expect(e).translationToFailWith('Filtered expression requires an aggregate computation');
@@ -171,6 +162,138 @@ describe('expressions', () => {
171
162
  }
172
163
  `).translationToFailWith('Filtered expression requires an aggregate computation');
173
164
  });
165
+ describe('expr props', () => {
166
+ test('props not allowed without experiments enabled', () => {
167
+ expect((0, test_translator_1.markSource) `
168
+ run: a -> {
169
+ group_by: ai
170
+ group_by: x1 is string_agg(astr) { order_by: ai }
171
+ group_by: x2 is lag(ai) { partition_by: ai }
172
+ group_by: x3 is string_agg(astr) { limit: 10 }
173
+ }
174
+ `).translationToFailWith("Experimental flag 'function_order_by' required to enable this feature", "Experimental flag 'partition_by' required to enable this feature", "Experimental flag 'aggregate_limit' required to enable this feature");
175
+ });
176
+ test('props not allowed on most expressions', () => {
177
+ expect((0, test_translator_1.markSource) `
178
+ ##! experimental { function_order_by partition_by aggregate_limit }
179
+ run: a -> {
180
+ group_by: x1 is 1 { order_by: ai }
181
+ group_by: x2 is 1 { partition_by: ai }
182
+ group_by: x3 is 1 { limit: 10 }
183
+ group_by: x4 is 1 { where: ai }
184
+ }
185
+ `).translationToFailWith('`order_by` is not supported for this kind of expression', '`partition_by` is not supported for this kind of expression', '`limit` is not supported for this kind of expression', 'Filtered expression requires an aggregate computation');
186
+ });
187
+ test('analytics can take parititon_by and order_by', () => {
188
+ expect((0, test_translator_1.markSource) `
189
+ ##! experimental { function_order_by partition_by }
190
+ run: a -> {
191
+ group_by: ai
192
+ calculate: x is lag(ai) { partition_by: ai; order_by: ai }
193
+ }
194
+ `).toTranslate();
195
+ });
196
+ test('can specify multiple partition_bys', () => {
197
+ expect((0, test_translator_1.markSource) `
198
+ ##! experimental { partition_by }
199
+ run: a -> {
200
+ group_by: ai, astr, abool
201
+ calculate: x is lag(ai) {
202
+ partition_by: ai
203
+ partition_by: astr, abool
204
+ }
205
+ }
206
+ `).toTranslate();
207
+ });
208
+ test('can specify multiple order_bys', () => {
209
+ expect((0, test_translator_1.markSource) `
210
+ ##! experimental { function_order_by }
211
+ run: a -> {
212
+ group_by: ai, astr, abool
213
+ calculate: x is lag(ai) {
214
+ order_by: ai
215
+ order_by: astr, abool
216
+ }
217
+ }
218
+ `).toTranslate();
219
+ });
220
+ test('aggregate order by cannot be aggregate', () => {
221
+ expect((0, test_translator_1.markSource) `
222
+ ##! experimental { function_order_by }
223
+ run: a -> {
224
+ aggregate: x is string_agg(astr) {
225
+ order_by: sum(ai)
226
+ }
227
+ }
228
+ `).translationToFailWith('aggregate `order_by` must be scalar');
229
+ });
230
+ test('aggregate order by cannot be analytic', () => {
231
+ expect((0, test_translator_1.markSource) `
232
+ ##! experimental { function_order_by }
233
+ run: a -> {
234
+ aggregate: x is string_agg(astr) {
235
+ order_by: rank()
236
+ }
237
+ }
238
+ `).translationToFailWith('aggregate `order_by` must be scalar');
239
+ });
240
+ test('analytic order by can be an aggregate', () => {
241
+ expect((0, test_translator_1.markSource) `
242
+ ##! experimental { function_order_by }
243
+ run: a -> {
244
+ group_by: abool
245
+ calculate: x is lag(abool) {
246
+ order_by: sum(ai)
247
+ }
248
+ }
249
+ `).toTranslate();
250
+ });
251
+ test('analytic order by can be an output field', () => {
252
+ expect((0, test_translator_1.markSource) `
253
+ ##! experimental { function_order_by }
254
+ run: a -> {
255
+ group_by: ai
256
+ calculate: x is lag(ai) {
257
+ order_by: ai
258
+ }
259
+ }
260
+ `).toTranslate();
261
+ });
262
+ test('analytic order by must be an output field', () => {
263
+ expect((0, test_translator_1.markSource) `
264
+ ##! experimental { function_order_by }
265
+ run: a -> {
266
+ group_by: abool
267
+ calculate: x is lag(abool) {
268
+ order_by: ai
269
+ }
270
+ }
271
+ `).translationToFailWith('analytic `order_by` must be an aggregate or an output field reference');
272
+ });
273
+ test('can specify multiple wheres', () => {
274
+ expect((0, test_translator_1.markSource) `
275
+ ##! experimental { function_order_by }
276
+ run: a -> {
277
+ aggregate: x is count() {
278
+ where: ai > 10
279
+ where: astr ~ '%foo%'
280
+ }
281
+ }
282
+ `).toTranslate();
283
+ });
284
+ test('string_agg can take order_by', () => {
285
+ expect((0, test_translator_1.markSource) `
286
+ ##! experimental { function_order_by }
287
+ run: a -> {
288
+ aggregate: x1 is string_agg(astr) { order_by: ai }
289
+ aggregate: x2 is string_agg(astr) { order_by: ai * 2 }
290
+ aggregate: x3 is string_agg(astr) { order_by: ai desc }
291
+ aggregate: x4 is string_agg(astr) { order_by: ai asc }
292
+ aggregate: x5 is string_agg(astr) { order_by: ai asc, ai }
293
+ }
294
+ `).toTranslate();
295
+ });
296
+ });
174
297
  describe('aggregate forms', () => {
175
298
  const m = (0, test_translator_1.model) `
176
299
  source: root is a extend {
@@ -85,8 +85,8 @@ declare class QueryField extends QueryNode {
85
85
  generateDialect(resultSet: FieldInstanceResult, context: QueryStruct, expr: DialectFragment, state: GenerateState): string;
86
86
  generateSqlString(resultSet: FieldInstanceResult, context: QueryStruct, expr: SqlStringFragment, state: GenerateState): string;
87
87
  generateSourceReference(resultSet: FieldInstanceResult, context: QueryStruct, expr: SourceReferenceFragment): string;
88
- getAnalyticPartitions(resultStruct: FieldInstanceResult): string;
89
- generateAnalyticFragment(resultStruct: FieldInstanceResult, context: QueryStruct, expr: Expr, overload: FunctionOverloadDef, state: GenerateState, args: Expr[]): string;
88
+ getAnalyticPartitions(resultStruct: FieldInstanceResult, extraPartitionFields?: string[]): string[];
89
+ generateAnalyticFragment(resultStruct: FieldInstanceResult, context: QueryStruct, expr: Expr, overload: FunctionOverloadDef, state: GenerateState, args: Expr[], partitionByFields?: string[], funcOrdering?: string): string;
90
90
  generateExpressionFromExpr(resultSet: FieldInstanceResult, context: QueryStruct, e: Expr, state?: GenerateState): string;
91
91
  getExpr(): Expr;
92
92
  generateExpression(resultSet: FieldInstanceResult): string;