6

我想在不使用 jdbc 连接的情况下使用 apache calcite api raw。我可以很好地使用 jdbc api,但是在尝试使用 api 时出现空 ptr 异常。到目前为止我所做的是:

package calcite.examples

import java.util.Properties

import calcite.demo.DemoSchema
import org.apache.calcite.DataContext
import org.apache.calcite.config.CalciteConnectionConfigImpl
import org.apache.calcite.jdbc.CalcitePrepare.Query
import org.apache.calcite.jdbc.{CalcitePrepare, CalciteSchema, JavaTypeFactoryImpl}
import org.apache.calcite.prepare.CalcitePrepareImpl

import scala.collection.JavaConverters._

object TryIt extends App
{
    val ctx = new AdapterContext
    val sql = Query.of[Any]("SELECT * FROM dep")
    //  assert(sql.rel != null)

    val elementType = classOf[Array[Object]]
    val prepared = new CalcitePrepareImpl().prepareSql(ctx, sql, elementType, -1)
    val enumerable = prepared.enumerable(new MyDataContext)
}

class AdapterContext extends CalcitePrepare.Context
{
    private val properties = new Properties
    private val rootSchema = CalciteSchema.createRootSchema(true)
    rootSchema.add("default", new DemoSchema)

    // default schema names
    override def getDefaultSchemaPath = List("default").asJava

    override def spark() = {
        val enable = config.spark
        CalcitePrepare.Dummy.getSparkHandler(enable)
    }

    override val config = new CalciteConnectionConfigImpl(properties)

    override val getTypeFactory = new JavaTypeFactoryImpl

    override def getRootSchema = rootSchema

    override def getDataContext = new MyDataContext
}

class MyDataContext extends DataContext
{
    override def get(name: String) = {
        println(s"MyDataContext name=$name")
        null
    }

    override def getTypeFactory = ???

    override def getQueryProvider = ???

    override def getRootSchema = ???
}

但是当我运行这个时,我得到

MyDataContext 名称=v0stashed

Exception in thread "main" java.lang.NullPointerException
at org.apache.calcite.interpreter.Interpreter.<init>(Interpreter.java:71)
at Baz.bind(Unknown Source)
at org.apache.calcite.jdbc.CalcitePrepare$CalciteSignature.enumerable(CalcitePrepare.java:327)
at calcite.examples.TryIt$.delayedEndpoint$calcite$examples$TryIt$1(TryIt.scala:26)
at calcite.examples.TryIt$delayedInit$body.apply(TryIt.scala:18)
at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:381)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
at scala.App$class.main(App.scala:76)
at calcite.examples.TryIt$.main(TryIt.scala:18)
at calcite.examples.TryIt.main(TryIt.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

请注意,它试图从上下文中获取 v0stashed,我不知道它应该是什么。我看到的唯一 CalcitePrepare.Context impl 是使用 CalciteConnection 的,我试图避免使用它。我还从方解石文档中获取了一些代码片段,但它在方解石 1.7 中已经过时了

想法?

4

2 回答 2

1

There's some crazy stuff going on here apparently. You need to pass internalParameters that you get out of the prepare call into your DataContext, and look them up in get. Apparently Calcite uses this to pass the query object around. You probably want to implement the other DataContext keys (current time, etc) as well.

final class MyDataContext(rootSchema: SchemaPlus, map: util.Map[String, Object])
        extends DataContext {
    override def get(name: String): AnyRef = map.get(name)

...
}

// ctx is your AdapterContext from above
val prepared = new CalcitePrepareImpl().prepareSql(ctx, query, classOf[Array[Object]], -1)
val dataContext = new DerpDataContext(
  ctx.getRootSchema.plus(),
  prepared.internalParameters
)
于 2019-03-29T19:31:01.677 回答
0

这应该几乎可以工作,我也有同样的事情,使用JdbcSchema. 我的预感是您正在尝试使用 spark 模式,并且仅从 Calcite 中的版本号来看,我认为它的维护不是很好。尝试一个更简单的模式,比如反射 HR 模式,或者 JDBC 模式,它应该可以工作,只需对你拥有的内容进行一些小改动。

于 2016-04-12T22:40:22.907 回答