@malloydata/malloy-tests 0.0.67 → 0.0.68-dev230808194809
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/dist/databases/all/db_index.spec.d.ts +1 -0
- package/dist/databases/all/db_index.spec.js +36 -0
- package/dist/databases/all/db_index.spec.js.map +1 -0
- package/dist/databases/all/expr.spec.d.ts +0 -2
- package/dist/databases/all/expr.spec.js +2 -547
- package/dist/databases/all/expr.spec.js.map +1 -1
- package/dist/databases/all/functions.spec.d.ts +1 -2
- package/dist/databases/all/functions.spec.js +2 -751
- package/dist/databases/all/functions.spec.js.map +1 -1
- package/dist/databases/all/join.spec.d.ts +1 -2
- package/dist/databases/all/join.spec.js +2 -276
- package/dist/databases/all/join.spec.js.map +1 -1
- package/dist/databases/all/nomodel.spec.d.ts +1 -2
- package/dist/databases/all/nomodel.spec.js +2 -923
- package/dist/databases/all/nomodel.spec.js.map +1 -1
- package/dist/databases/all/orderby.spec.d.ts +1 -2
- package/dist/databases/all/orderby.spec.js +2 -191
- package/dist/databases/all/orderby.spec.js.map +1 -1
- package/dist/databases/all/problems.spec.d.ts +1 -2
- package/dist/databases/all/problems.spec.js +2 -80
- package/dist/databases/all/problems.spec.js.map +1 -1
- package/dist/databases/all/sql_expressions.spec.d.ts +1 -2
- package/dist/databases/all/sql_expressions.spec.js +2 -62
- package/dist/databases/all/sql_expressions.spec.js.map +1 -1
- package/dist/databases/all/time.spec.d.ts +1 -3
- package/dist/databases/all/time.spec.js +2 -615
- package/dist/databases/all/time.spec.js.map +1 -1
- package/dist/databases/{all/index.spec.d.ts → shared/db_index.d.ts} +1 -0
- package/dist/databases/{all/index.spec.js → shared/db_index.js} +2 -33
- package/dist/databases/shared/db_index.js.map +1 -0
- package/dist/databases/shared/expr.d.ts +3 -0
- package/dist/databases/shared/expr.js +551 -0
- package/dist/databases/shared/expr.js.map +1 -0
- package/dist/databases/shared/functions.d.ts +3 -0
- package/dist/databases/shared/functions.js +754 -0
- package/dist/databases/shared/functions.js.map +1 -0
- package/dist/databases/shared/join.d.ts +3 -0
- package/dist/databases/shared/join.js +302 -0
- package/dist/databases/shared/join.js.map +1 -0
- package/dist/databases/shared/nomodel.d.ts +3 -0
- package/dist/databases/shared/nomodel.js +950 -0
- package/dist/databases/shared/nomodel.js.map +1 -0
- package/dist/databases/shared/orderby.d.ts +3 -0
- package/dist/databases/shared/orderby.js +217 -0
- package/dist/databases/shared/orderby.js.map +1 -0
- package/dist/databases/shared/problems.d.ts +3 -0
- package/dist/databases/shared/problems.js +106 -0
- package/dist/databases/shared/problems.js.map +1 -0
- package/dist/databases/shared/sql_expressions.d.ts +3 -0
- package/dist/databases/shared/sql_expressions.js +88 -0
- package/dist/databases/shared/sql_expressions.js.map +1 -0
- package/dist/databases/shared/test_list.js +18 -18
- package/dist/databases/shared/test_list.js.map +1 -1
- package/dist/databases/shared/time.d.ts +3 -0
- package/dist/databases/shared/time.js +640 -0
- package/dist/databases/shared/time.js.map +1 -0
- package/dist/index.d.ts +9 -10
- package/dist/index.js +19 -21
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/databases/all/db_index.spec.ts +37 -0
- package/src/databases/all/expr.spec.ts +2 -670
- package/src/databases/all/functions.spec.ts +1 -1101
- package/src/databases/all/join.spec.ts +1 -315
- package/src/databases/all/nomodel.spec.ts +2 -1124
- package/src/databases/all/orderby.spec.ts +1 -234
- package/src/databases/all/problems.spec.ts +1 -87
- package/src/databases/all/sql_expressions.spec.ts +1 -71
- package/src/databases/all/time.spec.ts +1 -761
- package/src/databases/{all/index.spec.ts → shared/db_index.ts} +2 -13
- package/src/databases/shared/expr.ts +695 -0
- package/src/databases/shared/functions.ts +1126 -0
- package/src/databases/shared/join.ts +340 -0
- package/src/databases/shared/nomodel.ts +1150 -0
- package/src/databases/shared/orderby.ts +260 -0
- package/src/databases/shared/problems.ts +113 -0
- package/src/databases/shared/sql_expressions.ts +96 -0
- package/src/databases/shared/test_list.ts +9 -9
- package/src/databases/shared/time.ts +786 -0
- package/src/index.ts +10 -11
- package/dist/databases/all/index.spec.js.map +0 -1
|
@@ -0,0 +1,950 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
/*
|
|
4
|
+
* Copyright 2023 Google LLC
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
|
7
|
+
* a copy of this software and associated documentation files
|
|
8
|
+
* (the "Software"), to deal in the Software without restriction,
|
|
9
|
+
* including without limitation the rights to use, copy, modify, merge,
|
|
10
|
+
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
11
|
+
* and to permit persons to whom the Software is furnished to do so,
|
|
12
|
+
* subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be
|
|
15
|
+
* included in all copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
18
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
19
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
20
|
+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
21
|
+
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
22
|
+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
23
|
+
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.noModelSharedTests = void 0;
|
|
27
|
+
const util_1 = require("../../util");
|
|
28
|
+
require("../../util/db-jest-matchers");
|
|
29
|
+
// No prebuilt shared model, each test is complete. Makes debugging easier.
|
|
30
|
+
const noModelSharedTests = (runtimes, splitFunction) => {
|
|
31
|
+
function rootDbPath(databaseName) {
|
|
32
|
+
return databaseName === 'bigquery' ? 'malloy-data.' : '';
|
|
33
|
+
}
|
|
34
|
+
// TODO: Figure out how to generalize this.
|
|
35
|
+
function getSplitFunction(db) {
|
|
36
|
+
return (splitFunction !== null && splitFunction !== void 0 ? splitFunction : {
|
|
37
|
+
'bigquery': (column, splitChar) => `split(${column}, '${splitChar}')`,
|
|
38
|
+
'postgres': (column, splitChar) => `string_to_array(${column}, '${splitChar}')`,
|
|
39
|
+
'duckdb': (column, splitChar) => `string_to_array(${column}, '${splitChar}')`,
|
|
40
|
+
'duckdb_wasm': (column, splitChar) => `string_to_array(${column}, '${splitChar}')`,
|
|
41
|
+
}[db]);
|
|
42
|
+
}
|
|
43
|
+
afterAll(async () => {
|
|
44
|
+
await runtimes.closeAll();
|
|
45
|
+
});
|
|
46
|
+
runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
47
|
+
// Issue: #151
|
|
48
|
+
it(`unknown dialect - ${databaseName}`, async () => {
|
|
49
|
+
const result = await runtime
|
|
50
|
+
.loadQuery(`
|
|
51
|
+
query: q is table('malloytest.aircraft')->{
|
|
52
|
+
where: state != null
|
|
53
|
+
group_by: state
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
source: r is from(->q){
|
|
57
|
+
query: foo is {
|
|
58
|
+
order_by: 1 desc
|
|
59
|
+
group_by: state
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
query: r->foo
|
|
64
|
+
`)
|
|
65
|
+
.run();
|
|
66
|
+
// console.log(result.data.toObject());
|
|
67
|
+
expect(result.data.path(0, 'state').value).toBe('WY');
|
|
68
|
+
});
|
|
69
|
+
// Issue #149
|
|
70
|
+
it(`refine query from query - ${databaseName}`, async () => {
|
|
71
|
+
const result = await runtime
|
|
72
|
+
.loadQuery(`
|
|
73
|
+
query: from(
|
|
74
|
+
table('malloytest.state_facts')->{group_by: state; order_by: 1 desc; limit: 1}
|
|
75
|
+
)
|
|
76
|
+
{
|
|
77
|
+
dimension: lower_state is lower(state)
|
|
78
|
+
}
|
|
79
|
+
-> {project: lower_state}
|
|
80
|
+
`)
|
|
81
|
+
.run();
|
|
82
|
+
// console.log(result.data.toObject());
|
|
83
|
+
expect(result.data.path(0, 'lower_state').value).toBe('wy');
|
|
84
|
+
});
|
|
85
|
+
// issue #157
|
|
86
|
+
it(`source- not -found - ${databaseName}`, async () => {
|
|
87
|
+
// console.log(result.data.toObject());
|
|
88
|
+
let error;
|
|
89
|
+
try {
|
|
90
|
+
await runtime
|
|
91
|
+
.loadQuery(`
|
|
92
|
+
source: foo is table('malloytest.state_facts'){primary_key: state}
|
|
93
|
+
query: foox->{aggregate: c is count()}
|
|
94
|
+
`)
|
|
95
|
+
.run();
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
error = e;
|
|
99
|
+
}
|
|
100
|
+
expect(error.toString()).not.toContain('Unknown Dialect');
|
|
101
|
+
});
|
|
102
|
+
it(`join_many - ${databaseName}`, async () => {
|
|
103
|
+
const result = await runtime
|
|
104
|
+
.loadQuery(`
|
|
105
|
+
source: a is table('malloytest.aircraft'){
|
|
106
|
+
measure: avg_year is floor(avg(year_built))
|
|
107
|
+
}
|
|
108
|
+
source: m is table('malloytest.aircraft_models'){
|
|
109
|
+
join_many: a on a.aircraft_model_code=aircraft_model_code
|
|
110
|
+
measure: avg_seats is floor(avg(seats))
|
|
111
|
+
}
|
|
112
|
+
query: m->{aggregate: avg_seats, a.avg_year}
|
|
113
|
+
`)
|
|
114
|
+
.run();
|
|
115
|
+
expect(result.data.value[0]['avg_year']).toBe(1969);
|
|
116
|
+
expect(result.data.value[0]['avg_seats']).toBe(7);
|
|
117
|
+
});
|
|
118
|
+
it(`join_many condition no primary key - ${databaseName}`, async () => {
|
|
119
|
+
const result = await runtime
|
|
120
|
+
.loadQuery(`
|
|
121
|
+
source: a is table('malloytest.airports'){}
|
|
122
|
+
source: b is table('malloytest.state_facts') {
|
|
123
|
+
join_many: a on state=a.state
|
|
124
|
+
}
|
|
125
|
+
query: b->{aggregate: c is airport_count.sum()}
|
|
126
|
+
`)
|
|
127
|
+
.run();
|
|
128
|
+
expect(result.data.value[0]['c']).toBe(19701);
|
|
129
|
+
});
|
|
130
|
+
it(`join_many filter multiple values - ${databaseName}`, async () => {
|
|
131
|
+
const result = await runtime
|
|
132
|
+
.loadQuery(`
|
|
133
|
+
source: a is table('malloytest.airports'){
|
|
134
|
+
where: state = 'NH' | 'CA'
|
|
135
|
+
}
|
|
136
|
+
source: b is table('malloytest.state_facts') {
|
|
137
|
+
join_many: a on state=a.state
|
|
138
|
+
}
|
|
139
|
+
query: b->{
|
|
140
|
+
aggregate: c is airport_count.sum()
|
|
141
|
+
group_by: a.state
|
|
142
|
+
}
|
|
143
|
+
`)
|
|
144
|
+
.run();
|
|
145
|
+
expect(result.data.value[0]['c']).toBe(18605);
|
|
146
|
+
expect(result.data.value[0]['state']).toBeNull();
|
|
147
|
+
expect(result.data.value[1]['c']).toBe(984);
|
|
148
|
+
expect(result.data.value[1]['state']).toBe('CA');
|
|
149
|
+
expect(result.data.value[2]['c']).toBe(112);
|
|
150
|
+
expect(result.data.value[2]['state']).toBe('NH');
|
|
151
|
+
});
|
|
152
|
+
it(`join_one condition no primary key - ${databaseName}`, async () => {
|
|
153
|
+
const result = await runtime
|
|
154
|
+
.loadQuery(`
|
|
155
|
+
source: a is table('malloytest.state_facts'){}
|
|
156
|
+
source: b is table('malloytest.airports') {
|
|
157
|
+
join_one: a on state=a.state
|
|
158
|
+
}
|
|
159
|
+
query: b->{aggregate: c is a.airport_count.sum()}
|
|
160
|
+
|
|
161
|
+
`)
|
|
162
|
+
.run();
|
|
163
|
+
expect(result.data.value[0]['c']).toBe(19701);
|
|
164
|
+
});
|
|
165
|
+
it(`join_one filter multiple values - ${databaseName}`, async () => {
|
|
166
|
+
const result = await runtime
|
|
167
|
+
.loadQuery(`
|
|
168
|
+
source: a is table('malloytest.state_facts'){
|
|
169
|
+
where: state = 'TX' | 'LA'
|
|
170
|
+
}
|
|
171
|
+
source: b is table('malloytest.airports') {
|
|
172
|
+
join_one: a on state=a.state
|
|
173
|
+
}
|
|
174
|
+
query: b->{
|
|
175
|
+
aggregate: c is a.airport_count.sum()
|
|
176
|
+
group_by: a.state
|
|
177
|
+
}
|
|
178
|
+
`)
|
|
179
|
+
.run();
|
|
180
|
+
// https://github.com/malloydata/malloy/pull/501#discussion_r861022857
|
|
181
|
+
expect(result.data.value).toHaveLength(3);
|
|
182
|
+
expect(result.data.value).toContainEqual({ c: 1845, state: 'TX' });
|
|
183
|
+
expect(result.data.value).toContainEqual({ c: 500, state: 'LA' });
|
|
184
|
+
expect(result.data.value).toContainEqual({ c: 0, state: null });
|
|
185
|
+
});
|
|
186
|
+
it(`join_many cross from - ${databaseName}`, async () => {
|
|
187
|
+
// a cross join produces a Many to Many result.
|
|
188
|
+
// symmetric aggregate are needed on both sides of the join
|
|
189
|
+
// Check the row count and that sums on each side work properly.
|
|
190
|
+
const result = await runtime
|
|
191
|
+
.loadQuery(`
|
|
192
|
+
source: a is table('malloytest.state_facts')
|
|
193
|
+
source: f is a{
|
|
194
|
+
join_cross: a
|
|
195
|
+
}
|
|
196
|
+
query: f->{
|
|
197
|
+
aggregate:
|
|
198
|
+
row_count is count(distinct concat(state,a.state))
|
|
199
|
+
left_count is count()
|
|
200
|
+
right_count is a.count()
|
|
201
|
+
left_sum is airport_count.sum()
|
|
202
|
+
right_sum is a.airport_count.sum()
|
|
203
|
+
}
|
|
204
|
+
`)
|
|
205
|
+
.run();
|
|
206
|
+
expect(result.data.value[0]['row_count']).toBe(51 * 51);
|
|
207
|
+
expect(result.data.value[0]['left_sum']).toBe(19701);
|
|
208
|
+
expect(result.data.value[0]['right_sum']).toBe(19701);
|
|
209
|
+
});
|
|
210
|
+
it(`join_one only - ${databaseName}`, async () => {
|
|
211
|
+
// a cross join produces a Many to Many result.
|
|
212
|
+
// symmetric aggregate are needed on both sides of the join
|
|
213
|
+
// Check the row count and that sums on each side work properly.
|
|
214
|
+
const result = await runtime
|
|
215
|
+
.loadQuery(`
|
|
216
|
+
query: q is table('malloytest.state_facts')->{
|
|
217
|
+
aggregate: r is airport_count.sum()
|
|
218
|
+
}
|
|
219
|
+
source: f is table('malloytest.state_facts'){
|
|
220
|
+
join_one: a is from(->q)
|
|
221
|
+
}
|
|
222
|
+
query: f->{
|
|
223
|
+
aggregate:
|
|
224
|
+
row_count is count(distinct concat(state,a.r))
|
|
225
|
+
left_sum is airport_count.sum()
|
|
226
|
+
right_sum is a.r.sum()
|
|
227
|
+
sum_sum is sum(airport_count + a.r)
|
|
228
|
+
}
|
|
229
|
+
`)
|
|
230
|
+
.run();
|
|
231
|
+
expect(result.data.value[0]['row_count']).toBe(51);
|
|
232
|
+
expect(result.data.value[0]['left_sum']).toBe(19701);
|
|
233
|
+
expect(result.data.value[0]['right_sum']).toBe(19701);
|
|
234
|
+
expect(result.data.value[0]['sum_sum']).toBe(19701 + 51 * 19701);
|
|
235
|
+
});
|
|
236
|
+
it(`join_many cross ON - ${databaseName}`, async () => {
|
|
237
|
+
// a cross join produces a Many to Many result.
|
|
238
|
+
// symmetric aggregate are needed on both sides of the join
|
|
239
|
+
// Check the row count and that sums on each side work properly.
|
|
240
|
+
const result = await runtime
|
|
241
|
+
.loadQuery(`
|
|
242
|
+
source: a is table('malloytest.state_facts')
|
|
243
|
+
source: f is a{
|
|
244
|
+
join_cross: a on a.state = 'CA' | 'NY'
|
|
245
|
+
}
|
|
246
|
+
query: f->{
|
|
247
|
+
aggregate:
|
|
248
|
+
row_count is count(distinct concat(state,a.state))
|
|
249
|
+
left_sum is airport_count.sum()
|
|
250
|
+
right_sum is a.airport_count.sum()
|
|
251
|
+
}
|
|
252
|
+
`)
|
|
253
|
+
.run();
|
|
254
|
+
expect(result.data.value[0]['row_count']).toBe(51 * 2);
|
|
255
|
+
expect(result.data.value[0]['left_sum']).toBe(19701);
|
|
256
|
+
expect(result.data.value[0]['right_sum']).toBe(1560);
|
|
257
|
+
});
|
|
258
|
+
it(`limit - provided - ${databaseName}`, async () => {
|
|
259
|
+
// a cross join produces a Many to Many result.
|
|
260
|
+
// symmetric aggregate are needed on both sides of the join
|
|
261
|
+
// Check the row count and that sums on each side work properly.
|
|
262
|
+
const result = await runtime
|
|
263
|
+
.loadQuery(`
|
|
264
|
+
query: table('malloytest.state_facts') -> {
|
|
265
|
+
group_by: state
|
|
266
|
+
aggregate: c is count()
|
|
267
|
+
limit: 3
|
|
268
|
+
}
|
|
269
|
+
`)
|
|
270
|
+
.run();
|
|
271
|
+
expect(result.resultExplore.limit).toBe(3);
|
|
272
|
+
});
|
|
273
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`number as null- ${databaseName}`, async () => {
|
|
274
|
+
// a cross join produces a Many to Many result.
|
|
275
|
+
// symmetric aggregate are needed on both sides of the join
|
|
276
|
+
// Check the row count and that sums on each side work properly.
|
|
277
|
+
const result = await runtime
|
|
278
|
+
.loadQuery(`
|
|
279
|
+
source: s is table('malloytest.state_facts') + {
|
|
280
|
+
}
|
|
281
|
+
query: s-> {
|
|
282
|
+
group_by: state
|
|
283
|
+
nest: ugly is {
|
|
284
|
+
group_by: popular_name
|
|
285
|
+
aggregate: foo is NULLIF(sum(airport_count)*0,0)+1
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
`)
|
|
289
|
+
.run();
|
|
290
|
+
expect(result.data.path(0, 'ugly', 0, 'foo').value).toBe(null);
|
|
291
|
+
});
|
|
292
|
+
// average should only include non-null values in the denominator
|
|
293
|
+
it(`avg ignore null- ${databaseName}`, async () => {
|
|
294
|
+
const result = await runtime
|
|
295
|
+
.loadQuery(`
|
|
296
|
+
sql: one is { select: """
|
|
297
|
+
SELECT 2 as a
|
|
298
|
+
UNION ALL SELECT 4
|
|
299
|
+
UNION ALL SELECT null
|
|
300
|
+
"""}
|
|
301
|
+
|
|
302
|
+
query: from_sql(one) -> {
|
|
303
|
+
join_cross: b is from_sql(one)
|
|
304
|
+
aggregate:
|
|
305
|
+
avg_a is a.avg()
|
|
306
|
+
avg_b is b.a.avg()
|
|
307
|
+
}
|
|
308
|
+
`)
|
|
309
|
+
.run();
|
|
310
|
+
expect(result.data.value[0]['avg_a']).toBe(3);
|
|
311
|
+
});
|
|
312
|
+
it(`limit - not provided - ${databaseName}`, async () => {
|
|
313
|
+
// a cross join produces a Many to Many result.
|
|
314
|
+
// symmetric aggregate are needed on both sides of the join
|
|
315
|
+
// Check the row count and that sums on each side work properly.
|
|
316
|
+
const result = await runtime
|
|
317
|
+
.loadQuery(`
|
|
318
|
+
query: table('malloytest.state_facts') -> {
|
|
319
|
+
group_by: state
|
|
320
|
+
aggregate: c is count()
|
|
321
|
+
}
|
|
322
|
+
`)
|
|
323
|
+
.run();
|
|
324
|
+
expect(result.resultExplore.limit).toBe(undefined);
|
|
325
|
+
});
|
|
326
|
+
it(`limit pipeline - provided - ${databaseName}`, async () => {
|
|
327
|
+
// a cross join produces a Many to Many result.
|
|
328
|
+
// symmetric aggregate are needed on both sides of the join
|
|
329
|
+
// Check the row count and that sums on each side work properly.
|
|
330
|
+
const result = await runtime
|
|
331
|
+
.loadQuery(`
|
|
332
|
+
query: table('malloytest.state_facts') -> {
|
|
333
|
+
project: state
|
|
334
|
+
limit: 10
|
|
335
|
+
}
|
|
336
|
+
-> {
|
|
337
|
+
project: state
|
|
338
|
+
limit: 3
|
|
339
|
+
}
|
|
340
|
+
`)
|
|
341
|
+
.run();
|
|
342
|
+
expect(result.resultExplore.limit).toBe(3);
|
|
343
|
+
});
|
|
344
|
+
it(`ungrouped top level - ${databaseName}`, async () => {
|
|
345
|
+
const result = await runtime
|
|
346
|
+
.loadQuery(`
|
|
347
|
+
source: s is table('malloytest.state_facts') + {
|
|
348
|
+
measure: total_births is births.sum()
|
|
349
|
+
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
query:s-> {
|
|
353
|
+
group_by: state
|
|
354
|
+
aggregate: births_per_100k
|
|
355
|
+
}
|
|
356
|
+
`)
|
|
357
|
+
.run();
|
|
358
|
+
// console.log(result.sql);
|
|
359
|
+
expect(result.data.path(0, 'births_per_100k').value).toBe(9742);
|
|
360
|
+
});
|
|
361
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`ungrouped top level with nested - ${databaseName}`, async () => {
|
|
362
|
+
const result = await runtime
|
|
363
|
+
.loadQuery(`
|
|
364
|
+
source: s is table('malloytest.state_facts') + {
|
|
365
|
+
measure: total_births is births.sum()
|
|
366
|
+
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
query:s-> {
|
|
370
|
+
group_by: state
|
|
371
|
+
aggregate: births_per_100k
|
|
372
|
+
nest: by_name is {
|
|
373
|
+
group_by: popular_name
|
|
374
|
+
aggregate: total_births
|
|
375
|
+
}
|
|
376
|
+
limit: 1000
|
|
377
|
+
}
|
|
378
|
+
`)
|
|
379
|
+
.run();
|
|
380
|
+
// console.log(result.sql);
|
|
381
|
+
expect(result.data.path(0, 'births_per_100k').value).toBe(9742);
|
|
382
|
+
});
|
|
383
|
+
it(`ungrouped - eliminate rows - ${databaseName}`, async () => {
|
|
384
|
+
const result = await runtime
|
|
385
|
+
.loadQuery(`
|
|
386
|
+
source: s is table('malloytest.state_facts') + {
|
|
387
|
+
measure: m is all(births.sum())
|
|
388
|
+
where: state='CA' | 'NY'
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
query:s-> {
|
|
392
|
+
group_by: state
|
|
393
|
+
aggregate: m
|
|
394
|
+
}
|
|
395
|
+
`)
|
|
396
|
+
.run();
|
|
397
|
+
// console.log(result.sql);
|
|
398
|
+
expect(result.data.toObject().length).toBe(2);
|
|
399
|
+
});
|
|
400
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`ungrouped nested with no grouping above - ${databaseName}`, async () => {
|
|
401
|
+
const result = await runtime
|
|
402
|
+
.loadQuery(`
|
|
403
|
+
source: s is table('malloytest.state_facts') + {
|
|
404
|
+
measure: total_births is births.sum()
|
|
405
|
+
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
query: s-> {
|
|
409
|
+
aggregate: total_births
|
|
410
|
+
nest: by_name is {
|
|
411
|
+
group_by: popular_name
|
|
412
|
+
aggregate: births_per_100k
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
`)
|
|
417
|
+
.run();
|
|
418
|
+
// console.log(result.sql);
|
|
419
|
+
expect(result.data.path(0, 'by_name', 0, 'births_per_100k').value).toBe(66703);
|
|
420
|
+
});
|
|
421
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`ungrouped - partial grouping - ${databaseName}`, async () => {
|
|
422
|
+
const result = await runtime
|
|
423
|
+
.loadQuery(`
|
|
424
|
+
source: airports is table('malloytest.airports') {
|
|
425
|
+
measure: c is count()
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
query: airports -> {
|
|
430
|
+
where: state = 'TX' | 'NY'
|
|
431
|
+
group_by:
|
|
432
|
+
faa_region
|
|
433
|
+
state
|
|
434
|
+
aggregate:
|
|
435
|
+
c
|
|
436
|
+
all_ is all(c)
|
|
437
|
+
airport_count is c {? fac_type = 'AIRPORT'}
|
|
438
|
+
nest: fac_type is {
|
|
439
|
+
group_by: fac_type
|
|
440
|
+
aggregate:
|
|
441
|
+
c
|
|
442
|
+
all_ is all(c)
|
|
443
|
+
all_state_region is exclude(c,fac_type)
|
|
444
|
+
all_of_this_type is exclude(c, state, faa_region)
|
|
445
|
+
all_top is exclude(c, state, faa_region, fac_type)
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
`)
|
|
450
|
+
.run();
|
|
451
|
+
// console.log(result.sql);
|
|
452
|
+
expect(result.data.path(0, 'fac_type', 0, 'all_').value).toBe(1845);
|
|
453
|
+
expect(result.data.path(0, 'fac_type', 0, 'all_state_region').value).toBe(1845);
|
|
454
|
+
expect(result.data.path(0, 'fac_type', 0, 'all_of_this_type').value).toBe(1782);
|
|
455
|
+
expect(result.data.path(0, 'fac_type', 0, 'all_top').value).toBe(2421);
|
|
456
|
+
});
|
|
457
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`ungrouped - all nested - ${databaseName}`, async () => {
|
|
458
|
+
const result = await runtime
|
|
459
|
+
.loadQuery(`
|
|
460
|
+
source: airports is table('malloytest.airports') {
|
|
461
|
+
measure: c is count()
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
query: airports -> {
|
|
466
|
+
where: state = 'TX' | 'NY'
|
|
467
|
+
group_by:
|
|
468
|
+
state
|
|
469
|
+
aggregate:
|
|
470
|
+
c
|
|
471
|
+
all_ is all(c)
|
|
472
|
+
airport_count is c {? fac_type = 'AIRPORT'}
|
|
473
|
+
nest: fac_type is {
|
|
474
|
+
group_by: fac_type, major
|
|
475
|
+
aggregate:
|
|
476
|
+
c
|
|
477
|
+
all_ is all(c)
|
|
478
|
+
all_major is all(c,major)
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
`)
|
|
484
|
+
.run();
|
|
485
|
+
// console.log(result.sql);
|
|
486
|
+
expect(result.data.path(0, 'fac_type', 0, 'all_').value).toBe(1845);
|
|
487
|
+
expect(result.data.path(0, 'fac_type', 0, 'all_major').value).toBe(1819);
|
|
488
|
+
});
|
|
489
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`ungrouped nested - ${databaseName}`, async () => {
|
|
490
|
+
const result = await runtime
|
|
491
|
+
.loadQuery(`
|
|
492
|
+
source: s is table('malloytest.state_facts') + {
|
|
493
|
+
measure: total_births is births.sum()
|
|
494
|
+
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
query:s -> {
|
|
498
|
+
group_by: popular_name
|
|
499
|
+
nest: by_state is {
|
|
500
|
+
group_by: state
|
|
501
|
+
aggregate: births_per_100k
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
`)
|
|
506
|
+
.run();
|
|
507
|
+
// console.log(result.sql);
|
|
508
|
+
expect(result.data.path(0, 'by_state', 0, 'births_per_100k').value).toBe(36593);
|
|
509
|
+
});
|
|
510
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`ungrouped nested expression - ${databaseName}`, async () => {
|
|
511
|
+
const result = await runtime
|
|
512
|
+
.loadQuery(`
|
|
513
|
+
source: s is table('malloytest.state_facts') + {
|
|
514
|
+
measure: total_births is births.sum()
|
|
515
|
+
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
query:s -> {
|
|
519
|
+
group_by: upper_name is upper(popular_name)
|
|
520
|
+
nest: by_state is {
|
|
521
|
+
group_by: state
|
|
522
|
+
aggregate: births_per_100k
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
`)
|
|
527
|
+
.run();
|
|
528
|
+
// console.log(result.sql);
|
|
529
|
+
expect(result.data.path(0, 'by_state', 0, 'births_per_100k').value).toBe(36593);
|
|
530
|
+
});
|
|
531
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`ungrouped nested group by float - ${databaseName}`, async () => {
|
|
532
|
+
const result = await runtime
|
|
533
|
+
.loadQuery(`
|
|
534
|
+
source: s is table('malloytest.state_facts') + {
|
|
535
|
+
measure: total_births is births.sum()
|
|
536
|
+
measure: ug is all(total_births)
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
query:s -> {
|
|
540
|
+
group_by: f is floor(airport_count/300.0)
|
|
541
|
+
nest: by_state is {
|
|
542
|
+
group_by: state
|
|
543
|
+
aggregate: ug
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
`)
|
|
548
|
+
.run();
|
|
549
|
+
// console.log(result.sql);
|
|
550
|
+
// console.log(JSON.stringify(result.data.toObject(), null, 2));
|
|
551
|
+
expect(result.data.path(0, 'by_state', 0, 'ug').value).toBe(62742230);
|
|
552
|
+
});
|
|
553
|
+
it(`all with parameters - basic - ${databaseName}`, async () => {
|
|
554
|
+
const result = await runtime
|
|
555
|
+
.loadQuery(`
|
|
556
|
+
source: s is table('malloytest.state_facts') + {
|
|
557
|
+
measure: total_births is births.sum()
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
query: s -> {
|
|
561
|
+
group_by: popular_name, state
|
|
562
|
+
aggregate:
|
|
563
|
+
total_births
|
|
564
|
+
all_births is all(total_births)
|
|
565
|
+
all_name is exclude(total_births, state)
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
`)
|
|
569
|
+
.run();
|
|
570
|
+
// console.log(result.sql);
|
|
571
|
+
// console.log(JSON.stringify(result.data.toObject(), null, 2));
|
|
572
|
+
expect(result.data.path(0, 'all_births').value).toBe(295727065);
|
|
573
|
+
expect(result.data.path(0, 'all_name').value).toBe(197260594);
|
|
574
|
+
});
|
|
575
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`all with parameters - nest - ${databaseName}`, async () => {
|
|
576
|
+
const result = await runtime
|
|
577
|
+
.loadQuery(`
|
|
578
|
+
source: s is table('malloytest.state_facts') + {
|
|
579
|
+
measure: total_births is births.sum()
|
|
580
|
+
dimension: abc is floor(airport_count/300)
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
query: s -> {
|
|
584
|
+
group_by: abc
|
|
585
|
+
aggregate: total_births
|
|
586
|
+
nest: by_stuff is {
|
|
587
|
+
group_by: popular_name, state
|
|
588
|
+
aggregate:
|
|
589
|
+
total_births
|
|
590
|
+
all_births is all(total_births)
|
|
591
|
+
all_name is exclude(total_births, state)
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
`)
|
|
596
|
+
.run();
|
|
597
|
+
// console.log(result.sql);
|
|
598
|
+
// console.log(JSON.stringify(result.data.toObject(), null, 2));
|
|
599
|
+
expect(result.data.path(0, 'by_stuff', 0, 'all_births').value).toBe(119809719);
|
|
600
|
+
expect(result.data.path(0, 'by_stuff', 0, 'all_name').value).toBe(61091215);
|
|
601
|
+
});
|
|
602
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`single value to udf - ${databaseName}`, async () => {
|
|
603
|
+
const result = await runtime
|
|
604
|
+
.loadQuery(`
|
|
605
|
+
source: f is table('malloytest.state_facts') {
|
|
606
|
+
query: fun is {
|
|
607
|
+
aggregate: t is count()
|
|
608
|
+
}
|
|
609
|
+
-> {
|
|
610
|
+
project: t1 is t+1
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
query: f-> {
|
|
614
|
+
nest: fun
|
|
615
|
+
}
|
|
616
|
+
`)
|
|
617
|
+
.run();
|
|
618
|
+
// console.log(result.sql);
|
|
619
|
+
expect(result.data.path(0, 'fun', 0, 't1').value).toBe(52);
|
|
620
|
+
});
|
|
621
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`Multi value to udf - ${databaseName}`, async () => {
|
|
622
|
+
const result = await runtime
|
|
623
|
+
.loadQuery(`
|
|
624
|
+
source: f is table('malloytest.state_facts') {
|
|
625
|
+
query: fun is {
|
|
626
|
+
group_by: one is 1
|
|
627
|
+
aggregate: t is count()
|
|
628
|
+
}
|
|
629
|
+
-> {
|
|
630
|
+
project: t1 is t+1
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
query: f-> {
|
|
634
|
+
nest: fun
|
|
635
|
+
}
|
|
636
|
+
`)
|
|
637
|
+
.run();
|
|
638
|
+
// console.log(result.sql);
|
|
639
|
+
// console.log(result.data.toObject());
|
|
640
|
+
expect(result.data.path(0, 'fun', 0, 't1').value).toBe(52);
|
|
641
|
+
});
|
|
642
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`Multi value to udf group by - ${databaseName}`, async () => {
|
|
643
|
+
const result = await runtime
|
|
644
|
+
.loadQuery(`
|
|
645
|
+
source: f is table('malloytest.state_facts') {
|
|
646
|
+
query: fun is {
|
|
647
|
+
group_by: one is 1
|
|
648
|
+
aggregate: t is count()
|
|
649
|
+
}
|
|
650
|
+
-> {
|
|
651
|
+
group_by: t1 is t+1
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
query: f-> {
|
|
655
|
+
nest: fun
|
|
656
|
+
}
|
|
657
|
+
`)
|
|
658
|
+
.run();
|
|
659
|
+
// console.log(result.sql);
|
|
660
|
+
// console.log(result.data.toObject());
|
|
661
|
+
expect(result.data.path(0, 'fun', 0, 't1').value).toBe(52);
|
|
662
|
+
});
|
|
663
|
+
const sql1234 = `
|
|
664
|
+
sql: one is {select: """
|
|
665
|
+
SELECT 1 as a, 2 as b
|
|
666
|
+
UNION ALL SELECT 3, 4
|
|
667
|
+
"""}`;
|
|
668
|
+
it(`sql_block - ${databaseName}`, async () => {
|
|
669
|
+
const result = await runtime
|
|
670
|
+
.loadQuery(`
|
|
671
|
+
${sql1234}
|
|
672
|
+
source: eone is from_sql(one) {}
|
|
673
|
+
|
|
674
|
+
query: eone -> { project: a }
|
|
675
|
+
`)
|
|
676
|
+
.run();
|
|
677
|
+
expect(result.data.value[0]['a']).toBe(1);
|
|
678
|
+
});
|
|
679
|
+
it(`sql_block no explore- ${databaseName}`, async () => {
|
|
680
|
+
const result = await runtime
|
|
681
|
+
.loadQuery(`
|
|
682
|
+
${sql1234}
|
|
683
|
+
query: from_sql(one) -> { project: a }
|
|
684
|
+
`)
|
|
685
|
+
.run();
|
|
686
|
+
expect(result.data.value[0]['a']).toBe(1);
|
|
687
|
+
});
|
|
688
|
+
it(`sql_block with turducken- ${databaseName}`, async () => {
|
|
689
|
+
if (databaseName !== 'postgres') {
|
|
690
|
+
const turduckenQuery = `
|
|
691
|
+
sql: state_as_sql is {
|
|
692
|
+
select: """
|
|
693
|
+
SELECT
|
|
694
|
+
ROW_NUMBER() OVER (ORDER BY state_count) as row_number,
|
|
695
|
+
*
|
|
696
|
+
FROM (%{
|
|
697
|
+
table('malloytest.state_facts')
|
|
698
|
+
-> {
|
|
699
|
+
group_by: popular_name
|
|
700
|
+
aggregate: state_count is count()
|
|
701
|
+
}
|
|
702
|
+
}%)
|
|
703
|
+
"""
|
|
704
|
+
}
|
|
705
|
+
query: from_sql(state_as_sql) -> {
|
|
706
|
+
project: *; where: popular_name = 'Emma'
|
|
707
|
+
}`;
|
|
708
|
+
const result = await runtime.loadQuery(turduckenQuery).run();
|
|
709
|
+
expect(result.data.value[0]['state_count']).toBe(6);
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
// it(`sql_block version- ${databaseName}`, async () => {
|
|
713
|
+
// const result = await runtime
|
|
714
|
+
// .loadQuery(
|
|
715
|
+
// `
|
|
716
|
+
// sql: one is ||
|
|
717
|
+
// select version() as version
|
|
718
|
+
// ;;
|
|
719
|
+
// query: from_sql(one) -> { project: version }
|
|
720
|
+
// `
|
|
721
|
+
// )
|
|
722
|
+
// .run();
|
|
723
|
+
// expect(result.data.value[0].version).toBe("something");
|
|
724
|
+
// });
|
|
725
|
+
// local declarations
|
|
726
|
+
it(`local declarations external query - ${databaseName}`, async () => {
|
|
727
|
+
const result = await runtime
|
|
728
|
+
.loadQuery(`
|
|
729
|
+
${sql1234}
|
|
730
|
+
query: from_sql(one) -> {
|
|
731
|
+
declare: c is a + 1
|
|
732
|
+
project: c
|
|
733
|
+
}
|
|
734
|
+
`)
|
|
735
|
+
.run();
|
|
736
|
+
expect(result.data.value[0]['c']).toBe(2);
|
|
737
|
+
});
|
|
738
|
+
it(`local declarations named query - ${databaseName}`, async () => {
|
|
739
|
+
const result = await runtime
|
|
740
|
+
.loadQuery(`
|
|
741
|
+
${sql1234}
|
|
742
|
+
source: foo is from_sql(one) + {
|
|
743
|
+
query: bar is {
|
|
744
|
+
declare: c is a + 1
|
|
745
|
+
project: c
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
query: foo-> bar
|
|
750
|
+
`)
|
|
751
|
+
.run();
|
|
752
|
+
expect(result.data.value[0]['c']).toBe(2);
|
|
753
|
+
});
|
|
754
|
+
it(`local declarations refined named query - ${databaseName}`, async () => {
|
|
755
|
+
const result = await runtime
|
|
756
|
+
.loadQuery(`
|
|
757
|
+
${sql1234}
|
|
758
|
+
source: foo is from_sql(one) + {
|
|
759
|
+
query: bar is {
|
|
760
|
+
declare: c is a + 1
|
|
761
|
+
project: c
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
query: baz is bar + {
|
|
765
|
+
declare: d is c + 1
|
|
766
|
+
project: d
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
query: foo-> baz
|
|
771
|
+
`)
|
|
772
|
+
.run();
|
|
773
|
+
expect(result.data.value[0]['d']).toBe(3);
|
|
774
|
+
});
|
|
775
|
+
it(`regexp match- ${databaseName}`, async () => {
|
|
776
|
+
const result = await runtime
|
|
777
|
+
.loadQuery(`
|
|
778
|
+
sql: one is { select: """
|
|
779
|
+
SELECT 'hello mom' as a, 'cheese tastes good' as b
|
|
780
|
+
UNION ALL SELECT 'lloyd is a bozo', 'michael likes poetry'
|
|
781
|
+
"""}
|
|
782
|
+
|
|
783
|
+
query: from_sql(one) -> {
|
|
784
|
+
aggregate: llo is count() {? a ~ r'llo'}
|
|
785
|
+
aggregate: m2 is count() {? a !~ r'bozo'}
|
|
786
|
+
}
|
|
787
|
+
`)
|
|
788
|
+
.run();
|
|
789
|
+
expect(result.data.value[0]['llo']).toBe(2);
|
|
790
|
+
expect(result.data.value[0]['m2']).toBe(1);
|
|
791
|
+
});
|
|
792
|
+
it(`substitution precidence- ${databaseName}`, async () => {
|
|
793
|
+
const result = await runtime
|
|
794
|
+
.loadQuery(`
|
|
795
|
+
sql: one is {select: """
|
|
796
|
+
SELECT 5 as a, 2 as b
|
|
797
|
+
UNION ALL SELECT 3, 4
|
|
798
|
+
"""}
|
|
799
|
+
|
|
800
|
+
query: from_sql(one) -> {
|
|
801
|
+
declare: c is b + 4
|
|
802
|
+
project: x is a * c
|
|
803
|
+
}
|
|
804
|
+
`)
|
|
805
|
+
.run();
|
|
806
|
+
expect(result.data.value[0]['x']).toBe(30);
|
|
807
|
+
});
|
|
808
|
+
it(`array unnest - ${databaseName}`, async () => {
|
|
809
|
+
const result = await runtime
|
|
810
|
+
.loadQuery(`
|
|
811
|
+
sql: atitle is {select:"""
|
|
812
|
+
SELECT
|
|
813
|
+
city,
|
|
814
|
+
${getSplitFunction(databaseName)('city', ' ')} as words
|
|
815
|
+
FROM ${rootDbPath(databaseName)}malloytest.aircraft
|
|
816
|
+
"""}
|
|
817
|
+
|
|
818
|
+
source: title is from_sql(atitle){}
|
|
819
|
+
|
|
820
|
+
query: title -> {
|
|
821
|
+
where: words.value != null
|
|
822
|
+
group_by: words.value
|
|
823
|
+
aggregate: c is count()
|
|
824
|
+
}
|
|
825
|
+
`)
|
|
826
|
+
.run();
|
|
827
|
+
expect(result.data.value[0]['c']).toBe(145);
|
|
828
|
+
});
|
|
829
|
+
// make sure we can count the total number of elements when fanning out.
|
|
830
|
+
it(`array unnest x 2 - ${databaseName}`, async () => {
|
|
831
|
+
const result = await runtime
|
|
832
|
+
.loadQuery(`
|
|
833
|
+
sql: atitle is {select: """
|
|
834
|
+
SELECT
|
|
835
|
+
city,
|
|
836
|
+
${getSplitFunction(databaseName)('city', ' ')} as words,
|
|
837
|
+
${getSplitFunction(databaseName)('city', 'A')} as abreak
|
|
838
|
+
FROM ${rootDbPath(databaseName)}malloytest.aircraft
|
|
839
|
+
where city IS NOT null
|
|
840
|
+
"""}
|
|
841
|
+
|
|
842
|
+
source: title is from_sql(atitle){}
|
|
843
|
+
|
|
844
|
+
query: title -> {
|
|
845
|
+
aggregate:
|
|
846
|
+
b is count()
|
|
847
|
+
c is words.count()
|
|
848
|
+
a is abreak.count()
|
|
849
|
+
}
|
|
850
|
+
`)
|
|
851
|
+
.run();
|
|
852
|
+
expect(result.data.value[0]['b']).toBe(3552);
|
|
853
|
+
expect(result.data.value[0]['c']).toBe(4586);
|
|
854
|
+
expect(result.data.value[0]['a']).toBe(6601);
|
|
855
|
+
});
|
|
856
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`nest null - ${databaseName}`, async () => {
|
|
857
|
+
const result = await runtime
|
|
858
|
+
.loadQuery(`
|
|
859
|
+
query: table('malloytest.airports') -> {
|
|
860
|
+
where: faa_region = null
|
|
861
|
+
group_by: faa_region
|
|
862
|
+
aggregate: airport_count is count()
|
|
863
|
+
nest: by_state is {
|
|
864
|
+
where: state != null
|
|
865
|
+
group_by: state
|
|
866
|
+
aggregate: airport_count is count()
|
|
867
|
+
}
|
|
868
|
+
nest: by_state1 is {
|
|
869
|
+
where: state != null
|
|
870
|
+
group_by: state
|
|
871
|
+
aggregate: airport_count is count()
|
|
872
|
+
limit: 1
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
`)
|
|
876
|
+
.run();
|
|
877
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
878
|
+
const d = result.data.toObject();
|
|
879
|
+
expect(d[0]['by_state']).not.toBe(null);
|
|
880
|
+
expect(d[0]['by_state1']).not.toBe(null);
|
|
881
|
+
});
|
|
882
|
+
(0, util_1.testIf)(runtime.supportsNesting)(`number as null- ${databaseName}`, async () => {
|
|
883
|
+
const result = await runtime
|
|
884
|
+
.loadQuery(`
|
|
885
|
+
source: s is table('malloytest.state_facts') + {
|
|
886
|
+
}
|
|
887
|
+
query: s-> {
|
|
888
|
+
group_by: state
|
|
889
|
+
nest: ugly is {
|
|
890
|
+
group_by: popular_name
|
|
891
|
+
aggregate: foo is NULLIF(sum(airport_count)*0,0)+1
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
`)
|
|
895
|
+
.run();
|
|
896
|
+
expect(result.data.path(0, 'ugly', 0, 'foo').value).toBe(null);
|
|
897
|
+
});
|
|
898
|
+
describe('quoting and strings', () => {
|
|
899
|
+
const tick = "'";
|
|
900
|
+
const back = '\\';
|
|
901
|
+
test('backslash quote', async () => {
|
|
902
|
+
const result = await runtime
|
|
903
|
+
.loadQuery(`
|
|
904
|
+
query: table('malloytest.state_facts') -> {
|
|
905
|
+
project: tick is '${back}${tick}'
|
|
906
|
+
}
|
|
907
|
+
`)
|
|
908
|
+
.run();
|
|
909
|
+
expect(result.data.value[0]['tick']).toBe(tick);
|
|
910
|
+
});
|
|
911
|
+
test('backslash backslash', async () => {
|
|
912
|
+
const result = await runtime
|
|
913
|
+
.loadQuery(`
|
|
914
|
+
query: table('malloytest.state_facts') -> {
|
|
915
|
+
project: back is '${back}${back}'
|
|
916
|
+
}
|
|
917
|
+
`)
|
|
918
|
+
.run();
|
|
919
|
+
expect(result.data.value[0]['back']).toBe(back);
|
|
920
|
+
});
|
|
921
|
+
(0, util_1.testIf)(runtime.supportsNesting)('spaces in names', async () => {
|
|
922
|
+
const result = await runtime
|
|
923
|
+
.loadQuery(`
|
|
924
|
+
source: \`space race\` is table('malloytest.state_facts') {
|
|
925
|
+
join_one: \`j space\` is table('malloytest.state_facts') on \`j space\`.state=state
|
|
926
|
+
query: \`q u e r y\` is {
|
|
927
|
+
group_by:
|
|
928
|
+
\`P O P\` is popular_name
|
|
929
|
+
\`J P O P\` is \`j space\`.popular_name
|
|
930
|
+
aggregate: \`c o u n t\` is count()
|
|
931
|
+
calculate:
|
|
932
|
+
\`R O W\` is row_number()
|
|
933
|
+
\`l a g\` is lag(\`P O P\`, 1)
|
|
934
|
+
nest: \`by state\` is {
|
|
935
|
+
group_by: \`J S\` is \`j space\`.state
|
|
936
|
+
aggregate: \`c o u n t\` is count()
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
query: \`space race\` -> \`q u e r y\`
|
|
942
|
+
`)
|
|
943
|
+
.run();
|
|
944
|
+
expect(result.data.value[0]['c o u n t']).toBe(24);
|
|
945
|
+
});
|
|
946
|
+
});
|
|
947
|
+
});
|
|
948
|
+
};
|
|
949
|
+
exports.noModelSharedTests = noModelSharedTests;
|
|
950
|
+
//# sourceMappingURL=nomodel.js.map
|