0

参考Calcite 文档的“背景”章节,我定义了以下“表格”:

public class Employee {
    public int empid = 0;
    public int deptno = 0;

    public Employee(int empid, int deptno) {
        this.empid = empid;
        this.deptno = deptno;
    }
}

public class Department {
    public int deptno = 0;

    public Department(int deptno) {
        this.deptno = deptno;
    }
}

和以下“数据库”:

public class HrSchema {
    public final Employee[] emps = new Employee[]{
            new Employee(1, 7),
            new Employee(2, 6),
            new Employee(3, 6)
    };
    public final Department[] depts = new Department[]{
            new Department(7),
            new Department(6)
    };
}

我使用 ReflectiveSchema 与这个“数据库”建立了连接:

Class.forName("org.apache.calcite.jdbc.Driver");
Properties info = new Properties();
info.setProperty("lex", "JAVA");
Connection connection =
        DriverManager.getConnection("jdbc:calcite:", info);
CalciteConnection calciteConnection =
        connection.unwrap(CalciteConnection.class);
SchemaPlus rootSchema = calciteConnection.getRootSchema();
ReflectiveSchema schema = new ReflectiveSchema(new HrSchema());
rootSchema.add("hr", schema);

由于我更喜欢​​ Linq 查询组合而不是 SQL 语句连接,因此在参考LinqFrontJdbcBackTest.java之后,我自适应地进行了以下查询:

ParameterExpression e =
        Expressions.parameter(Employee.class, "e");

List<Employee> s =
        Schemas.queryable(Schemas.createDataContext(connection, rootSchema),
                        rootSchema.getSubSchema("hr"),
                        Employee.class, "emps")
                .where(
                        Expressions.lambda(
                                Expressions.greaterThan(
                                        Expressions.field(e, "empid"),
                                        Expressions.constant(0)
                                ), e)
                )
                .toList();

for (Employee emp : s ) {
    System.out.println(emp.empid);
}

最后我得到了:

Exception in thread "main" java.lang.RuntimeException: Error while compiling generated Java code:
public static class Record2_1 implements java.io.Serializable {
  public int empid;
  public int deptno;
  public Record2_1() {}
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof Record2_1)) {
      return false;
    }
    return this.empid == ((Record2_1) o).empid && this.deptno == ((Record2_1) o).deptno;
  }

  public int hashCode() {
    int h = 0;
    h = org.apache.calcite.runtime.Utilities.hash(h, this.empid);
    h = org.apache.calcite.runtime.Utilities.hash(h, this.deptno);
    return h;
  }

  public int compareTo(Record2_1 that) {
    int c;
    c = org.apache.calcite.runtime.Utilities.compare(this.empid, that.empid);
    if (c != 0) {
      return c;
    }
    c = org.apache.calcite.runtime.Utilities.compare(this.deptno, that.deptno);
    if (c != 0) {
      return c;
    }
    return 0;
  }

  public String toString() {
    return "{empid=" + this.empid + ", deptno=" + this.deptno + "}";
  }

}

public org.apache.calcite.linq4j.Enumerable bind(final org.apache.calcite.DataContext root) {
  final org.apache.calcite.linq4j.Enumerable _inputEnumerable = org.apache.calcite.linq4j.Linq4j.asEnumerable(((demo.HrSchema) ((org.apache.calcite.adapter.java.ReflectiveSchema) root.getRootSchema().getSubSchema("hr").unwrap(org.apache.calcite.adapter.java.ReflectiveSchema.class)).getTarget()).emps);
  return new org.apache.calcite.linq4j.AbstractEnumerable(){
      public org.apache.calcite.linq4j.Enumerator enumerator() {
        return new org.apache.calcite.linq4j.Enumerator(){
            public final org.apache.calcite.linq4j.Enumerator inputEnumerator = _inputEnumerable.enumerator();
            public void reset() {
              inputEnumerator.reset();
            }

            public boolean moveNext() {
              while (inputEnumerator.moveNext()) {
                if (((demo.Employee) inputEnumerator.current()).empid > 0) {
                  return true;
                }
              }
              return false;
            }

            public void close() {
              inputEnumerator.close();
            }

            public Object current() {
              final demo.Employee current = (demo.Employee) inputEnumerator.current();
              return new Record2_1(
                  current.empid,
                  current.deptno);
            }

          };
      }

    };
}


public Class getElementType() {
  return Record2_1.class;
}



    at org.apache.calcite.avatica.Helper.wrap(Helper.java:37)
    at org.apache.calcite.adapter.enumerable.EnumerableInterpretable.toBindable(EnumerableInterpretable.java:129)
    at org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.implement(CalcitePrepareImpl.java:1130)
    at org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.prepare_(CalcitePrepareImpl.java:1032)
    at org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.prepareQueryable(CalcitePrepareImpl.java:979)
    at org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:663)
    at org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:513)
    at org.apache.calcite.prepare.CalcitePrepareImpl.prepareQueryable(CalcitePrepareImpl.java:474)
    at org.apache.calcite.jdbc.CalciteStatement.prepare(CalciteStatement.java:80)
    at org.apache.calcite.jdbc.CalciteConnectionImpl.executeQuery(CalciteConnectionImpl.java:299)
    at org.apache.calcite.linq4j.QueryableDefaults$ReplayableQueryable.enumerator(QueryableDefaults.java:1171)
    at org.apache.calcite.linq4j.EnumerableDefaults.into(EnumerableDefaults.java:3810)
    at org.apache.calcite.linq4j.DefaultEnumerable.into(DefaultEnumerable.java:372)
    at org.apache.calcite.linq4j.EnumerableDefaults.toList(EnumerableDefaults.java:3556)
    at org.apache.calcite.linq4j.DefaultEnumerable.toList(DefaultEnumerable.java:744)
    at demo.Main.main(Main.java:61)
Caused by: org.codehaus.commons.compiler.CompileException: Line 66, Column 25: No applicable constructor/method found for actual parameters "int, int"; candidates are: "Baz$Record2_1()"
    at org.codehaus.janino.UnitCompiler.compileError(UnitCompiler.java:12211)
    at org.codehaus.janino.UnitCompiler.findMostSpecificIInvocable(UnitCompiler.java:9263)
    at org.codehaus.janino.UnitCompiler.invokeConstructor(UnitCompiler.java:7971)
    at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:5409)
    at org.codehaus.janino.UnitCompiler.access$9800(UnitCompiler.java:215)
    at org.codehaus.janino.UnitCompiler$16.visitNewClassInstance(UnitCompiler.java:4435)
    at org.codehaus.janino.UnitCompiler$16.visitNewClassInstance(UnitCompiler.java:4396)
    at org.codehaus.janino.Java$NewClassInstance.accept(Java.java:5190)
    at org.codehaus.janino.UnitCompiler.compileGet(UnitCompiler.java:4396)
    at org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:5662)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:2649)
    at org.codehaus.janino.UnitCompiler.access$2800(UnitCompiler.java:215)
    at org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1504)
    at org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1487)
    at org.codehaus.janino.Java$ReturnStatement.accept(Java.java:3563)
    at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:1487)
    at org.codehaus.janino.UnitCompiler.compileStatements(UnitCompiler.java:1567)
    at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:3388)
    at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1357)
    at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1330)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:822)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:981)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:951)
    at org.codehaus.janino.UnitCompiler.access$200(UnitCompiler.java:215)
    at org.codehaus.janino.UnitCompiler$2.visitAnonymousClassDeclaration(UnitCompiler.java:409)
    at org.codehaus.janino.UnitCompiler$2.visitAnonymousClassDeclaration(UnitCompiler.java:406)
    at org.codehaus.janino.Java$AnonymousClassDeclaration.accept(Java.java:1149)
    at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:406)
    at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:5509)
    at org.codehaus.janino.UnitCompiler.access$9500(UnitCompiler.java:215)
    at org.codehaus.janino.UnitCompiler$16.visitNewAnonymousClassInstance(UnitCompiler.java:4432)
    at org.codehaus.janino.UnitCompiler$16.visitNewAnonymousClassInstance(UnitCompiler.java:4396)
    at org.codehaus.janino.Java$NewAnonymousClassInstance.accept(Java.java:5238)
    at org.codehaus.janino.UnitCompiler.compileGet(UnitCompiler.java:4396)
    at org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:5662)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:2649)
    at org.codehaus.janino.UnitCompiler.access$2800(UnitCompiler.java:215)
    at org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1504)
    at org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1487)
    at org.codehaus.janino.Java$ReturnStatement.accept(Java.java:3563)
    at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:1487)
    at org.codehaus.janino.UnitCompiler.compileStatements(UnitCompiler.java:1567)
    at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:3388)
    at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1357)
    at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1330)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:822)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:981)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:951)
    at org.codehaus.janino.UnitCompiler.access$200(UnitCompiler.java:215)
    at org.codehaus.janino.UnitCompiler$2.visitAnonymousClassDeclaration(UnitCompiler.java:409)
    at org.codehaus.janino.UnitCompiler$2.visitAnonymousClassDeclaration(UnitCompiler.java:406)
    at org.codehaus.janino.Java$AnonymousClassDeclaration.accept(Java.java:1149)
    at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:406)
    at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:5509)
    at org.codehaus.janino.UnitCompiler.access$9500(UnitCompiler.java:215)
    at org.codehaus.janino.UnitCompiler$16.visitNewAnonymousClassInstance(UnitCompiler.java:4432)
    at org.codehaus.janino.UnitCompiler$16.visitNewAnonymousClassInstance(UnitCompiler.java:4396)
    at org.codehaus.janino.Java$NewAnonymousClassInstance.accept(Java.java:5238)
    at org.codehaus.janino.UnitCompiler.compileGet(UnitCompiler.java:4396)
    at org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:5662)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:2649)
    at org.codehaus.janino.UnitCompiler.access$2800(UnitCompiler.java:215)
    at org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1504)
    at org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1487)
    at org.codehaus.janino.Java$ReturnStatement.accept(Java.java:3563)
    at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:1487)
    at org.codehaus.janino.UnitCompiler.compileStatements(UnitCompiler.java:1567)
    at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:3388)
    at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1357)
    at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1330)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:822)
    at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:432)
    at org.codehaus.janino.UnitCompiler.access$400(UnitCompiler.java:215)
    at org.codehaus.janino.UnitCompiler$2.visitPackageMemberClassDeclaration(UnitCompiler.java:411)
    at org.codehaus.janino.UnitCompiler$2.visitPackageMemberClassDeclaration(UnitCompiler.java:406)
    at org.codehaus.janino.Java$PackageMemberClassDeclaration.accept(Java.java:1414)
    at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:406)
    at org.codehaus.janino.UnitCompiler.compileUnit(UnitCompiler.java:378)
    at org.codehaus.janino.SimpleCompiler.cook(SimpleCompiler.java:237)
    at org.codehaus.janino.SimpleCompiler.compileToClassLoader(SimpleCompiler.java:465)
    at org.codehaus.janino.ClassBodyEvaluator.compileToClass(ClassBodyEvaluator.java:313)
    at org.codehaus.janino.ClassBodyEvaluator.cook(ClassBodyEvaluator.java:235)
    at org.codehaus.janino.SimpleCompiler.cook(SimpleCompiler.java:207)
    at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:50)
    at org.codehaus.janino.ClassBodyEvaluator.createInstance(ClassBodyEvaluator.java:347)
    at org.apache.calcite.adapter.enumerable.EnumerableInterpretable.getBindable(EnumerableInterpretable.java:163)
    at org.apache.calcite.adapter.enumerable.EnumerableInterpretable.toBindable(EnumerableInterpretable.java:126)
    ... 14 more

Process finished with exit code 1

但是,如果我替换Expressions.field(e, "empid")Expressions.constant(5),则完全没有问题!查询成功返回:

1
2
3

ReflectiveSchema 与“where”子句中的 Expressions.field 相处一定有问题。因为在“where”子句之外构造表达式没有任何问题。

Expressions.lambda(
        Expressions.greaterThan(
                Expressions.field(e, "empid"),
                Expressions.constant(0)
        ), e);

Expressions.field(e, "empid")必须有正确的字段,因为当表达式稍微修改为 时Expressions.field(e, "empi"),会出现异常:

Exception in thread "main" java.lang.RuntimeException: Unknown field 'empi' in class class demo.Employee
    at org.apache.calcite.linq4j.tree.Types.getField(Types.java:110)
    at org.apache.calcite.linq4j.tree.Types.getField(Types.java:121)
    at org.apache.calcite.linq4j.tree.Expressions.field(Expressions.java:840)
    at demo.main(Main.java:51)
Caused by: java.lang.NoSuchFieldException: empi
    at java.lang.Class.getField(Class.java:1703)
    at org.apache.calcite.linq4j.tree.Types.getField(Types.java:108)
    ... 3 more

有人知道问题出在哪里吗?让“where”子句对基于 ReflectiveSchema 的“数据库”上的包含 ParameterExpression 的 Linq 比较查询有意义所需的任何配置?

4

0 回答 0