apache calcite, запрос без использования API JDBC
Я хотел бы использовать apache calcite api raw без использования соединений jdbc. Я могу использовать API jdbc просто отлично, но я получаю исключения null ptr при попытке использовать API. Что я сделал до сих пор:
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 name=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, использует CalciteConnection, которого я стараюсь избегать. Также я взял фрагменты кода из документов кальцита, но он был устаревшим с кальцитом 1.7
Идеи?
1 ответ
Очевидно, здесь происходят какие-то безумные вещи. Вам нужно пройтиinternalParameters
что вы выходите из вызова подготовки в свой DataContext и просматриваете их в get
. По-видимому, Calcite использует это для передачи объекта запроса. Вероятно, вы захотите реализовать и другие ключи DataContext (текущее время и т. Д.).
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
)
Это должно почти сработать, у меня то же самое с некоторыми вещами, измененными с помощью JdbcSchema
, Я догадываюсь, что вы пытаетесь использовать схему spark, и, судя по номерам версий в Calcite, я не думаю, что она поддерживается очень хорошо. Попробуйте более простую схему, например рефлексивную схему HR или схему JDBC, и она должна работать, с небольшими изменениями того, что у вас есть.