将 ROW() 用于嵌套数据结构
Using ROW() for nested data structure
我已经成功地使用来自 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 扰乱了,正如堆栈跟踪所说:
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() 吗?
这是一个错误吗?
进一步挖掘后,我得出以下结果:你只需要与 ROW() 很好地交谈即可。
这会起作用:
INSERT INTO outputTable
SELECT ROW(col1, col2)
FROM (
SELECT
col1,
ROW(col1, col1) as col2
FROM inputTable
) tbl2
注:
- 嵌套:可能SQL只允许一层嵌套。但是您可以使用多个 table 表达式。我的看法是,Flink 目前在将 SQL 语义推送到执行引擎之前几乎没有做任何转换。执行计划将在单个单元中创建一个融合的 ROW(col1, ROW(col1, col1)),因此影响不大。
- ROW(col1, col1): 辅助 table 中的 ROW(col1) 将不起作用。 (它将在第一个 table 中独立运行)。不知道为什么。但是,嘿,当我只有一个值时,我真的需要它吗?我可以折叠那个值。如果您在输出模式中有一些余地,这将不是问题。
我在这里提交了一个 JIRA 问题:
https://issues.apache.org/jira/projects/FLINK/issues/FLINK-11399
将相应更新post
我已经成功地使用来自 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 扰乱了,正如堆栈跟踪所说:
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() 吗?
这是一个错误吗?
进一步挖掘后,我得出以下结果:你只需要与 ROW() 很好地交谈即可。
这会起作用:
INSERT INTO outputTable
SELECT ROW(col1, col2)
FROM (
SELECT
col1,
ROW(col1, col1) as col2
FROM inputTable
) tbl2
注:
- 嵌套:可能SQL只允许一层嵌套。但是您可以使用多个 table 表达式。我的看法是,Flink 目前在将 SQL 语义推送到执行引擎之前几乎没有做任何转换。执行计划将在单个单元中创建一个融合的 ROW(col1, ROW(col1, col1)),因此影响不大。
- ROW(col1, col1): 辅助 table 中的 ROW(col1) 将不起作用。 (它将在第一个 table 中独立运行)。不知道为什么。但是,嘿,当我只有一个值时,我真的需要它吗?我可以折叠那个值。如果您在输出模式中有一些余地,这将不是问题。
我在这里提交了一个 JIRA 问题:
https://issues.apache.org/jira/projects/FLINK/issues/FLINK-11399
将相应更新post