@malloydata/malloy 0.0.88-dev231002231014 → 0.0.88-dev231002235732

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 (50) hide show
  1. package/dist/lang/ast/elements/define-query.d.ts +3 -3
  2. package/dist/lang/ast/elements/define-query.js +9 -4
  3. package/dist/lang/ast/elements/define-source.d.ts +3 -3
  4. package/dist/lang/ast/elements/define-source.js +12 -4
  5. package/dist/lang/ast/elements/pipeline-desc.d.ts +1 -0
  6. package/dist/lang/ast/elements/pipeline-desc.js +3 -0
  7. package/dist/lang/ast/elements/source-query-nodes.d.ts +72 -0
  8. package/dist/lang/ast/elements/source-query-nodes.js +368 -0
  9. package/dist/lang/ast/elements/source-query.d.ts +11 -0
  10. package/dist/lang/ast/{query-elements/run-query.js → elements/source-query.js} +32 -21
  11. package/dist/lang/ast/index.d.ts +2 -2
  12. package/dist/lang/ast/index.js +2 -2
  13. package/dist/lang/ast/query-elements/anonymous-query.d.ts +3 -3
  14. package/dist/lang/ast/query-elements/anonymous-query.js +15 -8
  15. package/dist/lang/ast/query-elements/existing-query.js +1 -1
  16. package/dist/lang/ast/query-items/field-references.d.ts +4 -0
  17. package/dist/lang/ast/query-items/field-references.js +11 -1
  18. package/dist/lang/ast/query-items/typecheck_utils.js +5 -5
  19. package/dist/lang/ast/query-properties/joins.d.ts +7 -5
  20. package/dist/lang/ast/query-properties/joins.js +22 -8
  21. package/dist/lang/ast/sources/sql-source.js +5 -0
  22. package/dist/lang/ast/sql-elements/sql-string.d.ts +2 -2
  23. package/dist/lang/ast/sql-elements/sql-string.js +19 -9
  24. package/dist/lang/ast/types/malloy-element.d.ts +3 -1
  25. package/dist/lang/ast/types/malloy-element.js +16 -5
  26. package/dist/lang/lib/Malloy/MalloyParser.d.ts +179 -184
  27. package/dist/lang/lib/Malloy/MalloyParser.js +3141 -2928
  28. package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +147 -199
  29. package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +88 -120
  30. package/dist/lang/malloy-to-ast.d.ts +16 -15
  31. package/dist/lang/malloy-to-ast.js +147 -141
  32. package/dist/lang/parse-tree-walkers/document-symbol-walker.js +1 -1
  33. package/dist/lang/parse-utils.js +2 -2
  34. package/dist/lang/test/annotation.spec.js +35 -46
  35. package/dist/lang/test/document-symbol-walker.spec.js +2 -2
  36. package/dist/lang/test/expressions.spec.js +16 -16
  37. package/dist/lang/test/imports.spec.js +10 -8
  38. package/dist/lang/test/literals.spec.js +4 -4
  39. package/dist/lang/test/locations.spec.js +82 -80
  40. package/dist/lang/test/parse-expects.js +5 -1
  41. package/dist/lang/test/parse.spec.js +173 -117
  42. package/dist/lang/test/query.spec.js +199 -203
  43. package/dist/lang/test/source.spec.js +54 -45
  44. package/dist/lang/test/sql-block.spec.js +19 -12
  45. package/dist/lang/test/test-translator.js +8 -5
  46. package/dist/malloy.js +2 -2
  47. package/package.json +1 -2
  48. package/dist/lang/ast/query-elements/run-query.d.ts +0 -13
  49. package/dist/lang/ast/sources/named-source-or-query.d.ts +0 -10
  50. package/dist/lang/ast/sources/named-source-or-query.js +0 -71
@@ -27,53 +27,54 @@ require("./parse-expects");
27
27
  const model_1 = require("../../model");
28
28
  describe('query:', () => {
29
29
  describe('basic query syntax', () => {
30
- test('anonymous query', () => {
31
- expect((0, test_translator_1.markSource) `query: ${"table('aTable') -> { group_by: astr }"}`).toTranslate();
32
- });
33
- test('anonymous query', () => {
30
+ test('run:anonymous query', () => expect('run: a -> { group_by: astr }').toTranslate());
31
+ test('query:anonymous query m4 warning', () => {
34
32
  expect((0, test_translator_1.markSource) `##! m4warnings
35
- query: ${"conn.table('aTable') -> { group_by: astr }"}`).toTranslateWithWarnings('Anonymous `query:` statements are deprecated, use `run:` instead');
33
+ query: ${'a -> { group_by: astr }'}`).toTranslateWithWarnings('Anonymous `query:` statements are deprecated, use `run:` instead');
36
34
  });
37
- test('run query', () => expect("run: table('aTable') -> { group_by: astr }").toTranslate());
35
+ test('named query:', () => expect('query: aq is a -> { group_by: astr }').toTranslate());
38
36
  test('run query ref', () => expect(`
39
- query: foo is table('aTable') -> { group_by: astr }
40
- run: foo
37
+ query: foo is a -> { group_by: astr }
38
+ run: foo
41
39
  `).toTranslate());
42
- test('query', () => expect("query: name is table('aTable') -> { group_by: astr }").toTranslate());
43
- test('query', () => {
44
- expect("query: name is table('aTable') -> { group_by: astr }").toTranslate();
45
- });
46
40
  test('query from query', () => {
47
41
  expect(`
48
42
  query: q1 is ab->{ group_by: astr limit: 10 }
49
- query: q2 is ->q1
43
+ query: q2 is q1
50
44
  `).toTranslate();
51
45
  });
52
46
  test('query with refinements from query', () => {
53
47
  expect(`
54
48
  query: q1 is ab->{ group_by: astr limit: 10 }
55
- query: q2 is ->q1 { aggregate: acount }
49
+ query: q2 is q1 + { aggregate: acount }
56
50
  `).toTranslate();
57
51
  });
58
52
  test('chained query operations', () => {
59
53
  expect(`
60
- query: ab
54
+ run: ab
61
55
  -> { group_by: astr; aggregate: acount }
62
56
  -> { top: 5; where: astr ~ 'a%' group_by: astr }
63
57
  `).toTranslate();
64
58
  });
65
- test('from(query) refined into query', () => {
66
- expect('query: from(ab -> {group_by: astr}) { dimension: bigstr is upper(astr) } -> { group_by: bigstr }').toTranslate();
59
+ test('query output refined into another query pre-m4', () => {
60
+ expect(`
61
+ ##! -m4warnings
62
+ run: from(ab -> {group_by: astr}) extend { dimension: bigstr is upper(astr) } -> { group_by: bigstr }
63
+ `).toTranslate();
64
+ });
65
+ test('query output refined into another query', () => {
66
+ expect('run: ab -> {group_by: astr} extend { dimension: bigstr is upper(astr) } -> { group_by: bigstr }').toTranslate();
67
67
  });
68
68
  test('query with shortcut filtered turtle', () => {
69
- expect("query: allA is ab -> aturtle {? astr ~ 'a%' }").toTranslate();
69
+ expect(`##! -m4warnings
70
+ query: allA is ab -> aturtle + {? astr ~ 'a%' }`).toTranslate();
70
71
  });
71
72
  test('query with filtered turtle', () => {
72
- expect("query: allA is ab -> aturtle { where: astr ~ 'a%' }").toTranslate();
73
+ expect("query: allA is ab -> aturtle + { where: astr ~ 'a%' }").toTranslate();
73
74
  });
74
75
  test('nest: in group_by:', () => {
75
76
  expect(`
76
- query: ab -> {
77
+ run: ab -> {
77
78
  group_by: astr;
78
79
  nest: nested_count is {
79
80
  aggregate: acount
@@ -83,19 +84,19 @@ describe('query:', () => {
83
84
  });
84
85
  test('reduce pipe project', () => {
85
86
  expect(`
86
- query: a -> { aggregate: f is count() } -> { project: f2 is f + 1 }
87
+ run: a -> { aggregate: f is count() } -> { select: f2 is f + 1 }
87
88
  `).toTranslate();
88
89
  });
89
90
  test('refine and extend query', () => {
90
91
  expect(`
91
92
  query: a_by_str is a -> { group_by: astr }
92
- query: -> a_by_str { aggregate: str_count is count() }
93
+ run: a_by_str + { aggregate: str_count is count() }
93
94
  `).toTranslate();
94
95
  });
95
96
  test('query refinement preserves original', () => {
96
97
  const x = new test_translator_1.TestTranslator(`
97
98
  query: q is a -> { aggregate: acount is count() }
98
- query: nq is -> q + { group_by: astr }
99
+ query: nq is q + { group_by: astr }
99
100
  `);
100
101
  expect(x).toTranslate();
101
102
  const q = x.getQuery('q');
@@ -108,7 +109,7 @@ describe('query:', () => {
108
109
  test('query composition preserves original', () => {
109
110
  const x = new test_translator_1.TestTranslator(`
110
111
  query: q is ab -> { aggregate: acount }
111
- query: nq is -> q -> { project: * }
112
+ query: nq is q -> { select: * }
112
113
  `);
113
114
  expect(x).toTranslate();
114
115
  const q = x.getQuery('q');
@@ -119,7 +120,7 @@ describe('query:', () => {
119
120
  });
120
121
  test('all ungroup with args', () => {
121
122
  expect(`
122
- query: a -> {
123
+ run: a -> {
123
124
  group_by: astr
124
125
  nest: by_int is {
125
126
  group_by: ai
@@ -130,18 +131,17 @@ describe('query:', () => {
130
131
  });
131
132
  test('all ungroup checks args', () => {
132
133
  expect(`
133
- query: a -> {
134
- group_by: astr
135
- nest: by_int is {
136
- group_by: ai
137
- aggregate: bi_count is all(count(), afloat)
138
- }
139
- }
140
- `).translationToFailWith("all() 'afloat' is missing from query output");
134
+ run: a -> {
135
+ group_by: astr
136
+ nest: by_int is {
137
+ group_by: ai
138
+ aggregate: bi_count is all(count(), afloat)
139
+ }
140
+ }`).translationToFailWith("all() 'afloat' is missing from query output");
141
141
  });
142
142
  test('exclude ungroup with args', () => {
143
143
  expect(`
144
- query: a -> {
144
+ run: a -> {
145
145
  group_by: aa is 'a'
146
146
  nest: by_b is {
147
147
  group_by: bb is 'b'
@@ -155,7 +155,7 @@ describe('query:', () => {
155
155
  });
156
156
  test('exclude ungroup checks args', () => {
157
157
  expect(`
158
- query: a -> {
158
+ run: a -> {
159
159
  group_by: aa is 'a'
160
160
  nest: by_b is {
161
161
  group_by: bb is 'b'
@@ -169,14 +169,14 @@ describe('query:', () => {
169
169
  });
170
170
  test('exclude problem revealed by production models', () => {
171
171
  expect(`
172
- source: carriers is table('malloytest.carriers') {
172
+ source: carriers is _db_.table('malloytest.carriers') extend {
173
173
  primary_key: code
174
174
  }
175
- source: flights is table('malloytest.flights') {
175
+ source: flights is _db_.table('malloytest.flights') extend {
176
176
  primary_key: id2
177
177
  join_one: carriers with carrier
178
178
 
179
- query: carrier_overview is {
179
+ view: carrier_overview is {
180
180
  group_by: carrier_name is carriers.nickname
181
181
  nest: top_destinations is {
182
182
  group_by: destination
@@ -191,93 +191,94 @@ describe('query:', () => {
191
191
  describe('query operation typechecking', () => {
192
192
  describe('field declarations', () => {
193
193
  test('cannot use aggregate in group_by', () => {
194
- expect('query: a -> { group_by: s is count()}').translationToFailWith('Cannot use an aggregate field in a group_by operation, did you mean to use an aggregate operation instead?');
194
+ expect('run: a -> { group_by: s is count()}').translationToFailWith('Cannot use an aggregate field in a group_by operation, did you mean to use an aggregate operation instead?');
195
195
  });
196
196
  test('cannot use ungrouped_aggregate in group_by', () => {
197
- expect('query: a -> { group_by: s is all(count())}').translationToFailWith('Cannot use an aggregate field in a group_by operation, did you mean to use an aggregate operation instead?');
197
+ expect('run: a -> { group_by: s is all(count())}').translationToFailWith('Cannot use an aggregate field in a group_by operation, did you mean to use an aggregate operation instead?');
198
198
  });
199
199
  test('cannot use analytic in group_by', () => {
200
- expect('query: a -> { group_by: s is row_number()}').translationToFailWith('Cannot use an analytic field in a group_by operation, did you mean to use a calculate operation instead?');
200
+ expect('run: a -> { group_by: s is row_number()}').translationToFailWith('Cannot use an analytic field in a group_by operation, did you mean to use a calculate operation instead?');
201
201
  });
202
202
  test('cannot use aggregate in dimension', () => {
203
- expect('source: a1 is a { dimension: s is count()}').translationToFailWith('Cannot use an aggregate field in a dimension declaration, did you mean to use a measure declaration instead?');
203
+ expect('source: a1 is a extend { dimension: s is count()}').translationToFailWith('Cannot use an aggregate field in a dimension declaration, did you mean to use a measure declaration instead?');
204
204
  });
205
205
  test('cannot use ungrouped_aggregate in dimension', () => {
206
- expect('source: a1 is a { dimension: s is all(count())}').translationToFailWith('Cannot use an aggregate field in a dimension declaration, did you mean to use a measure declaration instead?');
206
+ expect('source: a1 is a extend { dimension: s is all(count())}').translationToFailWith('Cannot use an aggregate field in a dimension declaration, did you mean to use a measure declaration instead?');
207
207
  });
208
208
  test('cannot use analytic in dimension', () => {
209
- expect('source: a1 is a { dimension: s is row_number()}').translationToFailWith('Cannot use an analytic field in a dimension declaration');
209
+ expect('source: a1 is a extend { dimension: s is row_number()}').translationToFailWith('Cannot use an analytic field in a dimension declaration');
210
210
  });
211
211
  test('cannot use scalar in measure', () => {
212
- expect('source: a1 is a { measure: s is 1}').translationToFailWith('Cannot use a scalar field in a measure declaration, did you mean to use a dimension declaration instead?');
212
+ expect('source: a1 is a extend { measure: s is 1}').translationToFailWith('Cannot use a scalar field in a measure declaration, did you mean to use a dimension declaration instead?');
213
213
  });
214
214
  test('cannot use analytic in measure', () => {
215
- expect('source: a1 is a { measure: s is lag(count())}').translationToFailWith('Cannot use an analytic field in a measure declaration');
215
+ expect('source: a1 is a extend { measure: s is lag(count())}').translationToFailWith('Cannot use an analytic field in a measure declaration');
216
216
  });
217
217
  test('cannot use scalar in aggregate', () => {
218
- expect('query: a -> { aggregate: s is 1}').translationToFailWith('Cannot use a scalar field in an aggregate operation, did you mean to use a group_by or project operation instead?');
218
+ expect('run: a -> { aggregate: s is 1}').translationToFailWith('Cannot use a scalar field in an aggregate operation, did you mean to use a group_by or project operation instead?');
219
219
  });
220
220
  test('cannot use analytic in aggregate', () => {
221
- expect('query: a -> { aggregate: s is lag(count())}').translationToFailWith('Cannot use an analytic field in an aggregate operation, did you mean to use a calculate operation instead?');
221
+ expect('run: a -> { aggregate: s is lag(count())}').translationToFailWith('Cannot use an analytic field in an aggregate operation, did you mean to use a calculate operation instead?');
222
222
  });
223
223
  test('cannot use scalar in calculate', () => {
224
- expect('query: a -> { group_by: a is 1; calculate: s is 1 }').translationToFailWith('Cannot use a scalar field in a calculate operation, did you mean to use a group_by or project operation instead?');
224
+ expect('run: a -> { group_by: a is 1; calculate: s is 1 }').translationToFailWith('Cannot use a scalar field in a calculate operation, did you mean to use a group_by or project operation instead?');
225
225
  });
226
226
  test('cannot use aggregate in calculate', () => {
227
- expect('query: a -> { group_by: a is 1; calculate: s is count() }').translationToFailWith('Cannot use an aggregate field in a calculate operation, did you mean to use an aggregate operation instead?');
227
+ expect('run: a -> { group_by: a is 1; calculate: s is count() }').translationToFailWith('Cannot use an aggregate field in a calculate operation, did you mean to use an aggregate operation instead?');
228
228
  });
229
229
  test('cannot use aggregate in project', () => {
230
- expect('query: a -> { project: s is count() }').translationToFailWith('Cannot use an aggregate field in a project operation, did you mean to use an aggregate operation instead?');
230
+ expect('run: a -> { select: s is count() }').translationToFailWith('Cannot use an aggregate field in a project operation, did you mean to use an aggregate operation instead?');
231
231
  });
232
232
  test('cannot use analytic in project', () => {
233
- expect('query: a -> { project: s is row_number() }').translationToFailWith('Cannot use an analytic field in a project operation, did you mean to use a calculate operation instead?');
233
+ expect('run: a -> { select: s is row_number() }').translationToFailWith('Cannot use an analytic field in a project operation, did you mean to use a calculate operation instead?');
234
234
  });
235
235
  test('cannot use analytic in declare', () => {
236
- expect('query: a -> { group_by: a is 1; declare: s is row_number() }').translationToFailWith('Analytic expressions can not be used in a declare block');
236
+ expect(`##! -m4warnings
237
+ run: a -> { group_by: a is 1; declare: s is row_number() }`).translationToFailWith('Analytic expressions can not be used in a declare block');
237
238
  });
238
239
  test('cannot use aggregate in index', () => {
239
- expect('query: a { measure: acount is count() } -> { index: acount }').translationToFailWith('Cannot use an aggregate field in an index operation');
240
+ expect('run: a extend { measure: acount is count() } -> { index: acount }').translationToFailWith('Cannot use an aggregate field in an index operation');
240
241
  });
241
242
  test('can use aggregate in except', () => {
242
243
  expect(`
243
- source: b1 is a { measure: acount is count() }
244
- source: c1 is b1 { except: acount }
244
+ source: b1 is a extend { measure: acount is count() }
245
+ source: c1 is b1 extend { except: acount }
245
246
  `).toTranslate();
246
247
  });
247
248
  });
248
249
  describe('field references', () => {
249
250
  test('cannot use aggregate in group_by', () => {
250
- expect('query: a -> { declare: acount is count(); group_by: acount }').translationToFailWith('Cannot use an aggregate field in a group_by operation, did you mean to use an aggregate operation instead?');
251
+ expect('run: a -> { extend: {measure: acount is count()} group_by: acount }').translationToFailWith('Cannot use an aggregate field in a group_by operation, did you mean to use an aggregate operation instead?');
251
252
  });
252
253
  test('cannot use query in group_by', () => {
253
- expect('query: a { query: q is { group_by: x is 1 } } -> { group_by: q }').translationToFailWith('Cannot use a query field in a group_by operation, did you mean to use a nest operation instead?');
254
+ expect('run: a extend { view: q is { group_by: x is 1 } } -> { group_by: q }').translationToFailWith('Cannot use a view field in a group_by operation, did you mean to use a nest operation instead?');
254
255
  });
255
256
  test('cannot use scalar in aggregate', () => {
256
- expect('query: a -> { declare: aconst is 1; aggregate: aconst }').translationToFailWith('Cannot use a scalar field in an aggregate operation, did you mean to use a group_by or project operation instead?');
257
+ expect('run: a -> { extend: {dimension: aconst is 1} aggregate: aconst }').translationToFailWith('Cannot use a scalar field in an aggregate operation, did you mean to use a group_by or project operation instead?');
257
258
  });
258
259
  test('cannot use scalar in calculate', () => {
259
- expect('query: a -> { declare: aconst is 1; group_by: x is 1; calculate: aconst }').translationToFailWith('Cannot use a scalar field in a calculate operation, did you mean to use a group_by or project operation instead?');
260
+ expect('run: a -> { extend: {dimension: aconst is 1} group_by: x is 1; calculate: aconst }').translationToFailWith('Cannot use a scalar field in a calculate operation, did you mean to use a group_by or project operation instead?');
260
261
  });
261
262
  test('cannot use aggregate in calculate', () => {
262
- expect('query: a -> { declare: acount is count(); group_by: x is 1; calculate: acount }').translationToFailWith('Cannot use an aggregate field in a calculate operation, did you mean to use an aggregate operation instead?');
263
+ expect('run: a -> { extend: {measure: acount is count()} group_by: x is 1; calculate: acount }').translationToFailWith('Cannot use an aggregate field in a calculate operation, did you mean to use an aggregate operation instead?');
263
264
  });
264
265
  test('cannot use query in project', () => {
265
- expect('query: a { query: q is { group_by: x is 1 } } -> { project: q }').translationToFailWith('Cannot use a query field in a project operation, did you mean to use a nest operation instead?');
266
+ expect('run: a extend { view: q is { group_by: x is 1 } } -> { select: q }').translationToFailWith('Cannot use a view field in a project operation, did you mean to use a nest operation instead?');
266
267
  });
267
268
  test('cannot use query in index', () => {
268
- expect('query: a { query: q is { group_by: x is 1 } } -> { index: q }').translationToFailWith('Cannot use a query field in an index operation');
269
+ expect('run: a extend { view: q is { group_by: x is 1 } } -> { index: q }').translationToFailWith('Cannot use a view field in an index operation');
269
270
  });
270
271
  test('cannot use query in calculate', () => {
271
- expect('query: a { query: q is { group_by: x is 1 } } -> { group_by: x is 1; calculate: q }').translationToFailWith('Cannot use a query field in a calculate operation, did you mean to use a nest operation instead?');
272
+ expect('run: a extend { view: q is { group_by: x is 1 } } -> { group_by: x is 1; calculate: q }').translationToFailWith('Cannot use a view field in a calculate operation, did you mean to use a nest operation instead?');
272
273
  });
273
274
  test('cannot use query in aggregate', () => {
274
- expect('query: a { query: q is { group_by: x is 1 } } -> { aggregate: q }').translationToFailWith('Cannot use a query field in an aggregate operation, did you mean to use a nest operation instead?');
275
+ expect('run: a extend { view: q is { group_by: x is 1 } } -> { aggregate: q }').translationToFailWith('Cannot use a view field in an aggregate operation, did you mean to use a nest operation instead?');
275
276
  });
276
277
  test('cannot use aggregate in calculate, preserved over refinement', () => {
277
278
  expect(`query: a1 is a -> {
278
279
  aggregate: c is count()
279
280
  }
280
- query: -> a1 {
281
+ run: a1 + {
281
282
  calculate: b is c
282
283
  }`).translationToFailWith('Cannot use an aggregate field in a calculate operation, did you mean to use an aggregate operation instead?');
283
284
  });
@@ -285,7 +286,7 @@ describe('query:', () => {
285
286
  expect(`query: a1 is a -> {
286
287
  group_by: c is 1
287
288
  }
288
- query: -> a1 {
289
+ run: a1 + {
289
290
  calculate: b is c
290
291
  }`).translationToFailWith('Cannot use a scalar field in a calculate operation, did you mean to use a group_by or project operation instead?');
291
292
  });
@@ -294,7 +295,7 @@ describe('query:', () => {
294
295
  group_by: c is 1
295
296
  calculate: c2 is lag(c)
296
297
  }
297
- query: -> a1 {
298
+ run: a1 + {
298
299
  group_by: b is c2
299
300
  }`).translationToFailWith(
300
301
  // c2 is not defined because group_by doesn't know to look in the output space
@@ -305,7 +306,7 @@ describe('query:', () => {
305
306
  group_by: c is 1
306
307
  calculate: c2 is lag(c)
307
308
  }
308
- query: -> a1 {
309
+ run: a1 + {
309
310
  order_by: c2
310
311
  }`).translationToFailWith('Illegal order by of analytic field c2');
311
312
  });
@@ -331,7 +332,7 @@ describe('query:', () => {
331
332
  expect(`query: a1 is a -> {
332
333
  group_by: c is 1
333
334
  }
334
- query: -> a1 {
335
+ run: a1 + {
335
336
  order_by: c
336
337
  }`).toTranslate();
337
338
  });
@@ -339,7 +340,7 @@ describe('query:', () => {
339
340
  expect(`query: a1 is a -> {
340
341
  group_by: c is astr
341
342
  }
342
- query: -> a1 {
343
+ run: a1 + {
343
344
  order_by: c
344
345
  }`).toTranslate();
345
346
  });
@@ -347,30 +348,30 @@ describe('query:', () => {
347
348
  });
348
349
  describe('function typechecking', () => {
349
350
  test('use function correctly', () => {
350
- expect(`query: a -> {
351
+ expect(`run: a -> {
351
352
  group_by: s is concat('a', 'b')
352
353
  }`).toTranslate();
353
354
  });
354
355
  test('function incorrect case', () => {
355
- expect(`query: a -> {
356
+ expect(`run: a -> {
356
357
  group_by: s is CONCAT('a', 'b')
357
358
  }`).toTranslateWithWarnings("Case insensitivity for function names is deprecated, use 'concat' instead");
358
359
  });
359
360
  test('function no matching overload', () => {
360
- expect(`query: a -> {
361
+ expect(`run: a -> {
361
362
  group_by: s is floor('a', 'b')
362
363
  }`).translationToFailWith('No matching overload for function floor(string, string)');
363
364
  });
364
365
  test('unknown function', () => {
365
- expect(`query: a -> {
366
+ expect(`run: a -> {
366
367
  group_by: s is asdfasdf()
367
368
  }`).translationToFailWith("Unknown function 'asdfasdf'. Use 'asdfasdf!(...)' to call a SQL function directly.");
368
369
  });
369
370
  test('can select different overload', () => {
370
- expect('query: a -> { group_by: s is concat() }').toTranslate();
371
+ expect('run: a -> { group_by: s is concat() }').toTranslate();
371
372
  });
372
373
  test('can pass different expression types', () => {
373
- expect(`query: a -> {
374
+ expect(`run: a -> {
374
375
  group_by: f1 is sqrt(1)
375
376
  aggregate: f2 is sqrt(count())
376
377
  aggregate: f3 is sqrt(all(count()))
@@ -379,29 +380,29 @@ describe('query:', () => {
379
380
  }`).toTranslate();
380
381
  });
381
382
  test('function return type correct', () => {
382
- expect(`query: a -> {
383
+ expect(`run: a -> {
383
384
  group_by: s is floor(1.2) + 1
384
385
  }`).toTranslate();
385
386
  });
386
387
  test('function return type incorrect', () => {
387
- expect(`query: a -> {
388
+ expect(`run: a -> {
388
389
  group_by: s is floor(1.2) + 'a'
389
390
  }`).translationToFailWith("Non numeric('number,string') value with '+'");
390
391
  });
391
392
  test('can use output value in calculate', () => {
392
- expect(`query: a -> {
393
+ expect(`run: a -> {
393
394
  group_by: x is 1
394
395
  calculate: s is lag(x)
395
396
  }`).toTranslate();
396
397
  });
397
398
  test('cannot use output value in group_by', () => {
398
- expect(`query: a -> {
399
+ expect(`run: a -> {
399
400
  group_by: x is 1
400
401
  group_by: y is x
401
402
  }`).translationToFailWith("'x' is not defined");
402
403
  });
403
404
  test('lag can check that other args are constant', () => {
404
- expect(`query: a -> {
405
+ expect(`run: a -> {
405
406
  group_by: x is 1
406
407
  calculate: s is lag(x, 1, x)
407
408
  }`).translationToFailWith(
@@ -409,7 +410,7 @@ describe('query:', () => {
409
410
  "Parameter 3 ('default') of lag must be literal or constant, but received output");
410
411
  });
411
412
  test('lag can check that other args are literal', () => {
412
- expect(`query: a -> {
413
+ expect(`run: a -> {
413
414
  group_by: x is 1
414
415
  calculate: s is lag(x, 1 + 1)
415
416
  }`).translationToFailWith(
@@ -417,13 +418,13 @@ describe('query:', () => {
417
418
  "Parameter 2 ('offset') of lag must be literal, but received constant");
418
419
  });
419
420
  test('lag can check that other args are nonnull', () => {
420
- expect(`query: a -> {
421
+ expect(`run: a -> {
421
422
  group_by: x is 1
422
423
  calculate: s is lag(x, null)
423
424
  }`).translationToFailWith("Parameter 2 ('offset') of lag must not be a literal null");
424
425
  });
425
426
  test('lag can use constant values for other args', () => {
426
- expect(`query: a -> {
427
+ expect(`run: a -> {
427
428
  group_by: x is 1
428
429
  calculate: s is lag(x, 2)
429
430
  }`).toTranslate();
@@ -434,7 +435,7 @@ describe('query:', () => {
434
435
  "'concat' is already defined, cannot redefine");
435
436
  });
436
437
  test('`now` is considered constant`', () => {
437
- expect(`query: a -> {
438
+ expect(`run: a -> {
438
439
  group_by: n is now
439
440
  calculate: l is lag(n, 1, now)
440
441
  }`).toTranslate();
@@ -442,7 +443,7 @@ describe('query:', () => {
442
443
  // TODO it might be nice to reference a field which is a constant, and be able to
443
444
  // use that as a constant param. Same with a literal.
444
445
  test('cannot use a field which is a constant in a constant param', () => {
445
- expect(`query: a -> {
446
+ expect(`run: a -> {
446
447
  group_by: ai, pi is pi()
447
448
  calculate: l is lag(ai, 1, pi)
448
449
  }`).translationToFailWith("Parameter 3 ('default') of lag must be literal or constant, but received output");
@@ -452,7 +453,7 @@ describe('query:', () => {
452
453
  // as a function argument.
453
454
  // We add <join_name>_id to the query, but it's not included in the output space
454
455
  test('cannot use struct in function arg', () => {
455
- expect(`query: a {join_one: b with astr } -> {
456
+ expect(`run: a extend {join_one: b with astr } -> {
456
457
  group_by: b
457
458
  calculate: foo is lag(b)
458
459
  }`).translationToFailWith('No matching overload for function lag(struct)');
@@ -460,37 +461,37 @@ describe('query:', () => {
460
461
  // TODO this doesn't work today, we're not rigorous enough with integer
461
462
  // subtypes. But we should probably make this typecheck properly.
462
463
  test.skip('cannot use float in round precision', () => {
463
- expect(`query: a -> {
464
+ expect(`run: a -> {
464
465
  group_by: x is round(1.5, 1.6)
465
466
  }`).translationToFailWith(
466
467
  // TODO improve this error message
467
468
  "Parameter 2 ('precision') for round must be integer, received float");
468
469
  });
469
470
  test('cannot use stddev with no arguments', () => {
470
- expect(`query: a -> {
471
+ expect(`run: a -> {
471
472
  aggregate: x is stddev()
472
473
  }`).translationToFailWith('No matching overload for function stddev()');
473
474
  });
474
475
  test('can use stddev with postfix syntax', () => {
475
- expect(`query: a -> {
476
- declare: y is 1
476
+ expect(`run: a -> {
477
+ extend: { dimension: y is 1 }
477
478
  aggregate: x is y.stddev()
478
479
  }`).toTranslate();
479
480
  });
480
481
  test('can use stddev with postfix syntax on join', () => {
481
- expect(`query: a -> {
482
- join_one: b with astr
482
+ expect(`run: a -> {
483
+ extend: { join_one: b with astr }
483
484
  aggregate: x is b.ai.stddev()
484
485
  }`).toTranslate();
485
486
  });
486
487
  test('can use calculate with a measure', () => {
487
- expect(`query: a { measure: c is count() } -> {
488
+ expect(`run: a extend { measure: c is count() } -> {
488
489
  group_by: y is 1
489
490
  calculate: x is lag(c)
490
491
  }`).toTranslate();
491
492
  });
492
493
  test('cannot use calculate with input fields', () => {
493
- expect(`query: a -> {
494
+ expect(`run: a -> {
494
495
  group_by: y is 1
495
496
  calculate: x is lag(ai)
496
497
  }`).translationToFailWith(
@@ -501,24 +502,24 @@ describe('query:', () => {
501
502
  "Parameter 1 ('value') of lag must be literal, constant or output, but received input");
502
503
  });
503
504
  test('can use calculate with aggregate field which is not in query', () => {
504
- expect(`query: a { measure: acount is count() } -> {
505
+ expect(`run: a extend { measure: acount is count() } -> {
505
506
  group_by: astr
506
507
  calculate: pc is lag(acount)
507
508
  }`).toTranslate();
508
509
  });
509
510
  test('cannot use agregate as argument to agg function', () => {
510
- expect(`query: a -> {
511
+ expect(`run: a -> {
511
512
  aggregate: x is stddev(count())
512
513
  }`).translationToFailWith("Parameter 1 ('value') of stddev must be scalar, but received aggregate");
513
514
  });
514
515
  test('cannot use calculate with no other fields', () => {
515
- expect(`query: a -> {
516
+ expect(`run: a -> {
516
517
  calculate: x is row_number()
517
518
  }`).translationToFailWith("Can't determine query type (group_by/aggregate/nest,project,index)");
518
519
  });
519
520
  // TODO someday make it so we can order by an analytic function
520
521
  test('today: cannot order by analytic function', () => {
521
- expect(`query: a -> {
522
+ expect(`run: a -> {
522
523
  group_by: astr
523
524
  calculate: row_num is row_number()
524
525
  order_by: row_num desc
@@ -529,45 +530,44 @@ describe('query:', () => {
529
530
  group_by: astr
530
531
  calculate: p is lag(astr)
531
532
  }
532
- query: -> a1 {
533
+ run: a1 + {
533
534
  calculate: p1 is lag(p)
534
535
  }`).translationToFailWith("Parameter 1 ('value') of lag must be scalar or aggregate, but received scalar_analytic");
535
536
  });
536
537
  test('cannot use aggregate analytic in project', () => {
537
- expect(`query: a -> {
538
- project: astr
538
+ expect(`run: a -> {
539
+ select: astr
539
540
  calculate: p is lag(count())
540
541
  }`).translationToFailWith('Cannot add aggregate analyics to project');
541
542
  });
542
543
  test('reference field in join', () => {
543
- expect(`query: a -> {
544
- join_one: b with astr
544
+ expect(`run: a -> {
545
+ extend: { join_one: b with astr }
545
546
  group_by: b.ai
546
547
  }`).toTranslate();
547
548
  });
548
- // TODO decide whether this syntax should be legal, really...
549
549
  test('reference join name in group_by', () => {
550
- expect(`query: a -> {
551
- join_one: b with astr
550
+ expect(`run: a -> {
551
+ extend: { join_one: b with astr }
552
552
  group_by: b
553
553
  }`).toTranslate();
554
554
  });
555
- test('can reference project: inline join.* field in calculate', () => {
556
- expect(`query: a -> {
557
- join_one: b with astr
558
- project: b.*
555
+ test('can reference select: inline join.* field in calculate', () => {
556
+ expect(`run: a -> {
557
+ extend: { join_one: b with astr }
558
+ select: b.*
559
559
  calculate: s is lag(ai)
560
560
  }`).toTranslate();
561
561
  });
562
- test('can reference project: join.* field in calculate', () => {
563
- expect(`query: a { join_one: b with astr } -> {
564
- project: b.*
562
+ test('can reference select: join.* field in calculate', () => {
563
+ expect(`run: a extend { join_one: b with astr } -> {
564
+ select: b.*
565
565
  calculate: s is lag(ai)
566
566
  }`).toTranslate();
567
567
  });
568
568
  test('can reference implied output entries in calculate', () => {
569
569
  expect(`source: aaa is a extend { dimension: big_i is ai+10 }
570
- query: a extend { join_one: aaa on astr=aaa.astr } -> {
570
+ run: a extend { join_one: aaa on astr=aaa.astr } -> {
571
571
  group_by: aaa.big_i
572
572
  aggregate: s is aaa.big_i.sum()
573
573
  calculate: a is lag(big_i)
@@ -576,26 +576,26 @@ describe('query:', () => {
576
576
  });
577
577
  describe('qops', () => {
578
578
  test('group by single', () => {
579
- expect('query: a->{ group_by: astr }').toTranslate();
579
+ expect('run: a->{ group_by: astr }').toTranslate();
580
580
  });
581
581
  test("group_by x is x'", () => {
582
- expect('query: a->{ group_by: ai is ai/2 }').toTranslate();
582
+ expect('run: a->{ group_by: ai is ai/2 }').toTranslate();
583
583
  });
584
584
  test('group by multiple', () => {
585
- expect('query: a->{ group_by: astr,ai }').toTranslate();
585
+ expect('run: a->{ group_by: astr,ai }').toTranslate();
586
586
  });
587
587
  test('aggregate single', () => {
588
- expect('query: a->{ aggregate: num is count() }').toTranslate();
588
+ expect('run: a->{ aggregate: num is count() }').toTranslate();
589
589
  });
590
590
  test('calculate in reduce', () => {
591
- expect('query: a->{ group_by: astr, ai calculate: num is lag(ai) }').toTranslate();
591
+ expect('run: a->{ group_by: astr, ai calculate: num is lag(ai) }').toTranslate();
592
592
  });
593
593
  test('calculate in project', () => {
594
- expect('query: a->{ project: astr, ai calculate: num is lag(ai) }').toTranslate();
594
+ expect('run: a->{ select: astr, ai calculate: num is lag(ai) }').toTranslate();
595
595
  });
596
596
  test('aggregate reference', () => {
597
597
  var _a;
598
- const doc = (0, test_translator_1.model) `query: a->{ aggregate: ai.sum() }`;
598
+ const doc = (0, test_translator_1.model) `run: a->{ aggregate: ai.sum() }`;
599
599
  expect(doc).toTranslate();
600
600
  const q = doc.translator.getQuery(0);
601
601
  expect(q).toBeDefined();
@@ -608,7 +608,7 @@ describe('query:', () => {
608
608
  });
609
609
  test('timeunit reference', () => {
610
610
  var _a;
611
- const doc = (0, test_translator_1.model) `query: a->{ group_by: ats.day }`;
611
+ const doc = (0, test_translator_1.model) `run: a->{ group_by: ats.day }`;
612
612
  expect(doc).toTranslate();
613
613
  const q = doc.translator.getQuery(0);
614
614
  expect(q).toBeDefined();
@@ -617,13 +617,13 @@ describe('query:', () => {
617
617
  });
618
618
  test('aggregate multiple', () => {
619
619
  expect(`
620
- query: a->{
620
+ run: a->{
621
621
  aggregate: num is count(), total is sum(ai)
622
622
  }
623
623
  `).toTranslate();
624
624
  });
625
625
  test('project ref', () => {
626
- expect('query:ab->{ project: b.astr }').toTranslate();
626
+ expect('run:ab->{ select: b.astr }').toTranslate();
627
627
  });
628
628
  const afields = test_translator_1.aTableDef.fields
629
629
  .filter(f => (0, model_1.isAtomicFieldType)(f.type))
@@ -678,14 +678,10 @@ describe('query:', () => {
678
678
  expect(fields.sort()).toEqual(afields.concat('x'));
679
679
  });
680
680
  test('project def', () => {
681
- expect('query:ab->{ project: one is 1 }').toTranslate();
681
+ expect('run: ab->{ select: one is 1 }').toTranslate();
682
682
  });
683
683
  test('project multiple', () => {
684
- expect(`
685
- query: a->{
686
- project: one is 1, astr
687
- }
688
- `).toTranslate();
684
+ expect('run: a->{ select: one is 1, astr }').toTranslate();
689
685
  });
690
686
  test('index single', () => { });
691
687
  test('regress check extend: and star', () => {
@@ -697,29 +693,29 @@ describe('query:', () => {
697
693
  expect(fields.sort()).toEqual(afields.concat('x'));
698
694
  });
699
695
  test('project def', () => {
700
- expect('query:ab->{ project: one is 1 }').toTranslate();
696
+ expect('run:ab->{ select: one is 1 }').toTranslate();
701
697
  });
702
698
  test('project multiple', () => {
703
699
  expect(`
704
- query: a->{
705
- project: one is 1, astr
700
+ run: a->{
701
+ select: one is 1, astr
706
702
  }
707
703
  `).toTranslate();
708
704
  });
709
705
  test('index single', () => {
710
- expect('query:a->{index: astr}').toTranslate();
706
+ expect('run:a->{index: astr}').toTranslate();
711
707
  });
712
708
  test('index path', () => {
713
- expect('query:ab->{index: ab.astr}').toTranslate();
709
+ expect('run:ab->{index: ab.astr}').toTranslate();
714
710
  });
715
711
  test('index unique on path', () => {
716
- expect('query:ab->{index: b.astr, ab.astr}').toTranslate();
712
+ expect('run:ab->{index: b.astr, ab.astr}').toTranslate();
717
713
  });
718
714
  test('index join.*', () => {
719
- expect('query:ab->{index: ab.*}').toTranslate();
715
+ expect('run:ab->{index: ab.*}').toTranslate();
720
716
  });
721
717
  test('index multiple', () => {
722
- const model = new test_translator_1.TestTranslator('query:a->{index: af, astr}');
718
+ const model = new test_translator_1.TestTranslator('run:a->{index: af, astr}');
723
719
  expect(model).toTranslate();
724
720
  const q = model.getQuery(0);
725
721
  expect(q).toBeDefined();
@@ -730,7 +726,7 @@ describe('query:', () => {
730
726
  }
731
727
  });
732
728
  test('index star', () => {
733
- const model = new test_translator_1.TestTranslator('query:a->{index: *, astr}');
729
+ const model = new test_translator_1.TestTranslator('run:a->{index: *, astr}');
734
730
  expect(model).toTranslate();
735
731
  const q = model.getQuery(0);
736
732
  expect(q).toBeDefined();
@@ -741,16 +737,16 @@ describe('query:', () => {
741
737
  }
742
738
  });
743
739
  test('index by', () => {
744
- expect('query:a->{index: * by ai}').toTranslate();
740
+ expect('run:a->{index: * by ai}').toTranslate();
745
741
  });
746
742
  test('index sampled', () => {
747
- expect('query:a->{index: *; sample: true}').toTranslate();
743
+ expect('run:a->{index: *; sample: true}').toTranslate();
748
744
  });
749
745
  test('index unsampled', () => {
750
- expect('query:a->{index: *; sample: false}').toTranslate();
746
+ expect('run:a->{index: *; sample: false}').toTranslate();
751
747
  });
752
748
  test('index sample-percent', () => {
753
- const model = new test_translator_1.TestTranslator('query:a->{index: *; sample: 42%}');
749
+ const model = new test_translator_1.TestTranslator('run:a->{index: *; sample: 42%}');
754
750
  expect(model).toTranslate();
755
751
  const q = model.getQuery(0);
756
752
  expect(q).toBeDefined();
@@ -763,74 +759,75 @@ describe('query:', () => {
763
759
  }
764
760
  });
765
761
  test('index sample-rows', () => {
766
- expect('query:a->{index: *; sample: 100000}').toTranslate();
762
+ expect('run:a->{index: *; sample: 100000}').toTranslate();
767
763
  });
768
764
  test('top N', () => {
769
- expect('query: a->{ top: 5; group_by: astr }').toTranslate();
765
+ expect('run: a->{ top: 5; group_by: astr }').toTranslate();
770
766
  });
771
767
  test('top N by field', () => {
772
- expect('query: a->{top: 5 by astr; group_by: astr}').toTranslate();
768
+ expect(`##! m4warnings
769
+ run: a->{top: 5 ${'by astr'}; group_by: astr}`).toTranslateWithWarnings('by clause of top statement unupported. Use order_by instead');
773
770
  });
774
771
  test('top N by expression', () => {
775
- expect('query: ab->{top: 5 by ai + 1; group_by: ai}').toTranslate();
772
+ expect(`##! m4warnings
773
+ run: ab->{top: 5 by ai + 1; group_by: ai}`).toTranslateWithWarnings('by clause of top statement unupported. Use order_by instead');
776
774
  });
777
- test('top N by field must be in the output space', () => expect('query: a->{top: 5 by af; group_by: astr}').translationToFailWith('Unknown field af in output space'));
778
775
  test('limit N', () => {
779
- expect('query: a->{ limit: 5; group_by: astr }').toTranslate();
776
+ expect('run: a->{ limit: 5; group_by: astr }').toTranslate();
780
777
  });
781
778
  test('order by', () => {
782
- expect('query: a->{ order_by: astr; group_by: astr }').toTranslate();
779
+ expect('run: a->{ order_by: astr; group_by: astr }').toTranslate();
783
780
  });
784
781
  test('order by preserved over refinement', () => {
785
782
  expect(`
786
783
  query: a1 is a -> { group_by: astr }
787
- query: -> a1 { order_by: astr }
784
+ run: a1 + { order_by: astr }
788
785
  `).toTranslate();
789
786
  });
790
- test('order by must be in the output space', () => expect('query: a -> { order_by: af; group_by: astr }').translationToFailWith('Unknown field af in output space'));
787
+ test('order by must be in the output space', () => expect('run: a -> { order_by: af; group_by: astr }').translationToFailWith('Unknown field af in output space'));
791
788
  test('order by asc', () => {
792
- expect('query: a->{ order_by: astr asc; group_by: astr }').toTranslate();
789
+ expect('run: a->{ order_by: astr asc; group_by: astr }').toTranslate();
793
790
  });
794
791
  test('order by desc', () => {
795
- expect('query: a->{ order_by: astr desc; group_by: astr }').toTranslate();
792
+ expect('run: a->{ order_by: astr desc; group_by: astr }').toTranslate();
796
793
  });
797
794
  test('order by N', () => {
798
- expect('query: a->{ order_by: 1 asc; group_by: astr }').toTranslate();
795
+ expect('run: a->{ order_by: 1 asc; group_by: astr }').toTranslate();
799
796
  });
800
797
  test('order by multiple', () => {
801
798
  expect(`
802
- query: a->{
799
+ run: a->{
803
800
  order_by: 1 asc, af desc
804
801
  group_by: astr, af
805
802
  }
806
803
  `).toTranslate();
807
804
  });
808
805
  test('agg cannot be used in where', () => {
809
- expect('query:ab->{ aggregate: acount; group_by: astr; where: acount > 10 }').translationToFailWith('Aggregate expressions are not allowed in `where:`; use `having:`');
806
+ expect('run:ab->{ aggregate: acount; group_by: astr; where: acount > 10 }').translationToFailWith('Aggregate expressions are not allowed in `where:`; use `having:`');
810
807
  });
811
808
  test('analytic cannot be used in where', () => {
812
- expect('query:ab->{ calculate: prevc is lag(count()); group_by: astr; where: prevc > 10 }').translationToFailWith("'prevc' is not defined");
809
+ expect('run:ab->{ calculate: prevc is lag(count()); group_by: astr; where: prevc > 10 }').translationToFailWith("'prevc' is not defined");
813
810
  });
814
811
  test('analytic cannot be used in having', () => {
815
- expect('query:ab->{ calculate: prevc is lag(count()); group_by: astr; having: prevc > 10 }').translationToFailWith('Analytic expressions are not allowed in `having:`');
812
+ expect('run:ab->{ calculate: prevc is lag(count()); group_by: astr; having: prevc > 10 }').translationToFailWith('Analytic expressions are not allowed in `having:`');
816
813
  });
817
814
  test('where single', () => {
818
- expect('query:a->{ group_by: astr; where: af > 10 }').toTranslate();
815
+ expect('run:a->{ group_by: astr; where: af > 10 }').toTranslate();
819
816
  });
820
817
  test('having single', () => {
821
- expect('query:ab->{ aggregate: acount; group_by: astr; having: acount > 10 }').toTranslate();
818
+ expect('run:ab->{ aggregate: acount; group_by: astr; having: acount > 10 }').toTranslate();
822
819
  });
823
820
  test('compound having still works', () => {
824
- expect('query:ab->{ aggregate: acount; having: acount > 10 and acount < 100 }').toTranslate();
821
+ expect('run:ab->{ aggregate: acount; having: acount > 10 and acount < 100 }').toTranslate();
825
822
  });
826
823
  test('compound aggregate still works', () => {
827
- expect('query:ab->{ aggregate: thing is acount > 10 and acount < 100 }').toTranslate();
824
+ expect('run:ab->{ aggregate: thing is acount > 10 and acount < 100 }').toTranslate();
828
825
  });
829
826
  test('where multiple', () => {
830
- expect("query:a->{ group_by: astr; where: af > 10,astr~'a%' }").toTranslate();
827
+ expect("run:a->{ group_by: astr; where: af > 10,astr~'a%' }").toTranslate();
831
828
  });
832
829
  test('filters preserve source formatting in code:', () => {
833
- const model = new test_translator_1.TestTranslator("source: notb is a + { where: astr != 'b' }");
830
+ const model = new test_translator_1.TestTranslator("source: notb is a extend { where: astr != 'b' }");
834
831
  expect(model).toTranslate();
835
832
  const notb = model.getSourceDef('notb');
836
833
  expect(notb).toBeDefined();
@@ -843,7 +840,7 @@ describe('query:', () => {
843
840
  }
844
841
  });
845
842
  test('field expressions preserve source formatting in code:', () => {
846
- const model = new test_translator_1.TestTranslator('source: notb is a + { dimension: d is 1 + 2 }');
843
+ const model = new test_translator_1.TestTranslator('source: notb is a extend { dimension: d is 1 + 2 }');
847
844
  expect(model).toTranslate();
848
845
  const notb = model.getSourceDef('notb');
849
846
  expect(notb).toBeDefined();
@@ -858,42 +855,42 @@ describe('query:', () => {
858
855
  });
859
856
  test('nest single', () => {
860
857
  expect(`
861
- query: a->{
858
+ run: a->{
862
859
  group_by: ai
863
860
  nest: nestbystr is { group_by: astr; aggregate: N is count() }
864
861
  }
865
862
  `).toTranslate();
866
863
  });
867
864
  test('nest multiple', () => expect(`
868
- query: a->{
865
+ run: a->{
869
866
  group_by: ai
870
867
  nest:
871
868
  nestbystr is { group_by: astr; aggregate: N is count() },
872
869
  renest is { group_by: astr; aggregate: N is count() }
873
870
  }
874
871
  `).toTranslate());
875
- test('nest ref', () => expect('query: ab->{group_by: ai; nest: aturtle}').toTranslate());
872
+ test('nest ref', () => expect('run: ab->{group_by: ai; nest: aturtle}').toTranslate());
876
873
  describe('extend block', () => {
877
874
  test('works with dimension', () => {
878
- expect('query: a -> { extend: { dimension: x is 1 }; group_by: x }').toTranslate();
875
+ expect('run: a -> { extend: { dimension: x is 1 }; group_by: x }').toTranslate();
879
876
  });
880
877
  test('works with measure', () => {
881
- expect('query: a -> { extend: { measure: x is count() }; aggregate: x }').toTranslate();
878
+ expect('run: a -> { extend: { measure: x is count() }; aggregate: x }').toTranslate();
882
879
  });
883
880
  test('works with join_one', () => {
884
- expect('query: a -> { extend: { join_one: bb is b on bb.astr = astr }; group_by: bb.astr }').toTranslate();
881
+ expect('run: a -> { extend: { join_one: bb is b on bb.astr = astr }; group_by: bb.astr }').toTranslate();
885
882
  });
886
883
  test('works with join_many', () => {
887
- expect('query: a -> { extend: { join_many: b on astr = b.astr }; group_by: b.astr }').toTranslate();
884
+ expect('run: a -> { extend: { join_many: b on astr = b.astr }; group_by: b.astr }').toTranslate();
888
885
  });
889
886
  test('works with join_cross', () => {
890
- expect('query: a -> { extend: { join_cross: b on true }; group_by: b.astr }').toTranslate();
887
+ expect('run: a -> { extend: { join_cross: b on true }; group_by: b.astr }').toTranslate();
891
888
  });
892
889
  test('works with multiple in one block', () => {
893
- expect('query: a -> { extend: { dimension: x is 1, y is 2 }; group_by: x, y }').toTranslate();
890
+ expect('run: a -> { extend: { dimension: x is 1, y is 2 }; group_by: x, y }').toTranslate();
894
891
  });
895
892
  test('works with multiple blocks', () => {
896
- expect('query: a -> { extend: { dimension: x is 1; dimension: y is 2; measure: c is count() }; group_by: x, y; aggregate: c }').toTranslate();
893
+ expect('run: a -> { extend: { dimension: x is 1; dimension: y is 2; measure: c is count() }; group_by: x, y; aggregate: c }').toTranslate();
897
894
  });
898
895
  });
899
896
  describe('declare/query join warnings', () => {
@@ -912,12 +909,11 @@ describe('query:', () => {
912
909
  });
913
910
  test('refine query with extended source', () => {
914
911
  const m = new test_translator_1.TestTranslator(`
915
- source: nab is ab {
916
- query: xturtle is aturtle + {
917
- declare: aratio is ai / acount
912
+ run: ab extend {
913
+ view: xturtle is aturtle + {
914
+ extend: { measure: aratio is ai / acount }
918
915
  }
919
- }
920
- query: nab -> xturtle + { aggregate: aratio }
916
+ } -> xturtle + { aggregate: aratio }
921
917
  `);
922
918
  expect(m).toTranslate();
923
919
  const t = m.translate();
@@ -939,8 +935,8 @@ describe('query:', () => {
939
935
  });
940
936
  test('refine query source with field', () => {
941
937
  const m = new test_translator_1.TestTranslator(`
942
- query: ab -> aturtle + {
943
- declare: aratio is ai / acount
938
+ run: ab -> aturtle + {
939
+ extend: { measure: aratio is ai / acount }
944
940
  aggregate: aratio
945
941
  }
946
942
  `);
@@ -963,8 +959,8 @@ describe('query:', () => {
963
959
  });
964
960
  test('refine query source with join', () => {
965
961
  const m = new test_translator_1.TestTranslator(`
966
- query: ab -> aturtle + {
967
- join_one: bb is b on bb.astr = astr
962
+ run: ab -> aturtle + {
963
+ extend: { join_one: bb is b on bb.astr = astr }
968
964
  group_by: foo is bb.astr
969
965
  }
970
966
  `);
@@ -985,8 +981,8 @@ describe('query:', () => {
985
981
  describe('refinement location rules', () => {
986
982
  test('where clauses go into the first segment', () => {
987
983
  const doc = (0, test_translator_1.model) `
988
- query: refineme is a -> { project: stage is "stage1" } -> { project: stage is "stage2" }
989
- query: checkme is refineme refine { where: astr = 'a' }`;
984
+ query: refineme is a -> { select: stage is "stage1" } -> { select: stage is "stage2" }
985
+ query: checkme is refineme + { where: astr = 'a' }`;
990
986
  expect(doc).toTranslate();
991
987
  const checkme = doc.translator.getQuery('checkme');
992
988
  expect(checkme).toBeDefined();
@@ -1001,7 +997,7 @@ describe('query:', () => {
1001
997
  test('having clauses go into the last segment', () => {
1002
998
  const doc = (0, test_translator_1.model) `
1003
999
  query: refineme is a -> { group_by: ai,astr } -> { group_by: ai, aggregate: ac is count() }
1004
- query: checkme is refineme refine { having: ac > 0 }`;
1000
+ query: checkme is refineme + { having: ac > 0 }`;
1005
1001
  expect(doc).toTranslate();
1006
1002
  const checkme = doc.translator.getQuery('checkme');
1007
1003
  expect(checkme).toBeDefined();
@@ -1016,7 +1012,7 @@ describe('query:', () => {
1016
1012
  test('limit goes into the last segment', () => {
1017
1013
  const doc = (0, test_translator_1.model) `
1018
1014
  query: refineme is a -> { group_by: ai,astr } -> { group_by: ai, aggregate: ac is count() }
1019
- query: checkme is refineme refine { limit: 1 }`;
1015
+ query: checkme is refineme + { limit: 1 }`;
1020
1016
  expect(doc).toTranslate();
1021
1017
  const checkme = doc.translator.getQuery('checkme');
1022
1018
  expect(checkme).toBeDefined();
@@ -1027,7 +1023,7 @@ describe('query:', () => {
1027
1023
  test('order_by goes into the last segment', () => {
1028
1024
  const doc = (0, test_translator_1.model) `
1029
1025
  query: refineme is a -> { group_by: ai,astr } -> { group_by: ai, aggregate: ac is count() }
1030
- query: checkme is refineme refine { order_by: 2 }`;
1026
+ query: checkme is refineme + { order_by: 2 }`;
1031
1027
  expect(doc).toTranslate();
1032
1028
  const checkme = doc.translator.getQuery('checkme');
1033
1029
  expect(checkme).toBeDefined();
@@ -1037,28 +1033,28 @@ describe('query:', () => {
1037
1033
  });
1038
1034
  const stageErr = 'Illegal in refinement of a query with more than one stage';
1039
1035
  test('group_by illegal in long pipes', () => {
1040
- expect((0, test_translator_1.markSource) `query: refineme is a -> { project: stage is "stage1" } -> { project: stage is "stage2" }
1041
- query: checkme is refineme refine { ${'group_by: stage'} }`).translationToFailWith(stageErr);
1036
+ expect((0, test_translator_1.markSource) `query: refineme is a -> { select: stage is "stage1" } -> { select: stage is "stage2" }
1037
+ query: checkme is refineme + { ${'group_by: stage'} }`).translationToFailWith(stageErr);
1042
1038
  });
1043
1039
  test('aggregate illegal in long pipes', () => {
1044
- expect((0, test_translator_1.markSource) `query: refineme is a -> { project: stage is "stage1" } -> { project: stage is "stage2" }
1045
- query: checkme is refineme refine { ${'aggregate: c is count()'} }`).translationToFailWith(stageErr);
1040
+ expect((0, test_translator_1.markSource) `query: refineme is a -> { select: stage is "stage1" } -> { select: stage is "stage2" }
1041
+ query: checkme is refineme + { ${'aggregate: c is count()'} }`).translationToFailWith(stageErr);
1046
1042
  });
1047
1043
  test('calcluate illegal in long pipes', () => {
1048
- expect((0, test_translator_1.markSource) `query: refineme is a -> { project: stage is "stage1" } -> { project: stage is "stage2" }
1049
- query: checkme is refineme refine { ${'calculate: c is count()'} }`).translationToFailWith(stageErr);
1044
+ expect((0, test_translator_1.markSource) `query: refineme is a -> { select: stage is "stage1" } -> { select: stage is "stage2" }
1045
+ query: checkme is refineme + { ${'calculate: c is count()'} }`).translationToFailWith(stageErr);
1050
1046
  });
1051
1047
  test('extend illegal in long pipes', () => {
1052
- expect((0, test_translator_1.markSource) `query: refineme is a -> { project: stage is "stage1" } -> { project: stage is "stage2" }
1053
- query: checkme is refineme refine { ${'extend: {measure: c is count()}'} }`).translationToFailWith(stageErr);
1048
+ expect((0, test_translator_1.markSource) `query: refineme is a -> { select: stage is "stage1" } -> { select: stage is "stage2" }
1049
+ query: checkme is refineme + { ${'extend: {measure: c is count()}'} }`).translationToFailWith(stageErr);
1054
1050
  });
1055
1051
  test('nest illegal in long pipes', () => {
1056
- expect((0, test_translator_1.markSource) `query: refineme is a -> { project: stage is "stage1" } -> { project: stage is "stage2" }
1057
- query: checkme is refineme refine { ${'nest: b is {group_by: stage}'} }`).translationToFailWith(stageErr);
1052
+ expect((0, test_translator_1.markSource) `query: refineme is a -> { select: stage is "stage1" } -> { select: stage is "stage2" }
1053
+ query: checkme is refineme + { ${'nest: b is {group_by: stage}'} }`).translationToFailWith(stageErr);
1058
1054
  });
1059
1055
  test('all single stage refinements are accepted', () => {
1060
1056
  expect((0, test_translator_1.markSource) `query: refineme is a -> { group_by: stage is "stage1" }
1061
- query: checkme is refineme refine {
1057
+ query: checkme is refineme + {
1062
1058
  extend: { dimension: red is 'red' }
1063
1059
  nest: nestRed is { group_by: red }
1064
1060
  group_by: ai