From a9304900878d5759a21dc301e562db2fbf17d55c Mon Sep 17 00:00:00 2001 From: Shivadarshan Date: Mon, 7 Sep 2026 02:14:16 +0530 Subject: [PATCH 1/3] Added fix for SPARK-59278 --- .../analysis/ApplyCharTypePaddingHelper.scala | 18 +- .../analysis/TypeCoercionHelper.scala | 8 +- .../sql/catalyst/util/CharVarcharUtils.scala | 24 ++- .../catalyst/analysis/TypeCoercionSuite.scala | 4 +- .../charvarchar-standard-semantics.sql.out | 16 +- .../predicate-functions.sql.out | 12 +- .../analyzer-results/selectExcept.sql.out | 4 +- ...n-unit-tests-single-column-literal.sql.out | 2 +- .../sql-tests/analyzer-results/time.sql.out | 4 +- .../typeCoercion/native/inConversion.sql.out | 176 +++++++++--------- .../spark/sql/CharVarcharTestSuite.scala | 149 +++++++++++++++ 11 files changed, 297 insertions(+), 120 deletions(-) diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ApplyCharTypePaddingHelper.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ApplyCharTypePaddingHelper.scala index 26c85469e3f32..2077448728006 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ApplyCharTypePaddingHelper.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ApplyCharTypePaddingHelper.scala @@ -104,17 +104,21 @@ object ApplyCharTypePaddingHelper { .getRawType(attr.metadata) .flatMap { case c: CharType => - val (nulls, literalChars) = - list.map(_.eval().asInstanceOf[UTF8String]).partition(_ == null) - val literalCharLengths = literalChars.map(_.numChars()) - val targetLen = (c.length +: literalCharLengths).max + // Compute the length of every list element in place, so that each length stays + // aligned with the element it came from. NULL elements have no length: they can + // never match, so they are left untouched instead of being padded. + val literalCharLengths = list.map { lit => + Option(lit.eval().asInstanceOf[UTF8String]).map(_.numChars()) + } + val targetLen = (c.length +: literalCharLengths.flatten).max Some( i.copy( value = addPadding(e, c.length, targetLen, alwaysPad = padCharCol), list = list.zip(literalCharLengths).map { - case (lit, charLength) => - addPadding(lit, charLength, targetLen, alwaysPad = false) - } ++ nulls.map(Literal.create(_, StringType)) + case (lit, Some(charLength)) => + addPadding(lit, charLength, targetLen, alwaysPad = false) + case (lit, None) => lit + } ) ) case _ => None diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionHelper.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionHelper.scala index f64f9a09a5e45..51cb4f9228351 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionHelper.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionHelper.scala @@ -447,9 +447,13 @@ abstract class TypeCoercionHelper { i } - case i @ In(a, b) if b.exists(_.dataType != a.dataType) => + case i @ In(_, _) if !haveSameType(i.children.map(_.dataType)) => findWiderCommonType(i.children.map(_.dataType)) match { - case Some(finalDataType) => i.withNewChildren(i.children.map(Cast(_, finalDataType))) + // Only cast the children that are not already of the common type. A redundant Cast + // would hide an attribute from rules that match on it, such as the CHAR type padding + // in ApplyCharTypePadding. + case Some(finalDataType) => + i.withNewChildren(i.children.map(castIfNotSameType(_, finalDataType))) case None => i } diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/CharVarcharUtils.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/CharVarcharUtils.scala index 00adcfe69bc56..dd0b0d3ba5775 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/CharVarcharUtils.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/CharVarcharUtils.scala @@ -295,6 +295,11 @@ object CharVarcharUtils extends Logging with SparkCharVarcharUtils { val rawTypes = attrs.map(attr => getRawType(attr.metadata)) if (rawTypes.exists(_.isEmpty)) { attrs + } else if (attrs.exists(attr => !RowOrdering.isOrderable(attr.dataType))) { + // Comparing a non-orderable type, such as a struct holding a MAP, is rejected later by + // CheckAnalysis. Leave it alone so the error names the attribute the user wrote rather + // than the rewritten struct. + attrs } else { val typeWithTargetCharLength = rawTypes.map(_.get).reduce(typeWithWiderCharLength) attrs.zip(rawTypes.map(_.get)).map { case (attr, rawType) => @@ -337,12 +342,27 @@ object CharVarcharUtils extends Logging with SparkCharVarcharUtils { val fieldExpr = GetStructField(expr, i, Some(field.name)) val padded = padCharToTargetLength( fieldExpr, field.dataType, targets(i).dataType, alwaysPad) - needPadding = padded.isDefined + // Accumulate: any single field needing padding means the struct must be rebuilt, + // otherwise the padding computed for earlier fields would be discarded. + needPadding |= padded.isDefined createStructExprs += Literal(field.name) createStructExprs += padded.getOrElse(fieldExpr) i += 1 } - if (needPadding) Some(CreateNamedStruct(createStructExprs.toSeq)) else None + if (needPadding) { + val struct = CreateNamedStruct(createStructExprs.toSeq) + // Rebuilding the struct field by field loses the nullability of the struct itself: + // GetStructField on a NULL struct yields NULL fields, which CreateNamedStruct would + // turn into a non-NULL struct of NULLs. Guard it the same way the scan-side rewrite + // in processStringForCharVarchar does. + Some(if (expr.nullable) { + If(IsNull(expr), Literal(null, struct.dataType), struct) + } else { + struct + }) + } else { + None + } case (ArrayType(et, containsNull), ArrayType(target, _)) => val param = NamedLambdaVariable("x", replaceCharVarcharWithString(et), containsNull) diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionSuite.scala index 577ff6de4f1cb..80cdf90fc9735 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionSuite.scala @@ -1747,10 +1747,10 @@ class TypeCoercionSuite extends TypeCoercionSuiteBase { In(Literal("test"), Seq(UnresolvedAttribute("a"), Literal(1))), In(Literal("test"), Seq(UnresolvedAttribute("a"), Literal(1))) ) + // Only the children that are not already of the common type are cast. ruleTest(inConversion, In(Literal("a"), Seq(Literal(1), Literal("b"))), - In(Cast(Literal("a"), StringType), - Seq(Cast(Literal(1), StringType), Cast(Literal("b"), StringType))) + In(Literal("a"), Seq(Cast(Literal(1), StringType), Literal("b"))) ) } diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/charvarchar-standard-semantics.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/charvarchar-standard-semantics.sql.out index 8081f9cecaaf0..a154c51c87869 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/charvarchar-standard-semantics.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/charvarchar-standard-semantics.sql.out @@ -93,7 +93,7 @@ Project [CASE WHEN true THEN cast(cast(abcdef as varchar(2)) as varchar(4)) ELSE -- !query SELECT CAST('abcdef' AS VARCHAR(2)) IN (CAST('ab' AS VARCHAR(4))) -- !query analysis -Project [cast(cast(abcdef as varchar(2)) as varchar(4)) IN (cast(cast(ab as varchar(4)) as varchar(4))) AS (CAST(abcdef AS VARCHAR(2)) IN (CAST(ab AS VARCHAR(4))))#x] +Project [cast(cast(abcdef as varchar(2)) as varchar(4)) IN (cast(ab as varchar(4))) AS (CAST(abcdef AS VARCHAR(2)) IN (CAST(ab AS VARCHAR(4))))#x] +- OneRowRelation @@ -166,7 +166,7 @@ Project [typeof(CASE WHEN true THEN cast(cast(a as char(2)) as char(4)) ELSE cas -- !query SELECT cast('a' AS CHAR(2)) IN (cast('a ' AS CHAR(2)), cast('bbb' AS VARCHAR(3))) -- !query analysis -Project [cast(cast(a as char(2)) as varchar(3)) IN (cast(cast(a as char(2)) as varchar(3)),cast(cast(bbb as varchar(3)) as varchar(3))) AS (CAST(a AS CHAR(2)) IN (CAST(a AS CHAR(2)), CAST(bbb AS VARCHAR(3))))#x] +Project [cast(cast(a as char(2)) as varchar(3)) IN (cast(cast(a as char(2)) as varchar(3)),cast(bbb as varchar(3))) AS (CAST(a AS CHAR(2)) IN (CAST(a AS CHAR(2)), CAST(bbb AS VARCHAR(3))))#x] +- OneRowRelation @@ -174,7 +174,7 @@ Project [cast(cast(a as char(2)) as varchar(3)) IN (cast(cast(a as char(2)) as SELECT typeof(c) FROM (SELECT cast('a' AS CHAR(2)) AS c) t WHERE c IN ('a ', 'b') -- !query analysis Project [typeof(c#x) AS typeof(c)#x] -+- Filter cast(c#x as string collate UTF8_BINARY) IN (cast(a as string collate UTF8_BINARY),cast(b as string collate UTF8_BINARY)) ++- Filter cast(c#x as string collate UTF8_BINARY) IN (a ,b) +- SubqueryAlias t +- Project [cast(a as char(2)) AS c#x] +- OneRowRelation @@ -703,35 +703,35 @@ Project [(cast(cast(a as char(2) collate UTF8_BINARY_RTRIM) as char(4) collate U -- !query SELECT cast('a' AS CHAR(2)) IN (cast('a' AS CHAR(4))) -- !query analysis -Project [cast(cast(a as char(2)) as char(4)) IN (cast(cast(a as char(4)) as char(4))) AS (CAST(a AS CHAR(2)) IN (CAST(a AS CHAR(4))))#x] +Project [cast(cast(a as char(2)) as char(4)) IN (cast(a as char(4))) AS (CAST(a AS CHAR(2)) IN (CAST(a AS CHAR(4))))#x] +- OneRowRelation -- !query SELECT cast('a' AS CHAR(2)) IN (cast('a' AS VARCHAR(2))) -- !query analysis -Project [cast(cast(a as char(2)) as varchar(2)) IN (cast(cast(a as varchar(2)) as varchar(2))) AS (CAST(a AS CHAR(2)) IN (CAST(a AS VARCHAR(2))))#x] +Project [cast(cast(a as char(2)) as varchar(2)) IN (cast(a as varchar(2))) AS (CAST(a AS CHAR(2)) IN (CAST(a AS VARCHAR(2))))#x] +- OneRowRelation -- !query SELECT cast('a' AS CHAR(2)) IN (cast('a ' AS VARCHAR(2))) -- !query analysis -Project [cast(cast(a as char(2)) as varchar(2)) IN (cast(cast(a as varchar(2)) as varchar(2))) AS (CAST(a AS CHAR(2)) IN (CAST(a AS VARCHAR(2))))#x] +Project [cast(cast(a as char(2)) as varchar(2)) IN (cast(a as varchar(2))) AS (CAST(a AS CHAR(2)) IN (CAST(a AS VARCHAR(2))))#x] +- OneRowRelation -- !query SELECT cast('a' AS CHAR(2)) IN ('a', 'b') -- !query analysis -Project [cast(cast(a as char(2)) as string collate UTF8_BINARY) IN (cast(a as string collate UTF8_BINARY),cast(b as string collate UTF8_BINARY)) AS (CAST(a AS CHAR(2)) IN (a, b))#x] +Project [cast(cast(a as char(2)) as string collate UTF8_BINARY) IN (a,b) AS (CAST(a AS CHAR(2)) IN (a, b))#x] +- OneRowRelation -- !query SELECT cast('a' AS CHAR(2)) IN ('a ', 'b') -- !query analysis -Project [cast(cast(a as char(2)) as string collate UTF8_BINARY) IN (cast(a as string collate UTF8_BINARY),cast(b as string collate UTF8_BINARY)) AS (CAST(a AS CHAR(2)) IN (a , b))#x] +Project [cast(cast(a as char(2)) as string collate UTF8_BINARY) IN (a ,b) AS (CAST(a AS CHAR(2)) IN (a , b))#x] +- OneRowRelation diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/predicate-functions.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/predicate-functions.sql.out index d894ce26af499..091524d97f19f 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/predicate-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/predicate-functions.sql.out @@ -415,7 +415,7 @@ Project [1 IN (1,2,3) AS (1 IN (1, 2, 3))#x] -- !query select 1 in (1, 2, 3, null) -- !query analysis -Project [cast(1 as int) IN (cast(1 as int),cast(2 as int),cast(3 as int),cast(null as int)) AS (1 IN (1, 2, 3, NULL))#x] +Project [1 IN (1,2,3,cast(null as int)) AS (1 IN (1, 2, 3, NULL))#x] +- OneRowRelation @@ -450,14 +450,14 @@ Project [cast(1 as bigint) IN (cast(2 as bigint),cast(3 as bigint),cast(4 as big -- !query select null in (1, 2, 3) -- !query analysis -Project [cast(null as int) IN (cast(1 as int),cast(2 as int),cast(3 as int)) AS (NULL IN (1, 2, 3))#x] +Project [cast(null as int) IN (1,2,3) AS (NULL IN (1, 2, 3))#x] +- OneRowRelation -- !query select null in (1, 2, null) -- !query analysis -Project [cast(null as int) IN (cast(1 as int),cast(2 as int),cast(null as int)) AS (NULL IN (1, 2, NULL))#x] +Project [cast(null as int) IN (1,2,cast(null as int)) AS (NULL IN (1, 2, NULL))#x] +- OneRowRelation @@ -471,7 +471,7 @@ Project [NOT 1 IN (1,2,3) AS (NOT (1 IN (1, 2, 3)))#x] -- !query select 1 not in (1, 2, 3, null) -- !query analysis -Project [NOT cast(1 as int) IN (cast(1 as int),cast(2 as int),cast(3 as int),cast(null as int)) AS (NOT (1 IN (1, 2, 3, NULL)))#x] +Project [NOT 1 IN (1,2,3,cast(null as int)) AS (NOT (1 IN (1, 2, 3, NULL)))#x] +- OneRowRelation @@ -506,14 +506,14 @@ Project [NOT cast(1 as bigint) IN (cast(2 as bigint),cast(3 as bigint),cast(4 as -- !query select null not in (1, 2, 3) -- !query analysis -Project [NOT cast(null as int) IN (cast(1 as int),cast(2 as int),cast(3 as int)) AS (NOT (NULL IN (1, 2, 3)))#x] +Project [NOT cast(null as int) IN (1,2,3) AS (NOT (NULL IN (1, 2, 3)))#x] +- OneRowRelation -- !query select null not in (1, 2, null) -- !query analysis -Project [NOT cast(null as int) IN (cast(1 as int),cast(2 as int),cast(null as int)) AS (NOT (NULL IN (1, 2, NULL)))#x] +Project [NOT cast(null as int) IN (1,2,cast(null as int)) AS (NOT (NULL IN (1, 2, NULL)))#x] +- OneRowRelation diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/selectExcept.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/selectExcept.sql.out index 33435514b6e2c..013105b68ebd7 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/selectExcept.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/selectExcept.sql.out @@ -448,7 +448,7 @@ Project [greatest(c1#x, c2#x, cast(c3#x as int), c4#x, c5#x) AS greatest(c1, c2, -- !query SELECT 5 IN (*) FROM v1 -- !query analysis -Project [cast(5 as int) IN (cast(c1#x as int),cast(c2#x as int),cast(c3#x as int),cast(c4#x as int),cast(c5#x as int)) AS (5 IN (c1, c2, c3, c4, c5))#x] +Project [5 IN (c1#x,c2#x,cast(c3#x as int),c4#x,c5#x) AS (5 IN (c1, c2, c3, c4, c5))#x] +- SubqueryAlias v1 +- View (`v1`, [c1#x, c2#x, c3#x, c4#x, c5#x]) +- Project [cast(c1#x as int) AS c1#x, cast(c2#x as int) AS c2#x, cast(c3#x as void) AS c3#x, cast(c4#x as int) AS c4#x, cast(c5#x as int) AS c5#x] @@ -492,7 +492,7 @@ Project [1 AS 1#x] SELECT 1 FROM v1 WHERE 4 IN (*) -- !query analysis Project [1 AS 1#x] -+- Filter cast(4 as int) IN (cast(c1#x as int),cast(c2#x as int),cast(c3#x as int),cast(c4#x as int),cast(c5#x as int)) ++- Filter 4 IN (c1#x,c2#x,cast(c3#x as int),c4#x,c5#x) +- SubqueryAlias v1 +- View (`v1`, [c1#x, c2#x, c3#x, c4#x, c5#x]) +- Project [cast(c1#x as int) AS c1#x, cast(c2#x as int) AS c2#x, cast(c3#x as void) AS c3#x, cast(c4#x as int) AS c4#x, cast(c5#x as int) AS c5#x] diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/not-in-unit-tests-single-column-literal.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/not-in-unit-tests-single-column-literal.sql.out index 2812b7643c5b0..c491c6d3d4d13 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/not-in-unit-tests-single-column-literal.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/not-in-unit-tests-single-column-literal.sql.out @@ -18,7 +18,7 @@ FROM m WHERE a NOT IN (null) -- !query analysis Project [a#x, b#x] -+- Filter NOT cast(a#x as int) IN (cast(null as int)) ++- Filter NOT a#x IN (cast(null as int)) +- SubqueryAlias m +- View (`m`, [a#x, b#x]) +- Project [cast(col1#x as int) AS a#x, cast(col2#x as decimal(2,1)) AS b#x] diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/time.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/time.sql.out index 3173aa5e2f935..3fb5379900209 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/time.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/time.sql.out @@ -2441,7 +2441,7 @@ Project [typeof(map(a, cast(cast(12:34:56.789 as time(3)) as time(6)), b, cast(0 -- !query SELECT '01:02:03.456789' :: TIME(6) IN ('12:34:56.789' :: TIME(3), '01:02:03.456789' :: TIME(6)) -- !query analysis -Project [cast(cast(01:02:03.456789 as time(6)) as time(6)) IN (cast(cast(12:34:56.789 as time(3)) as time(6)),cast(cast(01:02:03.456789 as time(6)) as time(6))) AS (CAST(01:02:03.456789 AS TIME(6)) IN (CAST(12:34:56.789 AS TIME(3)), CAST(01:02:03.456789 AS TIME(6))))#x] +Project [cast(01:02:03.456789 as time(6)) IN (cast(cast(12:34:56.789 as time(3)) as time(6)),cast(01:02:03.456789 as time(6))) AS (CAST(01:02:03.456789 AS TIME(6)) IN (CAST(12:34:56.789 AS TIME(3)), CAST(01:02:03.456789 AS TIME(6))))#x] +- OneRowRelation @@ -2449,7 +2449,7 @@ Project [cast(cast(01:02:03.456789 as time(6)) as time(6)) IN (cast(cast(12:34:5 SELECT '01:02:03.456789123' :: TIME(9) IN ( '12:34:56.789' :: TIME(3), '01:02:03.456789' :: TIME(6), '01:02:03.456789123' :: TIME(9)) -- !query analysis -Project [cast(cast(01:02:03.456789123 as time(9)) as time(9)) IN (cast(cast(12:34:56.789 as time(3)) as time(9)),cast(cast(01:02:03.456789 as time(6)) as time(9)),cast(cast(01:02:03.456789123 as time(9)) as time(9))) AS (CAST(01:02:03.456789123 AS TIME(9)) IN (CAST(12:34:56.789 AS TIME(3)), CAST(01:02:03.456789 AS TIME(6)), CAST(01:02:03.456789123 AS TIME(9))))#x] +Project [cast(01:02:03.456789123 as time(9)) IN (cast(cast(12:34:56.789 as time(3)) as time(9)),cast(cast(01:02:03.456789 as time(6)) as time(9)),cast(01:02:03.456789123 as time(9))) AS (CAST(01:02:03.456789123 AS TIME(9)) IN (CAST(12:34:56.789 AS TIME(3)), CAST(01:02:03.456789 AS TIME(6)), CAST(01:02:03.456789123 AS TIME(9))))#x] +- OneRowRelation diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/typeCoercion/native/inConversion.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/typeCoercion/native/inConversion.sql.out index 71bc2fef3ab8e..d81aef29d5114 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/typeCoercion/native/inConversion.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/typeCoercion/native/inConversion.sql.out @@ -21,7 +21,7 @@ Project [cast(1 as tinyint) IN (cast(1 as tinyint)) AS (CAST(1 AS TINYINT) IN (C -- !query SELECT cast(1 as tinyint) in (cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as smallint) IN (cast(cast(1 as smallint) as smallint)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS SMALLINT)))#x] +Project [cast(cast(1 as tinyint) as smallint) IN (cast(1 as smallint)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -32,7 +32,7 @@ Project [cast(cast(1 as tinyint) as smallint) IN (cast(cast(1 as smallint) as sm -- !query SELECT cast(1 as tinyint) in (cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as int) IN (cast(cast(1 as int) as int)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS INT)))#x] +Project [cast(cast(1 as tinyint) as int) IN (cast(1 as int)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -43,7 +43,7 @@ Project [cast(cast(1 as tinyint) as int) IN (cast(cast(1 as int) as int)) AS (CA -- !query SELECT cast(1 as tinyint) in (cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as bigint) IN (cast(cast(1 as bigint) as bigint)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS BIGINT)))#x] +Project [cast(cast(1 as tinyint) as bigint) IN (cast(1 as bigint)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -65,7 +65,7 @@ Project [cast(cast(1 as tinyint) as double) IN (cast(cast(1 as float) as double) -- !query SELECT cast(1 as tinyint) in (cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as double) IN (cast(cast(1 as double) as double)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as tinyint) as double) IN (cast(1 as double)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -76,7 +76,7 @@ Project [cast(cast(1 as tinyint) as double) IN (cast(cast(1 as double) as double -- !query SELECT cast(1 as tinyint) in (cast(1 as decimal(10, 0))) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as decimal(10,0)) IN (cast(cast(1 as decimal(10,0)) as decimal(10,0))) AS (CAST(1 AS TINYINT) IN (CAST(1 AS DECIMAL(10,0))))#x] +Project [cast(cast(1 as tinyint) as decimal(10,0)) IN (cast(1 as decimal(10,0))) AS (CAST(1 AS TINYINT) IN (CAST(1 AS DECIMAL(10,0))))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -186,7 +186,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as smallint) in (cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as smallint) IN (cast(cast(1 as tinyint) as smallint)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS TINYINT)))#x] +Project [cast(1 as smallint) IN (cast(cast(1 as tinyint) as smallint)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -208,7 +208,7 @@ Project [cast(1 as smallint) IN (cast(1 as smallint)) AS (CAST(1 AS SMALLINT) IN -- !query SELECT cast(1 as smallint) in (cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as int) IN (cast(cast(1 as int) as int)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS INT)))#x] +Project [cast(cast(1 as smallint) as int) IN (cast(1 as int)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -219,7 +219,7 @@ Project [cast(cast(1 as smallint) as int) IN (cast(cast(1 as int) as int)) AS (C -- !query SELECT cast(1 as smallint) in (cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as bigint) IN (cast(cast(1 as bigint) as bigint)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS BIGINT)))#x] +Project [cast(cast(1 as smallint) as bigint) IN (cast(1 as bigint)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -241,7 +241,7 @@ Project [cast(cast(1 as smallint) as double) IN (cast(cast(1 as float) as double -- !query SELECT cast(1 as smallint) in (cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as double) IN (cast(cast(1 as double) as double)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as smallint) as double) IN (cast(1 as double)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -252,7 +252,7 @@ Project [cast(cast(1 as smallint) as double) IN (cast(cast(1 as double) as doubl -- !query SELECT cast(1 as smallint) in (cast(1 as decimal(10, 0))) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as decimal(10,0)) IN (cast(cast(1 as decimal(10,0)) as decimal(10,0))) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS DECIMAL(10,0))))#x] +Project [cast(cast(1 as smallint) as decimal(10,0)) IN (cast(1 as decimal(10,0))) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS DECIMAL(10,0))))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -362,7 +362,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as int) in (cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as int) as int) IN (cast(cast(1 as tinyint) as int)) AS (CAST(1 AS INT) IN (CAST(1 AS TINYINT)))#x] +Project [cast(1 as int) IN (cast(cast(1 as tinyint) as int)) AS (CAST(1 AS INT) IN (CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -373,7 +373,7 @@ Project [cast(cast(1 as int) as int) IN (cast(cast(1 as tinyint) as int)) AS (CA -- !query SELECT cast(1 as int) in (cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as int) as int) IN (cast(cast(1 as smallint) as int)) AS (CAST(1 AS INT) IN (CAST(1 AS SMALLINT)))#x] +Project [cast(1 as int) IN (cast(cast(1 as smallint) as int)) AS (CAST(1 AS INT) IN (CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -395,7 +395,7 @@ Project [cast(1 as int) IN (cast(1 as int)) AS (CAST(1 AS INT) IN (CAST(1 AS INT -- !query SELECT cast(1 as int) in (cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as int) as bigint) IN (cast(cast(1 as bigint) as bigint)) AS (CAST(1 AS INT) IN (CAST(1 AS BIGINT)))#x] +Project [cast(cast(1 as int) as bigint) IN (cast(1 as bigint)) AS (CAST(1 AS INT) IN (CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -417,7 +417,7 @@ Project [cast(cast(1 as int) as double) IN (cast(cast(1 as float) as double)) AS -- !query SELECT cast(1 as int) in (cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as int) as double) IN (cast(cast(1 as double) as double)) AS (CAST(1 AS INT) IN (CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as int) as double) IN (cast(1 as double)) AS (CAST(1 AS INT) IN (CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -428,7 +428,7 @@ Project [cast(cast(1 as int) as double) IN (cast(cast(1 as double) as double)) A -- !query SELECT cast(1 as int) in (cast(1 as decimal(10, 0))) FROM t -- !query analysis -Project [cast(cast(1 as int) as decimal(10,0)) IN (cast(cast(1 as decimal(10,0)) as decimal(10,0))) AS (CAST(1 AS INT) IN (CAST(1 AS DECIMAL(10,0))))#x] +Project [cast(cast(1 as int) as decimal(10,0)) IN (cast(1 as decimal(10,0))) AS (CAST(1 AS INT) IN (CAST(1 AS DECIMAL(10,0))))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -538,7 +538,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as bigint) in (cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as tinyint) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS TINYINT)))#x] +Project [cast(1 as bigint) IN (cast(cast(1 as tinyint) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -549,7 +549,7 @@ Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as tinyint) as bigint -- !query SELECT cast(1 as bigint) in (cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as smallint) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS SMALLINT)))#x] +Project [cast(1 as bigint) IN (cast(cast(1 as smallint) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -560,7 +560,7 @@ Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as smallint) as bigin -- !query SELECT cast(1 as bigint) in (cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as int) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS INT)))#x] +Project [cast(1 as bigint) IN (cast(cast(1 as int) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -593,7 +593,7 @@ Project [cast(cast(1 as bigint) as double) IN (cast(cast(1 as float) as double)) -- !query SELECT cast(1 as bigint) in (cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as double) IN (cast(cast(1 as double) as double)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as bigint) as double) IN (cast(1 as double)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -615,7 +615,7 @@ Project [cast(cast(1 as bigint) as decimal(20,0)) IN (cast(cast(1 as decimal(10, -- !query SELECT cast(1 as bigint) in (cast(1 as string)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as string) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS STRING)))#x] +Project [cast(1 as bigint) IN (cast(cast(1 as string) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -769,7 +769,7 @@ Project [cast(1 as float) IN (cast(1 as float)) AS (CAST(1 AS FLOAT) IN (CAST(1 -- !query SELECT cast(1 as float) in (cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as float) as double) IN (cast(cast(1 as double) as double)) AS (CAST(1 AS FLOAT) IN (CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as float) as double) IN (cast(1 as double)) AS (CAST(1 AS FLOAT) IN (CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -890,7 +890,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as double) in (cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as tinyint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS TINYINT)))#x] +Project [cast(1 as double) IN (cast(cast(1 as tinyint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -901,7 +901,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as tinyint) as double -- !query SELECT cast(1 as double) in (cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as smallint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS SMALLINT)))#x] +Project [cast(1 as double) IN (cast(cast(1 as smallint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -912,7 +912,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as smallint) as doubl -- !query SELECT cast(1 as double) in (cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as int) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS INT)))#x] +Project [cast(1 as double) IN (cast(cast(1 as int) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -923,7 +923,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as int) as double)) A -- !query SELECT cast(1 as double) in (cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as bigint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS BIGINT)))#x] +Project [cast(1 as double) IN (cast(cast(1 as bigint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -934,7 +934,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as bigint) as double) -- !query SELECT cast(1 as double) in (cast(1 as float)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as float) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS FLOAT)))#x] +Project [cast(1 as double) IN (cast(cast(1 as float) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS FLOAT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -956,7 +956,7 @@ Project [cast(1 as double) IN (cast(1 as double)) AS (CAST(1 AS DOUBLE) IN (CAST -- !query SELECT cast(1 as double) in (cast(1 as decimal(10, 0))) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as decimal(10,0)) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DECIMAL(10,0))))#x] +Project [cast(1 as double) IN (cast(cast(1 as decimal(10,0)) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DECIMAL(10,0))))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -967,7 +967,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as decimal(10,0)) as -- !query SELECT cast(1 as double) in (cast(1 as string)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as string) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS STRING)))#x] +Project [cast(1 as double) IN (cast(cast(1 as string) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1066,7 +1066,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as decimal(10, 0)) in (cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as tinyint) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS TINYINT)))#x] +Project [cast(1 as decimal(10,0)) IN (cast(cast(1 as tinyint) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1077,7 +1077,7 @@ Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as tiny -- !query SELECT cast(1 as decimal(10, 0)) in (cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as smallint) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS SMALLINT)))#x] +Project [cast(1 as decimal(10,0)) IN (cast(cast(1 as smallint) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1088,7 +1088,7 @@ Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as smal -- !query SELECT cast(1 as decimal(10, 0)) in (cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as int) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS INT)))#x] +Project [cast(1 as decimal(10,0)) IN (cast(cast(1 as int) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1121,7 +1121,7 @@ Project [cast(cast(1 as decimal(10,0)) as double) IN (cast(cast(1 as float) as d -- !query SELECT cast(1 as decimal(10, 0)) in (cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as decimal(10,0)) as double) IN (cast(cast(1 as double) as double)) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as decimal(10,0)) as double) IN (cast(1 as double)) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1275,7 +1275,7 @@ Project [cast(cast(1 as string) as bigint) IN (cast(cast(1 as int) as bigint)) A -- !query SELECT cast(1 as string) in (cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as string) as bigint) IN (cast(cast(1 as bigint) as bigint)) AS (CAST(1 AS STRING) IN (CAST(1 AS BIGINT)))#x] +Project [cast(cast(1 as string) as bigint) IN (cast(1 as bigint)) AS (CAST(1 AS STRING) IN (CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1297,7 +1297,7 @@ Project [cast(cast(1 as string) as double) IN (cast(cast(1 as float) as double)) -- !query SELECT cast(1 as string) in (cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as string) as double) IN (cast(cast(1 as double) as double)) AS (CAST(1 AS STRING) IN (CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as string) as double) IN (cast(1 as double)) AS (CAST(1 AS STRING) IN (CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1330,7 +1330,7 @@ Project [cast(1 as string) IN (cast(1 as string)) AS (CAST(1 AS STRING) IN (CAST -- !query SELECT cast(1 as string) in (cast('1' as binary)) FROM t -- !query analysis -Project [cast(cast(1 as string) as binary) IN (cast(cast(1 as binary) as binary)) AS (CAST(1 AS STRING) IN (CAST(1 AS BINARY)))#x] +Project [cast(cast(1 as string) as binary) IN (cast(1 as binary)) AS (CAST(1 AS STRING) IN (CAST(1 AS BINARY)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1341,7 +1341,7 @@ Project [cast(cast(1 as string) as binary) IN (cast(cast(1 as binary) as binary) -- !query SELECT cast(1 as string) in (cast(1 as boolean)) FROM t -- !query analysis -Project [cast(cast(1 as string) as boolean) IN (cast(cast(1 as boolean) as boolean)) AS (CAST(1 AS STRING) IN (CAST(1 AS BOOLEAN)))#x] +Project [cast(cast(1 as string) as boolean) IN (cast(1 as boolean)) AS (CAST(1 AS STRING) IN (CAST(1 AS BOOLEAN)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1352,7 +1352,7 @@ Project [cast(cast(1 as string) as boolean) IN (cast(cast(1 as boolean) as boole -- !query SELECT cast(1 as string) in (cast('2017-12-11 09:30:00.0' as timestamp)) FROM t -- !query analysis -Project [cast(cast(1 as string) as timestamp) IN (cast(cast(2017-12-11 09:30:00.0 as timestamp) as timestamp)) AS (CAST(1 AS STRING) IN (CAST(2017-12-11 09:30:00.0 AS TIMESTAMP)))#x] +Project [cast(cast(1 as string) as timestamp) IN (cast(2017-12-11 09:30:00.0 as timestamp)) AS (CAST(1 AS STRING) IN (CAST(2017-12-11 09:30:00.0 AS TIMESTAMP)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1363,7 +1363,7 @@ Project [cast(cast(1 as string) as timestamp) IN (cast(cast(2017-12-11 09:30:00. -- !query SELECT cast(1 as string) in (cast('2017-12-11 09:30:00' as date)) FROM t -- !query analysis -Project [cast(cast(1 as string) as date) IN (cast(cast(2017-12-11 09:30:00 as date) as date)) AS (CAST(1 AS STRING) IN (CAST(2017-12-11 09:30:00 AS DATE)))#x] +Project [cast(cast(1 as string) as date) IN (cast(2017-12-11 09:30:00 as date)) AS (CAST(1 AS STRING) IN (CAST(2017-12-11 09:30:00 AS DATE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1528,7 +1528,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast('1' as binary) in (cast(1 as string)) FROM t -- !query analysis -Project [cast(cast(1 as binary) as binary) IN (cast(cast(1 as string) as binary)) AS (CAST(1 AS BINARY) IN (CAST(1 AS STRING)))#x] +Project [cast(1 as binary) IN (cast(cast(1 as string) as binary)) AS (CAST(1 AS BINARY) IN (CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -1770,7 +1770,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT true in (cast(1 as string)) FROM t -- !query analysis -Project [cast(true as boolean) IN (cast(cast(1 as string) as boolean)) AS (true IN (CAST(1 AS STRING)))#x] +Project [true IN (cast(cast(1 as string) as boolean)) AS (true IN (CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2012,7 +2012,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast('2017-12-12 09:30:00.0' as timestamp) in (cast(2 as string)) FROM t -- !query analysis -Project [cast(cast(2017-12-12 09:30:00.0 as timestamp) as timestamp) IN (cast(cast(2 as string) as timestamp)) AS (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP) IN (CAST(2 AS STRING)))#x] +Project [cast(2017-12-12 09:30:00.0 as timestamp) IN (cast(cast(2 as string) as timestamp)) AS (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP) IN (CAST(2 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2078,7 +2078,7 @@ Project [cast(2017-12-12 09:30:00.0 as timestamp) IN (cast(2017-12-11 09:30:00.0 -- !query SELECT cast('2017-12-12 09:30:00.0' as timestamp) in (cast('2017-12-11 09:30:00' as date)) FROM t -- !query analysis -Project [cast(cast(2017-12-12 09:30:00.0 as timestamp) as timestamp) IN (cast(cast(2017-12-11 09:30:00 as date) as timestamp)) AS (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP) IN (CAST(2017-12-11 09:30:00 AS DATE)))#x] +Project [cast(2017-12-12 09:30:00.0 as timestamp) IN (cast(cast(2017-12-11 09:30:00 as date) as timestamp)) AS (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP) IN (CAST(2017-12-11 09:30:00 AS DATE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2243,7 +2243,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast('2017-12-12 09:30:00' as date) in (cast(2 as string)) FROM t -- !query analysis -Project [cast(cast(2017-12-12 09:30:00 as date) as date) IN (cast(cast(2 as string) as date)) AS (CAST(2017-12-12 09:30:00 AS DATE) IN (CAST(2 AS STRING)))#x] +Project [cast(2017-12-12 09:30:00 as date) IN (cast(cast(2 as string) as date)) AS (CAST(2017-12-12 09:30:00 AS DATE) IN (CAST(2 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2298,7 +2298,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast('2017-12-12 09:30:00' as date) in (cast('2017-12-11 09:30:00.0' as timestamp)) FROM t -- !query analysis -Project [cast(cast(2017-12-12 09:30:00 as date) as timestamp) IN (cast(cast(2017-12-11 09:30:00.0 as timestamp) as timestamp)) AS (CAST(2017-12-12 09:30:00 AS DATE) IN (CAST(2017-12-11 09:30:00.0 AS TIMESTAMP)))#x] +Project [cast(cast(2017-12-12 09:30:00 as date) as timestamp) IN (cast(2017-12-11 09:30:00.0 as timestamp)) AS (CAST(2017-12-12 09:30:00 AS DATE) IN (CAST(2017-12-11 09:30:00.0 AS TIMESTAMP)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2331,7 +2331,7 @@ Project [cast(1 as tinyint) IN (cast(1 as tinyint),cast(1 as tinyint)) AS (CAST( -- !query SELECT cast(1 as tinyint) in (cast(1 as tinyint), cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as smallint) IN (cast(cast(1 as tinyint) as smallint),cast(cast(1 as smallint) as smallint)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS SMALLINT)))#x] +Project [cast(cast(1 as tinyint) as smallint) IN (cast(cast(1 as tinyint) as smallint),cast(1 as smallint)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2342,7 +2342,7 @@ Project [cast(cast(1 as tinyint) as smallint) IN (cast(cast(1 as tinyint) as sma -- !query SELECT cast(1 as tinyint) in (cast(1 as tinyint), cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as int) IN (cast(cast(1 as tinyint) as int),cast(cast(1 as int) as int)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS INT)))#x] +Project [cast(cast(1 as tinyint) as int) IN (cast(cast(1 as tinyint) as int),cast(1 as int)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2353,7 +2353,7 @@ Project [cast(cast(1 as tinyint) as int) IN (cast(cast(1 as tinyint) as int),cas -- !query SELECT cast(1 as tinyint) in (cast(1 as tinyint), cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as bigint) IN (cast(cast(1 as tinyint) as bigint),cast(cast(1 as bigint) as bigint)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS BIGINT)))#x] +Project [cast(cast(1 as tinyint) as bigint) IN (cast(cast(1 as tinyint) as bigint),cast(1 as bigint)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2375,7 +2375,7 @@ Project [cast(cast(1 as tinyint) as double) IN (cast(cast(1 as tinyint) as doubl -- !query SELECT cast(1 as tinyint) in (cast(1 as tinyint), cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as double) IN (cast(cast(1 as tinyint) as double),cast(cast(1 as double) as double)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as tinyint) as double) IN (cast(cast(1 as tinyint) as double),cast(1 as double)) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2386,7 +2386,7 @@ Project [cast(cast(1 as tinyint) as double) IN (cast(cast(1 as tinyint) as doubl -- !query SELECT cast(1 as tinyint) in (cast(1 as tinyint), cast(1 as decimal(10, 0))) FROM t -- !query analysis -Project [cast(cast(1 as tinyint) as decimal(10,0)) IN (cast(cast(1 as tinyint) as decimal(10,0)),cast(cast(1 as decimal(10,0)) as decimal(10,0))) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS DECIMAL(10,0))))#x] +Project [cast(cast(1 as tinyint) as decimal(10,0)) IN (cast(cast(1 as tinyint) as decimal(10,0)),cast(1 as decimal(10,0))) AS (CAST(1 AS TINYINT) IN (CAST(1 AS TINYINT), CAST(1 AS DECIMAL(10,0))))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2496,7 +2496,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as smallint) in (cast(1 as smallint), cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as smallint) IN (cast(cast(1 as smallint) as smallint),cast(cast(1 as tinyint) as smallint)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS TINYINT)))#x] +Project [cast(1 as smallint) IN (cast(1 as smallint),cast(cast(1 as tinyint) as smallint)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2518,7 +2518,7 @@ Project [cast(1 as smallint) IN (cast(1 as smallint),cast(1 as smallint)) AS (CA -- !query SELECT cast(1 as smallint) in (cast(1 as smallint), cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as int) IN (cast(cast(1 as smallint) as int),cast(cast(1 as int) as int)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS INT)))#x] +Project [cast(cast(1 as smallint) as int) IN (cast(cast(1 as smallint) as int),cast(1 as int)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2529,7 +2529,7 @@ Project [cast(cast(1 as smallint) as int) IN (cast(cast(1 as smallint) as int),c -- !query SELECT cast(1 as smallint) in (cast(1 as smallint), cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as bigint) IN (cast(cast(1 as smallint) as bigint),cast(cast(1 as bigint) as bigint)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS BIGINT)))#x] +Project [cast(cast(1 as smallint) as bigint) IN (cast(cast(1 as smallint) as bigint),cast(1 as bigint)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2551,7 +2551,7 @@ Project [cast(cast(1 as smallint) as double) IN (cast(cast(1 as smallint) as dou -- !query SELECT cast(1 as smallint) in (cast(1 as smallint), cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as double) IN (cast(cast(1 as smallint) as double),cast(cast(1 as double) as double)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as smallint) as double) IN (cast(cast(1 as smallint) as double),cast(1 as double)) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2562,7 +2562,7 @@ Project [cast(cast(1 as smallint) as double) IN (cast(cast(1 as smallint) as dou -- !query SELECT cast(1 as smallint) in (cast(1 as smallint), cast(1 as decimal(10, 0))) FROM t -- !query analysis -Project [cast(cast(1 as smallint) as decimal(10,0)) IN (cast(cast(1 as smallint) as decimal(10,0)),cast(cast(1 as decimal(10,0)) as decimal(10,0))) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS DECIMAL(10,0))))#x] +Project [cast(cast(1 as smallint) as decimal(10,0)) IN (cast(cast(1 as smallint) as decimal(10,0)),cast(1 as decimal(10,0))) AS (CAST(1 AS SMALLINT) IN (CAST(1 AS SMALLINT), CAST(1 AS DECIMAL(10,0))))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2672,7 +2672,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as int) in (cast(1 as int), cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as int) as int) IN (cast(cast(1 as int) as int),cast(cast(1 as tinyint) as int)) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS TINYINT)))#x] +Project [cast(1 as int) IN (cast(1 as int),cast(cast(1 as tinyint) as int)) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2683,7 +2683,7 @@ Project [cast(cast(1 as int) as int) IN (cast(cast(1 as int) as int),cast(cast(1 -- !query SELECT cast(1 as int) in (cast(1 as int), cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as int) as int) IN (cast(cast(1 as int) as int),cast(cast(1 as smallint) as int)) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS SMALLINT)))#x] +Project [cast(1 as int) IN (cast(1 as int),cast(cast(1 as smallint) as int)) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2705,7 +2705,7 @@ Project [cast(1 as int) IN (cast(1 as int),cast(1 as int)) AS (CAST(1 AS INT) IN -- !query SELECT cast(1 as int) in (cast(1 as int), cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as int) as bigint) IN (cast(cast(1 as int) as bigint),cast(cast(1 as bigint) as bigint)) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS BIGINT)))#x] +Project [cast(cast(1 as int) as bigint) IN (cast(cast(1 as int) as bigint),cast(1 as bigint)) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2727,7 +2727,7 @@ Project [cast(cast(1 as int) as double) IN (cast(cast(1 as int) as double),cast( -- !query SELECT cast(1 as int) in (cast(1 as int), cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as int) as double) IN (cast(cast(1 as int) as double),cast(cast(1 as double) as double)) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as int) as double) IN (cast(cast(1 as int) as double),cast(1 as double)) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2738,7 +2738,7 @@ Project [cast(cast(1 as int) as double) IN (cast(cast(1 as int) as double),cast( -- !query SELECT cast(1 as int) in (cast(1 as int), cast(1 as decimal(10, 0))) FROM t -- !query analysis -Project [cast(cast(1 as int) as decimal(10,0)) IN (cast(cast(1 as int) as decimal(10,0)),cast(cast(1 as decimal(10,0)) as decimal(10,0))) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS DECIMAL(10,0))))#x] +Project [cast(cast(1 as int) as decimal(10,0)) IN (cast(cast(1 as int) as decimal(10,0)),cast(1 as decimal(10,0))) AS (CAST(1 AS INT) IN (CAST(1 AS INT), CAST(1 AS DECIMAL(10,0))))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2848,7 +2848,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as bigint) in (cast(1 as bigint), cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as bigint) as bigint),cast(cast(1 as tinyint) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS TINYINT)))#x] +Project [cast(1 as bigint) IN (cast(1 as bigint),cast(cast(1 as tinyint) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2859,7 +2859,7 @@ Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as bigint) as bigint) -- !query SELECT cast(1 as bigint) in (cast(1 as bigint), cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as bigint) as bigint),cast(cast(1 as smallint) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS SMALLINT)))#x] +Project [cast(1 as bigint) IN (cast(1 as bigint),cast(cast(1 as smallint) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2870,7 +2870,7 @@ Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as bigint) as bigint) -- !query SELECT cast(1 as bigint) in (cast(1 as bigint), cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as bigint) as bigint),cast(cast(1 as int) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS INT)))#x] +Project [cast(1 as bigint) IN (cast(1 as bigint),cast(cast(1 as int) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2903,7 +2903,7 @@ Project [cast(cast(1 as bigint) as double) IN (cast(cast(1 as bigint) as double) -- !query SELECT cast(1 as bigint) in (cast(1 as bigint), cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as double) IN (cast(cast(1 as bigint) as double),cast(cast(1 as double) as double)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as bigint) as double) IN (cast(cast(1 as bigint) as double),cast(1 as double)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -2925,7 +2925,7 @@ Project [cast(cast(1 as bigint) as decimal(20,0)) IN (cast(cast(1 as bigint) as -- !query SELECT cast(1 as bigint) in (cast(1 as bigint), cast(1 as string)) FROM t -- !query analysis -Project [cast(cast(1 as bigint) as bigint) IN (cast(cast(1 as bigint) as bigint),cast(cast(1 as string) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS STRING)))#x] +Project [cast(1 as bigint) IN (cast(1 as bigint),cast(cast(1 as string) as bigint)) AS (CAST(1 AS BIGINT) IN (CAST(1 AS BIGINT), CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3079,7 +3079,7 @@ Project [cast(1 as float) IN (cast(1 as float),cast(1 as float)) AS (CAST(1 AS F -- !query SELECT cast(1 as float) in (cast(1 as float), cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as float) as double) IN (cast(cast(1 as float) as double),cast(cast(1 as double) as double)) AS (CAST(1 AS FLOAT) IN (CAST(1 AS FLOAT), CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as float) as double) IN (cast(cast(1 as float) as double),cast(1 as double)) AS (CAST(1 AS FLOAT) IN (CAST(1 AS FLOAT), CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3200,7 +3200,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as double) in (cast(1 as double), cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double),cast(cast(1 as tinyint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS TINYINT)))#x] +Project [cast(1 as double) IN (cast(1 as double),cast(cast(1 as tinyint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3211,7 +3211,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double) -- !query SELECT cast(1 as double) in (cast(1 as double), cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double),cast(cast(1 as smallint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS SMALLINT)))#x] +Project [cast(1 as double) IN (cast(1 as double),cast(cast(1 as smallint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3222,7 +3222,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double) -- !query SELECT cast(1 as double) in (cast(1 as double), cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double),cast(cast(1 as int) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS INT)))#x] +Project [cast(1 as double) IN (cast(1 as double),cast(cast(1 as int) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3233,7 +3233,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double) -- !query SELECT cast(1 as double) in (cast(1 as double), cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double),cast(cast(1 as bigint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS BIGINT)))#x] +Project [cast(1 as double) IN (cast(1 as double),cast(cast(1 as bigint) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3244,7 +3244,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double) -- !query SELECT cast(1 as double) in (cast(1 as double), cast(1 as float)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double),cast(cast(1 as float) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS FLOAT)))#x] +Project [cast(1 as double) IN (cast(1 as double),cast(cast(1 as float) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS FLOAT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3266,7 +3266,7 @@ Project [cast(1 as double) IN (cast(1 as double),cast(1 as double)) AS (CAST(1 A -- !query SELECT cast(1 as double) in (cast(1 as double), cast(1 as decimal(10, 0))) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double),cast(cast(1 as decimal(10,0)) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS DECIMAL(10,0))))#x] +Project [cast(1 as double) IN (cast(1 as double),cast(cast(1 as decimal(10,0)) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS DECIMAL(10,0))))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3277,7 +3277,7 @@ Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double) -- !query SELECT cast(1 as double) in (cast(1 as double), cast(1 as string)) FROM t -- !query analysis -Project [cast(cast(1 as double) as double) IN (cast(cast(1 as double) as double),cast(cast(1 as string) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS STRING)))#x] +Project [cast(1 as double) IN (cast(1 as double),cast(cast(1 as string) as double)) AS (CAST(1 AS DOUBLE) IN (CAST(1 AS DOUBLE), CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3376,7 +3376,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast(1 as decimal(10, 0)) in (cast(1 as decimal(10, 0)), cast(1 as tinyint)) FROM t -- !query analysis -Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as decimal(10,0)) as decimal(10,0)),cast(cast(1 as tinyint) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DECIMAL(10,0)), CAST(1 AS TINYINT)))#x] +Project [cast(1 as decimal(10,0)) IN (cast(1 as decimal(10,0)),cast(cast(1 as tinyint) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DECIMAL(10,0)), CAST(1 AS TINYINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3387,7 +3387,7 @@ Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as deci -- !query SELECT cast(1 as decimal(10, 0)) in (cast(1 as decimal(10, 0)), cast(1 as smallint)) FROM t -- !query analysis -Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as decimal(10,0)) as decimal(10,0)),cast(cast(1 as smallint) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DECIMAL(10,0)), CAST(1 AS SMALLINT)))#x] +Project [cast(1 as decimal(10,0)) IN (cast(1 as decimal(10,0)),cast(cast(1 as smallint) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DECIMAL(10,0)), CAST(1 AS SMALLINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3398,7 +3398,7 @@ Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as deci -- !query SELECT cast(1 as decimal(10, 0)) in (cast(1 as decimal(10, 0)), cast(1 as int)) FROM t -- !query analysis -Project [cast(cast(1 as decimal(10,0)) as decimal(10,0)) IN (cast(cast(1 as decimal(10,0)) as decimal(10,0)),cast(cast(1 as int) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DECIMAL(10,0)), CAST(1 AS INT)))#x] +Project [cast(1 as decimal(10,0)) IN (cast(1 as decimal(10,0)),cast(cast(1 as int) as decimal(10,0))) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DECIMAL(10,0)), CAST(1 AS INT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3431,7 +3431,7 @@ Project [cast(cast(1 as decimal(10,0)) as double) IN (cast(cast(1 as decimal(10, -- !query SELECT cast(1 as decimal(10, 0)) in (cast(1 as decimal(10, 0)), cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as decimal(10,0)) as double) IN (cast(cast(1 as decimal(10,0)) as double),cast(cast(1 as double) as double)) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DECIMAL(10,0)), CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as decimal(10,0)) as double) IN (cast(cast(1 as decimal(10,0)) as double),cast(1 as double)) AS (CAST(1 AS DECIMAL(10,0)) IN (CAST(1 AS DECIMAL(10,0)), CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3585,7 +3585,7 @@ Project [cast(cast(1 as string) as bigint) IN (cast(cast(1 as string) as bigint) -- !query SELECT cast(1 as string) in (cast(1 as string), cast(1 as bigint)) FROM t -- !query analysis -Project [cast(cast(1 as string) as bigint) IN (cast(cast(1 as string) as bigint),cast(cast(1 as bigint) as bigint)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(1 AS BIGINT)))#x] +Project [cast(cast(1 as string) as bigint) IN (cast(cast(1 as string) as bigint),cast(1 as bigint)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(1 AS BIGINT)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3607,7 +3607,7 @@ Project [cast(cast(1 as string) as double) IN (cast(cast(1 as string) as double) -- !query SELECT cast(1 as string) in (cast(1 as string), cast(1 as double)) FROM t -- !query analysis -Project [cast(cast(1 as string) as double) IN (cast(cast(1 as string) as double),cast(cast(1 as double) as double)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(1 AS DOUBLE)))#x] +Project [cast(cast(1 as string) as double) IN (cast(cast(1 as string) as double),cast(1 as double)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(1 AS DOUBLE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3640,7 +3640,7 @@ Project [cast(1 as string) IN (cast(1 as string),cast(1 as string)) AS (CAST(1 A -- !query SELECT cast(1 as string) in (cast(1 as string), cast('1' as binary)) FROM t -- !query analysis -Project [cast(cast(1 as string) as binary) IN (cast(cast(1 as string) as binary),cast(cast(1 as binary) as binary)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(1 AS BINARY)))#x] +Project [cast(cast(1 as string) as binary) IN (cast(cast(1 as string) as binary),cast(1 as binary)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(1 AS BINARY)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3651,7 +3651,7 @@ Project [cast(cast(1 as string) as binary) IN (cast(cast(1 as string) as binary) -- !query SELECT cast(1 as string) in (cast(1 as string), cast(1 as boolean)) FROM t -- !query analysis -Project [cast(cast(1 as string) as boolean) IN (cast(cast(1 as string) as boolean),cast(cast(1 as boolean) as boolean)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(1 AS BOOLEAN)))#x] +Project [cast(cast(1 as string) as boolean) IN (cast(cast(1 as string) as boolean),cast(1 as boolean)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(1 AS BOOLEAN)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3662,7 +3662,7 @@ Project [cast(cast(1 as string) as boolean) IN (cast(cast(1 as string) as boolea -- !query SELECT cast(1 as string) in (cast(1 as string), cast('2017-12-11 09:30:00.0' as timestamp)) FROM t -- !query analysis -Project [cast(cast(1 as string) as timestamp) IN (cast(cast(1 as string) as timestamp),cast(cast(2017-12-11 09:30:00.0 as timestamp) as timestamp)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(2017-12-11 09:30:00.0 AS TIMESTAMP)))#x] +Project [cast(cast(1 as string) as timestamp) IN (cast(cast(1 as string) as timestamp),cast(2017-12-11 09:30:00.0 as timestamp)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(2017-12-11 09:30:00.0 AS TIMESTAMP)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3673,7 +3673,7 @@ Project [cast(cast(1 as string) as timestamp) IN (cast(cast(1 as string) as time -- !query SELECT cast(1 as string) in (cast(1 as string), cast('2017-12-11 09:30:00' as date)) FROM t -- !query analysis -Project [cast(cast(1 as string) as date) IN (cast(cast(1 as string) as date),cast(cast(2017-12-11 09:30:00 as date) as date)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(2017-12-11 09:30:00 AS DATE)))#x] +Project [cast(cast(1 as string) as date) IN (cast(cast(1 as string) as date),cast(2017-12-11 09:30:00 as date)) AS (CAST(1 AS STRING) IN (CAST(1 AS STRING), CAST(2017-12-11 09:30:00 AS DATE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -3838,7 +3838,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast('1' as binary) in (cast('1' as binary), cast(1 as string)) FROM t -- !query analysis -Project [cast(cast(1 as binary) as binary) IN (cast(cast(1 as binary) as binary),cast(cast(1 as string) as binary)) AS (CAST(1 AS BINARY) IN (CAST(1 AS BINARY), CAST(1 AS STRING)))#x] +Project [cast(1 as binary) IN (cast(1 as binary),cast(cast(1 as string) as binary)) AS (CAST(1 AS BINARY) IN (CAST(1 AS BINARY), CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -4080,7 +4080,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast('1' as boolean) in (cast('1' as boolean), cast(1 as string)) FROM t -- !query analysis -Project [cast(cast(1 as boolean) as boolean) IN (cast(cast(1 as boolean) as boolean),cast(cast(1 as string) as boolean)) AS (CAST(1 AS BOOLEAN) IN (CAST(1 AS BOOLEAN), CAST(1 AS STRING)))#x] +Project [cast(1 as boolean) IN (cast(1 as boolean),cast(cast(1 as string) as boolean)) AS (CAST(1 AS BOOLEAN) IN (CAST(1 AS BOOLEAN), CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -4322,7 +4322,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast('2017-12-12 09:30:00.0' as timestamp) in (cast('2017-12-12 09:30:00.0' as timestamp), cast(1 as string)) FROM t -- !query analysis -Project [cast(cast(2017-12-12 09:30:00.0 as timestamp) as timestamp) IN (cast(cast(2017-12-12 09:30:00.0 as timestamp) as timestamp),cast(cast(1 as string) as timestamp)) AS (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP) IN (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP), CAST(1 AS STRING)))#x] +Project [cast(2017-12-12 09:30:00.0 as timestamp) IN (cast(2017-12-12 09:30:00.0 as timestamp),cast(cast(1 as string) as timestamp)) AS (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP) IN (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP), CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -4388,7 +4388,7 @@ Project [cast(2017-12-12 09:30:00.0 as timestamp) IN (cast(2017-12-12 09:30:00.0 -- !query SELECT cast('2017-12-12 09:30:00.0' as timestamp) in (cast('2017-12-12 09:30:00.0' as timestamp), cast('2017-12-11 09:30:00' as date)) FROM t -- !query analysis -Project [cast(cast(2017-12-12 09:30:00.0 as timestamp) as timestamp) IN (cast(cast(2017-12-12 09:30:00.0 as timestamp) as timestamp),cast(cast(2017-12-11 09:30:00 as date) as timestamp)) AS (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP) IN (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP), CAST(2017-12-11 09:30:00 AS DATE)))#x] +Project [cast(2017-12-12 09:30:00.0 as timestamp) IN (cast(2017-12-12 09:30:00.0 as timestamp),cast(cast(2017-12-11 09:30:00 as date) as timestamp)) AS (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP) IN (CAST(2017-12-12 09:30:00.0 AS TIMESTAMP), CAST(2017-12-11 09:30:00 AS DATE)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -4553,7 +4553,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast('2017-12-12 09:30:00' as date) in (cast('2017-12-12 09:30:00' as date), cast(1 as string)) FROM t -- !query analysis -Project [cast(cast(2017-12-12 09:30:00 as date) as date) IN (cast(cast(2017-12-12 09:30:00 as date) as date),cast(cast(1 as string) as date)) AS (CAST(2017-12-12 09:30:00 AS DATE) IN (CAST(2017-12-12 09:30:00 AS DATE), CAST(1 AS STRING)))#x] +Project [cast(2017-12-12 09:30:00 as date) IN (cast(2017-12-12 09:30:00 as date),cast(cast(1 as string) as date)) AS (CAST(2017-12-12 09:30:00 AS DATE) IN (CAST(2017-12-12 09:30:00 AS DATE), CAST(1 AS STRING)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] @@ -4608,7 +4608,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException -- !query SELECT cast('2017-12-12 09:30:00' as date) in (cast('2017-12-12 09:30:00' as date), cast('2017-12-11 09:30:00.0' as timestamp)) FROM t -- !query analysis -Project [cast(cast(2017-12-12 09:30:00 as date) as timestamp) IN (cast(cast(2017-12-12 09:30:00 as date) as timestamp),cast(cast(2017-12-11 09:30:00.0 as timestamp) as timestamp)) AS (CAST(2017-12-12 09:30:00 AS DATE) IN (CAST(2017-12-12 09:30:00 AS DATE), CAST(2017-12-11 09:30:00.0 AS TIMESTAMP)))#x] +Project [cast(cast(2017-12-12 09:30:00 as date) as timestamp) IN (cast(cast(2017-12-12 09:30:00 as date) as timestamp),cast(2017-12-11 09:30:00.0 as timestamp)) AS (CAST(2017-12-12 09:30:00 AS DATE) IN (CAST(2017-12-12 09:30:00 AS DATE), CAST(2017-12-11 09:30:00.0 AS TIMESTAMP)))#x] +- SubqueryAlias t +- View (`t`, [1#x]) +- Project [cast(1#x as int) AS 1#x] diff --git a/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala index 39694ad3d6869..753daddd2e833 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala @@ -508,6 +508,80 @@ trait CharVarcharTestSuite extends QueryTest { } } + test("SPARK-59278: char type IN list with a NULL ahead of the matching literal") { + // A NULL element must not shift the literals that follow it. `c IN (null, 'a')` is TRUE + // because one of the comparisons is TRUE, and NULL OR TRUE is TRUE. Both spellings of NULL + // are covered: an untyped NULL makes InConversion coerce every element of the IN, while a + // pre-typed one leaves the CHAR value untouched. + val nulls = Seq("null", "cast(null as string)") + val trueConditions = nulls.flatMap { n => + Seq( + (s"c IN ($n, 'a')", true), + (s"c IN ($n, 'a ')", true), + (s"c IN ('a', $n)", true), + (s"c IN ($n, 'x', $n, 'a')", true), + // 'bcd' widens the comparison to 3 characters, so the padded 'a' has to match 'a '. + (s"c IN ($n, 'a', 'bcd')", true)) + } + val nullConditions = nulls.flatMap { n => + Seq(s"c IN ($n, 'b')", s"c IN ($n, 'abc')") + } + + def checkTable(): Unit = { + testConditions(spark.table("t"), trueConditions) + testNullConditions(spark.table("t"), nullConditions) + } + + withTable("t") { + sql(s"CREATE TABLE t(c CHAR(2)) USING $format") + sql("INSERT INTO t VALUES ('a')") + checkTable() + } + + withTable("t") { + sql(s"CREATE TABLE t(i INT, c CHAR(2)) USING $format PARTITIONED BY (c)") + sql("INSERT INTO t VALUES (1, 'a')") + checkTable() + } + + // Without read-side padding the column is padded in the predicate instead of at scan. + withSQLConf(SQLConf.READ_SIDE_CHAR_PADDING.key -> "false") { + withTable("t") { + sql(s"CREATE TABLE t(c CHAR(2)) USING $format") + sql("INSERT INTO t VALUES ('a')") + checkTable() + } + } + + // NOT IN, and a correlated subquery where the value is an OuterReference. + withTable("t1", "t2") { + sql(s"CREATE TABLE t1(c CHAR(2)) USING $format") + sql(s"CREATE TABLE t2(c CHAR(5)) USING $format") + sql("INSERT INTO t1 VALUES ('a')") + sql("INSERT INTO t2 VALUES ('a')") + checkAnswer( + sql("SELECT c NOT IN (null, 'a'), c NOT IN (null, 'b') FROM t1"), + Row(false, null)) + checkAnswer( + sql("SELECT c FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t1.c IN (null, 'a'))"), + Row("a ")) + checkAnswer( + sql("SELECT c FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t1.c IN (null, 'zz'))"), + Nil) + } + + // A collated CHAR column used to fail analysis with DATA_DIFF_TYPES, because the NULL + // elements were rebuilt as default-collation StringType literals while the padded ones + // kept the column's collation. + withTable("t") { + sql(s"CREATE TABLE t(c CHAR(2) COLLATE UTF8_LCASE) USING $format") + sql("INSERT INTO t VALUES ('a')") + checkAnswer( + sql("SELECT c IN (null, 'A'), c IN ('A', null), c IN (null, 'zz') FROM t"), + Row(true, true, null)) + } + } + test("char type comparison: partition pruning") { withTable("t") { sql(s"CREATE TABLE t(i INT, c1 CHAR(2), c2 VARCHAR(5)) USING $format PARTITIONED BY (c1, c2)") @@ -549,6 +623,81 @@ trait CharVarcharTestSuite extends QueryTest { } } + test("SPARK-59278: char type comparison: struct nullability is preserved") { + // Padding rebuilds a struct field by field, which must not turn a NULL struct into a + // non-NULL struct of NULL fields. Single-field (s*) and multi-field (m*) structs agree. + withTable("t") { + sql("CREATE TABLE t(id INT, " + + "m1 STRUCT, m2 STRUCT, " + + s"s1 STRUCT, s2 STRUCT) USING $format") + sql("INSERT INTO t VALUES (1, null, null, null, null)") + sql("INSERT INTO t VALUES (2, struct('a', 1), null, struct('a'), null)") + sql("INSERT INTO t VALUES (3, null, struct('a', 1), null, struct('a'))") + checkAnswer( + sql("SELECT m1 = m2, s1 = s2, m1 <=> m2, s1 <=> s2 FROM t ORDER BY id"), + Seq( + // Both sides NULL: `=` is NULL, null-safe `<=>` is true. + Row(null, null, true, true), + // Exactly one side NULL: `=` is NULL, `<=>` is false. + Row(null, null, false, false), + Row(null, null, false, false))) + } + + // Arrays keep their nullability through ArrayTransform, NULL elements included. + withTable("t") { + sql("CREATE TABLE t(id INT, a1 ARRAY>, " + + s"a2 ARRAY>) USING $format") + sql("INSERT INTO t VALUES (1, null, null)") + sql("INSERT INTO t VALUES (2, array(null, struct('a', 1)), array(null, struct('a', 1)))") + checkAnswer( + sql("SELECT a1 = a2, a1 <=> a2 FROM t ORDER BY id"), + Seq(Row(null, true), Row(true, true))) + } + } + + test("SPARK-59278: char type comparison: non-orderable struct keeps its original error") { + // A struct holding a MAP is not comparable. Padding must leave the comparison alone so + // CheckAnalysis reports the attribute the user wrote, not the rewritten struct. + withTable("t") { + sql("CREATE TABLE t(s1 STRUCT>, " + + s"s2 STRUCT>) USING $format") + val e = intercept[AnalysisException](sql("SELECT s1 = s2 FROM t").collect()) + assert(e.getCondition == "DATATYPE_MISMATCH.INVALID_ORDERING_TYPE") + assert(e.getMessageParameters.get("sqlExpr") == "\"(s1 = s2)\"") + } + } + + test("SPARK-59278: char type comparison: multi-field struct") { + // Padding is decided per field, but a struct that needs padding in any field has to be + // rebuilt as a whole. A field that needs no padding must not discard the padding computed + // for the fields before it, whatever its position in the struct or its nesting depth. + Seq( + // CHAR field first, non-char field last. + ("STRUCT", "STRUCT", "struct('a', 1)"), + // Non-char field first, CHAR field last. This order already worked. + ("STRUCT", "STRUCT", "struct(1, 'a')"), + // Both fields are CHAR, but only the first one needs padding. + ("STRUCT", "STRUCT", "struct('a', 'b')"), + // Multi-field struct nested one level down. + ("STRUCT>", "STRUCT>", + "struct(struct('a', 1))"), + // Multi-field struct inside an array. + ("ARRAY>", "ARRAY>", + "array(struct('a', 1))") + ).foreach { case (type1, type2, value) => + withClue(s"$type1 vs $type2: ") { + withTable("t") { + sql(s"CREATE TABLE t(c1 $type1, c2 $type2) USING $format") + sql(s"INSERT INTO t VALUES ($value, $value)") + testConditions(spark.table("t"), Seq( + ("c1 = c2", true), + ("c1 < c2", false), + ("c1 IN (c2)", true))) + } + } + } + } + test("char type comparison: nested in array") { withTable("t") { sql(s"CREATE TABLE t(c1 ARRAY, c2 ARRAY) USING $format") From 60716924ac3b5a0690cd2c5a46331e7c8dbc760b Mon Sep 17 00:00:00 2001 From: Shivadarshan Date: Tue, 8 Sep 2026 20:12:20 +0530 Subject: [PATCH 2/3] addressing comments --- .../scala/org/apache/spark/sql/CharVarcharTestSuite.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala index 753daddd2e833..ace8cff4b942d 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala @@ -511,8 +511,9 @@ trait CharVarcharTestSuite extends QueryTest { test("SPARK-59278: char type IN list with a NULL ahead of the matching literal") { // A NULL element must not shift the literals that follow it. `c IN (null, 'a')` is TRUE // because one of the comparisons is TRUE, and NULL OR TRUE is TRUE. Both spellings of NULL - // are covered: an untyped NULL makes InConversion coerce every element of the IN, while a - // pre-typed one leaves the CHAR value untouched. + // are covered: an untyped NULL goes through InConversion, which casts only that NULL to the + // wider common type, while a pre-typed STRING NULL needs no coercion at all. The CHAR-backed + // value stays unchanged in both cases. val nulls = Seq("null", "cast(null as string)") val trueConditions = nulls.flatMap { n => Seq( From 0607809ce3f9e62782e751657fd6966f58db4492 Mon Sep 17 00:00:00 2001 From: Shivadarshan Date: Tue, 8 Sep 2026 23:26:11 +0530 Subject: [PATCH 3/3] adding suggested changes --- .../spark/sql/CharVarcharTestSuite.scala | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala index ace8cff4b942d..40783ceaa9fd6 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala @@ -23,7 +23,7 @@ import org.apache.spark.{SparkConf, SparkException, SparkRuntimeException, Spark import org.apache.spark.sql.catalyst.analysis.FunctionRegistry import org.apache.spark.sql.catalyst.analysis.resolver.ResolverGuard import org.apache.spark.sql.catalyst.expressions.{ - ArrayJoin, Attribute, Concat, EqualTo, Expression, GreaterThan, Literal, ScalarSubquery, + ArrayJoin, Attribute, Concat, EqualTo, Expression, GreaterThan, InSet, Literal, ScalarSubquery, StringRPad, StringToMap, Upper } import org.apache.spark.sql.catalyst.expressions.Cast.toSQLId @@ -554,6 +554,31 @@ trait CharVarcharTestSuite extends QueryTest { } } + // Once the list is long enough, OptimizeIn freezes it into an InSet whose HashSet is built + // by evaluating the elements, so a list corrupted at analysis time cannot be recovered from + // later. The NULL has to reach the set as a NULL instead of displacing the literals after it. + withSQLConf(SQLConf.OPTIMIZER_INSET_CONVERSION_THRESHOLD.key -> "1") { + withTable("t") { + sql(s"CREATE TABLE t(c CHAR(2)) USING $format") + sql("INSERT INTO t VALUES ('a')") + val df = sql("SELECT c IN (null, 'a', 'b'), c IN (null, 'x', 'y') FROM t") + assert( + df.queryExecution.optimizedPlan.exists( + _.expressions.exists(_.exists(_.isInstanceOf[InSet]))), + "the IN list was expected to be converted to an InSet") + checkAnswer(df, Row(true, null)) + } + // The InSet path looks the padded value up in a CollationAwareSet, so a collated column + // has to keep its collation through both padding and the set conversion. + withTable("t") { + sql(s"CREATE TABLE t(c CHAR(2) COLLATE UTF8_LCASE) USING $format") + sql("INSERT INTO t VALUES ('a')") + checkAnswer( + sql("SELECT c IN (null, 'A', 'b'), c IN (null, 'x', 'y') FROM t"), + Row(true, null)) + } + } + // NOT IN, and a correlated subquery where the value is an OuterReference. withTable("t1", "t2") { sql(s"CREATE TABLE t1(c CHAR(2)) USING $format")