簡體   English   中英

如何創建同時也是 ScannableTable 的 StreamableTable(Apache Calcite)?

[英]How to create a StreamableTable which is also a ScannableTable (Apache Calcite)?

我希望實現一個org.apache.calcite.schema.Table ,它可以用作 stream 以及一個表。

我正在瀏覽 Calcite 文檔, 這里提到了一個Orders表的示例,它是一個 stream 以及表。 它還提到以下兩個查詢都適用於此Orders表/流,

SELECT STREAM * FROM Orders;

SELECT * FROM Orders;

我正在嘗試實現一個 class,其實例就是這樣的表。 我實現了StreamableTable接口和ScannableTable接口,但仍然無法讓它同時工作。 當我嘗試執行非流查詢(如SELECT * FROM TEST_TABLE )時,出現以下錯誤,

Caused by: org.apache.calcite.runtime.CalciteContextException: From line 1, column 15 to line 1, column 38: Cannot convert stream 'TEST_TABLE' to relation
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.apache.calcite.runtime.Resources$ExInstWithCause.ex(Resources.java:467)
at org.apache.calcite.sql.SqlUtil.newContextException(SqlUtil.java:883)
at org.apache.calcite.sql.SqlUtil.newContextException(SqlUtil.java:868)
at org.apache.calcite.sql.validate.SqlValidatorImpl.newValidationError(SqlValidatorImpl.java:5043)
at org.apache.calcite.sql.validate.SqlValidatorImpl.validateModality(SqlValidatorImpl.java:3739)
at org.apache.calcite.sql.validate.SqlValidatorImpl.validateModality(SqlValidatorImpl.java:3664)
at org.apache.calcite.sql.validate.SqlValidatorImpl.validateQuery(SqlValidatorImpl.java:1048)
at org.apache.calcite.sql.SqlSelect.validate(SqlSelect.java:232)
at org.apache.calcite.sql.validate.SqlValidatorImpl.validateScopedExpression(SqlValidatorImpl.java:1016)
at org.apache.calcite.sql.validate.SqlValidatorImpl.validate(SqlValidatorImpl.java:724)
at org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(SqlToRelConverter.java:567)
at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:242)
at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:208)
at org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:642)
at org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:508)
at org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:478)
at org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:231)
at org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:556)
at org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:675)
at org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:156)
... 3 more

SELECT STREAM * FROM TEST_TABLE這樣的查詢按預期工作。

有人可以幫我創建這樣一個表嗎?

Select * FROM Orders的形式是RELATION但該表是StreamableTable的一個實例,這就是拋出上述異常的原因。 我如下更改了RelOptTableImpl#supportsModality

  @Override public boolean supportsModality(SqlModality modality) {
    switch (modality) {
    case STREAM:
      return table instanceof StreamableTable;
    default:
      // check whether the table is scannable 
      if (table instanceof ScannableTable) {
        return true;
      }
      return !(table instanceof StreamableTable);
    }
  }

對於上面的 SQL,現在生成的計划照常:

邏輯:

LogicalProject(ROWTIME=[$0], ID=[$1], PRODUCT=[$2], UNITS=[$3])
  LogicalTableScan(table=[[STREAMS, ORDERS]])

身體的:

EnumerableTableScan(table=[[STREAMS, ORDERS]])

結果集開始於:

ROWTIME=2015-02-15 10:15:00; ID=1; PRODUCT=paint; UNITS=10",
ROWTIME=2015-02-15 10:24:15; ID=2; PRODUCT=paper; UNITS=5"

您可以使用上述更改在 StreamTest 中為此創建一個測試用例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM