[
https://issues.apache.org/jira/browse/CALCITE-5229?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17578200#comment-17578200
]
Zhengqiang Duan commented on CALCITE-5229:
------------------------------------------
Recently I did some investigation on this exception. First of all, the direct
cause of this problem is that the filed in PositionedCursor is
`Baz$Record5_1.empid`, and current() returns an `Emplyee` object, which makes
an exception occur during reflection.
Second, I investigated the source of the field, which is created in the
CalcitePrepareImpl class with the following code.
{code:java}
Class resultClazz = null;
if (preparedResult instanceof Typed) {
resultClazz = (Class) ((Typed) preparedResult).getElementType();
}
final Meta.CursorFactory cursorFactory =
preparingStmt.resultConvention == BindableConvention.INSTANCE
? Meta.CursorFactory.ARRAY
: Meta.CursorFactory.deduce(columns, resultClazz); {code}
resultClazz determines the type of field, and resultClazz is obtained through
bindable#getElementType. I compared the code generation results of PR#2848 and
the main branch and found that the Record5_1 class was included in the results
of PR#2848.
* main branch code generate result:
{code:java}
public static class Record1_0 implements java.io.Serializable {
public int f0;
public Record1_0() {}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Record1_0)) {
return false;
}
return this.f0 == ((Record1_0) o).f0;
}
public int hashCode() {
int h = 0;
h = org.apache.calcite.runtime.Utilities.hash(h, this.f0);
return h;
}
public int compareTo(Record1_0 that) {
final int c;
c = org.apache.calcite.runtime.Utilities.compare(this.f0, that.f0);
if (c != 0) {
return c;
}
return 0;
}
public String toString() {
return "{f0=" + this.f0 + "}";
}
}
public org.apache.calcite.linq4j.Enumerable bind(final
org.apache.calcite.DataContext root) {
java.util.List accumulatorAdders = new java.util.LinkedList();
accumulatorAdders.add(new org.apache.calcite.linq4j.function.Function2() {
public Record1_0 apply(Record1_0 acc,
org.apache.calcite.test.schemata.hr.Employee in) {
acc.f0 = org.apache.calcite.runtime.SqlFunctions.greater(acc.f0,
in.deptno);
return acc;
}
public Record1_0 apply(Object acc, Object in) {
return apply(
(Record1_0) acc,
(org.apache.calcite.test.schemata.hr.Employee) in);
}
}
);
org.apache.calcite.adapter.enumerable.AggregateLambdaFactory lambdaFactory =
new org.apache.calcite.adapter.enumerable.BasicAggregateLambdaFactory(
new org.apache.calcite.linq4j.function.Function0() {
public Object apply() {
int a0s0;
a0s0 = -2147483648;
Record1_0 record0;
record0 = new Record1_0();
record0.f0 = a0s0;
return record0;
}
}
,
accumulatorAdders);
final org.apache.calcite.linq4j.Enumerable _inputEnumerable =
org.apache.calcite.linq4j.Linq4j.asEnumerable(((org.apache.calcite.test.schemata.hr.HrSchema)
((org.apache.calcite.adapter.java.ReflectiveSchema)
root.getRootSchema().getSubSchema("hr").unwrap(org.apache.calcite.adapter.java.ReflectiveSchema.class)).getTarget()).emps).groupBy(new
org.apache.calcite.linq4j.function.Function1() {
public int apply(org.apache.calcite.test.schemata.hr.Employee a0) {
return a0.empid;
}
public Object apply(Object a0) {
return apply(
(org.apache.calcite.test.schemata.hr.Employee) a0);
}
}
, lambdaFactory.accumulatorInitializer(), lambdaFactory.accumulatorAdder(),
lambdaFactory.resultSelector(new org.apache.calcite.linq4j.function.Function2()
{
public Object[] apply(int key, Record1_0 acc) {
return new Object[] {
key,
acc.f0};
}
public Object[] apply(Integer key, Record1_0 acc) {
return apply(
key.intValue(),
acc);
}
public Object[] apply(Object key, Object acc) {
return apply(
(Integer) key,
(Record1_0) acc);
}
}
)).hashJoin(org.apache.calcite.linq4j.Linq4j.asEnumerable(((org.apache.calcite.test.schemata.hr.HrSchema)
((org.apache.calcite.adapter.java.ReflectiveSchema)
root.getRootSchema().getSubSchema("hr").unwrap(org.apache.calcite.adapter.java.ReflectiveSchema.class)).getTarget()).emps),
new org.apache.calcite.linq4j.function.Function1() {
public java.util.List apply(Object[] v1) {
return
org.apache.calcite.runtime.FlatLists.of(org.apache.calcite.runtime.SqlFunctions.toInt(v1[0]),
org.apache.calcite.runtime.SqlFunctions.toInt(v1[1]));
}
public Object apply(Object v1) {
return apply(
(Object[]) v1);
}
}
, new org.apache.calcite.linq4j.function.Function1() {
public java.util.List apply(org.apache.calcite.test.schemata.hr.Employee
v1) {
return org.apache.calcite.runtime.FlatLists.of(v1.empid, v1.deptno);
}
public Object apply(Object v1) {
return apply(
(org.apache.calcite.test.schemata.hr.Employee) v1);
}
}
, new org.apache.calcite.linq4j.function.Function2() {
public Object[] apply(Object[] left,
org.apache.calcite.test.schemata.hr.Employee right) {
return new Object[] {
left[0],
left[1],
right.empid,
right.deptno,
right.name,
right.salary,
right.commission};
}
public Object[] apply(Object left, Object right) {
return apply(
(Object[]) left,
(org.apache.calcite.test.schemata.hr.Employee) right);
}
}
, null, false, false, null);
final org.apache.calcite.linq4j.AbstractEnumerable child = new
org.apache.calcite.linq4j.AbstractEnumerable(){
public org.apache.calcite.linq4j.Enumerator enumerator() {
return new org.apache.calcite.linq4j.Enumerator(){
public final org.apache.calcite.linq4j.Enumerator inputEnumerator =
_inputEnumerable.enumerator();
public void reset() {
inputEnumerator.reset();
}
public boolean moveNext() {
return inputEnumerator.moveNext();
}
public void close() {
inputEnumerator.close();
}
public Object current() {
final Object[] current = (Object[]) inputEnumerator.current();
final Object input_value = current[2];
final Object input_value0 = current[3];
final Object input_value1 = current[4];
final Object input_value2 = current[5];
final Object input_value3 = current[6];
return new Object[] {
input_value,
input_value0,
input_value1,
input_value2,
input_value3};
}
};
}
};
return child.orderBy(new org.apache.calcite.linq4j.function.Function1() {
public float apply(Object[] v) {
return org.apache.calcite.runtime.SqlFunctions.toFloat(v[3]);
}
public Object apply(Object v) {
return apply(
(Object[]) v);
}
}
, org.apache.calcite.linq4j.function.Functions.nullsComparator(false,
false)).skip((Integer) root.get("?1")).take((Integer) root.get("?0"));
}
public Class getElementType() {
return java.lang.Object[].class;
}
{code}
* PR#2848 code generate result:
{code:java}
public static class Record1_0 implements java.io.Serializable {
public int f0;
public Record1_0() {}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Record1_0)) {
return false;
}
return this.f0 == ((Record1_0) o).f0;
}
public int hashCode() {
int h = 0;
h = org.apache.calcite.runtime.Utilities.hash(h, this.f0);
return h;
}
public int compareTo(Record1_0 that) {
final int c;
c = org.apache.calcite.runtime.Utilities.compare(this.f0, that.f0);
if (c != 0) {
return c;
}
return 0;
}
public String toString() {
return "{f0=" + this.f0 + "}";
}
}
public static class Record5_1 implements java.io.Serializable {
public int empid;
public int deptno;
public String name;
public float salary;
public Integer commission;
public Record5_1() {}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Record5_1)) {
return false;
}
return this.empid == ((Record5_1) o).empid && this.deptno == ((Record5_1)
o).deptno && java.util.Objects.equals(this.name, ((Record5_1) o).name) &&
this.salary == ((Record5_1) o).salary &&
java.util.Objects.equals(this.commission, ((Record5_1) o).commission);
}
public int hashCode() {
int h = 0;
h = org.apache.calcite.runtime.Utilities.hash(h, this.empid);
h = org.apache.calcite.runtime.Utilities.hash(h, this.deptno);
h = org.apache.calcite.runtime.Utilities.hash(h, this.name);
h = org.apache.calcite.runtime.Utilities.hash(h, this.salary);
h = org.apache.calcite.runtime.Utilities.hash(h, this.commission);
return h;
}
public int compareTo(Record5_1 that) {
int c;
c = org.apache.calcite.runtime.Utilities.compare(this.empid, that.empid);
if (c != 0) {
return c;
}
c = org.apache.calcite.runtime.Utilities.compare(this.deptno, that.deptno);
if (c != 0) {
return c;
}
c = org.apache.calcite.runtime.Utilities.compareNullsLast(this.name,
that.name);
if (c != 0) {
return c;
}
c = org.apache.calcite.runtime.Utilities.compare(this.salary, that.salary);
if (c != 0) {
return c;
}
c = org.apache.calcite.runtime.Utilities.compareNullsLast(this.commission,
that.commission);
if (c != 0) {
return c;
}
return 0;
}
public String toString() {
return "{empid=" + this.empid + ", deptno=" + this.deptno + ", name=" +
this.name + ", salary=" + this.salary + ", commission=" + this.commission + "}";
}
}
public org.apache.calcite.linq4j.Enumerable bind(final
org.apache.calcite.DataContext root) {
java.util.List accumulatorAdders = new java.util.LinkedList();
accumulatorAdders.add(new org.apache.calcite.linq4j.function.Function2() {
public Record1_0 apply(Record1_0 acc,
org.apache.calcite.test.schemata.hr.Employee in) {
acc.f0 = org.apache.calcite.runtime.SqlFunctions.greater(acc.f0,
in.deptno);
return acc;
}
public Record1_0 apply(Object acc, Object in) {
return apply(
(Record1_0) acc,
(org.apache.calcite.test.schemata.hr.Employee) in);
}
}
);
org.apache.calcite.adapter.enumerable.AggregateLambdaFactory lambdaFactory =
new org.apache.calcite.adapter.enumerable.BasicAggregateLambdaFactory(
new org.apache.calcite.linq4j.function.Function0() {
public Object apply() {
int a0s0;
a0s0 = -2147483648;
Record1_0 record0;
record0 = new Record1_0();
record0.f0 = a0s0;
return record0;
}
}
,
accumulatorAdders);
final java.util.Comparator comparator = new java.util.Comparator(){
public int compare(Object[] v0, Object[] v1) {
int c;
c =
org.apache.calcite.runtime.Utilities.compare(org.apache.calcite.runtime.SqlFunctions.toInt(v0[0]),
org.apache.calcite.runtime.SqlFunctions.toInt(v1[0]));
if (c != 0) {
return c;
}
c =
org.apache.calcite.runtime.Utilities.compare(org.apache.calcite.runtime.SqlFunctions.toInt(v0[1]),
org.apache.calcite.runtime.SqlFunctions.toInt(v1[1]));
if (c != 0) {
return c;
}
return 0;
}
public int compare(Object o0, Object o1) {
return this.compare((Object[]) o0, (Object[]) o1);
}
};
return
org.apache.calcite.linq4j.EnumerableDefaults.semiJoin(org.apache.calcite.linq4j.Linq4j.asEnumerable(((org.apache.calcite.test.schemata.hr.HrSchema)
((org.apache.calcite.adapter.java.ReflectiveSchema)
root.getRootSchema().getSubSchema("hr").unwrap(org.apache.calcite.adapter.java.ReflectiveSchema.class)).getTarget()).emps),
org.apache.calcite.linq4j.Linq4j.asEnumerable(((org.apache.calcite.test.schemata.hr.HrSchema)
((org.apache.calcite.adapter.java.ReflectiveSchema)
root.getRootSchema().getSubSchema("hr").unwrap(org.apache.calcite.adapter.java.ReflectiveSchema.class)).getTarget()).emps).groupBy(new
org.apache.calcite.linq4j.function.Function1() {
public int apply(org.apache.calcite.test.schemata.hr.Employee a0) {
return a0.empid;
}
public Object apply(Object a0) {
return apply(
(org.apache.calcite.test.schemata.hr.Employee) a0);
}
}
, lambdaFactory.accumulatorInitializer(), lambdaFactory.accumulatorAdder(),
lambdaFactory.resultSelector(new org.apache.calcite.linq4j.function.Function2()
{
public Object[] apply(int key, Record1_0 acc) {
return new Object[] {
key,
acc.f0};
}
public Object[] apply(Integer key, Record1_0 acc) {
return apply(
key.intValue(),
acc);
}
public Object[] apply(Object key, Object acc) {
return apply(
(Integer) key,
(Record1_0) acc);
}
}
)).orderBy(org.apache.calcite.linq4j.function.Functions.identitySelector(),
comparator), new org.apache.calcite.linq4j.function.Function1() {
public java.util.List apply(org.apache.calcite.test.schemata.hr.Employee
v1) {
return org.apache.calcite.runtime.FlatLists.of(v1.empid, v1.deptno);
}
public Object apply(Object v1) {
return apply(
(org.apache.calcite.test.schemata.hr.Employee) v1);
}
}
, new org.apache.calcite.linq4j.function.Function1() {
public java.util.List apply(Object[] v1) {
return
org.apache.calcite.runtime.FlatLists.of(org.apache.calcite.runtime.SqlFunctions.toInt(v1[0]),
org.apache.calcite.runtime.SqlFunctions.toInt(v1[1]));
}
public Object apply(Object v1) {
return apply(
(Object[]) v1);
}
}
, null, null).orderBy(new org.apache.calcite.linq4j.function.Function1() {
public float apply(org.apache.calcite.test.schemata.hr.Employee v) {
return v.salary;
}
public Object apply(Object v) {
return apply(
(org.apache.calcite.test.schemata.hr.Employee) v);
}
}
, org.apache.calcite.linq4j.function.Functions.nullsComparator(false,
false)).skip((Integer) root.get("?1")).take((Integer) root.get("?0"));
}
public Class getElementType() {
return Record5_1.class;
}
{code}
I'll keep working on the code generation logic to try and fix this.
> JdbcTest#testDynamicParameterInLimitOffset throws IllegalArgumentException
> --------------------------------------------------------------------------
>
> Key: CALCITE-5229
> URL: https://issues.apache.org/jira/browse/CALCITE-5229
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.31.0
> Reporter: Benchao Li
> Assignee: Zhengqiang Duan
> Priority: Major
>
> After CALCITE-5201, this test will fail because we can transform more cases
> to semi join, and the physical type for some {{EnumerableRel}}s is wrong, we
> should fix them.
> See https://github.com/apache/calcite/pull/2848/files#r913566595
> {code:java}
> java.lang.IllegalArgumentException: Can not set int field Baz$Record5_1.empid
> to null value
> java.sql.SQLException: java.lang.IllegalArgumentException: Can not set int
> field Baz$Record5_1.empid to null value
> at
> org.apache.calcite.avatica.util.PositionedCursor$FieldGetter.getObject(PositionedCursor.java:132)
> at
> org.apache.calcite.avatica.util.AbstractCursor$AccessorImpl.getObject(AbstractCursor.java:357)
> at
> org.apache.calcite.avatica.util.AbstractCursor$AccessorImpl.getString(AbstractCursor.java:300)
> at
> org.apache.calcite.avatica.AvaticaResultSet.getString(AvaticaResultSet.java:241)
> at
> org.apache.calcite.test.CalciteAssert$ResultSetFormatter.rowToString(CalciteAssert.java:1986)
> at
> org.apache.calcite.test.CalciteAssert$ResultSetFormatter.resultSet(CalciteAssert.java:1972)
> at
> org.apache.calcite.test.CalciteAssert.lambda$checkResult$2(CalciteAssert.java:310)
> at
> org.apache.calcite.test.CalciteAssert.assertPrepare(CalciteAssert.java:631)
> at
> org.apache.calcite.test.CalciteAssert.access$700(CalciteAssert.java:149)
> at
> org.apache.calcite.test.CalciteAssert$AssertQuery.lambda$returns$1(CalciteAssert.java:1448)
> at
> org.apache.calcite.test.CalciteAssert$AssertQuery.withConnection(CalciteAssert.java:1384)
> at
> org.apache.calcite.test.CalciteAssert$AssertQuery.returns(CalciteAssert.java:1443)
> at
> org.apache.calcite.test.CalciteAssert$AssertQuery.returns(CalciteAssert.java:1433)
> at
> org.apache.calcite.test.CalciteAssert$AssertQuery.returns(CalciteAssert.java:1396)
> at
> org.apache.calcite.test.JdbcTest.testDynamicParameterInLimitOffset(JdbcTest.java:5448){code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)