Skip to content

Commit e3311e1

Browse files
committed
Fix column level lineage miss when use unnest
1 parent a132f04 commit e3311e1

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,9 +1665,21 @@ else if (expressionType instanceof MapType mapType) {
16651665

16661666
ordinalityField.ifPresent(outputFieldsBuilder::add);
16671667

1668-
analysis.setUnnest(node, new UnnestAnalysis(mappingsBuilder.buildOrThrow(), ordinalityField));
1668+
Map<NodeRef<Expression>, List<Field>> mappings = mappingsBuilder.buildOrThrow();
1669+
analysis.setUnnest(node, new UnnestAnalysis(mappings, ordinalityField));
16691670

1670-
return createAndAssignScope(node, scope, outputFieldsBuilder.build());
1671+
List<Field> outputFields = outputFieldsBuilder.build();
1672+
for (Field field : outputFields) {
1673+
for (Map.Entry<NodeRef<Expression>, List<Field>> entry : mappings.entrySet()) {
1674+
Expression expression = entry.getKey().getNode();
1675+
List<Field> fields = entry.getValue();
1676+
if (fields.contains(field)) {
1677+
analysis.addSourceColumns(field, analysis.getExpressionSourceColumns(expression));
1678+
}
1679+
}
1680+
}
1681+
1682+
return createAndAssignScope(node, scope, outputFields);
16711683
}
16721684

16731685
@Override

testing/trino-tests/src/test/java/io/trino/execution/TestEventListenerBasic.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import io.trino.spi.eventlistener.TableInfo;
5252
import io.trino.spi.metrics.Metrics;
5353
import io.trino.spi.security.ViewExpression;
54+
import io.trino.spi.type.ArrayType;
5455
import io.trino.spi.type.Type;
5556
import io.trino.spi.type.TypeManager;
5657
import io.trino.spi.type.TypeSignature;
@@ -110,6 +111,9 @@ public class TestEventListenerBasic
110111
private static final String IGNORE_EVENT_MARKER = " -- ignore_generated_event";
111112
private static final String VARCHAR_TYPE = "varchar(15)";
112113
private static final String BIGINT_TYPE = BIGINT.getDisplayName();
114+
private static final String VARCHAR_ARRAY_TYPE = "array(varchar(15))";
115+
private static final String BIGINT_ARRAY_TYPE = "array(bigint)";
116+
private static final Type VARCHAR_15 = createVarcharType(15);
113117
private static final Metrics TEST_METRICS = new Metrics(ImmutableMap.of("test_metrics", new LongCount(1)));
114118

115119
private EventsAwaitingQueries queries;
@@ -155,8 +159,10 @@ public Iterable<ConnectorFactory> getConnectorFactories()
155159
return ImmutableList.of(new ColumnMetadata("test_column", BIGINT));
156160
}
157161
return ImmutableList.of(
158-
new ColumnMetadata("test_varchar", createVarcharType(15)),
159-
new ColumnMetadata("test_bigint", BIGINT));
162+
new ColumnMetadata("test_varchar", VARCHAR_15),
163+
new ColumnMetadata("test_bigint", BIGINT),
164+
new ColumnMetadata("test_varchar_array", new ArrayType(VARCHAR_15)),
165+
new ColumnMetadata("test_bigint_array", new ArrayType(BIGINT)));
160166
})
161167
.withGetTableHandle((session, schemaTableName) -> {
162168
if (!schemaTableName.getTableName().startsWith("create")) {
@@ -194,7 +200,7 @@ public Iterable<ConnectorFactory> getConnectorFactories()
194200
"SELECT test_varchar AS test_column FROM mock.default.test_table_with_row_filter",
195201
Optional.empty(),
196202
Optional.empty(),
197-
ImmutableList.of(new ConnectorViewDefinition.ViewColumn("test_column", createVarcharType(15).getTypeId(), Optional.empty())),
203+
ImmutableList.of(new ConnectorViewDefinition.ViewColumn("test_column", VARCHAR_15.getTypeId(), Optional.empty())),
198204
Optional.empty(),
199205
Optional.empty(),
200206
true,
@@ -761,7 +767,7 @@ public void testReferencedTablesWithColumnMask()
761767
throws Exception
762768
{
763769
QueryEvents queryEvents = runQueryAndWaitForEvents(
764-
"CREATE TABLE mock.default.create_table_with_referring_mask AS SELECT * FROM mock.default.test_table_with_column_mask"
770+
"CREATE TABLE mock.default.create_table_with_referring_mask AS SELECT test_varchar, test_bigint FROM mock.default.test_table_with_column_mask"
765771
).getQueryEvents();
766772

767773
QueryCompletedEvent event = queryEvents.getQueryCompletedEvent();
@@ -1372,7 +1378,9 @@ public void testCreateTableLike()
13721378
.containsExactly(
13731379
new OutputColumnMetadata("test_column", BIGINT_TYPE, ImmutableSet.of()),
13741380
new OutputColumnMetadata("test_varchar", VARCHAR_TYPE, ImmutableSet.of()),
1375-
new OutputColumnMetadata("test_bigint", BIGINT_TYPE, ImmutableSet.of()));
1381+
new OutputColumnMetadata("test_bigint", BIGINT_TYPE, ImmutableSet.of()),
1382+
new OutputColumnMetadata("test_varchar_array", VARCHAR_ARRAY_TYPE, ImmutableSet.of()),
1383+
new OutputColumnMetadata("test_bigint_array", BIGINT_ARRAY_TYPE, ImmutableSet.of()));
13761384
}
13771385

13781386
@Test
@@ -1419,6 +1427,27 @@ private void testOutputColumnsForSetOperations(String setOperator)
14191427
new ColumnDetail("tpch", "sf1", "orders", "custkey"))));
14201428
}
14211429

1430+
@Test
1431+
public void testOutputColumnsWithUnnestQueries()
1432+
throws Exception
1433+
{
1434+
assertLineage(
1435+
"SELECT test_varchar_unnest AS test_varchar, test_bigint AS test_bigint FROM mock.default.tests_table_unnest CROSS JOIN UNNEST(test_varchar_array) AS t(test_varchar_unnest)",
1436+
ImmutableSet.of("mock.default.tests_table_unnest"),
1437+
new OutputColumnMetadata("test_varchar", VARCHAR_TYPE, ImmutableSet.of(new ColumnDetail("mock", "default", "tests_table_unnest", "test_varchar_array"))),
1438+
new OutputColumnMetadata("test_bigint", BIGINT_TYPE, ImmutableSet.of(new ColumnDetail("mock", "default", "tests_table_unnest", "test_bigint"))));
1439+
assertLineage(
1440+
"SELECT test_varchar_unnest AS test_varchar, test_bigint_unnest AS test_bigint FROM mock.default.tests_table_unnest CROSS JOIN UNNEST(test_varchar_array) WITH ORDINALITY AS t(test_varchar_unnest, test_bigint_unnest)",
1441+
ImmutableSet.of("mock.default.tests_table_unnest"),
1442+
new OutputColumnMetadata("test_varchar", VARCHAR_TYPE, ImmutableSet.of(new ColumnDetail("mock", "default", "tests_table_unnest", "test_varchar_array"))),
1443+
new OutputColumnMetadata("test_bigint", BIGINT_TYPE, ImmutableSet.of()));
1444+
assertLineage(
1445+
"SELECT test_varchar_unnest AS test_varchar, test_bigint_unnest AS test_bigint FROM mock.default.tests_table_unnest CROSS JOIN UNNEST(test_varchar_array, test_bigint_array) AS t(test_varchar_unnest, test_bigint_unnest)",
1446+
ImmutableSet.of("mock.default.tests_table_unnest"),
1447+
new OutputColumnMetadata("test_varchar", VARCHAR_TYPE, ImmutableSet.of(new ColumnDetail("mock", "default", "tests_table_unnest", "test_varchar_array"))),
1448+
new OutputColumnMetadata("test_bigint", BIGINT_TYPE, ImmutableSet.of(new ColumnDetail("mock", "default", "tests_table_unnest", "test_bigint_array"))));
1449+
}
1450+
14221451
@Test
14231452
public void testTableStats()
14241453
throws Exception

0 commit comments

Comments
 (0)