@malloydata/malloy-tests 0.0.225-dev250113200903 → 0.0.225
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/composite_sources.spec.ts +1 -1
- package/src/databases/all/expr.spec.ts +54 -2
- package/src/databases/all/functions.spec.ts +2 -2
- package/src/databases/all/nomodel.spec.ts +6 -23
- package/src/databases/all/parameters.spec.ts +1 -1
- package/src/databases/bigquery/malloy_query.spec.ts +2 -2
- package/src/databases/bigquery/nested_source_table.spec.ts +1 -1
- package/src/databases/duckdb/nested_source_table.spec.ts +1 -1
- package/src/databases/duckdb/streaming.spec.ts +2 -2
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.225
|
|
25
|
-
"@malloydata/db-duckdb": "^0.0.225
|
|
26
|
-
"@malloydata/db-postgres": "^0.0.225
|
|
27
|
-
"@malloydata/db-snowflake": "^0.0.225
|
|
28
|
-
"@malloydata/db-trino": "^0.0.225
|
|
29
|
-
"@malloydata/malloy": "^0.0.225
|
|
30
|
-
"@malloydata/render": "^0.0.225
|
|
24
|
+
"@malloydata/db-bigquery": "^0.0.225",
|
|
25
|
+
"@malloydata/db-duckdb": "^0.0.225",
|
|
26
|
+
"@malloydata/db-postgres": "^0.0.225",
|
|
27
|
+
"@malloydata/db-snowflake": "^0.0.225",
|
|
28
|
+
"@malloydata/db-trino": "^0.0.225",
|
|
29
|
+
"@malloydata/malloy": "^0.0.225",
|
|
30
|
+
"@malloydata/render": "^0.0.225",
|
|
31
31
|
"events": "^3.3.0",
|
|
32
32
|
"jsdom": "^22.1.0",
|
|
33
33
|
"luxon": "^2.4.0",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"@types/jsdom": "^21.1.1",
|
|
38
38
|
"@types/luxon": "^2.4.0"
|
|
39
39
|
},
|
|
40
|
-
"version": "0.0.225
|
|
40
|
+
"version": "0.0.225"
|
|
41
41
|
}
|
|
@@ -397,7 +397,7 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
|
|
|
397
397
|
run: compose(
|
|
398
398
|
state_facts extend { dimension: bar is 1 },
|
|
399
399
|
state_facts
|
|
400
|
-
) -> { index: bar } -> { group_by: fieldName; where: fieldName
|
|
400
|
+
) -> { index: bar } -> { group_by: fieldName; where: fieldName is not null }
|
|
401
401
|
`).malloyResultMatches(runtime, {fieldName: 'bar'});
|
|
402
402
|
});
|
|
403
403
|
});
|
|
@@ -234,7 +234,7 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
|
|
|
234
234
|
run: aircraft->{
|
|
235
235
|
top: 10
|
|
236
236
|
order_by: 1
|
|
237
|
-
where: region
|
|
237
|
+
where: region is not null
|
|
238
238
|
group_by: region
|
|
239
239
|
nest: by_state is {
|
|
240
240
|
top: 10
|
|
@@ -823,7 +823,7 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
|
|
|
823
823
|
SELECT '' as ${q`null_value`}, '' as ${q`string_value`}
|
|
824
824
|
UNION ALL SELECT null, 'correct'
|
|
825
825
|
""") -> {
|
|
826
|
-
where: null_value
|
|
826
|
+
where: null_value is null
|
|
827
827
|
select:
|
|
828
828
|
found_null is null_value ?? 'correct',
|
|
829
829
|
else_pass is string_value ?? 'incorrect'
|
|
@@ -836,6 +836,58 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
|
|
|
836
836
|
});
|
|
837
837
|
});
|
|
838
838
|
|
|
839
|
+
describe('null safe booleans', () => {
|
|
840
|
+
const nulls = `${databaseName}.sql("""
|
|
841
|
+
SELECT
|
|
842
|
+
0 as ${q`n`},
|
|
843
|
+
1 as ${q`x`}, 2 as ${q`y`},
|
|
844
|
+
'a' as ${q`a`}, 'b' as ${q`b`},
|
|
845
|
+
(1 = 1) as ${q`tf`}
|
|
846
|
+
UNION ALL SELECT
|
|
847
|
+
5,
|
|
848
|
+
null, null, null, null, null
|
|
849
|
+
""") extend { where: n > 0 }`;
|
|
850
|
+
const is_true = databaseName === 'mysql' ? 1 : true;
|
|
851
|
+
|
|
852
|
+
it('select boolean', async () => {
|
|
853
|
+
await expect(`run: ${nulls} -> {
|
|
854
|
+
select:
|
|
855
|
+
null_boolean is tf
|
|
856
|
+
}`).malloyResultMatches(runtime, {null_boolean: null});
|
|
857
|
+
});
|
|
858
|
+
it('not boolean', async () => {
|
|
859
|
+
await expect(`run: ${nulls} -> {
|
|
860
|
+
select:
|
|
861
|
+
not_null_boolean is not tf
|
|
862
|
+
}`).malloyResultMatches(runtime, {not_null_boolean: is_true});
|
|
863
|
+
});
|
|
864
|
+
it('numeric != non-null to null', async () => {
|
|
865
|
+
await expect(
|
|
866
|
+
`run: ${nulls} -> { select: val_ne_null is x != 9 }`
|
|
867
|
+
).malloyResultMatches(runtime, {val_ne_null: is_true});
|
|
868
|
+
});
|
|
869
|
+
it('string !~ non-null to null', async () => {
|
|
870
|
+
await expect(
|
|
871
|
+
`run: ${nulls} -> { select: val_ne_null is a !~ 'z' }`
|
|
872
|
+
).malloyResultMatches(runtime, {val_ne_null: is_true});
|
|
873
|
+
});
|
|
874
|
+
it('regex !~ non-null to null', async () => {
|
|
875
|
+
await expect(
|
|
876
|
+
`run: ${nulls} -> { select: val_ne_null is a !~ r'z' }`
|
|
877
|
+
).malloyResultMatches(runtime, {val_ne_null: is_true});
|
|
878
|
+
});
|
|
879
|
+
it('numeric != null-to-null', async () => {
|
|
880
|
+
await expect(
|
|
881
|
+
`run: ${nulls} -> { select: null_ne_null is x != y }`
|
|
882
|
+
).malloyResultMatches(runtime, {null_ne_null: is_true});
|
|
883
|
+
});
|
|
884
|
+
it('string !~ null-to-null', async () => {
|
|
885
|
+
await expect(
|
|
886
|
+
`run: ${nulls} -> { select: null_ne_null is a !~ b }`
|
|
887
|
+
).malloyResultMatches(runtime, {null_ne_null: is_true});
|
|
888
|
+
});
|
|
889
|
+
});
|
|
890
|
+
|
|
839
891
|
test('dimension expressions expanded with parens properly', async () => {
|
|
840
892
|
await expect(
|
|
841
893
|
`run: ${databaseName}.sql("SELECT 1 as one") extend {
|
|
@@ -642,7 +642,7 @@ expressionModels.forEach((x, databaseName) => {
|
|
|
642
642
|
`
|
|
643
643
|
run: aircraft -> {
|
|
644
644
|
group_by: state
|
|
645
|
-
where: state
|
|
645
|
+
where: state is not null
|
|
646
646
|
nest: by_county is {
|
|
647
647
|
limit: 2
|
|
648
648
|
group_by: county
|
|
@@ -680,7 +680,7 @@ expressionModels.forEach((x, databaseName) => {
|
|
|
680
680
|
`
|
|
681
681
|
run: airports extend { measure: airport_count is count() } -> {
|
|
682
682
|
group_by: state
|
|
683
|
-
where: state
|
|
683
|
+
where: state is not null
|
|
684
684
|
calculate: prev_airport_count is lag(airport_count)
|
|
685
685
|
}`
|
|
686
686
|
)
|
|
@@ -63,23 +63,6 @@ afterAll(async () => {
|
|
|
63
63
|
|
|
64
64
|
runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
65
65
|
const q = runtime.getQuoter();
|
|
66
|
-
// Issue #1824
|
|
67
|
-
it.when(runtime.dialect.nativeBoolean)(
|
|
68
|
-
`not boolean field with null - ${databaseName}`,
|
|
69
|
-
async () => {
|
|
70
|
-
await expect(`
|
|
71
|
-
run: ${databaseName}.sql("""
|
|
72
|
-
SELECT
|
|
73
|
-
CASE WHEN 1=1 THEN NULL ELSE false END as ${q`n`}
|
|
74
|
-
""") -> {
|
|
75
|
-
select:
|
|
76
|
-
is_true is not n
|
|
77
|
-
}
|
|
78
|
-
`).malloyResultMatches(runtime, {
|
|
79
|
-
is_true: true,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
);
|
|
83
66
|
|
|
84
67
|
// Issue: #1284
|
|
85
68
|
it(`parenthesize output field values - ${databaseName}`, async () => {
|
|
@@ -99,7 +82,7 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
99
82
|
it(`bug 151 which used to throw unknown dialect is still fixed- ${databaseName}`, async () => {
|
|
100
83
|
await expect(`
|
|
101
84
|
query: q is ${databaseName}.table('malloytest.aircraft')->{
|
|
102
|
-
where: state
|
|
85
|
+
where: state is not null
|
|
103
86
|
group_by: state
|
|
104
87
|
}
|
|
105
88
|
run: q extend {
|
|
@@ -1052,7 +1035,7 @@ SELECT row_to_json(finalStage) as row FROM __stage0 AS finalStage`);
|
|
|
1052
1035
|
${splitFN!(q`city`, ' ')} as ${q`words`}
|
|
1053
1036
|
FROM ${rootDbPath(databaseName)}malloytest.aircraft
|
|
1054
1037
|
""") -> {
|
|
1055
|
-
where: words.value
|
|
1038
|
+
where: words.value is not null
|
|
1056
1039
|
group_by: words.value
|
|
1057
1040
|
aggregate: c is count()
|
|
1058
1041
|
}
|
|
@@ -1106,7 +1089,7 @@ SELECT row_to_json(finalStage) as row FROM __stage0 AS finalStage`);
|
|
|
1106
1089
|
await expect(`
|
|
1107
1090
|
source: ga_sample is ${databaseName}.table('malloytest.ga_sample')
|
|
1108
1091
|
run: ga_sample -> {
|
|
1109
|
-
where: hits.product.productBrand
|
|
1092
|
+
where: hits.product.productBrand is not null
|
|
1110
1093
|
group_by:
|
|
1111
1094
|
hits.product.productBrand
|
|
1112
1095
|
hits.product.productSKU
|
|
@@ -1141,16 +1124,16 @@ SELECT row_to_json(finalStage) as row FROM __stage0 AS finalStage`);
|
|
|
1141
1124
|
.loadQuery(
|
|
1142
1125
|
`
|
|
1143
1126
|
run: ${databaseName}.table('malloytest.airports') -> {
|
|
1144
|
-
where: faa_region
|
|
1127
|
+
where: faa_region is null
|
|
1145
1128
|
group_by: faa_region
|
|
1146
1129
|
aggregate: airport_count is count()
|
|
1147
1130
|
nest: by_state is {
|
|
1148
|
-
where: state
|
|
1131
|
+
where: state is not null
|
|
1149
1132
|
group_by: state
|
|
1150
1133
|
aggregate: airport_count is count()
|
|
1151
1134
|
}
|
|
1152
1135
|
nest: by_state1 is {
|
|
1153
|
-
where: state
|
|
1136
|
+
where: state is not null
|
|
1154
1137
|
group_by: state
|
|
1155
1138
|
aggregate: airport_count is count()
|
|
1156
1139
|
limit: 1
|
|
@@ -320,7 +320,7 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
|
|
|
320
320
|
param::string is null,
|
|
321
321
|
state_filter::string is "CA"
|
|
322
322
|
) is ${databaseName}.table('malloytest.state_facts') extend {
|
|
323
|
-
where: param
|
|
323
|
+
where: param is null and state = state_filter
|
|
324
324
|
}
|
|
325
325
|
run: state_facts -> { group_by: state }
|
|
326
326
|
`).malloyResultMatches(runtime, {state: 'CA'});
|
|
@@ -486,7 +486,7 @@ describe('BigQuery expression tests', () => {
|
|
|
486
486
|
}
|
|
487
487
|
}
|
|
488
488
|
-> {
|
|
489
|
-
where: state.code.code
|
|
489
|
+
where: state.code.code is not null
|
|
490
490
|
group_by: state.code.code
|
|
491
491
|
}
|
|
492
492
|
`
|
|
@@ -639,7 +639,7 @@ describe('airport_tests', () => {
|
|
|
639
639
|
`
|
|
640
640
|
run: airports-> {
|
|
641
641
|
nest: zero is {
|
|
642
|
-
nest: by_faa_region_i is { where: county ~'I%' and state
|
|
642
|
+
nest: by_faa_region_i is { where: county ~'I%' and state is not null
|
|
643
643
|
group_by: faa_region
|
|
644
644
|
aggregate: airport_count
|
|
645
645
|
nest: by_state is {
|
|
@@ -154,7 +154,7 @@ describe.each(runtimes.runtimeList)(
|
|
|
154
154
|
test(`search_index - ${databaseName}`, async () => {
|
|
155
155
|
await expect(`
|
|
156
156
|
run: ga_sessions->search_index -> {
|
|
157
|
-
where: fieldName
|
|
157
|
+
where: fieldName is not null
|
|
158
158
|
select: *
|
|
159
159
|
order_by: fieldName, weight desc
|
|
160
160
|
limit: 10
|
|
@@ -154,7 +154,7 @@ describe.each(runtimes.runtimeList)(
|
|
|
154
154
|
test(`search_index - ${databaseName}`, async () => {
|
|
155
155
|
await expect(`
|
|
156
156
|
run: ga_sessions->search_index -> {
|
|
157
|
-
where: fieldName
|
|
157
|
+
where: fieldName is not null
|
|
158
158
|
select: *
|
|
159
159
|
order_by: fieldName, weight desc
|
|
160
160
|
limit: 10
|
|
@@ -56,7 +56,7 @@ function modelText(databaseName: string) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
view: by_county is {
|
|
59
|
-
where: county
|
|
59
|
+
where: county is not null
|
|
60
60
|
group_by: county
|
|
61
61
|
aggregate: airport_count
|
|
62
62
|
limit: 2
|
|
@@ -64,7 +64,7 @@ function modelText(databaseName: string) {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
view: by_state is {
|
|
67
|
-
where: state
|
|
67
|
+
where: state is not null
|
|
68
68
|
group_by: state
|
|
69
69
|
aggregate: airport_count
|
|
70
70
|
limit: 2
|