diff --git a/datafusion/sqllogictest/test_files/case.slt b/datafusion/sqllogictest/test_files/case.slt index 3905575d22dc9..074d216ac7524 100644 --- a/datafusion/sqllogictest/test_files/case.slt +++ b/datafusion/sqllogictest/test_files/case.slt @@ -703,3 +703,137 @@ logical_plan physical_plan 01)ProjectionExec: expr=[column1@0 as CASE WHEN CASE WHEN t.a IS NOT NULL THEN t.a ELSE Int64(1) END IS NOT NULL THEN t.a ELSE Int64(1) END] 02)--DataSourceExec: partitions=1, partition_sizes=[1] + +##### +# CASE with literal characters (to test lookup table CASE optimization) +##### +statement ok +create table source (letter varchar) as values ('a'), ('b'), (NULL), ('c'), ('a'), ('c'), ('d'); + +# Table with different string types +statement ok +create table letters as +select + arrow_cast(letter, 'Utf8') as letter_utf8, + arrow_cast(letter, 'LargeUtf8') as letter_large_utf8, + arrow_cast(letter, 'Utf8View') as letter_utf8_view, + arrow_cast(letter, 'Dictionary(Int32, Utf8)') as letter_string_dict, +from source; + + +query TIIIII +select + letter_utf8 as letter + ,CASE letter_utf8 WHEN 'b' THEN 1 WHEN 'a' THEN 2 WHEN 'd' THEN 3 ELSE 0 END as utf8 + ,CASE letter_large_utf8 WHEN 'b' THEN 1 WHEN 'a' THEN 2 WHEN 'd' THEN 3 ELSE 0 END as large_utf8 + ,CASE letter_utf8_view WHEN 'b' THEN 1 WHEN 'a' THEN 2 WHEN 'd' THEN 3 ELSE 0 END as utf8_view + ,CASE letter_string_dict WHEN 'b' THEN 1 WHEN 'a' THEN 2 WHEN 'd' THEN 3 ELSE 0 END as string_dict + ,CASE letter_utf8 WHEN 'b' THEN 1 WHEN NULL THEN 2 WHEN 'd' THEN 3 ELSE 0 END as utf8_with_null +FROM letters; +---- +a 2 2 2 2 0 +b 1 1 1 1 1 +NULL 0 0 0 0 0 +c 0 0 0 0 0 +a 2 2 2 2 0 +c 0 0 0 0 0 +d 3 3 3 3 3 + +statement ok +create table letters_binary as +select + arrow_cast(letter, 'Binary') as letter_binary, + arrow_cast(letter, 'LargeBinary') as letter_large_binary, + arrow_cast(letter, 'BinaryView') as letter_binary_view, + arrow_cast(letter, 'Dictionary(Int32, Binary)') as letter_binary_dict, + arrow_cast(arrow_cast(letter, 'Binary'), 'FixedSizeBinary(1)') as letter_fsb +from source; + +query ?IIIII +select + letter_binary as letter + ,CASE letter_binary WHEN X'62' THEN 1 WHEN X'61' THEN 2 WHEN X'64' THEN 3 ELSE 0 END as binary + ,CASE letter_large_binary WHEN X'62' THEN 1 WHEN X'61' THEN 2 WHEN X'64' THEN 3 ELSE 0 END as large_binary + ,CASE letter_binary_view WHEN X'62' THEN 1 WHEN X'61' THEN 2 WHEN X'64' THEN 3 ELSE 0 END as binary_view + ,CASE letter_binary_dict WHEN X'62' THEN 1 WHEN X'61' THEN 2 WHEN X'64' THEN 3 ELSE 0 END as binary_dict + ,CASE letter_fsb WHEN X'62' THEN 1 WHEN X'61' THEN 2 WHEN X'64' THEN 3 ELSE 0 END as fsb +FROM letters_binary; +---- +61 2 2 2 2 2 +62 1 1 1 1 1 +NULL 0 0 0 0 0 +63 0 0 0 0 0 +61 2 2 2 2 2 +63 0 0 0 0 0 +64 3 3 3 3 3 + +statement ok +drop table source; + + +statement ok +drop table letters; + +statement ok +drop table letters_binary; + +# Tests for CASE with boolean expressions +statement ok +create table booleans (b boolean) as values (true), (false), (null), (true), (null), (false); + +query BIII +select + b as boolean_value + ,CASE b WHEN true THEN 1 WHEN false THEN 2 ELSE 0 END as boolean_case + ,CASE b WHEN false THEN 1 WHEN true THEN 2 ELSE 0 END as boolean_case_rev + ,CASE b WHEN true THEN 1 WHEN NULL THEN 2 WHEN false THEN 3 ELSE 0 END as boolean_with_nulls +FROM booleans; +---- +true 1 2 1 +false 2 1 3 +NULL 0 0 0 +true 1 2 1 +NULL 0 0 0 +false 2 1 3 + +statement ok +drop table booleans; + +# Tests for CASE with floating point literals +statement ok +create table float_source (f float) as values (1.0), (2.0), (null), (3.5), (2.0), (null); + +statement ok +create table floats as +select + arrow_cast(f, 'Float16') as f16, + arrow_cast(f, 'Float32') as f32, + arrow_cast(f, 'Float64') as f64, + arrow_cast(f, 'Dictionary(Int32, Float32)') as f32_dict, +from float_source; + +query RTTTT +select + f32 as float_value + ,CASE f16 WHEN 1.0 THEN 'one' WHEN 3.5 THEN 'three_point_five' WHEN 2.0 THEN 'two' ELSE 'N/A' END as f16_case + ,CASE f32 WHEN 1.0 THEN 'one' WHEN 3.5 THEN 'three_point_five' WHEN 2.0 THEN 'two' ELSE 'N/A' END as f32_case + ,CASE f64 WHEN 1.0 THEN 'one' WHEN 3.5 THEN 'three_point_five' WHEN 2.0 THEN 'two' ELSE 'N/A' END as f64_case + ,CASE f32_dict WHEN 1.0 THEN 'one' WHEN 3.5 THEN 'three_point_five' WHEN 2.0 THEN 'two' ELSE 'N/A' END as f32_dict_case +FROM floats; +---- +1 one one one one +2 two two two two +NULL N/A N/A N/A N/A +3.5 three_point_five three_point_five three_point_five three_point_five +2 two two two two +NULL N/A N/A N/A N/A + +statement ok +drop table float_source; + +statement ok +drop table floats; + +##### +# End of lookup table CASE tests +#####