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