Wegdan Ghazi created CALCITE-6244:
-------------------------------------
Summary: Improve `Expressions#constant` to allow passing models
with non-public fields
Key: CALCITE-6244
URL: https://issues.apache.org/jira/browse/CALCITE-6244
Project: Calcite
Issue Type: Improvement
Components: avatica
Reporter: Wegdan Ghazi
Assignee: Wegdan Ghazi
To use
[Expressions#constant|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java#L540]
with complex models, it's required to pass a model with public fields, as can
be seen in this
[test|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java#L865].
i.e. to successfully pass an instance of `Employee`, it must be defined as
follows:
{code:java}
public static class Employee {
public final int empno;
public final String name;
public final int deptno; public Employee(int empno, String name, int
deptno) {
this.empno = empno;
this.name = name;
this.deptno = deptno;
} public String toString() {
return "Employee(name: " + name + ", deptno:" + deptno + ")";
} @Override public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + deptno;
result = prime * result + empno;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
} @Override public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Employee other = (Employee) obj;
if (deptno != other.deptno) {
return false;
}
if (empno != other.empno) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
} {code}
This makes it difficult to use generated classes e.g. Java records or
immutables, or even encapsulated POJOs to pass through Linq4j.
This is caused by the logic to
[explore|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L299]
and
[create|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L216]
the model constructor; which depends on:
{code:java}
value.getClass().getFields() {code}
which only accesses public fields.
{*}Proposed solution{*}: Access fields using reflection, by accessing their
getter methods.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)