[ 
https://issues.apache.org/jira/browse/CALCITE-5130?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17532023#comment-17532023
 ] 

Yingyu Wang commented on CALCITE-5130:
--------------------------------------

[~libenchao] , thanks for you help!

I briefly investigated this issue. It looks to me the expected record type here 
should be *{{RecordType(VARCHAR EXPR$0) NOT NULL}}*  and the 
{{isNullable=true}} flag 
is lost at AbstractTypeCoercion:promoteToVarChar() :
{noformat}
promoteToVarChar:446, AbstractTypeCoercion 
(org.apache.calcite.sql.validate.implicit)
getWiderTypeForTwo:554, AbstractTypeCoercion 
(org.apache.calcite.sql.validate.implicit)
getWiderTypeFor:612, AbstractTypeCoercion 
(org.apache.calcite.sql.validate.implicit)
checkOperandTypes:122, SetopOperandTypeChecker (org.apache.calcite.sql.type)
checkOperandTypes:753, SqlOperator (org.apache.calcite.sql)
validateOperands:499, SqlOperator (org.apache.calcite.sql)
deriveType:605, SqlOperator (org.apache.calcite.sql)
deriveType:178, SqlBinaryOperator (org.apache.calcite.sql)
validateImpl:115, SetopNamespace (org.apache.calcite.sql.validate)
validate:89, AbstractNamespace (org.apache.calcite.sql.validate)
validateNamespace:1100, SqlValidatorImpl (org.apache.calcite.sql.validate)
validateQuery:1071, SqlValidatorImpl (org.apache.calcite.sql.validate)
validateCall:90, SqlSetOperator (org.apache.calcite.sql)
validateCall:5971, SqlValidatorImpl (org.apache.calcite.sql.validate)
validate:138, SqlCall (org.apache.calcite.sql)
validateScopedExpression:1046, SqlValidatorImpl 
(org.apache.calcite.sql.validate)
validate:752, SqlValidatorImpl (org.apache.calcite.sql.validate)
convertQuery:587, SqlToRelConverter (org.apache.calcite.sql2rel)
prepareSql:257, Prepare (org.apache.calcite.prepare)
prepareSql:220, Prepare (org.apache.calcite.prepare)
prepare2_:648, CalcitePrepareImpl (org.apache.calcite.prepare)
prepare_:514, CalcitePrepareImpl (org.apache.calcite.prepare)
prepareSql:484, CalcitePrepareImpl (org.apache.calcite.prepare)
parseQuery:234, CalciteConnectionImpl (org.apache.calcite.jdbc)
prepareAndExecute:623, CalciteMetaImpl (org.apache.calcite.jdbc)
prepareAndExecuteInternal:674, AvaticaConnection (org.apache.calcite.avatica)
executeInternal:156, AvaticaStatement (org.apache.calcite.avatica)
executeQuery:227, AvaticaStatement (org.apache.calcite.avatica)
assertQuery:539, CalciteAssert (org.apache.calcite.test)
lambda$returns$1:1445, CalciteAssert$AssertQuery (org.apache.calcite.test)
accept:-1, 651166656 
(org.apache.calcite.test.CalciteAssert$AssertQuery$$Lambda$367)
withConnection:1384, CalciteAssert$AssertQuery (org.apache.calcite.test)
returns:1443, CalciteAssert$AssertQuery (org.apache.calcite.test)
returns:1433, CalciteAssert$AssertQuery (org.apache.calcite.test)
returnsUnordered:1455, CalciteAssert$AssertQuery 
(org.apache.calcite.test){noformat}
Where the type1 and type2 are:
{noformat}
type1 = {BasicSqlType@6071} "CHAR(2)"
 precision = 2
 scale = -2147483648
 typeSystem = {RelDataTypeSystem$1@6122} 
 collation = {SqlCollation@6126} "COLLATE ISO-8859-1$en_US$primary"
 wrappedCharset = {SerializableCharset@6127} 
 typeName = {SqlTypeName@6128} "CHAR"
 isNullable = false  <------
 fieldList = null
 digest = "CHAR(2) NOT NULL"
type2 = {BasicSqlType@5993} "INTEGER"
 precision = -1
 scale = -2147483648
 typeSystem = {RelDataTypeSystem$1@6122} 
 collation = null
 wrappedCharset = null
 typeName = {SqlTypeName@6123} "INTEGER"
 isNullable = true <------
 fieldList = null
 digest = "INTEGER"{noformat}
And I also experimented that adding the following change at the end of 
{{promoteToVarChar()}} can fix the problem:
{code:java}
    if (null != resultType) {
      resultType = factory.createTypeWithNullability(resultType,
          type1.isNullable() || type2.isNullable());
    } {code}
To be frank I am not very familiar with the Type Coercion code base. So not 
sure if it's the right place to address this issue. If the fix looks good to 
you I can fire a PR (with test case of course).
If more consideration is required for this issue then feel free to take it over 
and fix it in a proper way.
Thanks again!

> AssertionError: "Conversion to relational algebra failed to preserve 
> datatypes" when union VARCHAR literal and CAST(null AS INTEGER) 
> -------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CALCITE-5130
>                 URL: https://issues.apache.org/jira/browse/CALCITE-5130
>             Project: Calcite
>          Issue Type: Bug
>    Affects Versions: 1.31.0
>            Reporter: Yingyu Wang
>            Priority: Major
>
> 0: jdbc:calcite:model=src/test/resources/mode> select CAST(null AS INTEGER) 
> union select '10';
> java.lang.AssertionError: Conversion to relational algebra failed to preserve 
> datatypes:
> validated type:
> RecordType(VARCHAR NOT NULL EXPR$0) NOT NULL
> converted type:
> RecordType(VARCHAR EXPR$0) NOT NULL
> rel:
> LogicalUnion(all=[false])
>   LogicalValues(tuples=[[\{ null }]])
>   LogicalValues(tuples=[[\{ '10' }]])
>  
> at 
> org.apache.calcite.sql2rel.SqlToRelConverter.checkConvertedType(SqlToRelConverter.java:487)
> at 
> org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(SqlToRelConverter.java:602)
> at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:257)
> at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:220)
> at 
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:648)
> at 
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:514)
> at 
> org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:484)
> at 
> org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:234)
> at 
> org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:623)
> at 
> org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:674)
> at 
> org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:156)
> at 
> org.apache.calcite.avatica.AvaticaStatement.execute(AvaticaStatement.java:217)
> at sqlline.Commands.executeSingleQuery(Commands.java:1130)
> at sqlline.Commands.execute(Commands.java:1079)
> at sqlline.Commands.sql(Commands.java:1033)
> at sqlline.SqlLine.dispatch(SqlLine.java:822)
> at sqlline.SqlLine.begin(SqlLine.java:596)
> at sqlline.SqlLine.start(SqlLine.java:269)
> at sqlline.SqlLine.main(SqlLine.java:208)



--
This message was sent by Atlassian Jira
(v8.20.7#820007)

Reply via email to