This is an automated email from the ASF dual-hosted git repository.
mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new cfaadedd8f [CALCITE-7118] Rex-to-Lix Translation fails to correctly
truncate/pad RexDynamicParam values
cfaadedd8f is described below
commit cfaadedd8fd34c480395f9e843a73bf4bb8fe459
Author: Chris Dennis <[email protected]>
AuthorDate: Fri Aug 1 09:30:45 2025 -0400
[CALCITE-7118] Rex-to-Lix Translation fails to correctly truncate/pad
RexDynamicParam values
---
.../adapter/enumerable/RexToLixTranslator.java | 23 +++++++++++------
.../java/org/apache/calcite/test/JdbcTest.java | 29 ++++++++++++++++++++++
2 files changed, 44 insertions(+), 8 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java
b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java
index 7e29e6e78b..e82cde56a9 100644
---
a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java
+++
b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java
@@ -31,6 +31,7 @@
import org.apache.calcite.linq4j.tree.ParameterExpression;
import org.apache.calcite.linq4j.tree.Primitive;
import org.apache.calcite.linq4j.tree.Statement;
+import org.apache.calcite.linq4j.tree.Types;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rex.RexBuilder;
@@ -1642,29 +1643,35 @@ private Result toInnerStorageType(Result result, Type
storageType) {
if (rexWithStorageTypeResultMap.containsKey(key)) {
return rexWithStorageTypeResultMap.get(key);
}
- final Type storageType = currentStorageType != null
- ? currentStorageType :
typeFactory.getJavaClass(dynamicParam.getType());
+ final Type valueType = typeFactory.getJavaClass(dynamicParam.getType());
+ final Type storageType = currentStorageType != null ? currentStorageType :
valueType;
final boolean isNumeric =
SqlTypeFamily.NUMERIC.contains(dynamicParam.getType());
// For numeric types, use java.lang.Number to prevent cast exception
// when the parameter type differs from the target type
- final Expression valueExpression = isNumeric
+ final Expression rawValueExpression = isNumeric
? EnumUtils.convert(
EnumUtils.convert(
Expressions.call(root, BuiltInMethod.DATA_CONTEXT_GET.method,
Expressions.constant("?" + dynamicParam.getIndex())),
java.lang.Number.class),
- storageType)
+ valueType)
: EnumUtils.convert(
Expressions.call(root, BuiltInMethod.DATA_CONTEXT_GET.method,
Expressions.constant("?" + dynamicParam.getIndex())),
- storageType);
+ valueType);
+
+ final Expression valueExpression =
+ checkExpressionPadTruncate(rawValueExpression,
+
typeFactory.createJavaType(Types.toClass(rawValueExpression.getType())),
+ dynamicParam.getType());
final ParameterExpression valueVariable =
- Expressions.parameter(valueExpression.getType(),
- list.newName("value_dynamic_param"));
- list.add(Expressions.declare(Modifier.FINAL, valueVariable,
valueExpression));
+ Expressions.parameter(storageType,
list.newName("value_dynamic_param"));
+ list.add(
+ Expressions.declare(Modifier.FINAL, valueVariable,
+ EnumUtils.convert(valueExpression, storageType)));
final ParameterExpression isNullVariable =
Expressions.parameter(Boolean.TYPE,
list.newName("isNull_dynamic_param"));
list.add(
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index a0101cd649..5add262ee5 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -116,6 +116,7 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
import java.io.File;
import java.io.IOException;
@@ -9222,6 +9223,34 @@ void checkCalciteSchemaGetSubSchemaMap(boolean cache) {
.returnsUnordered("EMPID=100");
}
+ @ValueSource(strings = {"a", "a ", "a a"})
+ @ParameterizedTest void bindCharParameter(String value) {
+ final String sql =
+ "with cte as (select cast('a' as char(2)) as empid)"
+ + "select * from cte where empid = ?";
+
+ CalciteAssert.hr()
+ .query(sql)
+ .consumesPreparedStatement(p -> {
+ p.setString(1, value);
+ })
+ .returnsUnordered("EMPID=a ");
+ }
+
+ @ValueSource(strings = {"aa", "aaa"})
+ @ParameterizedTest void bindVarcharParameter(String value) {
+ final String sql =
+ "with cte as (select cast('aa' as varchar(2)) as empid)"
+ + "select * from cte where empid = ?";
+
+ CalciteAssert.hr()
+ .query(sql)
+ .consumesPreparedStatement(p -> {
+ p.setString(1, value);
+ })
+ .returnsUnordered("EMPID=aa");
+ }
+
private static String sums(int n, boolean c) {
final StringBuilder b = new StringBuilder();
for (int i = 0; i < n; i++) {