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)