@malloydata/malloy-tests 0.0.95-dev231019211822 → 0.0.95
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/README.md +213 -1
- package/dist/api.spec.d.ts +1 -1
- package/dist/api.spec.js +6 -13
- package/dist/api.spec.js.map +1 -1
- package/dist/databases/all/db_index.spec.js +21 -41
- package/dist/databases/all/db_index.spec.js.map +1 -1
- package/dist/databases/all/expr.spec.js +262 -339
- package/dist/databases/all/expr.spec.js.map +1 -1
- package/dist/databases/all/functions.spec.js +37 -35
- package/dist/databases/all/functions.spec.js.map +1 -1
- package/dist/databases/all/join.spec.js +125 -169
- package/dist/databases/all/join.spec.js.map +1 -1
- package/dist/databases/all/nomodel.spec.js +335 -594
- package/dist/databases/all/nomodel.spec.js.map +1 -1
- package/dist/databases/all/orderby.spec.js +82 -128
- package/dist/databases/all/orderby.spec.js.map +1 -1
- package/dist/databases/all/sql_expressions.spec.js +27 -43
- package/dist/databases/all/sql_expressions.spec.js.map +1 -1
- package/dist/databases/all/time.spec.js +63 -103
- package/dist/databases/all/time.spec.js.map +1 -1
- package/dist/databases/bigquery/double_truncation.spec.js +1 -1
- package/dist/databases/bigquery/handexpr.spec.js +12 -12
- package/dist/databases/bigquery/injestion_time_partitioning.spec.js +22 -22
- package/dist/databases/bigquery/joined_filters.spec.js +3 -3
- package/dist/databases/bigquery/json.spec.d.ts +1 -1
- package/dist/databases/bigquery/json.spec.js +25 -45
- package/dist/databases/bigquery/json.spec.js.map +1 -1
- package/dist/databases/bigquery/malloy_query.spec.d.ts +1 -1
- package/dist/databases/bigquery/malloy_query.spec.js +47 -48
- package/dist/databases/bigquery/malloy_query.spec.js.map +1 -1
- package/dist/databases/bigquery/time.spec.js +9 -13
- package/dist/databases/bigquery/time.spec.js.map +1 -1
- package/dist/databases/bigquery/wildcard_table_names.spec.js +19 -19
- package/dist/databases/bigquery-duckdb/nested_source_table.spec.js +53 -87
- package/dist/databases/bigquery-duckdb/nested_source_table.spec.js.map +1 -1
- package/dist/databases/bigquery-postgres/multi_connection.spec.js +5 -20
- package/dist/databases/bigquery-postgres/multi_connection.spec.js.map +1 -1
- package/dist/databases/bigquery-postgres/streaming.spec.js +6 -6
- package/dist/databases/bigquery-postgres/streaming.spec.js.map +1 -1
- package/dist/databases/duckdb/duckdb.spec.js +24 -33
- package/dist/databases/duckdb/duckdb.spec.js.map +1 -1
- package/dist/databases/postgres/postgres.spec.js +46 -67
- package/dist/databases/postgres/postgres.spec.js.map +1 -1
- package/dist/jestMatcher.spec.d.ts +1 -0
- package/dist/jestMatcher.spec.js +81 -0
- package/dist/jestMatcher.spec.js.map +1 -0
- package/dist/render/render.spec.js +10 -12
- package/dist/render/render.spec.js.map +1 -1
- package/dist/tags.spec.js +22 -2
- package/dist/tags.spec.js.map +1 -1
- package/dist/util/db-jest-matchers.d.ts +17 -6
- package/dist/util/db-jest-matchers.js +81 -20
- package/dist/util/db-jest-matchers.js.map +1 -1
- package/dist/util/index.d.ts +1 -2
- package/dist/util/index.js +11 -13
- package/dist/util/index.js.map +1 -1
- package/package.json +6 -6
- package/src/api.spec.ts +7 -16
- package/src/databases/all/db_index.spec.ts +22 -48
- package/src/databases/all/expr.spec.ts +273 -431
- package/src/databases/all/functions.spec.ts +37 -35
- package/src/databases/all/join.spec.ts +130 -196
- package/src/databases/all/nomodel.spec.ts +333 -689
- package/src/databases/all/orderby.spec.ts +87 -161
- package/src/databases/all/sql_expressions.spec.ts +29 -49
- package/src/databases/all/time.spec.ts +73 -130
- package/src/databases/bigquery/double_truncation.spec.ts +1 -1
- package/src/databases/bigquery/handexpr.spec.ts +12 -12
- package/src/databases/bigquery/injestion_time_partitioning.spec.ts +22 -22
- package/src/databases/bigquery/joined_filters.spec.ts +3 -3
- package/src/databases/bigquery/json.spec.ts +25 -49
- package/src/databases/bigquery/malloy_query.spec.ts +47 -54
- package/src/databases/bigquery/time.spec.ts +13 -17
- package/src/databases/bigquery/wildcard_table_names.spec.ts +19 -19
- package/src/databases/bigquery-duckdb/nested_source_table.spec.ts +56 -98
- package/src/databases/bigquery-postgres/multi_connection.spec.ts +5 -23
- package/src/databases/bigquery-postgres/streaming.spec.ts +12 -6
- package/src/databases/duckdb/duckdb.spec.ts +31 -43
- package/src/databases/postgres/postgres.spec.ts +54 -84
- package/src/jestMatcher.spec.ts +88 -0
- package/src/render/render.spec.ts +10 -12
- package/src/tags.spec.ts +22 -2
- package/src/util/db-jest-matchers.ts +106 -32
- package/src/util/index.ts +16 -14
|
@@ -56,67 +56,43 @@ afterAll(async () => {
|
|
|
56
56
|
runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
57
57
|
// Issue: #1284
|
|
58
58
|
it(`parenthesize output field values - ${databaseName}`, async () => {
|
|
59
|
-
|
|
60
|
-
.
|
|
61
|
-
|
|
62
|
-
group_by:
|
|
63
|
-
r is 1
|
|
59
|
+
await expect(`
|
|
60
|
+
run: ${databaseName}.table('malloytest.aircraft') -> {
|
|
61
|
+
group_by: r is 1
|
|
64
62
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
.run();
|
|
72
|
-
const bare = result.data.path(0, 'zero_bare').number.value;
|
|
73
|
-
const paren = result.data.path(0, 'zero_paren').number.value;
|
|
74
|
-
expect(bare).toBe(0);
|
|
75
|
-
expect(paren).toBe(0);
|
|
63
|
+
calculate:
|
|
64
|
+
zero is 1 - rank()
|
|
65
|
+
zero_bare is 0 - zero
|
|
66
|
+
zero_paren is 0 - (zero)
|
|
67
|
+
}
|
|
68
|
+
`).malloyResultMatches(runtime, {zero_bare: 0, zero_paren: 0});
|
|
76
69
|
});
|
|
77
70
|
|
|
78
71
|
// Issue: #151
|
|
79
|
-
it(`unknown dialect
|
|
80
|
-
|
|
81
|
-
.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
72
|
+
it(`bug 151 which used to throw unknown dialect is still fixed- ${databaseName}`, async () => {
|
|
73
|
+
await expect(`
|
|
74
|
+
query: q is ${databaseName}.table('malloytest.aircraft')->{
|
|
75
|
+
where: state != null
|
|
76
|
+
group_by: state
|
|
77
|
+
}
|
|
78
|
+
run: q extend {
|
|
79
|
+
view: foo is {
|
|
80
|
+
order_by: 1 desc
|
|
85
81
|
group_by: state
|
|
86
82
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
query: foo is {
|
|
90
|
-
order_by: 1 desc
|
|
91
|
-
group_by: state
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
query: r->foo
|
|
96
|
-
`
|
|
97
|
-
)
|
|
98
|
-
.run();
|
|
99
|
-
// console.log(result.data.toObject());
|
|
100
|
-
expect(result.data.path(0, 'state').value).toBe('WY');
|
|
83
|
+
} -> foo
|
|
84
|
+
`).malloyResultMatches(runtime, {state: 'WY'});
|
|
101
85
|
});
|
|
102
86
|
|
|
103
87
|
// Issue #149
|
|
104
88
|
it(`refine query from query - ${databaseName}`, async () => {
|
|
105
|
-
|
|
106
|
-
.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
dimension: lower_state is lower(state)
|
|
113
|
-
}
|
|
114
|
-
-> {select: lower_state}
|
|
115
|
-
`
|
|
116
|
-
)
|
|
117
|
-
.run();
|
|
118
|
-
// console.log(result.data.toObject());
|
|
119
|
-
expect(result.data.path(0, 'lower_state').value).toBe('wy');
|
|
89
|
+
await expect(`
|
|
90
|
+
run: ${databaseName}.table('malloytest.state_facts')
|
|
91
|
+
-> {group_by: state; order_by: 1 desc; limit: 1}
|
|
92
|
+
extend {
|
|
93
|
+
dimension: lower_state is lower(state)
|
|
94
|
+
} -> {select: lower_state}
|
|
95
|
+
`).malloyResultMatches(runtime, {lower_state: 'wy'});
|
|
120
96
|
});
|
|
121
97
|
|
|
122
98
|
// issue #157
|
|
@@ -127,8 +103,8 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
127
103
|
await runtime
|
|
128
104
|
.loadQuery(
|
|
129
105
|
`
|
|
130
|
-
source: foo is table('malloytest.state_facts'){primary_key: state}
|
|
131
|
-
|
|
106
|
+
source: foo is ${databaseName}.table('malloytest.state_facts') extend {primary_key: state}
|
|
107
|
+
run: foox->{aggregate: c is count()}
|
|
132
108
|
`
|
|
133
109
|
)
|
|
134
110
|
.run();
|
|
@@ -139,116 +115,87 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
139
115
|
});
|
|
140
116
|
|
|
141
117
|
it(`join_many - ${databaseName}`, async () => {
|
|
142
|
-
|
|
143
|
-
.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
source: m is table('malloytest.aircraft_models'){
|
|
149
|
-
join_many: a on a.aircraft_model_code=aircraft_model_code
|
|
118
|
+
await expect(`
|
|
119
|
+
source: m is ${databaseName}.table('malloytest.aircraft_models') extend {
|
|
120
|
+
join_many:
|
|
121
|
+
a is ${databaseName}.table('malloytest.aircraft') extend {
|
|
122
|
+
measure: avg_year is floor(avg(year_built))
|
|
123
|
+
} on a.aircraft_model_code=aircraft_model_code
|
|
150
124
|
measure: avg_seats is floor(avg(seats))
|
|
151
125
|
}
|
|
152
|
-
|
|
153
|
-
`
|
|
154
|
-
)
|
|
155
|
-
.run();
|
|
156
|
-
expect(result.data.value[0]['avg_year']).toBe(1969);
|
|
157
|
-
expect(result.data.value[0]['avg_seats']).toBe(7);
|
|
126
|
+
run: m->{aggregate: avg_seats, a.avg_year}
|
|
127
|
+
`).malloyResultMatches(runtime, {avg_year: 1969, avg_seats: 7});
|
|
158
128
|
});
|
|
159
129
|
|
|
160
130
|
it(`join_many condition no primary key - ${databaseName}`, async () => {
|
|
161
|
-
|
|
162
|
-
.
|
|
163
|
-
|
|
164
|
-
source: a is table('malloytest.airports'){}
|
|
165
|
-
source: b is table('malloytest.state_facts') {
|
|
131
|
+
await expect(`
|
|
132
|
+
source: a is ${databaseName}.table('malloytest.airports')
|
|
133
|
+
source: b is ${databaseName}.table('malloytest.state_facts') extend {
|
|
166
134
|
join_many: a on state=a.state
|
|
167
135
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
)
|
|
171
|
-
.run();
|
|
172
|
-
expect(result.data.value[0]['c']).toBe(19701);
|
|
136
|
+
run: b->{aggregate: c is airport_count.sum()}
|
|
137
|
+
`).malloyResultMatches(runtime, {c: 19701});
|
|
173
138
|
});
|
|
174
139
|
|
|
175
140
|
it(`join_many filter multiple values - ${databaseName}`, async () => {
|
|
176
|
-
|
|
177
|
-
.
|
|
178
|
-
`
|
|
179
|
-
source: a is table('malloytest.airports'){
|
|
141
|
+
await expect(`
|
|
142
|
+
source: a is ${databaseName}.table('malloytest.airports') extend {
|
|
180
143
|
where: state = 'NH' | 'CA'
|
|
181
144
|
}
|
|
182
|
-
|
|
145
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
183
146
|
join_many: a on state=a.state
|
|
184
|
-
}
|
|
185
|
-
query: b->{
|
|
147
|
+
} -> {
|
|
186
148
|
aggregate: c is airport_count.sum()
|
|
187
149
|
group_by: a.state
|
|
188
150
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
expect(result.data.value[1]['c']).toBe(984);
|
|
195
|
-
expect(result.data.value[1]['state']).toBe('CA');
|
|
196
|
-
expect(result.data.value[2]['c']).toBe(112);
|
|
197
|
-
expect(result.data.value[2]['state']).toBe('NH');
|
|
151
|
+
`).malloyResultMatches(runtime, [
|
|
152
|
+
{state: null, c: 18605},
|
|
153
|
+
{state: 'CA', c: 984},
|
|
154
|
+
{state: 'NH', c: 112},
|
|
155
|
+
]);
|
|
198
156
|
});
|
|
199
157
|
|
|
200
158
|
it(`join_one condition no primary key - ${databaseName}`, async () => {
|
|
201
|
-
|
|
202
|
-
.
|
|
203
|
-
|
|
204
|
-
source: a is table('malloytest.state_facts'){}
|
|
205
|
-
source: b is table('malloytest.airports') {
|
|
159
|
+
await expect(`
|
|
160
|
+
source: a is ${databaseName}.table('malloytest.state_facts')
|
|
161
|
+
source: b is ${databaseName}.table('malloytest.airports') extend {
|
|
206
162
|
join_one: a on state=a.state
|
|
207
163
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
.run();
|
|
213
|
-
expect(result.data.value[0]['c']).toBe(19701);
|
|
164
|
+
run: b -> {
|
|
165
|
+
aggregate: c is a.airport_count.sum()
|
|
166
|
+
}
|
|
167
|
+
`).malloyResultMatches(runtime, {c: 19701});
|
|
214
168
|
});
|
|
215
169
|
|
|
216
170
|
it(`join_one filter multiple values - ${databaseName}`, async () => {
|
|
217
|
-
|
|
218
|
-
.
|
|
219
|
-
`
|
|
220
|
-
source: a is table('malloytest.state_facts'){
|
|
171
|
+
await expect(`
|
|
172
|
+
source: a is ${databaseName}.table('malloytest.state_facts') extend {
|
|
221
173
|
where: state = 'TX' | 'LA'
|
|
222
174
|
}
|
|
223
|
-
source: b is table('malloytest.airports') {
|
|
175
|
+
source: b is ${databaseName}.table('malloytest.airports') extend {
|
|
224
176
|
join_one: a on state=a.state
|
|
225
177
|
}
|
|
226
|
-
|
|
178
|
+
run: b-> {
|
|
227
179
|
aggregate: c is a.airport_count.sum()
|
|
228
180
|
group_by: a.state
|
|
229
181
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
expect(result.data.value).toContainEqual({c: 1845, state: 'TX'});
|
|
236
|
-
expect(result.data.value).toContainEqual({c: 500, state: 'LA'});
|
|
237
|
-
expect(result.data.value).toContainEqual({c: 0, state: null});
|
|
182
|
+
`).malloyResultMatches(runtime, [
|
|
183
|
+
{state: 'TX', c: 1845},
|
|
184
|
+
{state: 'LA', c: 500},
|
|
185
|
+
{state: null, c: 0},
|
|
186
|
+
]);
|
|
238
187
|
});
|
|
239
188
|
|
|
240
189
|
it(`join_many cross from - ${databaseName}`, async () => {
|
|
241
190
|
// a cross join produces a Many to Many result.
|
|
242
191
|
// symmetric aggregate are needed on both sides of the join
|
|
243
192
|
// Check the row count and that sums on each side work properly.
|
|
244
|
-
|
|
245
|
-
.
|
|
246
|
-
|
|
247
|
-
source: a is table('malloytest.state_facts')
|
|
248
|
-
source: f is a{
|
|
193
|
+
await expect(`
|
|
194
|
+
source: a is ${databaseName}.table('malloytest.state_facts')
|
|
195
|
+
source: f is a extend {
|
|
249
196
|
join_cross: a
|
|
250
197
|
}
|
|
251
|
-
|
|
198
|
+
run: f->{
|
|
252
199
|
aggregate:
|
|
253
200
|
row_count is count(concat(state,a.state))
|
|
254
201
|
left_count is count()
|
|
@@ -256,66 +203,59 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
256
203
|
left_sum is airport_count.sum()
|
|
257
204
|
right_sum is a.airport_count.sum()
|
|
258
205
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
expect(result.data.value[0]['right_sum']).toBe(19701);
|
|
206
|
+
`).malloyResultMatches(runtime, {
|
|
207
|
+
row_count: 51 * 51,
|
|
208
|
+
left_sum: 19701,
|
|
209
|
+
right_sum: 19701,
|
|
210
|
+
});
|
|
265
211
|
});
|
|
266
212
|
|
|
267
213
|
it(`join_one only - ${databaseName}`, async () => {
|
|
268
214
|
// a cross join produces a Many to Many result.
|
|
269
215
|
// symmetric aggregate are needed on both sides of the join
|
|
270
216
|
// Check the row count and that sums on each side work properly.
|
|
271
|
-
|
|
272
|
-
.
|
|
273
|
-
`
|
|
274
|
-
query: q is table('malloytest.state_facts')->{
|
|
217
|
+
await expect(`
|
|
218
|
+
query: q is ${databaseName}.table('malloytest.state_facts')->{
|
|
275
219
|
aggregate: r is airport_count.sum()
|
|
276
220
|
}
|
|
277
|
-
source: f is table('malloytest.state_facts'){
|
|
278
|
-
join_one: a is
|
|
221
|
+
source: f is ${databaseName}.table('malloytest.state_facts') extend {
|
|
222
|
+
join_one: a is q
|
|
279
223
|
}
|
|
280
|
-
|
|
224
|
+
run: f->{
|
|
281
225
|
aggregate:
|
|
282
226
|
row_count is count(concat(state,a.r))
|
|
283
227
|
left_sum is airport_count.sum()
|
|
284
228
|
right_sum is a.r.sum()
|
|
285
229
|
sum_sum is sum(airport_count + a.r)
|
|
286
230
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
expect(result.data.value[0]['sum_sum']).toBe(19701 + 51 * 19701);
|
|
231
|
+
`).malloyResultMatches(runtime, {
|
|
232
|
+
row_count: 51,
|
|
233
|
+
left_sum: 19701,
|
|
234
|
+
right_sum: 19701,
|
|
235
|
+
sum_sum: 19701 + 51 * 19701,
|
|
236
|
+
});
|
|
294
237
|
});
|
|
295
238
|
|
|
296
239
|
it(`join_many cross ON - ${databaseName}`, async () => {
|
|
297
240
|
// a cross join produces a Many to Many result.
|
|
298
241
|
// symmetric aggregate are needed on both sides of the join
|
|
299
242
|
// Check the row count and that sums on each side work properly.
|
|
300
|
-
|
|
301
|
-
.
|
|
302
|
-
|
|
303
|
-
source: a is table('malloytest.state_facts')
|
|
304
|
-
source: f is a{
|
|
243
|
+
await expect(`
|
|
244
|
+
source: a is ${databaseName}.table('malloytest.state_facts')
|
|
245
|
+
source: f is a extend {
|
|
305
246
|
join_cross: a on a.state = 'CA' | 'NY'
|
|
306
247
|
}
|
|
307
|
-
|
|
248
|
+
run: f->{
|
|
308
249
|
aggregate:
|
|
309
250
|
row_count is count(concat(state,a.state))
|
|
310
251
|
left_sum is airport_count.sum()
|
|
311
252
|
right_sum is a.airport_count.sum()
|
|
312
253
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
expect(result.data.value[0]['right_sum']).toBe(1560);
|
|
254
|
+
`).malloyResultMatches(runtime, {
|
|
255
|
+
row_count: 51 * 2,
|
|
256
|
+
left_sum: 19701,
|
|
257
|
+
right_sum: 1560,
|
|
258
|
+
});
|
|
319
259
|
});
|
|
320
260
|
|
|
321
261
|
it(`limit - provided - ${databaseName}`, async () => {
|
|
@@ -325,7 +265,7 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
325
265
|
const result = await runtime
|
|
326
266
|
.loadQuery(
|
|
327
267
|
`
|
|
328
|
-
|
|
268
|
+
run: ${databaseName}.table('malloytest.state_facts') -> {
|
|
329
269
|
group_by: state
|
|
330
270
|
aggregate: c is count()
|
|
331
271
|
limit: 3
|
|
@@ -342,46 +282,32 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
342
282
|
// a cross join produces a Many to Many result.
|
|
343
283
|
// symmetric aggregate are needed on both sides of the join
|
|
344
284
|
// Check the row count and that sums on each side work properly.
|
|
345
|
-
|
|
346
|
-
.
|
|
347
|
-
`
|
|
348
|
-
source: s is table('malloytest.state_facts') + {
|
|
349
|
-
}
|
|
350
|
-
query: s-> {
|
|
285
|
+
await expect(`
|
|
286
|
+
run: ${databaseName}.table('malloytest.state_facts') -> {
|
|
351
287
|
group_by: state
|
|
352
288
|
nest: ugly is {
|
|
353
289
|
group_by: popular_name
|
|
354
290
|
aggregate: foo is NULLIF(sum(airport_count)*0,0)+1
|
|
355
291
|
}
|
|
356
292
|
}
|
|
357
|
-
`
|
|
358
|
-
)
|
|
359
|
-
.run();
|
|
360
|
-
expect(result.data.path(0, 'ugly', 0, 'foo').value).toBe(null);
|
|
293
|
+
`).malloyResultMatches(runtime, {'ugly.foo': null});
|
|
361
294
|
}
|
|
362
295
|
);
|
|
363
296
|
|
|
364
297
|
// average should only include non-null values in the denominator
|
|
365
298
|
it(`avg ignore null- ${databaseName}`, async () => {
|
|
366
|
-
|
|
367
|
-
.
|
|
368
|
-
`
|
|
369
|
-
sql: one is { select: """
|
|
299
|
+
await expect(`
|
|
300
|
+
source: one is ${databaseName}.sql("""
|
|
370
301
|
SELECT 2 as a
|
|
371
302
|
UNION ALL SELECT 4
|
|
372
303
|
UNION ALL SELECT null
|
|
373
|
-
"""
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
join_cross: b is from_sql(one)
|
|
304
|
+
""")
|
|
305
|
+
run: one -> {
|
|
306
|
+
extend: { join_cross: x1 is one }
|
|
377
307
|
aggregate:
|
|
378
308
|
avg_a is a.avg()
|
|
379
|
-
avg_b is
|
|
380
|
-
}
|
|
381
|
-
`
|
|
382
|
-
)
|
|
383
|
-
.run();
|
|
384
|
-
expect(result.data.value[0]['avg_a']).toBe(3);
|
|
309
|
+
avg_b is x1.a.avg()
|
|
310
|
+
}`).malloyResultMatches(runtime, {avg_a: 3});
|
|
385
311
|
});
|
|
386
312
|
|
|
387
313
|
it(`limit - not provided - ${databaseName}`, async () => {
|
|
@@ -390,147 +316,84 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
390
316
|
// Check the row count and that sums on each side work properly.
|
|
391
317
|
const result = await runtime
|
|
392
318
|
.loadQuery(
|
|
393
|
-
`
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
`
|
|
319
|
+
`run: ${databaseName}.table('malloytest.state_facts') -> {
|
|
320
|
+
group_by: state
|
|
321
|
+
aggregate: c is count()
|
|
322
|
+
}`
|
|
399
323
|
)
|
|
400
324
|
.run();
|
|
401
325
|
expect(result.resultExplore.limit).toBe(undefined);
|
|
402
326
|
});
|
|
403
327
|
|
|
404
|
-
it(`limit pipeline - provided - ${databaseName}`, async () => {
|
|
405
|
-
// a cross join produces a Many to Many result.
|
|
406
|
-
// symmetric aggregate are needed on both sides of the join
|
|
407
|
-
// Check the row count and that sums on each side work properly.
|
|
408
|
-
const result = await runtime
|
|
409
|
-
.loadQuery(
|
|
410
|
-
`
|
|
411
|
-
query: table('malloytest.state_facts') -> {
|
|
412
|
-
select: state
|
|
413
|
-
limit: 10
|
|
414
|
-
}
|
|
415
|
-
-> {
|
|
416
|
-
select: state
|
|
417
|
-
limit: 3
|
|
418
|
-
}
|
|
419
|
-
`
|
|
420
|
-
)
|
|
421
|
-
.run();
|
|
422
|
-
expect(result.resultExplore.limit).toBe(3);
|
|
423
|
-
});
|
|
424
|
-
|
|
425
328
|
it(`ungrouped top level - ${databaseName}`, async () => {
|
|
426
|
-
|
|
427
|
-
.
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
query:s-> {
|
|
435
|
-
group_by: state
|
|
436
|
-
aggregate: births_per_100k
|
|
437
|
-
}
|
|
438
|
-
`
|
|
439
|
-
)
|
|
440
|
-
.run();
|
|
441
|
-
// console.log(result.sql);
|
|
442
|
-
expect(result.data.path(0, 'births_per_100k').value).toBe(9742);
|
|
329
|
+
await expect(`
|
|
330
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
331
|
+
measure: total_births is births.sum()
|
|
332
|
+
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
333
|
+
} -> {
|
|
334
|
+
group_by: state
|
|
335
|
+
aggregate: births_per_100k
|
|
336
|
+
}`).malloyResultMatches(runtime, {births_per_100k: 9742});
|
|
443
337
|
});
|
|
444
338
|
|
|
445
339
|
testIf(runtime.supportsNesting)(
|
|
446
340
|
`ungrouped top level with nested - ${databaseName}`,
|
|
447
341
|
async () => {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
aggregate: births_per_100k
|
|
459
|
-
nest: by_name is {
|
|
460
|
-
group_by: popular_name
|
|
461
|
-
aggregate: total_births
|
|
462
|
-
}
|
|
463
|
-
limit: 1000
|
|
342
|
+
await expect(`
|
|
343
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
344
|
+
measure: total_births is births.sum()
|
|
345
|
+
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
346
|
+
} -> {
|
|
347
|
+
group_by: state
|
|
348
|
+
aggregate: births_per_100k
|
|
349
|
+
nest: by_name is {
|
|
350
|
+
group_by: popular_name
|
|
351
|
+
aggregate: total_births
|
|
464
352
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
.run();
|
|
468
|
-
// console.log(result.sql);
|
|
469
|
-
expect(result.data.path(0, 'births_per_100k').value).toBe(9742);
|
|
353
|
+
limit: 1000
|
|
354
|
+
}`).malloyResultMatches(runtime, {births_per_100k: 9742});
|
|
470
355
|
}
|
|
471
356
|
);
|
|
472
357
|
|
|
473
358
|
it(`ungrouped - eliminate rows - ${databaseName}`, async () => {
|
|
474
|
-
|
|
475
|
-
.
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
`
|
|
487
|
-
)
|
|
488
|
-
.run();
|
|
489
|
-
// console.log(result.sql);
|
|
490
|
-
expect(result.data.toObject().length).toBe(2);
|
|
359
|
+
await expect(`
|
|
360
|
+
run : ${databaseName}.table('malloytest.state_facts') extend {
|
|
361
|
+
measure: m is all(births.sum())
|
|
362
|
+
where: state='CA' | 'NY'
|
|
363
|
+
} -> {
|
|
364
|
+
order_by: state
|
|
365
|
+
group_by: state
|
|
366
|
+
aggregate: m
|
|
367
|
+
}`).malloyResultMatches(runtime, [
|
|
368
|
+
{state: 'CA', m: 52504699},
|
|
369
|
+
{state: 'NY', m: 52504699},
|
|
370
|
+
]);
|
|
491
371
|
});
|
|
492
372
|
|
|
493
373
|
testIf(runtime.supportsNesting)(
|
|
494
374
|
`ungrouped nested with no grouping above - ${databaseName}`,
|
|
495
375
|
async () => {
|
|
496
|
-
|
|
497
|
-
.
|
|
498
|
-
`
|
|
499
|
-
source: s is table('malloytest.state_facts') + {
|
|
376
|
+
await expect(`
|
|
377
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
500
378
|
measure: total_births is births.sum()
|
|
501
379
|
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
query: s-> {
|
|
380
|
+
} -> {
|
|
505
381
|
aggregate: total_births
|
|
506
382
|
nest: by_name is {
|
|
507
383
|
group_by: popular_name
|
|
508
384
|
aggregate: births_per_100k
|
|
509
385
|
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
`
|
|
513
|
-
)
|
|
514
|
-
.run();
|
|
515
|
-
// console.log(result.sql);
|
|
516
|
-
expect(result.data.path(0, 'by_name', 0, 'births_per_100k').value).toBe(
|
|
517
|
-
66703
|
|
518
|
-
);
|
|
386
|
+
}`).malloyResultMatches(runtime, {'by_name.births_per_100k': 66703});
|
|
519
387
|
}
|
|
520
388
|
);
|
|
521
389
|
|
|
522
390
|
testIf(runtime.supportsNesting)(
|
|
523
391
|
`ungrouped - partial grouping - ${databaseName}`,
|
|
524
392
|
async () => {
|
|
525
|
-
|
|
526
|
-
.
|
|
527
|
-
`
|
|
528
|
-
source: airports is table('malloytest.airports') {
|
|
393
|
+
await expect(`
|
|
394
|
+
run: ${databaseName}.table('malloytest.airports') extend {
|
|
529
395
|
measure: c is count()
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
query: airports -> {
|
|
396
|
+
} -> {
|
|
534
397
|
where: state = 'TX' | 'NY'
|
|
535
398
|
group_by:
|
|
536
399
|
faa_region
|
|
@@ -538,7 +401,7 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
538
401
|
aggregate:
|
|
539
402
|
c
|
|
540
403
|
all_ is all(c)
|
|
541
|
-
airport_count is c {
|
|
404
|
+
airport_count is c { where: fac_type = 'AIRPORT'}
|
|
542
405
|
nest: fac_type is {
|
|
543
406
|
group_by: fac_type
|
|
544
407
|
aggregate:
|
|
@@ -549,41 +412,29 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
549
412
|
all_top is exclude(c, state, faa_region, fac_type)
|
|
550
413
|
}
|
|
551
414
|
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
.
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
expect(result.data.path(0, 'fac_type', 0, 'all_state_region').value).toBe(
|
|
559
|
-
1845
|
|
560
|
-
);
|
|
561
|
-
expect(result.data.path(0, 'fac_type', 0, 'all_of_this_type').value).toBe(
|
|
562
|
-
1782
|
|
563
|
-
);
|
|
564
|
-
expect(result.data.path(0, 'fac_type', 0, 'all_top').value).toBe(2421);
|
|
415
|
+
`).malloyResultMatches(runtime, {
|
|
416
|
+
'fac_type.all_': 1845,
|
|
417
|
+
'fac_type.all_state_region': 1845,
|
|
418
|
+
'fac_type.all_of_this_type': 1782,
|
|
419
|
+
'fac_type.all_top': 2421,
|
|
420
|
+
});
|
|
565
421
|
}
|
|
566
422
|
);
|
|
567
423
|
|
|
568
424
|
testIf(runtime.supportsNesting)(
|
|
569
425
|
`ungrouped - all nested - ${databaseName}`,
|
|
570
426
|
async () => {
|
|
571
|
-
|
|
572
|
-
.
|
|
573
|
-
`
|
|
574
|
-
source: airports is table('malloytest.airports') {
|
|
427
|
+
await expect(`
|
|
428
|
+
run: ${databaseName}.table('malloytest.airports') extend {
|
|
575
429
|
measure: c is count()
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
query: airports -> {
|
|
430
|
+
} -> {
|
|
580
431
|
where: state = 'TX' | 'NY'
|
|
581
432
|
group_by:
|
|
582
433
|
state
|
|
583
434
|
aggregate:
|
|
584
435
|
c
|
|
585
436
|
all_ is all(c)
|
|
586
|
-
airport_count is c {
|
|
437
|
+
airport_count is c { where: fac_type = 'AIRPORT'}
|
|
587
438
|
nest: fac_type is {
|
|
588
439
|
group_by: fac_type, major
|
|
589
440
|
aggregate:
|
|
@@ -592,140 +443,92 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
592
443
|
all_major is all(c,major)
|
|
593
444
|
}
|
|
594
445
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
.run();
|
|
600
|
-
// console.log(result.sql);
|
|
601
|
-
expect(result.data.path(0, 'fac_type', 0, 'all_').value).toBe(1845);
|
|
602
|
-
expect(result.data.path(0, 'fac_type', 0, 'all_major').value).toBe(1819);
|
|
446
|
+
`).malloyResultMatches(runtime, {
|
|
447
|
+
'fac_type.all_': 1845,
|
|
448
|
+
'fac_type.all_major': 1819,
|
|
449
|
+
});
|
|
603
450
|
}
|
|
604
451
|
);
|
|
605
452
|
|
|
606
453
|
testIf(runtime.supportsNesting)(
|
|
607
454
|
`ungrouped nested - ${databaseName}`,
|
|
608
455
|
async () => {
|
|
609
|
-
|
|
610
|
-
.
|
|
611
|
-
`
|
|
612
|
-
source: s is table('malloytest.state_facts') + {
|
|
456
|
+
await expect(`
|
|
457
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
613
458
|
measure: total_births is births.sum()
|
|
614
459
|
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
query:s -> {
|
|
460
|
+
} -> {
|
|
618
461
|
group_by: popular_name
|
|
619
462
|
nest: by_state is {
|
|
620
463
|
group_by: state
|
|
621
464
|
aggregate: births_per_100k
|
|
622
465
|
}
|
|
623
466
|
}
|
|
624
|
-
|
|
625
|
-
`
|
|
626
|
-
)
|
|
627
|
-
.run();
|
|
628
|
-
// console.log(result.sql);
|
|
629
|
-
expect(result.data.path(0, 'by_state', 0, 'births_per_100k').value).toBe(
|
|
630
|
-
36593
|
|
631
|
-
);
|
|
467
|
+
`).malloyResultMatches(runtime, {'by_state.births_per_100k': 36593});
|
|
632
468
|
}
|
|
633
469
|
);
|
|
634
470
|
|
|
635
471
|
testIf(runtime.supportsNesting)(
|
|
636
472
|
`ungrouped nested expression - ${databaseName}`,
|
|
637
473
|
async () => {
|
|
638
|
-
|
|
639
|
-
.
|
|
640
|
-
`
|
|
641
|
-
source: s is table('malloytest.state_facts') + {
|
|
474
|
+
await expect(`
|
|
475
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
642
476
|
measure: total_births is births.sum()
|
|
643
477
|
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
query:s -> {
|
|
478
|
+
} -> {
|
|
647
479
|
group_by: upper_name is upper(popular_name)
|
|
648
480
|
nest: by_state is {
|
|
649
481
|
group_by: state
|
|
650
482
|
aggregate: births_per_100k
|
|
651
483
|
}
|
|
652
484
|
}
|
|
653
|
-
|
|
654
|
-
`
|
|
655
|
-
)
|
|
656
|
-
.run();
|
|
657
|
-
// console.log(result.sql);
|
|
658
|
-
expect(result.data.path(0, 'by_state', 0, 'births_per_100k').value).toBe(
|
|
659
|
-
36593
|
|
660
|
-
);
|
|
485
|
+
`).malloyResultMatches(runtime, {'by_state.births_per_100k': 36593});
|
|
661
486
|
}
|
|
662
487
|
);
|
|
663
488
|
|
|
664
489
|
testIf(runtime.supportsNesting)(
|
|
665
490
|
`ungrouped nested group by float - ${databaseName}`,
|
|
666
491
|
async () => {
|
|
667
|
-
|
|
668
|
-
.
|
|
669
|
-
`
|
|
670
|
-
source: s is table('malloytest.state_facts') + {
|
|
492
|
+
await expect(`
|
|
493
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
671
494
|
measure: total_births is births.sum()
|
|
672
495
|
measure: ug is all(total_births)
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
query:s -> {
|
|
496
|
+
} -> {
|
|
676
497
|
group_by: f is floor(airport_count/300.0)
|
|
677
498
|
nest: by_state is {
|
|
678
499
|
group_by: state
|
|
679
500
|
aggregate: ug
|
|
680
501
|
}
|
|
681
502
|
}
|
|
682
|
-
|
|
683
|
-
`
|
|
684
|
-
)
|
|
685
|
-
.run();
|
|
686
|
-
// console.log(result.sql);
|
|
687
|
-
// console.log(JSON.stringify(result.data.toObject(), null, 2));
|
|
688
|
-
expect(result.data.path(0, 'by_state', 0, 'ug').value).toBe(62742230);
|
|
503
|
+
`).malloyResultMatches(runtime, {'by_state.ug': 62742230});
|
|
689
504
|
}
|
|
690
505
|
);
|
|
691
506
|
|
|
692
507
|
it(`all with parameters - basic - ${databaseName}`, async () => {
|
|
693
|
-
|
|
694
|
-
.
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
`
|
|
709
|
-
)
|
|
710
|
-
.run();
|
|
711
|
-
// console.log(result.sql);
|
|
712
|
-
// console.log(JSON.stringify(result.data.toObject(), null, 2));
|
|
713
|
-
expect(result.data.path(0, 'all_births').value).toBe(295727065);
|
|
714
|
-
expect(result.data.path(0, 'all_name').value).toBe(197260594);
|
|
508
|
+
await expect(`
|
|
509
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
510
|
+
measure: total_births is births.sum()
|
|
511
|
+
} -> {
|
|
512
|
+
group_by: popular_name, state
|
|
513
|
+
aggregate:
|
|
514
|
+
total_births
|
|
515
|
+
all_births is all(total_births)
|
|
516
|
+
all_name is exclude(total_births, state)
|
|
517
|
+
}
|
|
518
|
+
`).malloyResultMatches(runtime, {
|
|
519
|
+
all_births: 295727065,
|
|
520
|
+
all_name: 197260594,
|
|
521
|
+
});
|
|
715
522
|
});
|
|
716
523
|
|
|
717
524
|
testIf(runtime.supportsNesting)(
|
|
718
525
|
`all with parameters - nest - ${databaseName}`,
|
|
719
526
|
async () => {
|
|
720
|
-
|
|
721
|
-
.
|
|
722
|
-
`
|
|
723
|
-
source: s is table('malloytest.state_facts') + {
|
|
527
|
+
await expect(`
|
|
528
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
724
529
|
measure: total_births is births.sum()
|
|
725
530
|
dimension: abc is floor(airport_count/300)
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
query: s -> {
|
|
531
|
+
} -> {
|
|
729
532
|
group_by: abc
|
|
730
533
|
aggregate: total_births
|
|
731
534
|
nest: by_stuff is {
|
|
@@ -736,329 +539,186 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
736
539
|
all_name is exclude(total_births, state)
|
|
737
540
|
}
|
|
738
541
|
}
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
// console.log(result.sql);
|
|
744
|
-
// console.log(JSON.stringify(result.data.toObject(), null, 2));
|
|
745
|
-
expect(result.data.path(0, 'by_stuff', 0, 'all_births').value).toBe(
|
|
746
|
-
119809719
|
|
747
|
-
);
|
|
748
|
-
expect(result.data.path(0, 'by_stuff', 0, 'all_name').value).toBe(
|
|
749
|
-
61091215
|
|
750
|
-
);
|
|
542
|
+
`).malloyResultMatches(runtime, {
|
|
543
|
+
'by_stuff.all_births': 119809719,
|
|
544
|
+
'by_stuff.all_name': 61091215,
|
|
545
|
+
});
|
|
751
546
|
}
|
|
752
547
|
);
|
|
753
548
|
|
|
754
549
|
testIf(runtime.supportsNesting)(
|
|
755
550
|
`single value to udf - ${databaseName}`,
|
|
756
551
|
async () => {
|
|
757
|
-
|
|
758
|
-
.
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
-> {
|
|
765
|
-
select: t1 is t+1
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
query: f-> {
|
|
769
|
-
nest: fun
|
|
770
|
-
}
|
|
771
|
-
`
|
|
772
|
-
)
|
|
773
|
-
.run();
|
|
774
|
-
// console.log(result.sql);
|
|
775
|
-
expect(result.data.path(0, 'fun', 0, 't1').value).toBe(52);
|
|
552
|
+
await expect(`
|
|
553
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
554
|
+
view: fun is {
|
|
555
|
+
aggregate: t is count()
|
|
556
|
+
} -> { select: t1 is t+1 }
|
|
557
|
+
} -> { nest: fun }
|
|
558
|
+
`).malloyResultMatches(runtime, {'fun.t1': 52});
|
|
776
559
|
}
|
|
777
560
|
);
|
|
778
561
|
|
|
779
562
|
testIf(runtime.supportsNesting)(
|
|
780
563
|
`Multi value to udf - ${databaseName}`,
|
|
781
564
|
async () => {
|
|
782
|
-
|
|
783
|
-
.
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
query: f-> {
|
|
795
|
-
nest: fun
|
|
796
|
-
}
|
|
797
|
-
`
|
|
798
|
-
)
|
|
799
|
-
.run();
|
|
800
|
-
// console.log(result.sql);
|
|
801
|
-
// console.log(result.data.toObject());
|
|
802
|
-
expect(result.data.path(0, 'fun', 0, 't1').value).toBe(52);
|
|
565
|
+
await expect(`
|
|
566
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
567
|
+
view: fun is {
|
|
568
|
+
group_by: one is 1
|
|
569
|
+
aggregate: t is count()
|
|
570
|
+
} -> { select: t1 is t+1 }
|
|
571
|
+
} -> {
|
|
572
|
+
nest: fun
|
|
573
|
+
}
|
|
574
|
+
`).malloyResultMatches(runtime, {'fun.t1': 52});
|
|
803
575
|
}
|
|
804
576
|
);
|
|
805
577
|
|
|
806
578
|
testIf(runtime.supportsNesting)(
|
|
807
579
|
`Multi value to udf group by - ${databaseName}`,
|
|
808
580
|
async () => {
|
|
809
|
-
|
|
810
|
-
.
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
group_by:
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
query: f-> {
|
|
822
|
-
nest: fun
|
|
823
|
-
}
|
|
824
|
-
`
|
|
825
|
-
)
|
|
826
|
-
.run();
|
|
827
|
-
// console.log(result.sql);
|
|
828
|
-
// console.log(result.data.toObject());
|
|
829
|
-
expect(result.data.path(0, 'fun', 0, 't1').value).toBe(52);
|
|
581
|
+
await expect(`
|
|
582
|
+
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
583
|
+
view: fun is {
|
|
584
|
+
group_by: one is 1
|
|
585
|
+
aggregate: t is count()
|
|
586
|
+
} -> { group_by: t1 is t+1 }
|
|
587
|
+
} -> {
|
|
588
|
+
nest: fun
|
|
589
|
+
}
|
|
590
|
+
`).malloyResultMatches(runtime, {'fun.t1': 52});
|
|
830
591
|
}
|
|
831
592
|
);
|
|
832
593
|
|
|
833
|
-
const sql1234 =
|
|
834
|
-
sql: one is {select: """
|
|
835
|
-
SELECT 1 as a, 2 as b
|
|
836
|
-
UNION ALL SELECT 3, 4
|
|
837
|
-
"""}`;
|
|
838
|
-
|
|
839
|
-
it(`sql_block - ${databaseName}`, async () => {
|
|
840
|
-
const result = await runtime
|
|
841
|
-
.loadQuery(
|
|
842
|
-
`
|
|
843
|
-
${sql1234}
|
|
844
|
-
source: eone is from_sql(one) {}
|
|
594
|
+
const sql1234 = `${databaseName}.sql("SELECT 1 as a, 2 as b UNION ALL SELECT 3, 4")`;
|
|
845
595
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
expect(result.data.value[0]['a']).toBe(1);
|
|
596
|
+
it(`sql as source - ${databaseName}`, async () => {
|
|
597
|
+
await expect(`
|
|
598
|
+
run: ${sql1234} -> { select: a }
|
|
599
|
+
`).malloyResultMatches(runtime, {a: 1});
|
|
851
600
|
});
|
|
852
601
|
|
|
853
|
-
it(`
|
|
854
|
-
|
|
855
|
-
.loadQuery(
|
|
856
|
-
`
|
|
857
|
-
${sql1234}
|
|
858
|
-
query: from_sql(one) -> { select: a }
|
|
859
|
-
`
|
|
860
|
-
)
|
|
861
|
-
.run();
|
|
862
|
-
expect(result.data.value[0]['a']).toBe(1);
|
|
602
|
+
it(`sql directly - ${databaseName}`, async () => {
|
|
603
|
+
await expect(`run: ${sql1234}`).malloyResultMatches(runtime, {a: 1});
|
|
863
604
|
});
|
|
864
605
|
|
|
865
|
-
it(`
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
}
|
|
879
|
-
}%)
|
|
880
|
-
"""
|
|
881
|
-
}
|
|
882
|
-
query: from_sql(state_as_sql) -> {
|
|
606
|
+
it(`sql with turducken- ${databaseName}`, async () => {
|
|
607
|
+
const turduckenQuery = `
|
|
608
|
+
run: ${databaseName}.sql("""
|
|
609
|
+
SELECT
|
|
610
|
+
'something' as something,
|
|
611
|
+
*
|
|
612
|
+
FROM %{
|
|
613
|
+
${databaseName}.table('malloytest.state_facts') -> {
|
|
614
|
+
group_by: popular_name
|
|
615
|
+
aggregate: state_count is count()
|
|
616
|
+
}
|
|
617
|
+
} AS by_name_query
|
|
618
|
+
""") -> {
|
|
883
619
|
select: *; where: popular_name = 'Emma'
|
|
884
620
|
}`;
|
|
885
|
-
|
|
886
|
-
expect(result.data.value[0]['state_count']).toBe(6);
|
|
887
|
-
}
|
|
621
|
+
await expect(turduckenQuery).malloyResultMatches(runtime, {state_count: 6});
|
|
888
622
|
});
|
|
889
623
|
|
|
890
|
-
// it(`sql_block version- ${databaseName}`, async () => {
|
|
891
|
-
// const result = await runtime
|
|
892
|
-
// .loadQuery(
|
|
893
|
-
// `
|
|
894
|
-
// sql: one is ||
|
|
895
|
-
// select version() as version
|
|
896
|
-
// ;;
|
|
897
|
-
|
|
898
|
-
// query: from_sql(one) -> { select: version }
|
|
899
|
-
// `
|
|
900
|
-
// )
|
|
901
|
-
// .run();
|
|
902
|
-
// expect(result.data.value[0].version).toBe("something");
|
|
903
|
-
// });
|
|
904
|
-
|
|
905
624
|
// local declarations
|
|
906
625
|
it(`local declarations external query - ${databaseName}`, async () => {
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
${sql1234}
|
|
911
|
-
query: from_sql(one) -> {
|
|
912
|
-
declare: c is a + 1
|
|
626
|
+
await expect(`
|
|
627
|
+
run: ${sql1234} -> {
|
|
628
|
+
extend: { dimension: c is a + 1 }
|
|
913
629
|
select: c
|
|
914
630
|
}
|
|
915
|
-
|
|
916
|
-
)
|
|
917
|
-
.run();
|
|
918
|
-
expect(result.data.value[0]['c']).toBe(2);
|
|
631
|
+
`).malloyResultMatches(runtime, {c: 2});
|
|
919
632
|
});
|
|
920
633
|
|
|
921
634
|
it(`local declarations named query - ${databaseName}`, async () => {
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
source: foo is from_sql(one) + {
|
|
927
|
-
query: bar is {
|
|
928
|
-
declare: c is a + 1
|
|
635
|
+
await expect(`
|
|
636
|
+
run: ${sql1234} extend {
|
|
637
|
+
view: bar is {
|
|
638
|
+
extend: { dimension: c is a + 1 }
|
|
929
639
|
select: c
|
|
930
640
|
}
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
query: foo-> bar
|
|
934
|
-
`
|
|
935
|
-
)
|
|
936
|
-
.run();
|
|
937
|
-
expect(result.data.value[0]['c']).toBe(2);
|
|
641
|
+
} -> bar
|
|
642
|
+
`).malloyResultMatches(runtime, {c: 2});
|
|
938
643
|
});
|
|
939
644
|
|
|
940
645
|
it(`local declarations refined named query - ${databaseName}`, async () => {
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
source: foo is from_sql(one) + {
|
|
946
|
-
query: bar is {
|
|
947
|
-
declare: c is a + 1
|
|
646
|
+
await expect(`
|
|
647
|
+
run: ${sql1234} extend {
|
|
648
|
+
view: bar is {
|
|
649
|
+
extend: {dimension: c is a + 1}
|
|
948
650
|
select: c
|
|
949
651
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
declare: d is c + 1
|
|
652
|
+
view: baz is bar refine {
|
|
653
|
+
extend: {dimension: d is c + 1}
|
|
953
654
|
select: d
|
|
954
655
|
}
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
query: foo-> baz
|
|
958
|
-
`
|
|
959
|
-
)
|
|
960
|
-
.run();
|
|
961
|
-
expect(result.data.value[0]['d']).toBe(3);
|
|
656
|
+
} -> baz
|
|
657
|
+
`).malloyResultMatches(runtime, {d: 3});
|
|
962
658
|
});
|
|
963
659
|
|
|
964
660
|
it(`regexp match- ${databaseName}`, async () => {
|
|
965
|
-
|
|
966
|
-
.
|
|
967
|
-
`
|
|
968
|
-
sql: one is { select: """
|
|
661
|
+
await expect(`
|
|
662
|
+
run: ${databaseName}.sql("""
|
|
969
663
|
SELECT 'hello mom' as a, 'cheese tastes good' as b
|
|
970
664
|
UNION ALL SELECT 'lloyd is a bozo', 'michael likes poetry'
|
|
971
|
-
"""
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
aggregate: llo is count() {? a ~ r'llo'}
|
|
975
|
-
aggregate: m2 is count() {? a !~ r'bozo'}
|
|
665
|
+
""") -> {
|
|
666
|
+
aggregate: llo is count() {where: a ~ r'llo'}
|
|
667
|
+
aggregate: m2 is count() {where: a !~ r'bozo'}
|
|
976
668
|
}
|
|
977
|
-
|
|
978
|
-
)
|
|
979
|
-
.run();
|
|
980
|
-
expect(result.data.value[0]['llo']).toBe(2);
|
|
981
|
-
expect(result.data.value[0]['m2']).toBe(1);
|
|
669
|
+
`).malloyResultMatches(runtime, {llo: 2, m2: 1});
|
|
982
670
|
});
|
|
983
671
|
|
|
984
|
-
it(`substitution
|
|
985
|
-
|
|
986
|
-
.
|
|
987
|
-
`
|
|
988
|
-
sql: one is {select: """
|
|
672
|
+
it(`substitution precedence- ${databaseName}`, async () => {
|
|
673
|
+
await expect(`
|
|
674
|
+
run: ${databaseName}.sql("""
|
|
989
675
|
SELECT 5 as a, 2 as b
|
|
990
676
|
UNION ALL SELECT 3, 4
|
|
991
|
-
"""
|
|
992
|
-
|
|
993
|
-
query: from_sql(one) -> {
|
|
994
|
-
declare: c is b + 4
|
|
677
|
+
""") -> {
|
|
678
|
+
extend: {dimension: c is b + 4}
|
|
995
679
|
select: x is a * c
|
|
996
680
|
}
|
|
997
|
-
`
|
|
998
|
-
)
|
|
999
|
-
.run();
|
|
1000
|
-
expect(result.data.value[0]['x']).toBe(30);
|
|
681
|
+
`).malloyResultMatches(runtime, {x: 30});
|
|
1001
682
|
});
|
|
1002
683
|
|
|
1003
684
|
it(`array unnest - ${databaseName}`, async () => {
|
|
1004
|
-
|
|
1005
|
-
.
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
query: title -> {
|
|
1017
|
-
where: words.value != null
|
|
1018
|
-
group_by: words.value
|
|
1019
|
-
aggregate: c is count()
|
|
1020
|
-
}
|
|
1021
|
-
`
|
|
1022
|
-
)
|
|
1023
|
-
.run();
|
|
1024
|
-
expect(result.data.value[0]['c']).toBe(145);
|
|
685
|
+
await expect(`
|
|
686
|
+
run: ${databaseName}.sql("""
|
|
687
|
+
SELECT
|
|
688
|
+
city,
|
|
689
|
+
${getSplitFunction(databaseName)!('city', ' ')} as words
|
|
690
|
+
FROM ${rootDbPath(databaseName)}malloytest.aircraft
|
|
691
|
+
""") -> {
|
|
692
|
+
where: words.value != null
|
|
693
|
+
group_by: words.value
|
|
694
|
+
aggregate: c is count()
|
|
695
|
+
}
|
|
696
|
+
`).malloyResultMatches(runtime, {c: 145});
|
|
1025
697
|
});
|
|
1026
698
|
|
|
1027
699
|
// make sure we can count the total number of elements when fanning out.
|
|
1028
700
|
it(`array unnest x 2 - ${databaseName}`, async () => {
|
|
1029
|
-
|
|
1030
|
-
.
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
query: title -> {
|
|
1044
|
-
aggregate:
|
|
1045
|
-
b is count()
|
|
1046
|
-
c is words.count()
|
|
1047
|
-
a is abreak.count()
|
|
1048
|
-
}
|
|
1049
|
-
`
|
|
1050
|
-
)
|
|
1051
|
-
.run();
|
|
1052
|
-
expect(result.data.value[0]['b']).toBe(3552);
|
|
1053
|
-
expect(result.data.value[0]['c']).toBe(4586);
|
|
1054
|
-
expect(result.data.value[0]['a']).toBe(6601);
|
|
701
|
+
await expect(`
|
|
702
|
+
run: ${databaseName}.sql("""
|
|
703
|
+
SELECT
|
|
704
|
+
city,
|
|
705
|
+
${getSplitFunction(databaseName)!('city', ' ')} as words,
|
|
706
|
+
${getSplitFunction(databaseName)!('city', 'A')} as abreak
|
|
707
|
+
FROM ${rootDbPath(databaseName)}malloytest.aircraft
|
|
708
|
+
WHERE city IS NOT null
|
|
709
|
+
""") -> {
|
|
710
|
+
aggregate:
|
|
711
|
+
b is count()
|
|
712
|
+
c is words.count()
|
|
713
|
+
a is abreak.count()
|
|
714
|
+
}`).malloyResultMatches(runtime, {b: 3552, c: 4586, a: 6601});
|
|
1055
715
|
});
|
|
1056
716
|
|
|
1057
717
|
testIf(runtime.supportsNesting)(`nest null - ${databaseName}`, async () => {
|
|
1058
718
|
const result = await runtime
|
|
1059
719
|
.loadQuery(
|
|
1060
720
|
`
|
|
1061
|
-
|
|
721
|
+
run: ${databaseName}.table('malloytest.airports') -> {
|
|
1062
722
|
where: faa_region = null
|
|
1063
723
|
group_by: faa_region
|
|
1064
724
|
aggregate: airport_count is count()
|
|
@@ -1090,9 +750,9 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
1090
750
|
const result = await runtime
|
|
1091
751
|
.loadQuery(
|
|
1092
752
|
`
|
|
1093
|
-
source: s is table('malloytest.state_facts')
|
|
753
|
+
source: s is ${databaseName}.table('malloytest.state_facts') extend {
|
|
1094
754
|
}
|
|
1095
|
-
|
|
755
|
+
run: s-> {
|
|
1096
756
|
group_by: state
|
|
1097
757
|
nest: ugly is {
|
|
1098
758
|
group_by: popular_name
|
|
@@ -1110,56 +770,40 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
1110
770
|
const tick = "'";
|
|
1111
771
|
const back = '\\';
|
|
1112
772
|
test('backslash quote', async () => {
|
|
1113
|
-
|
|
1114
|
-
.
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
}
|
|
1119
|
-
`
|
|
1120
|
-
)
|
|
1121
|
-
.run();
|
|
1122
|
-
expect(result.data.value[0]['tick']).toBe(tick);
|
|
773
|
+
await expect(`
|
|
774
|
+
run: ${databaseName}.sql("SELECT 1") -> {
|
|
775
|
+
select: tick is '${back}${tick}'
|
|
776
|
+
}
|
|
777
|
+
`).malloyResultMatches(runtime, {tick});
|
|
1123
778
|
});
|
|
1124
779
|
test('backslash backslash', async () => {
|
|
1125
|
-
|
|
1126
|
-
.
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
}
|
|
1131
|
-
`
|
|
1132
|
-
)
|
|
1133
|
-
.run();
|
|
1134
|
-
expect(result.data.value[0]['back']).toBe(back);
|
|
780
|
+
await expect(`
|
|
781
|
+
run: ${databaseName}.sql("SELECT 1") -> {
|
|
782
|
+
select: back is '${back}${back}'
|
|
783
|
+
}
|
|
784
|
+
`).malloyResultMatches(runtime, {back});
|
|
1135
785
|
});
|
|
1136
786
|
|
|
1137
787
|
testIf(runtime.supportsNesting)('spaces in names', async () => {
|
|
1138
|
-
|
|
1139
|
-
.
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
group_by: \`J S\` is \`j space\`.state
|
|
1153
|
-
aggregate: \`c o u n t\` is count()
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
788
|
+
await expect(`
|
|
789
|
+
source: \`space race\` is ${databaseName}.table('malloytest.state_facts') extend {
|
|
790
|
+
join_one: \`j space\` is ${databaseName}.table('malloytest.state_facts') on \`j space\`.state=state
|
|
791
|
+
view: \`q u e r y\` is {
|
|
792
|
+
group_by:
|
|
793
|
+
\`P O P\` is popular_name
|
|
794
|
+
\`J P O P\` is \`j space\`.popular_name
|
|
795
|
+
aggregate: \`c o u n t\` is count()
|
|
796
|
+
calculate:
|
|
797
|
+
\`R O W\` is row_number()
|
|
798
|
+
\`l a g\` is lag(\`P O P\`, 1)
|
|
799
|
+
nest: \`by state\` is {
|
|
800
|
+
group_by: \`J S\` is \`j space\`.state
|
|
801
|
+
aggregate: \`c o u n t\` is count()
|
|
1156
802
|
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
.run();
|
|
1162
|
-
expect(result.data.value[0]['c o u n t']).toBe(24);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
run: \`space race\` -> \`q u e r y\`
|
|
806
|
+
`).malloyResultMatches(runtime, {'c o u n t': 24});
|
|
1163
807
|
});
|
|
1164
808
|
});
|
|
1165
809
|
});
|