1

I'm trying to create a simple schema using ReflectiveSchema and then trying to project an Employee "table" using Groovy as my programming language. Code below.

class CalciteDemo {
    String doDemo() {        
        RelNode node = new CalciteAlgebraBuilder().build()
        return RelOptUtil.toString(node)                
    }   

    class DummySchema {
        public final Employee[] emp = [new Employee(1, "Ting"), new Employee(2, "Tong")]

        @Override
        String toString() {
            return "DummySchema"
        }

        class Employee {
            Employee(int id, String name) {
                this.id = id
                this.name = name
            }
            public final int id
            public final String name
        }
    }

    class CalciteAlgebraBuilder {        
        FrameworkConfig config

        CalciteAlgebraBuilder() {            
            SchemaPlus rootSchema = Frameworks.createRootSchema(true)
            Schema schema = new ReflectiveSchema(new DummySchema())
            SchemaPlus rootPlusDummy = rootSchema.add("dummySchema", schema)
            this.config = Frameworks.newConfigBuilder().parserConfig(SqlParser.Config.DEFAULT).defaultSchema(rootPlusDummy).traitDefs((List<RelTraitDef>)null).build()
        }

        RelNode build() {
            RelBuilder.create(config).scan("emp").build()
        }
    }
}

I seem to be correctly passing in the "schema" object to the constructor of the ReflectiveSchema class, but I think its failing while trying to get the fields of the Employee class.

Here's the error

java.lang.StackOverflowError
    at java.lang.Class.copyFields(Class.java:3115)
    at java.lang.Class.getFields(Class.java:1557)
    at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createStructType(JavaTypeFactoryImpl.java:76)
    at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createType(JavaTypeFactoryImpl.java:160)
    at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createType(JavaTypeFactoryImpl.java:151)
    at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createStructType(JavaTypeFactoryImpl.java:84)
    at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createType(JavaTypeFactoryImpl.java:160)
    at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createStructType(JavaTypeFactoryImpl.java:84)

What is wrong with this example?

Abbas Gadhia
  • 14,532
  • 10
  • 61
  • 73

1 Answers1

2

Seems that by just moving the Employee class a level above, ie. making it a sibling of the DummySchema class, makes the problem go away.

I think the way the org.apache.calcite.jdbc.JavaTypeFactoryImpl of Calcite is written doesn't handle Groovy's internal fields well.

Abbas Gadhia
  • 14,532
  • 10
  • 61
  • 73