I’m trying to figure out if the following test represents an error in the rel 
graph generation, the enumerable code generation, or just a grey area in the 
SQL spec/Calcite implementation:

  @Test void bindCharParameter() {
    final String sql = "select * from (values ('a'), ('b')) as tab (foo) where 
foo = ?";
    CalciteAssert.that()
        .query(sql)
        .convertMatches(root -> {
          RelNodes.findRex(root, RexUtil.find(SqlKind.EQUALS), null, (rel, rex) 
-> {
            ((RexCall) ((Filter) rel).getCondition()).getOperands().forEach(o 
-> {
              assertThat(o.getType().getPrecision(), is(1));
            });
          });
        })
        .consumesPreparedStatement(p -> {
          p.setString(1, "a");
        })
        .returnsUnordered("FOO=a")
        .consumesPreparedStatement(p -> {
          p.setString(1, "aa");
        })
        .returnsUnordered("");
  }

In the test above the Rel graph generated from the query types both the column 
‘foo’ and the RelDynamicParam as CHAR(1). The code generated by Calcite however 
treats the values passed through the prepared statement as simple Java Strings 
of arbitrary length. This means the second invocation returns no rows. Is this 
correct? Would it also be correct for an implementation of the query to 
truncate the value of the dynamic parameter to one character before performing 
the comparison, and thereby return a non-empty result set?

Thanks,

Chris


Reply via email to