[ 
https://issues.apache.org/jira/browse/CALCITE-6244?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17814429#comment-17814429
 ] 

Julian Hyde commented on CALCITE-6244:
--------------------------------------

Do you propose to allow any class with public fields? I’d be happier if you 
supported some particular models, such as records, that we can verify are 
immutable. And add tests for each model. 

You say “use reflection”, and using reflection when building the AST is fine, 
but maybe not fine if the generated code uses reflection. I want the generated 
code to be such that Javac can do constant reduction. 

> 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
>
> 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)

Reply via email to