将ROW()用于嵌套数据结构

时间:2019-01-16 19:39:33

标签: apache-flink flink-streaming apache-calcite flink-sql

我已经成功地使用了来自flink-json工件的JsonRowSerializationSchema来创建TableSink<Row>并使用ROW从SQL输出json。它非常适合发射 flat 数据:

INSERT INTO outputTable 
SELECT 
  ROW(col1, col1)
FROM inputTable
>>>> OK:
{"outCol1":"dasdasdas","outCol2":"dasdasdas"}

现在,我正在尝试一个嵌套模式,它以一种奇怪的方式分解:

INSERT INTO outputTable 
SELECT 
  ROW('ttt', ROW('ppp'))
FROM inputTable
>>>> OK:
{"outCol1":"ttt","outCol2":{"outCol3":"ppp"}}

INSERT INTO outputTable 
SELECT 
  ROW('ttt', ROW(col1))
FROM inputTable
>>>> OK:
{"outCol1":"ttt","outCol2":{"outCol3":"dasdasdas"}}

INSERT INTO outputTable 
SELECT 
  ROW(col1, ROW(col1))
FROM inputTable
>>>> KO

这是一个解析问题,但是我对为什么会发生这样的问题感到困惑。 col1和'ttt'是String类型的表达式,应该可以替换;但是以某种方式,解析器会受到以下ROW的干扰,如stacktrace所示:

Caused by: org.apache.calcite.sql.parser.impl.ParseException: Encountered ", ROW" at line 3, column 11.
Was expecting one of:
    ")" ...
    "," <IDENTIFIER> ...
    "," <QUOTED_IDENTIFIER> ...
    "," <BACK_QUOTED_IDENTIFIER> ...
    "," <BRACKET_QUOTED_IDENTIFIER> ...
    "," <UNICODE_QUOTED_IDENTIFIER> ...

    at org.apache.calcite.sql.parser.impl.SqlParserImpl.generateParseException(SqlParserImpl.java:23019)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.jj_consume_token(SqlParserImpl.java:22836)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.ParenthesizedSimpleIdentifierList(SqlParserImpl.java:4466)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.Expression3(SqlParserImpl.java:3328)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.Expression2b(SqlParserImpl.java:3066)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.Expression2(SqlParserImpl.java:3092)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.Expression(SqlParserImpl.java:3045)
    at ...

我是否缺少语法方面的内容?解析器试图做什么?我应该以其他方式使用ROW()吗?

这是一个错误吗?

1 个答案:

答案 0 :(得分:0)

进一步研究之后,我得出以下结果:您只需要很好地与ROW()对话即可。

这将起作用:

INSERT INTO outputTable
SELECT ROW(col1, col2) 
FROM (
  SELECT 
    col1, 
    ROW(col1, col1) as col2 
  FROM inputTable
) tbl2

注意:

  • 嵌套:也许SQL仅允许一个嵌套级别。但是您可以使用几个表表达式。我的看法是,在将Flink推送到执行引擎之前,Flink目前几乎不做任何转换SQL语义的操作。执行计划将在单个单元中创建一个融合的ROW(col1,ROW(col1,col1)),因此影响不大。
  • ROW(col1,col1):辅助表中的ROW(col1)将不起作用。 (它将在第一个表中独立运行)。不知道为什么。但是,当我只有一个价值时,我真的需要吗?我可以将这一价值崩溃。如果您在输出模式中有一些余地,这将不是问题。

我已经在此处提交了JIRA问题:

https://issues.apache.org/jira/projects/FLINK/issues/FLINK-11399

将相应地更新此帖子