diff --git a/core/trino-main/src/main/java/io/trino/sql/planner/NullabilityAnalyzer.java b/core/trino-main/src/main/java/io/trino/sql/planner/NullabilityAnalyzer.java index dd503f403ea7..7e702405e26f 100644 --- a/core/trino-main/src/main/java/io/trino/sql/planner/NullabilityAnalyzer.java +++ b/core/trino-main/src/main/java/io/trino/sql/planner/NullabilityAnalyzer.java @@ -21,6 +21,7 @@ import io.trino.sql.tree.IfExpression; import io.trino.sql.tree.InPredicate; import io.trino.sql.tree.NullIfExpression; +import io.trino.sql.tree.NullLiteral; import io.trino.sql.tree.SearchedCaseExpression; import io.trino.sql.tree.SimpleCaseExpression; import io.trino.sql.tree.SubscriptExpression; @@ -65,6 +66,7 @@ protected Void visitCast(Cast node, AtomicBoolean result) // except for the CAST(NULL AS x) case -- we should fix this at some point) // // Also, try_cast (i.e., safe cast) can return null + process(node.getExpression(), result); result.compareAndSet(false, node.isSafe() || !node.isTypeOnly()); return null; } @@ -132,5 +134,12 @@ protected Void visitFunctionCall(FunctionCall node, AtomicBoolean result) result.set(true); return null; } + + @Override + protected Void visitNullLiteral(NullLiteral node, AtomicBoolean result) + { + result.set(true); + return null; + } } } diff --git a/core/trino-main/src/test/java/io/trino/sql/query/TestJoin.java b/core/trino-main/src/test/java/io/trino/sql/query/TestJoin.java index a1ef5aac4a3a..72fa7712355e 100644 --- a/core/trino-main/src/test/java/io/trino/sql/query/TestJoin.java +++ b/core/trino-main/src/test/java/io/trino/sql/query/TestJoin.java @@ -21,6 +21,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import java.util.List; + +import static io.trino.spi.type.VarcharType.VARCHAR; import static io.trino.sql.planner.assertions.PlanMatchPattern.aggregation; import static io.trino.sql.planner.assertions.PlanMatchPattern.anyTree; import static io.trino.sql.planner.assertions.PlanMatchPattern.functionCall; @@ -111,6 +114,21 @@ FROM t1 JOIN t2 ON (t1.id = t2.id)) .matches("VALUES (10, CAST('b' AS varchar(2)))"); } + @Test + public void testAliasingOfNullCasts() + { + // Test for https://github.com/trinodb/trino/issues/13565 + assertThat(assertions.query(""" + WITH t AS ( + SELECT CAST(null AS varchar) AS x, CAST(null AS varchar) AS y + FROM (VALUES 1) t(a) JOIN (VALUES 1) u(a) USING (a)) + SELECT * FROM t + WHERE CAST(x AS bigint) IS NOT NULL AND y = 'hello' + """)) + .hasOutputTypes(List.of(VARCHAR, VARCHAR)) + .returnsEmptyResult(); + } + @Test public void testInPredicateInJoinCriteria() {