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