@malloydata/malloy-tests 0.0.149-dev240706223116 → 0.0.150-dev240714131913
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/package.json +8 -8
- package/src/databases/all/db_index.spec.ts +8 -7
- package/src/databases/all/functions.spec.ts +35 -31
- package/src/databases/all/join.spec.ts +5 -6
- package/src/databases/all/nomodel.spec.ts +40 -13
- package/src/databases/all/time.spec.ts +62 -66
- package/src/runtimes.ts +9 -1
- package/trino/trino_start.sh +3 -3
package/package.json
CHANGED
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@jest/globals": "^29.4.3",
|
|
24
|
-
"@malloydata/db-bigquery": "^0.0.
|
|
25
|
-
"@malloydata/db-duckdb": "^0.0.
|
|
26
|
-
"@malloydata/db-postgres": "^0.0.
|
|
27
|
-
"@malloydata/db-snowflake": "^0.0.
|
|
28
|
-
"@malloydata/db-trino": "^0.0.
|
|
29
|
-
"@malloydata/malloy": "^0.0.
|
|
30
|
-
"@malloydata/render": "^0.0.
|
|
24
|
+
"@malloydata/db-bigquery": "^0.0.150-dev240714131913",
|
|
25
|
+
"@malloydata/db-duckdb": "^0.0.150-dev240714131913",
|
|
26
|
+
"@malloydata/db-postgres": "^0.0.150-dev240714131913",
|
|
27
|
+
"@malloydata/db-snowflake": "^0.0.150-dev240714131913",
|
|
28
|
+
"@malloydata/db-trino": "^0.0.150-dev240714131913",
|
|
29
|
+
"@malloydata/malloy": "^0.0.150-dev240714131913",
|
|
30
|
+
"@malloydata/render": "^0.0.150-dev240714131913",
|
|
31
31
|
"jsdom": "^22.1.0",
|
|
32
32
|
"luxon": "^2.4.0",
|
|
33
33
|
"madge": "^6.0.0"
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"@types/jsdom": "^21.1.1",
|
|
37
37
|
"@types/luxon": "^2.4.0"
|
|
38
38
|
},
|
|
39
|
-
"version": "0.0.
|
|
39
|
+
"version": "0.0.150-dev240714131913"
|
|
40
40
|
}
|
|
@@ -97,19 +97,20 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
97
97
|
});
|
|
98
98
|
|
|
99
99
|
// bigquery doesn't support row count based sampling.
|
|
100
|
-
test.when(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
test.when(
|
|
101
|
+
databaseName !== 'bigquery' &&
|
|
102
|
+
databaseName !== 'trino' &&
|
|
103
|
+
databaseName !== 'presto'
|
|
104
|
+
)(`index rows count - ${databaseName}`, async () => {
|
|
105
|
+
await expect(`
|
|
104
106
|
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
105
107
|
dimension: one is 'one'
|
|
106
108
|
} -> {index:one, state; sample: 10 }
|
|
107
109
|
-> {select: fieldName, weight, fieldValue; order_by: 2 desc; where: fieldName = 'one'}
|
|
108
110
|
`).malloyResultMatches(runtime, {fieldName: 'one', weight: 10});
|
|
109
|
-
|
|
110
|
-
);
|
|
111
|
+
});
|
|
111
112
|
|
|
112
|
-
it.when(databaseName !== 'trino')(
|
|
113
|
+
it.when(databaseName !== 'trino' && databaseName !== 'presto')(
|
|
113
114
|
`index rows count - ${databaseName}`,
|
|
114
115
|
async () => {
|
|
115
116
|
await expect(`
|
|
@@ -112,32 +112,32 @@ expressionModels.forEach((expressionModel, databaseName) => {
|
|
|
112
112
|
};
|
|
113
113
|
|
|
114
114
|
describe('concat', () => {
|
|
115
|
-
it.when(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
],
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
);
|
|
115
|
+
it.when(
|
|
116
|
+
!brokenIn('trino', databaseName) &&
|
|
117
|
+
!brokenIn('presto', databaseName) /* crswenson */
|
|
118
|
+
)(`works - ${databaseName}`, async () => {
|
|
119
|
+
const expected = {
|
|
120
|
+
'bigquery': 'foo2003-01-01 12:00:00+00',
|
|
121
|
+
'snowflake': 'foo2003-01-01T12:00:00.000Z',
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
await funcTestMultiple(
|
|
125
|
+
["concat('foo', 'bar')", 'foobar'],
|
|
126
|
+
["concat(1, 'bar')", '1bar'],
|
|
127
|
+
[
|
|
128
|
+
"concat('cons', true)",
|
|
129
|
+
databaseName === 'postgres' ? 'const' : 'construe',
|
|
130
|
+
],
|
|
131
|
+
["concat('foo', @2003)", 'foo2003-01-01'],
|
|
132
|
+
[
|
|
133
|
+
"concat('foo', @2003-01-01 12:00:00)",
|
|
134
|
+
expected[databaseName] ?? 'foo2003-01-01 12:00:00',
|
|
135
|
+
],
|
|
136
|
+
// TODO Maybe implement consistent null behavior
|
|
137
|
+
// ["concat('foo', null)", null],
|
|
138
|
+
['concat()', '']
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
141
|
});
|
|
142
142
|
|
|
143
143
|
describe('round', () => {
|
|
@@ -219,13 +219,15 @@ expressionModels.forEach((expressionModel, databaseName) => {
|
|
|
219
219
|
"replace('axbxc', r'(a).(b).(c)', '\\\\0 - \\\\1 - \\\\2 - \\\\3')",
|
|
220
220
|
databaseName === 'postgres'
|
|
221
221
|
? '\\0 - a - b - c'
|
|
222
|
-
: databaseName === 'trino'
|
|
222
|
+
: databaseName === 'trino' || databaseName === 'presto'
|
|
223
223
|
? '0 - 1 - 2 - 3'
|
|
224
224
|
: 'axbxc - a - b - c',
|
|
225
225
|
],
|
|
226
226
|
[
|
|
227
227
|
"replace('aaaa', '', 'c')",
|
|
228
|
-
databaseName === 'trino'
|
|
228
|
+
databaseName === 'trino' || databaseName === 'presto'
|
|
229
|
+
? 'cacacacac'
|
|
230
|
+
: 'aaaa',
|
|
229
231
|
],
|
|
230
232
|
["replace(null, 'a', 'c')", null],
|
|
231
233
|
["replace('aaaa', null, 'c')", null],
|
|
@@ -262,7 +264,8 @@ expressionModels.forEach((expressionModel, databaseName) => {
|
|
|
262
264
|
|
|
263
265
|
describe('stddev', () => {
|
|
264
266
|
// TODO symmetric aggregates don't work with custom aggregate functions in BQ currently
|
|
265
|
-
if (['bigquery', 'snowflake', 'trino'].includes(databaseName))
|
|
267
|
+
if (['bigquery', 'snowflake', 'trino', 'presto'].includes(databaseName))
|
|
268
|
+
return;
|
|
266
269
|
it(`works - ${databaseName}`, async () => {
|
|
267
270
|
await funcTestAgg('round(stddev(aircraft_models.seats))', 29);
|
|
268
271
|
});
|
|
@@ -786,7 +789,7 @@ expressionModels.forEach((expressionModel, databaseName) => {
|
|
|
786
789
|
});
|
|
787
790
|
});
|
|
788
791
|
describe('is_inf', () => {
|
|
789
|
-
const inf = ['trino'].includes(databaseName)
|
|
792
|
+
const inf = ['trino', 'presto'].includes(databaseName)
|
|
790
793
|
? 'infinity!()'
|
|
791
794
|
: "'+inf'::number";
|
|
792
795
|
it(`works - ${databaseName}`, async () => {
|
|
@@ -1327,7 +1330,8 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
|
|
|
1327
1330
|
|
|
1328
1331
|
it(`works with fanout and order_by - ${databaseName}`, async () => {
|
|
1329
1332
|
// TODO bigquery cannot handle both fanout and order_by today
|
|
1330
|
-
if (['bigquery', 'snowflake', 'trino'].includes(databaseName))
|
|
1333
|
+
if (['bigquery', 'snowflake', 'trino', 'presto'].includes(databaseName))
|
|
1334
|
+
return;
|
|
1331
1335
|
await expect(`##! experimental.aggregate_order_by
|
|
1332
1336
|
run: state_facts extend { join_many:
|
|
1333
1337
|
state_facts2 is ${databaseName}.table('malloytest.state_facts')
|
|
@@ -194,10 +194,10 @@ describe('join expression tests', () => {
|
|
|
194
194
|
`).malloyResultMatches(joinModel, {f_sum2: 60462});
|
|
195
195
|
});
|
|
196
196
|
|
|
197
|
-
test.when(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
197
|
+
test.when(
|
|
198
|
+
runtime.supportsNesting && runtime.dialect.supportsLeftJoinUnnest
|
|
199
|
+
)(`model: unnest is left join - ${database}`, async () => {
|
|
200
|
+
await expect(`
|
|
201
201
|
// produce a table with 4 rows that has a nested element
|
|
202
202
|
query: a_states is ${database}.table('malloytest.state_facts')-> {
|
|
203
203
|
where: state ? ~ 'A%'
|
|
@@ -220,8 +220,7 @@ describe('join expression tests', () => {
|
|
|
220
220
|
limit: 5
|
|
221
221
|
}
|
|
222
222
|
`).malloyResultMatches(joinModel, [{}, {}, {}, {}, {}]);
|
|
223
|
-
|
|
224
|
-
);
|
|
223
|
+
});
|
|
225
224
|
|
|
226
225
|
// not sure how to solve this one yet, just check for > 4 rows
|
|
227
226
|
it(`All joins at the same level - ${database}`, async () => {
|
|
@@ -52,6 +52,8 @@ function getSplitFunction(db: string) {
|
|
|
52
52
|
`split(${column}, '${splitChar}')`,
|
|
53
53
|
'trino': (column: string, splitChar: string) =>
|
|
54
54
|
`split(${column}, '${splitChar}')`,
|
|
55
|
+
'presto': (column: string, splitChar: string) =>
|
|
56
|
+
`split(${column}, '${splitChar}')`,
|
|
55
57
|
}[db];
|
|
56
58
|
}
|
|
57
59
|
|
|
@@ -480,11 +482,13 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
480
482
|
expect(q.sql.toLowerCase()).not.toContain('distinct');
|
|
481
483
|
});
|
|
482
484
|
|
|
483
|
-
it(
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
485
|
+
it.when(runtime.dialect.supportsLeftJoinUnnest)(
|
|
486
|
+
`leafy nested count - ${databaseName}`,
|
|
487
|
+
async () => {
|
|
488
|
+
// in a joined table when the joined is leafiest
|
|
489
|
+
// we need to make sure we don't count rows that
|
|
490
|
+
// don't match the join.
|
|
491
|
+
await expect(`
|
|
488
492
|
source: am_states is ${databaseName}.table('malloytest.state_facts') -> {
|
|
489
493
|
group_by: state,popular_name
|
|
490
494
|
where: state ~ r'^(A|M)'
|
|
@@ -496,7 +500,6 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
496
500
|
source: states is ${databaseName}.table('malloytest.state_facts') extend {
|
|
497
501
|
join_many: am_states on state=am_states.state
|
|
498
502
|
}
|
|
499
|
-
|
|
500
503
|
run: states -> {
|
|
501
504
|
where: state = 'CA'
|
|
502
505
|
group_by:
|
|
@@ -507,12 +510,13 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
507
510
|
root_count is count()
|
|
508
511
|
}
|
|
509
512
|
`).malloyResultMatches(runtime, {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
513
|
+
leafy_count: 0,
|
|
514
|
+
root_count: 1,
|
|
515
|
+
state: 'CA',
|
|
516
|
+
am_state: null,
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
);
|
|
516
520
|
|
|
517
521
|
it(`basic index - ${databaseName}`, async () => {
|
|
518
522
|
// Make sure basic indexing works.
|
|
@@ -548,6 +552,16 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
548
552
|
}
|
|
549
553
|
);
|
|
550
554
|
|
|
555
|
+
it(`sql block- ${databaseName}`, async () => {
|
|
556
|
+
await expect(`
|
|
557
|
+
source: one is ${databaseName}.sql("""
|
|
558
|
+
SELECT 2 as ${q`a`}
|
|
559
|
+
""")
|
|
560
|
+
run: one -> {
|
|
561
|
+
select: a
|
|
562
|
+
}`).malloyResultMatches(runtime, {a: 2});
|
|
563
|
+
});
|
|
564
|
+
|
|
551
565
|
// average should only include non-null values in the denominator
|
|
552
566
|
it(`avg ignore null- ${databaseName}`, async () => {
|
|
553
567
|
await expect(`
|
|
@@ -628,6 +642,7 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
628
642
|
'ungrouped nested with no grouping above - ${databaseName}',
|
|
629
643
|
async () => {
|
|
630
644
|
await expect(`
|
|
645
|
+
// # test.debug
|
|
631
646
|
run: ${databaseName}.table('malloytest.state_facts') extend {
|
|
632
647
|
measure: total_births is births.sum()
|
|
633
648
|
measure: births_per_100k is floor(total_births/ all(total_births) * 100000)
|
|
@@ -1041,11 +1056,23 @@ SELECT row_to_json(finalStage) as row FROM __stage0 AS finalStage`);
|
|
|
1041
1056
|
);
|
|
1042
1057
|
|
|
1043
1058
|
test.when(runtime.supportsNesting && runtime.dialect.readsNestedData)(
|
|
1044
|
-
`can unnest from file - ${databaseName}`,
|
|
1059
|
+
`can unnest simply from file - ${databaseName}`,
|
|
1045
1060
|
async () => {
|
|
1046
1061
|
await expect(`
|
|
1047
1062
|
source: ga_sample is ${databaseName}.table('malloytest.ga_sample')
|
|
1063
|
+
run: ga_sample -> {
|
|
1064
|
+
aggregate:
|
|
1065
|
+
h is hits.count()
|
|
1066
|
+
}
|
|
1067
|
+
`).malloyResultMatches(runtime, {h: 13233});
|
|
1068
|
+
}
|
|
1069
|
+
);
|
|
1048
1070
|
|
|
1071
|
+
test.when(runtime.supportsNesting && runtime.dialect.readsNestedData)(
|
|
1072
|
+
`can unnest from file - ${databaseName}`,
|
|
1073
|
+
async () => {
|
|
1074
|
+
await expect(`
|
|
1075
|
+
source: ga_sample is ${databaseName}.table('malloytest.ga_sample')
|
|
1049
1076
|
run: ga_sample -> {
|
|
1050
1077
|
where: hits.product.productBrand != null
|
|
1051
1078
|
group_by:
|
|
@@ -462,18 +462,17 @@ describe.each(runtimes.runtimeList)('%s date and time', (dbName, runtime) => {
|
|
|
462
462
|
});
|
|
463
463
|
});
|
|
464
464
|
|
|
465
|
-
test.when(
|
|
466
|
-
'
|
|
467
|
-
|
|
468
|
-
|
|
465
|
+
test.when(
|
|
466
|
+
!brokenIn('trino', dbName) && !brokenIn('presto', dbName) /* mtoy */
|
|
467
|
+
)('dependant join dialect fragments', async () => {
|
|
468
|
+
await expect(`
|
|
469
469
|
source: timeData is ${dbName}.sql("""${timeSQL}""")
|
|
470
470
|
run: timeData -> {
|
|
471
471
|
extend: {join_one: joined is timeData on t_date = joined.t_date}
|
|
472
472
|
group_by: t_month is joined.t_timestamp.month
|
|
473
473
|
}
|
|
474
474
|
`).malloyResultMatches(runtime, {t_month: new Date('2021-02-01')});
|
|
475
|
-
|
|
476
|
-
);
|
|
475
|
+
});
|
|
477
476
|
|
|
478
477
|
describe('timezone set correctly', () => {
|
|
479
478
|
test('timezone set in source used by query', async () => {
|
|
@@ -621,63 +620,60 @@ const utc_2020 = LuxonDateTime.fromObject(
|
|
|
621
620
|
);
|
|
622
621
|
|
|
623
622
|
describe.each(runtimes.runtimeList)('%s: tz literals', (dbName, runtime) => {
|
|
624
|
-
test.when(
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
623
|
+
test.when(
|
|
624
|
+
!brokenIn('trino', dbName) && !brokenIn('presto', dbName) /* mtoy */
|
|
625
|
+
)(`${dbName} - default timezone is UTC`, async () => {
|
|
626
|
+
// this makes sure that the tests which use the test timezome are actually
|
|
627
|
+
// testing something ... file this under "abundance of caution". It
|
|
628
|
+
// really tests nothing, but I feel calmer with this here.
|
|
629
|
+
const query = runtime.loadQuery(
|
|
630
|
+
`
|
|
632
631
|
run: ${dbName}.sql("SELECT 1 as one") -> {
|
|
633
632
|
group_by: literal_time is @2020-02-20 00:00:00
|
|
634
633
|
}
|
|
635
634
|
`
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
`
|
|
635
|
+
);
|
|
636
|
+
const result = await query.run();
|
|
637
|
+
const literal = result.data.path(0, 'literal_time').value as Date;
|
|
638
|
+
const have = LuxonDateTime.fromJSDate(literal);
|
|
639
|
+
expect(have.valueOf()).toEqual(utc_2020.valueOf());
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
test.when(
|
|
643
|
+
!brokenIn('trino', dbName) && !brokenIn('presto', dbName) /* mtoy */
|
|
644
|
+
)('literal with zone name', async () => {
|
|
645
|
+
const query = runtime.loadQuery(
|
|
646
|
+
`
|
|
649
647
|
run: ${dbName}.sql("SELECT 1 as one") -> {
|
|
650
648
|
group_by: literal_time is @2020-02-20 00:00:00[America/Mexico_City]
|
|
651
649
|
}
|
|
652
650
|
`
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
);
|
|
651
|
+
);
|
|
652
|
+
const result = await query.run();
|
|
653
|
+
const literal = result.data.path(0, 'literal_time').value as Date;
|
|
654
|
+
const have = LuxonDateTime.fromJSDate(literal);
|
|
655
|
+
expect(have.valueOf()).toEqual(zone_2020.valueOf());
|
|
656
|
+
});
|
|
660
657
|
});
|
|
661
658
|
|
|
662
659
|
describe.each(runtimes.runtimeList)('%s: query tz', (dbName, runtime) => {
|
|
663
660
|
const q = runtime.getQuoter();
|
|
664
|
-
test.when(
|
|
665
|
-
'
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
661
|
+
test.when(
|
|
662
|
+
!brokenIn('trino', dbName) && !brokenIn('presto', dbName) /* mtoy */
|
|
663
|
+
)('literal timestamps', async () => {
|
|
664
|
+
const query = runtime.loadQuery(
|
|
665
|
+
`
|
|
669
666
|
run: ${dbName}.sql("SELECT 1 as one") -> {
|
|
670
667
|
timezone: '${zone}'
|
|
671
668
|
group_by: literal_time is @2020-02-20 00:00:00
|
|
672
669
|
}
|
|
673
670
|
`
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
);
|
|
671
|
+
);
|
|
672
|
+
const result = await query.run();
|
|
673
|
+
const literal = result.data.path(0, 'literal_time').value as Date;
|
|
674
|
+
const have = LuxonDateTime.fromJSDate(literal);
|
|
675
|
+
expect(have.valueOf()).toEqual(zone_2020.valueOf());
|
|
676
|
+
});
|
|
681
677
|
|
|
682
678
|
test('extract', async () => {
|
|
683
679
|
await expect(
|
|
@@ -691,7 +687,9 @@ describe.each(runtimes.runtimeList)('%s: query tz', (dbName, runtime) => {
|
|
|
691
687
|
).malloyResultMatches(runtime, {mex_midnight: 18, mex_day: 19});
|
|
692
688
|
});
|
|
693
689
|
|
|
694
|
-
test.when(
|
|
690
|
+
test.when(
|
|
691
|
+
!brokenIn('trino', dbName) && !brokenIn('presto', dbName) /* mtoy */
|
|
692
|
+
)('truncate day', async () => {
|
|
695
693
|
// At midnight in london it the 19th in Mexico, so that truncates to
|
|
696
694
|
// midnight on the 19th
|
|
697
695
|
const mex_19 = LuxonDateTime.fromISO('2020-02-19T00:00:00', {zone});
|
|
@@ -704,32 +702,30 @@ describe.each(runtimes.runtimeList)('%s: query tz', (dbName, runtime) => {
|
|
|
704
702
|
).malloyResultMatches(runtime, {mex_day: mex_19.toJSDate()});
|
|
705
703
|
});
|
|
706
704
|
|
|
707
|
-
test.when(
|
|
708
|
-
'
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
705
|
+
test.when(
|
|
706
|
+
!brokenIn('trino', dbName) && !brokenIn('presto', dbName) /* mtoy */
|
|
707
|
+
)('cast timestamp to date', async () => {
|
|
708
|
+
// At midnight in london it is the 19th in Mexico, so when we cast that
|
|
709
|
+
// to a date, it should be the 19th.
|
|
710
|
+
await expect(
|
|
711
|
+
`run: ${dbName}.sql("SELECT 1 as x") -> {
|
|
714
712
|
timezone: '${zone}'
|
|
715
713
|
extend: { dimension: utc_midnight is @2020-02-20 00:00:00[UTC] }
|
|
716
714
|
select: mex_day is day(utc_midnight::date)
|
|
717
715
|
}`
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
`run: ${dbName}.sql(""" SELECT DATE '2020-02-20' AS ${q`mex_20`} """) -> {
|
|
716
|
+
).malloyResultMatches(runtime, {mex_day: 19});
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
test.when(
|
|
720
|
+
!brokenIn('trino', dbName) && !brokenIn('presto', dbName) /* mtoy */
|
|
721
|
+
)('cast date to timestamp', async () => {
|
|
722
|
+
await expect(
|
|
723
|
+
`run: ${dbName}.sql(""" SELECT DATE '2020-02-20' AS ${q`mex_20`} """) -> {
|
|
727
724
|
timezone: '${zone}'
|
|
728
725
|
select: mex_ts is mex_20::timestamp
|
|
729
726
|
}`
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
);
|
|
727
|
+
).malloyResultMatches(runtime, {mex_ts: zone_2020.toJSDate()});
|
|
728
|
+
});
|
|
733
729
|
});
|
|
734
730
|
|
|
735
731
|
afterAll(async () => {
|
package/src/runtimes.ts
CHANGED
|
@@ -37,6 +37,7 @@ import {SnowflakeConnection} from '@malloydata/db-snowflake';
|
|
|
37
37
|
import {PooledPostgresConnection} from '@malloydata/db-postgres';
|
|
38
38
|
import {TrinoConnection, TrinoExecutor} from '@malloydata/db-trino';
|
|
39
39
|
import {SnowflakeExecutor} from '@malloydata/db-snowflake/src/snowflake_executor';
|
|
40
|
+
import {PrestoConnection} from '@malloydata/db-trino/src/trino_connection';
|
|
40
41
|
|
|
41
42
|
export class SnowflakeTestConnection extends SnowflakeConnection {
|
|
42
43
|
public async runSQL(
|
|
@@ -166,7 +167,14 @@ export function runtimeFor(dbName: string): SingleConnectionRuntime {
|
|
|
166
167
|
connection = new TrinoConnection(
|
|
167
168
|
dbName,
|
|
168
169
|
{},
|
|
169
|
-
TrinoExecutor.getConnectionOptionsFromEnv()
|
|
170
|
+
TrinoExecutor.getConnectionOptionsFromEnv(dbName)
|
|
171
|
+
);
|
|
172
|
+
break;
|
|
173
|
+
case 'presto':
|
|
174
|
+
connection = new PrestoConnection(
|
|
175
|
+
dbName,
|
|
176
|
+
{},
|
|
177
|
+
TrinoExecutor.getConnectionOptionsFromEnv(dbName) // they share configs.
|
|
170
178
|
);
|
|
171
179
|
break;
|
|
172
180
|
default:
|
package/trino/trino_start.sh
CHANGED
|
@@ -12,7 +12,7 @@ bigquery.arrow-serialization.enabled=false
|
|
|
12
12
|
EOF
|
|
13
13
|
|
|
14
14
|
# run docker
|
|
15
|
-
docker run -p
|
|
15
|
+
docker run -p 8080:8080 -d -v ./.tmp/bigquery.properties:/etc/trino/catalog/bigquery.properties --name trino-malloy trinodb/trino
|
|
16
16
|
|
|
17
17
|
# wait for server to start
|
|
18
18
|
counter=0
|
|
@@ -21,7 +21,7 @@ do
|
|
|
21
21
|
sleep 1
|
|
22
22
|
counter=$((counter+1))
|
|
23
23
|
# if doesn't start after 2 minutes, output logs and kill process
|
|
24
|
-
if [ $counter -eq
|
|
24
|
+
if [ $counter -eq 300 ]
|
|
25
25
|
then
|
|
26
26
|
docker logs trino-malloy >& ./.tmp/trino-malloy.logs
|
|
27
27
|
docker rm -f trino-malloy
|
|
@@ -31,4 +31,4 @@ do
|
|
|
31
31
|
fi
|
|
32
32
|
done
|
|
33
33
|
|
|
34
|
-
echo "Trino running on port localhost:
|
|
34
|
+
echo "Trino running on port localhost:8080"
|