[
https://issues.apache.org/jira/browse/CALCITE-6244?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Wegdan Ghazi updated CALCITE-6244:
----------------------------------
Fix Version/s: 1.37.0
> 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: linq4j
> Reporter: Wegdan Ghazi
> Assignee: Wegdan Ghazi
> Priority: Minor
> Fix For: 1.37.0
>
>
> 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)