[
https://issues.apache.org/jira/browse/CALCITE-3953?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17090726#comment-17090726
]
Ruben Q L commented on CALCITE-3953:
------------------------------------
Relevant code is in {{SqlLiteral#createSqlType}}:
{code}
...
case CHAR:
NlsString string = (NlsString) value;
Charset charset = string.getCharset();
if (null == charset) {
charset = typeFactory.getDefaultCharset();
}
SqlCollation collation = string.getCollation();
if (null == collation) {
collation = SqlCollation.COERCIBLE;
}
RelDataType type =
typeFactory.createSqlType(
SqlTypeName.CHAR,
string.getValue().length());
type =
typeFactory.createTypeWithCharsetAndCollation(
type,
charset,
collation);
return type;
{code}
In the test of the description, that code does NOT return a type {{CHAR(3)}}
with {{SqlCollation.COERCIBLE}}, in fact it returns a {{CHAR(3)}} with
{{SqlCollation.IMPLICIT}}. The root cause is the
{{typeFactory.createTypeWithCharsetAndCollation}}, which internally does a
{{return canonize(newType);}} This canonization "breaks" the type's
SqlCollation. The reason for that is that type's digest
(BasicSqlType#generateTypeString) does not (always) include SqlCollation. And
apart from that, SqlCollation's name does not include coercibility info.
> SqlToRelConverter creates char literal with coercibility IMPLICIT
> -----------------------------------------------------------------
>
> Key: CALCITE-3953
> URL: https://issues.apache.org/jira/browse/CALCITE-3953
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.22.0
> Reporter: Ruben Q L
> Priority: Major
>
> The problem can be reproduced with the following test (to be added in
> SqlToRelConverterTest):
> {code:java}
> @Test void testLiteralCoercibility() {
> final String sql = "select * from dept where name = 'abc'";
> final RelNode rel = tester.convertSqlToRel(sql).rel;
> final List<LogicalFilter> filters = new ArrayList<>();
> final RelShuttleImpl visitor = new RelShuttleImpl() {
> @Override public RelNode visit(LogicalFilter filter) {
> filters.add(filter);
> return super.visit(filter);
> }
> };
> visitor.visit(rel);
> assertThat(filters.size(), is(1));
> assertThat(filters.get(0).getCondition(), instanceOf(RexCall.class));
> final RexCall call = (RexCall) filters.get(0).getCondition();
> final RexNode literal =
> call.getOperands().stream().filter(RexLiteral.class::isInstance).findFirst().orElse(null);
> assertThat (literal, notNullValue());
> assertThat (literal.getType().getCollation(), notNullValue());
> assertThat (literal.getType().getCollation().getCoercibility(),
> is(SqlCollation.Coercibility.COERCIBLE));
> }
> {code}
> Which fails with the message:
> {code:java}
> java.lang.AssertionError:
> Expected: is <COERCIBLE>
> but: was <IMPLICIT>
> {code}
> According to {{SqlCollation.Coercibility}} javadoc:
> _A character value expression consisting of a value other than a column
> (e.g., a host variable or a literal) has the coercibility characteristic
> Coercible, with the default collation for its character repertoire._
--
This message was sent by Atlassian Jira
(v8.3.4#803005)