diff --git a/packages/malloy/src/dialect/trino/trino.ts b/packages/malloy/src/dialect/trino/trino.ts index e6670f31c..b18c0e34b 100644 --- a/packages/malloy/src/dialect/trino/trino.ts +++ b/packages/malloy/src/dialect/trino/trino.ts @@ -621,17 +621,25 @@ export class PrestoDialect extends TrinoDialect { if (isArray) { if (needDistinctKey) { // return `LEFT JOIN UNNEST(transform(${source}, x -> CAST(ROW(x) as ROW(value) )) WITH ORDINALIITY as words_0(value,__row_id_from_${alias}) ON TRUE`; - return `CROSS JOIN UNNEST(${source}) WITH ORDINALITY as ${alias}(value, __row_id_from_${alias}) `; + return ( + '-- Simulate a left join\n' + + `CROSS JOIN UNNEST(COALESCE(${source},ARRAY[NULL])) WITH ORDINALITY as ${alias}(value, __row_id_almost_${alias})\n` + + `CROSS JOIN UNNEST(ARRAY[CASE WHEN ${source} IS NOT NULL THEN __row_id_almost_${alias} END]) as ${alias}_ignore(__row_id_from_${alias})` + ); } else { // return `CROSS JOIN UNNEST(zip_with(${source},array[],(r,ignore) -> (r, ignore))) as ${alias}(value, ignore)`; - return `CROSS JOIN UNNEST(${source}) as ${alias}(value) `; + return `CROSS JOIN UNNEST(COALESCE(${source}, ARRAY[NULL])) as ${alias}(value) `; } } else if (needDistinctKey) { // return `CROSS JOIN UNNEST(zip_with(${source},array[],(r,ignore) -> (r, ignore))) WITH ORDINALITY as ${alias}_outer(${alias}, ignore,__row_id_from_${alias})`; - return `CROSS JOIN UNNEST(${source}) WITH ORDINALITY as ${alias}_outer(${alias}, __row_id_from_${alias})`; + return ( + '-- Simulate a left join\n' + + `CROSS JOIN UNNEST(COALESCE(${source}, ARRAY[NULL])) WITH ORDINALITY as ${alias}_outer(${alias}, __row_id_almost_${alias})\n` + + `CROSS JOIN UNNEST(ARRAY[CASE WHEN ${source} IS NOT NULL THEN __row_id_almost_${alias} END]) as ${alias}_ignore(__row_id_from_${alias})` + ); } else { // return `CROSS JOIN UNNEST(zip_with(${source},array[],(r,ignore) -> (r, ignore)))as ${alias}_outer(${alias},ignore)`; - return `CROSS JOIN UNNEST(${source}) as ${alias}_outer(${alias})`; + return `CROSS JOIN UNNEST(COALESCE(${source}, ARRAY[NULL])) as ${alias}_outer(${alias})`; } } } diff --git a/test/src/databases/all/nomodel.spec.ts b/test/src/databases/all/nomodel.spec.ts index 95e5cca8f..89e3f96b2 100644 --- a/test/src/databases/all/nomodel.spec.ts +++ b/test/src/databases/all/nomodel.spec.ts @@ -1055,23 +1055,26 @@ SELECT row_to_json(finalStage) as row FROM __stage0 AS finalStage`); } ); - test.when(runtime.supportsNesting && runtime.dialect.readsNestedData)( - `can unnest simply from file - ${databaseName}`, - async () => { - await expect(` + test.when( + runtime.supportsNesting && + runtime.dialect.readsNestedData && + databaseName !== 'presto' + )(`can unnest simply from file - ${databaseName}`, async () => { + await expect(` source: ga_sample is ${databaseName}.table('malloytest.ga_sample') run: ga_sample -> { aggregate: h is hits.count() } `).malloyResultMatches(runtime, {h: 13233}); - } - ); + }); - test.when(runtime.supportsNesting && runtime.dialect.readsNestedData)( - `can unnest from file - ${databaseName}`, - async () => { - await expect(` + test.when( + runtime.supportsNesting && + runtime.dialect.readsNestedData && + databaseName !== 'presto' + )(`can unnest from file - ${databaseName}`, async () => { + await expect(` source: ga_sample is ${databaseName}.table('malloytest.ga_sample') run: ga_sample -> { where: hits.product.productBrand != null @@ -1084,13 +1087,14 @@ SELECT row_to_json(finalStage) as row FROM __stage0 AS finalStage`); p is hits.product.count() } `).malloyResultMatches(runtime, {h: 1192, c: 681, p: 1192}); - } - ); + }); - test.when(runtime.supportsNesting && runtime.dialect.readsNestedData)( - `can double unnest - ${databaseName}`, - async () => { - await expect(` + test.when( + runtime.supportsNesting && + runtime.dialect.readsNestedData && + databaseName !== 'presto' + )(`can double unnest - ${databaseName}`, async () => { + await expect(` source: ga_sample is ${databaseName}.table('malloytest.ga_sample') run: ga_sample -> { @@ -1098,8 +1102,7 @@ SELECT row_to_json(finalStage) as row FROM __stage0 AS finalStage`); p is floor(hits.product.productPrice.avg()) } `).malloyResultMatches(runtime, {p: 23001594}); - } - ); + }); test.when(runtime.supportsNesting)( 'nest null - ${databaseName}',