[
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)