[
https://issues.apache.org/jira/browse/CALCITE-4708?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17926287#comment-17926287
]
Vladimir Polukeev commented on CALCITE-4708:
--------------------------------------------
[~asimeshin] you proposal very interesting and promising. It looks more
convinient and easy to use for framework user rather than proposal described in
issue description. But I have only one concern about your solution. It is java
restrictions to access to private fields of class. I think this question
requires investigation. For example, are private fields accessable in JDK 17+
without additional configuration? For example, is it safe to use
accessable(true) on field in framework?
Also I completely agree with your about using collection. Arrays in Java have
some restrictions therefore they are rarely used in modern Java application as
I see today. Developers prefer different type collections.
And finally, there is some issue with this proposal. PR at Github is still open
and there is no comments or decision regarding this issue from framework
development team.
> Infer list generic type while Table instance is created at ReflectiveSchema
> class
> ---------------------------------------------------------------------------------
>
> Key: CALCITE-4708
> URL: https://issues.apache.org/jira/browse/CALCITE-4708
> Project: Calcite
> Issue Type: Improvement
> Components: core
> Affects Versions: 1.27.0
> Environment: Ubuntu 18.04
> Java 11
> Maven 3.6.0
> Reporter: Vladimir Polukeev
> Priority: Major
> Labels: pull-request-available
> Time Spent: 10m
> Remaining Estimate: 0h
>
> I have such code:
> {code:java}
> //
> public class Main {
> public static void main(String[] args) throws SQLException {
> // 1. Create calcite connection
> Properties info = new Properties();
> info.setProperty("lex", "JAVA");
> try(Connection connection =
> DriverManager.getConnection("jdbc:calcite:", info)) {
> Employee employee1 = new Employee("first name 1", "last name 1");
> Employee employee2 = new Employee("first name 2", "last name 2");
> Employee employee3 = new Employee("first name 3", "last name 3");
>
>
> List<Employee> employeeList = new LinkedList<>();
> employeeList.add(employee1);
> employeeList.add(employee2);
> employeeList.add(employee3);
> MyScheme myScheme = new MyScheme();
> myScheme.employees = employeeList;
> Schema schema = new ReflectiveSchema(myScheme);
> // 2. add scheme with data to root scheme
> CalciteConnection calciteConnection =
> connection.unwrap(CalciteConnection.class);
> SchemaPlus rootSchema = calciteConnection.getRootSchema();
> rootSchema.add("cache", schema);
> // 3. execute sql query against scheme
> String sql = "select e.* from cache.employees e";
> ResultSet resultSet =
> calciteConnection.createStatement().executeQuery(sql);
>
> // 4. read data from result set
> while (resultSet.next()) {
> printValues(resultSet);
> }
> }
> }
> public static class MyScheme {
> public List<Employee> employees;
> }
> @AllArgsConstructor
> public static class Employee {
> public String firstName;
> public String lastName;
> }
> public static void printValues(ResultSet resultSet) throws SQLException {
> System.out.println("--------------- row " + resultSet.getRow() + "
> ---------------");
> ResultSetMetaData metaData = resultSet.getMetaData();
> for (int i = 1; i <= metaData.getColumnCount(); i++) {
> String columnName = metaData.getColumnName(i);
> System.out.println(columnName + " : " +
> resultSet.getObject(columnName));
> }
> }
> }
> {code}
>
> Code execution output:
> {noformat}
> --------------- row 1 ---------------
> --------------- row 2 ---------------
> --------------- row 3 ---------------{noformat}
>
> Calcite correctly gets 3 rows, but there is no information about columns at
> output due to item class at Iterable collection infer as Object.class. Here
> is code from ReflectiveSchema.class:
>
> {code:java}
> //
> private static @Nullable Type getElementType(Class clazz) {
> if (clazz.isArray()) {
> return clazz.getComponentType();
> }
> if (Iterable.class.isAssignableFrom(clazz)) {
> return Object.class;
> }
> return null; // not a collection/array/iterable
> }
> {code}
>
>
> Information about columns is retured If I change List<Employee> to Employee[]
> at MyScheme.class. But I have to use List due to my task requirement.
> I manage this issue such way:
> Java compiler erise information about generic type at compile time. Therefore
> I supply information about class using annotation
> org.apache.calcite.adapter.java.Array:
> {code:java}
> //
> public static class MyScheme {
> + @Array(component = Employee.class)
> public List<Employee> employees;
> }
> {code}
> Than I read element type from annotation at runtime. Here is code from
> improved ReflectiveSchema.class:
> {code:java}
> //
> private <T> @Nullable Table fieldRelation(final Field field) {
> + Array arrayAnnotation = field.getAnnotation(Array.class);
> + Class<?> elementListClass = arrayAnnotation != null ?
> arrayAnnotation.component() : null;
> + final Type elementType = getElementType(field.getType(),
> elementListClass);
> ... // redundant method code is omitted
> }
> {code}
> Finally, I return type according to information retrieved from Array
> annotation:
> {code:java}
> //
> + private static @Nullable Type getElementType(Class clazz, Class<?>
> elementListClass) {
> if (clazz.isArray()) {
> return clazz.getComponentType();
> }
> if (Iterable.class.isAssignableFrom(clazz)) {
> + return elementListClass != null ? elementListClass : Object.class;
> }
> return null; // not a collection/array/iterable
> }
> {code}
>
> Now, code execution output:
> {noformat}
> --------------- row 1 ---------------
> firstName : first name 1
> lastName : last name 1
> --------------- row 2 ---------------
> firstName : first name 2
> lastName : last name 2
> --------------- row 3 ---------------
> firstName : first name 3
> lastName : last name 3{noformat}
>
> Does such improvement fit to framework design? Can I create pull request in
> order to make such improvement?
--
This message was sent by Atlassian Jira
(v8.20.10#820010)