@@ -215,8 +215,9 @@ private static String transactionConflictErrors()
215215 protected Optional <DataMappingTestSetup > filterCaseSensitiveDataMappingTestData (DataMappingTestSetup dataMappingTestSetup )
216216 {
217217 String typeName = dataMappingTestSetup .getTrinoTypeName ();
218- if (typeName .equals ("char(1)" )) {
219- return Optional .of (dataMappingTestSetup .asUnsupported ());
218+ if (typeName .equals ("char(3)" )) {
219+ // Use explicitly padded literal in char mapping test due to whitespace padding on coercion to varchar
220+ return Optional .of (new DataMappingTestSetup (typeName , "'ab '" , dataMappingTestSetup .getHighValueLiteral ()));
220221 }
221222 return Optional .of (dataMappingTestSetup );
222223 }
@@ -227,10 +228,13 @@ protected Optional<DataMappingTestSetup> filterDataMappingSmokeTestData(DataMapp
227228 String typeName = dataMappingTestSetup .getTrinoTypeName ();
228229 if (typeName .equals ("time" ) ||
229230 typeName .equals ("time(6)" ) ||
230- typeName .equals ("timestamp(6) with time zone" ) ||
231- typeName .equals ("char(3)" )) {
231+ typeName .equals ("timestamp(6) with time zone" )) {
232232 return Optional .of (dataMappingTestSetup .asUnsupported ());
233233 }
234+ if (typeName .equals ("char(3)" )) {
235+ // Use explicitly padded literal in char mapping test due to whitespace padding on coercion to varchar
236+ return Optional .of (new DataMappingTestSetup (typeName , "'ab '" , dataMappingTestSetup .getHighValueLiteral ()));
237+ }
234238 return Optional .of (dataMappingTestSetup );
235239 }
236240
@@ -551,9 +555,23 @@ public void testRenameColumnName()
551555 @ Override
552556 public void testCharVarcharComparison ()
553557 {
554- // Delta Lake doesn't have a char type
555- assertThatThrownBy (super ::testCharVarcharComparison )
556- .hasStackTraceContaining ("Unsupported type: char(3)" );
558+ // with char->varchar coercion on table creation, this is essentially varchar/varchar comparison
559+ try (TestTable table = new TestTable (
560+ getQueryRunner ()::execute ,
561+ "test_char_varchar" ,
562+ "(k, v) AS VALUES" +
563+ " (-1, CAST(NULL AS CHAR(3))), " +
564+ " (3, CAST(' ' AS CHAR(3)))," +
565+ " (6, CAST('x ' AS CHAR(3)))" )) {
566+ // varchar of length shorter than column's length
567+ assertThat (query ("SELECT k, v FROM " + table .getName () + " WHERE v = CAST(' ' AS varchar(2))" )).returnsEmptyResult ();
568+ // varchar of length longer than column's length
569+ assertThat (query ("SELECT k, v FROM " + table .getName () + " WHERE v = CAST(' ' AS varchar(4))" )).returnsEmptyResult ();
570+ // value that's not all-spaces
571+ assertThat (query ("SELECT k, v FROM " + table .getName () + " WHERE v = CAST('x ' AS varchar(2))" )).returnsEmptyResult ();
572+ // exact match
573+ assertQuery ("SELECT k, v FROM " + table .getName () + " WHERE v = CAST(' ' AS varchar(3))" , "VALUES (3, ' ')" );
574+ }
557575 }
558576
559577 @ Test
@@ -3960,6 +3978,12 @@ public void testTypeCoercionOnCreateTable()
39603978 testTimestampCoercionOnCreateTable ("TIMESTAMP '1969-12-31 23:59:59.9999995'" , "TIMESTAMP '1970-01-01 00:00:00.000000'" );
39613979 testTimestampCoercionOnCreateTable ("TIMESTAMP '1969-12-31 23:59:59.999999499999'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
39623980 testTimestampCoercionOnCreateTable ("TIMESTAMP '1969-12-31 23:59:59.9999994'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
3981+ testCharCoercionOnCreateTable ("CHAR 'ab '" , "'ab '" );
3982+ testCharCoercionOnCreateTable ("CHAR 'A'" , "'A'" );
3983+ testCharCoercionOnCreateTable ("CHAR 'é'" , "'é'" );
3984+ testCharCoercionOnCreateTable ("CHAR 'A '" , "'A '" );
3985+ testCharCoercionOnCreateTable ("CHAR ' A'" , "' A'" );
3986+ testCharCoercionOnCreateTable ("CHAR 'ABc'" , "'ABc'" );
39633987 }
39643988
39653989 private void testTimestampCoercionOnCreateTable (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String expectedValue )
@@ -3975,6 +3999,18 @@ private void testTimestampCoercionOnCreateTable(@Language("SQL") String actualVa
39753999 }
39764000 }
39774001
4002+ private void testCharCoercionOnCreateTable (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String expectedValue )
4003+ {
4004+ try (TestTable testTable = new TestTable (
4005+ getQueryRunner ()::execute ,
4006+ "test_char_coercion_on_create_table" ,
4007+ "(vch VARCHAR)" )) {
4008+ assertUpdate ("INSERT INTO " + testTable .getName () + " VALUES (" + actualValue + ")" , 1 );
4009+ assertThat (getColumnType (testTable .getName (), "vch" )).isEqualTo ("varchar" );
4010+ assertQuery ("SELECT * FROM " + testTable .getName (), "VALUES " + expectedValue );
4011+ }
4012+ }
4013+
39784014 @ Test
39794015 public void testTypeCoercionOnCreateTableAsSelect ()
39804016 {
@@ -4004,6 +4040,12 @@ public void testTypeCoercionOnCreateTableAsSelect()
40044040 testTimestampCoercionOnCreateTableAsSelect ("TIMESTAMP '1969-12-31 23:59:59.9999995'" , "TIMESTAMP '1970-01-01 00:00:00.000000'" );
40054041 testTimestampCoercionOnCreateTableAsSelect ("TIMESTAMP '1969-12-31 23:59:59.999999499999'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
40064042 testTimestampCoercionOnCreateTableAsSelect ("TIMESTAMP '1969-12-31 23:59:59.9999994'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
4043+ testCharCoercionOnCreateTableAsSelect ("CHAR 'ab '" , "'ab '" );
4044+ testCharCoercionOnCreateTableAsSelect ("CHAR 'A'" , "'A'" );
4045+ testCharCoercionOnCreateTableAsSelect ("CHAR 'é'" , "'é'" );
4046+ testCharCoercionOnCreateTableAsSelect ("CHAR 'A '" , "'A '" );
4047+ testCharCoercionOnCreateTableAsSelect ("CHAR ' A'" , "' A'" );
4048+ testCharCoercionOnCreateTableAsSelect ("CHAR 'ABc'" , "'ABc'" );
40074049 }
40084050
40094051 private void testTimestampCoercionOnCreateTableAsSelect (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String expectedValue )
@@ -4018,6 +4060,17 @@ private void testTimestampCoercionOnCreateTableAsSelect(@Language("SQL") String
40184060 }
40194061 }
40204062
4063+ private void testCharCoercionOnCreateTableAsSelect (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String expectedValue )
4064+ {
4065+ try (TestTable testTable = new TestTable (
4066+ getQueryRunner ()::execute ,
4067+ "test_char_coercion_on_create_table_as_select" ,
4068+ "AS SELECT %s vch" .formatted (actualValue ))) {
4069+ assertThat (getColumnType (testTable .getName (), "vch" )).isEqualTo ("varchar" );
4070+ assertQuery ("SELECT * FROM " + testTable .getName (), "VALUES " + expectedValue );
4071+ }
4072+ }
4073+
40214074 @ Test
40224075 public void testTypeCoercionOnCreateTableAsSelectWithNoData ()
40234076 {
@@ -4047,6 +4100,12 @@ public void testTypeCoercionOnCreateTableAsSelectWithNoData()
40474100 testTimestampCoercionOnCreateTableAsSelectWithNoData ("TIMESTAMP '1969-12-31 23:59:59.9999995'" );
40484101 testTimestampCoercionOnCreateTableAsSelectWithNoData ("TIMESTAMP '1969-12-31 23:59:59.999999499999'" );
40494102 testTimestampCoercionOnCreateTableAsSelectWithNoData ("TIMESTAMP '1969-12-31 23:59:59.9999994'" );
4103+ testCharCoercionOnCreateTableAsSelectWithNoData ("CHAR 'ab '" );
4104+ testCharCoercionOnCreateTableAsSelectWithNoData ("CHAR 'A'" );
4105+ testCharCoercionOnCreateTableAsSelectWithNoData ("CHAR 'é'" );
4106+ testCharCoercionOnCreateTableAsSelectWithNoData ("CHAR 'A '" );
4107+ testCharCoercionOnCreateTableAsSelectWithNoData ("CHAR ' A'" );
4108+ testCharCoercionOnCreateTableAsSelectWithNoData ("CHAR 'ABc'" );
40504109 }
40514110
40524111 private void testTimestampCoercionOnCreateTableAsSelectWithNoData (@ Language ("SQL" ) String actualValue )
@@ -4060,6 +4119,16 @@ private void testTimestampCoercionOnCreateTableAsSelectWithNoData(@Language("SQL
40604119 }
40614120 }
40624121
4122+ private void testCharCoercionOnCreateTableAsSelectWithNoData (@ Language ("SQL" ) String actualValue )
4123+ {
4124+ try (TestTable testTable = new TestTable (
4125+ getQueryRunner ()::execute ,
4126+ "test_char_coercion_on_create_table_as_select_with_no_data" ,
4127+ "AS SELECT %s vch WITH NO DATA" .formatted (actualValue ))) {
4128+ assertThat (getColumnType (testTable .getName (), "vch" )).isEqualTo ("varchar" );
4129+ }
4130+ }
4131+
40634132 @ Test
40644133 public void testTypeCoercionOnCreateTableAsWithRowType ()
40654134 {
@@ -4089,6 +4158,13 @@ public void testTypeCoercionOnCreateTableAsWithRowType()
40894158 testTimestampCoercionOnCreateTableAsWithRowType ("TIMESTAMP '1969-12-31 23:59:59.9999995'" , "TIMESTAMP '1970-01-01 00:00:00.000000'" );
40904159 testTimestampCoercionOnCreateTableAsWithRowType ("TIMESTAMP '1969-12-31 23:59:59.999999499999'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
40914160 testTimestampCoercionOnCreateTableAsWithRowType ("TIMESTAMP '1969-12-31 23:59:59.9999994'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
4161+ testCharCoercionOnCreateTableAsWithRowType ("CHAR 'ab '" , "CHAR(3)" , "'ab '" );
4162+ testCharCoercionOnCreateTableAsWithRowType ("CHAR 'A'" , "CHAR(3)" , "'A '" );
4163+ testCharCoercionOnCreateTableAsWithRowType ("CHAR 'A'" , "CHAR(1)" , "'A'" );
4164+ testCharCoercionOnCreateTableAsWithRowType ("CHAR 'é'" , "CHAR(3)" , "'é '" );
4165+ testCharCoercionOnCreateTableAsWithRowType ("CHAR 'A '" , "CHAR(3)" , "'A '" );
4166+ testCharCoercionOnCreateTableAsWithRowType ("CHAR ' A'" , "CHAR(3)" , "' A '" );
4167+ testCharCoercionOnCreateTableAsWithRowType ("CHAR 'ABc'" , "CHAR(3)" , "'ABc'" );
40924168 }
40934169
40944170 private void testTimestampCoercionOnCreateTableAsWithRowType (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String expectedValue )
@@ -4105,6 +4181,19 @@ private void testTimestampCoercionOnCreateTableAsWithRowType(@Language("SQL") St
41054181 }
41064182 }
41074183
4184+ private void testCharCoercionOnCreateTableAsWithRowType (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String actualTypeLiteral , @ Language ("SQL" ) String expectedValue )
4185+ {
4186+ try (TestTable testTable = new TestTable (
4187+ getQueryRunner ()::execute ,
4188+ "test_char_coercion_on_create_table_as_with_row_type" ,
4189+ "AS SELECT CAST(row(%s) AS row(value %s)) vch" .formatted (actualValue , actualTypeLiteral ))) {
4190+ assertThat (getColumnType (testTable .getName (), "vch" )).isEqualTo ("row(value varchar)" );
4191+ assertThat (query ("SELECT vch.value FROM " + testTable .getName ()))
4192+ .skippingTypesCheck ()
4193+ .matches ("VALUES " + expectedValue );
4194+ }
4195+ }
4196+
41084197 @ Test
41094198 public void testTypeCoercionOnCreateTableAsWithArrayType ()
41104199 {
@@ -4134,6 +4223,12 @@ public void testTypeCoercionOnCreateTableAsWithArrayType()
41344223 testTimestampCoercionOnCreateTableAsWithArrayType ("TIMESTAMP '1969-12-31 23:59:59.9999995'" , "TIMESTAMP '1970-01-01 00:00:00.000000'" );
41354224 testTimestampCoercionOnCreateTableAsWithArrayType ("TIMESTAMP '1969-12-31 23:59:59.999999499999'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
41364225 testTimestampCoercionOnCreateTableAsWithArrayType ("TIMESTAMP '1969-12-31 23:59:59.9999994'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
4226+ testCharCoercionOnCreateTableAsWithArrayType ("CHAR 'ab '" , "'ab '" );
4227+ testCharCoercionOnCreateTableAsWithArrayType ("CHAR 'A'" , "'A'" );
4228+ testCharCoercionOnCreateTableAsWithArrayType ("CHAR 'é'" , "'é'" );
4229+ testCharCoercionOnCreateTableAsWithArrayType ("CHAR 'A '" , "'A '" );
4230+ testCharCoercionOnCreateTableAsWithArrayType ("CHAR ' A'" , "' A'" );
4231+ testCharCoercionOnCreateTableAsWithArrayType ("CHAR 'ABc'" , "'ABc'" );
41374232 }
41384233
41394234 private void testTimestampCoercionOnCreateTableAsWithArrayType (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String expectedValue )
@@ -4149,6 +4244,18 @@ private void testTimestampCoercionOnCreateTableAsWithArrayType(@Language("SQL")
41494244 assertTimestampNtzFeature (testTable .getName ());
41504245 }
41514246 }
4247+ private void testCharCoercionOnCreateTableAsWithArrayType (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String expectedValue )
4248+ {
4249+ try (TestTable testTable = new TestTable (
4250+ getQueryRunner ()::execute ,
4251+ "test_char_coercion_on_create_table_as_with_array_type" ,
4252+ "AS SELECT array[%s] vch" .formatted (actualValue ))) {
4253+ assertThat (getColumnType (testTable .getName (), "vch" )).isEqualTo ("array(varchar)" );
4254+ assertThat (query ("SELECT vch[1] FROM " + testTable .getName ()))
4255+ .skippingTypesCheck ()
4256+ .matches ("VALUES " + expectedValue );
4257+ }
4258+ }
41524259
41534260 @ Test
41544261 public void testTypeCoercionOnCreateTableAsWithMapType ()
@@ -4179,6 +4286,12 @@ public void testTypeCoercionOnCreateTableAsWithMapType()
41794286 testTimestampCoercionOnCreateTableAsWithMapType ("TIMESTAMP '1969-12-31 23:59:59.9999995'" , "TIMESTAMP '1970-01-01 00:00:00.000000'" );
41804287 testTimestampCoercionOnCreateTableAsWithMapType ("TIMESTAMP '1969-12-31 23:59:59.999999499999'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
41814288 testTimestampCoercionOnCreateTableAsWithMapType ("TIMESTAMP '1969-12-31 23:59:59.9999994'" , "TIMESTAMP '1969-12-31 23:59:59.999999'" );
4289+ testCharCoercionOnCreateTableAsWithMapType ("CHAR 'ab '" , "'ab '" );
4290+ testCharCoercionOnCreateTableAsWithMapType ("CHAR 'A'" , "'A'" );
4291+ testCharCoercionOnCreateTableAsWithMapType ("CHAR 'é'" , "'é'" );
4292+ testCharCoercionOnCreateTableAsWithMapType ("CHAR 'A '" , "'A '" );
4293+ testCharCoercionOnCreateTableAsWithMapType ("CHAR ' A'" , "' A'" );
4294+ testCharCoercionOnCreateTableAsWithMapType ("CHAR 'ABc'" , "'ABc'" );
41824295 }
41834296
41844297 private void testTimestampCoercionOnCreateTableAsWithMapType (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String expectedValue )
@@ -4195,6 +4308,19 @@ private void testTimestampCoercionOnCreateTableAsWithMapType(@Language("SQL") St
41954308 }
41964309 }
41974310
4311+ private void testCharCoercionOnCreateTableAsWithMapType (@ Language ("SQL" ) String actualValue , @ Language ("SQL" ) String expectedValue )
4312+ {
4313+ try (TestTable testTable = new TestTable (
4314+ getQueryRunner ()::execute ,
4315+ "test_char_coercion_on_create_table_as_with_map_type" ,
4316+ "AS SELECT map(array[%1$s], array[%1$s]) vch" .formatted (actualValue ))) {
4317+ assertThat (getColumnType (testTable .getName (), "vch" )).isEqualTo ("map(varchar, varchar)" );
4318+ assertThat (query ("SELECT * FROM " + testTable .getName ()))
4319+ .skippingTypesCheck ()
4320+ .matches ("SELECT map(array[%1$s], array[%1$s])" .formatted (expectedValue ));
4321+ }
4322+ }
4323+
41984324 private void assertTimestampNtzFeature (String tableName )
41994325 {
42004326 assertThat (query ("SELECT * FROM \" " + tableName + "$properties\" " ))
0 commit comments