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