-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CALCITE-1581] UDTF like in hive #1138
[CALCITE-1581] UDTF like in hive #1138
Conversation
20fbc8a
to
8d17df4
Compare
8d17df4
to
11c067f
Compare
@@ -1320,6 +1331,175 @@ protected SqlNode performUnconditionalRewrites( | |||
return node; | |||
} | |||
|
|||
private SqlNode performHiveUdtfRewrite(SqlNode node) { | |||
Map<SqlSelect, UdtfInfo> selectUdtfInfo = new HashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add some comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done! Thanks for the review.
Map<SqlSelect, UdtfInfo> selectUdtfInfo = new HashMap<>(); | ||
SqlNode rewirte = performHiveUdtfRewriteInternal(node, selectUdtfInfo); | ||
// System.out.println("before:\n" + node.toString() +" \nafter:\n" + rewirte.toString()); | ||
return node; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should remove this useless comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to push this test code.remove now!
private SqlNode performHiveUdtfRewriteInternal(SqlNode current, | ||
Map<SqlSelect, UdtfInfo> selectUdtfInfos) { | ||
System.out.println("start rewrite:" + current); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't print anything in general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for push this test code,remove now!
// join the from node with the table function. | ||
if (udtfInfo != null && select.getFrom() != null) { | ||
SqlBasicCall joinRight = createLateralTable(udtfInfo); | ||
SqlNode newFrom = new SqlJoin( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use SqlCall
instead of SqlBasicCall
is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well,the createLateralTable() method return a "as" node, so it must be a SqlBasicCall.
ed821b5
to
635914d
Compare
@BaseMessage("''{0}'' should be a table function") | ||
ExInst<SqlValidatorException> exceptTableFunction(String name); | ||
|
||
@BaseMessage("Only one table function allowed in select list") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is allowed
for (int i = 0; i < info.fieldNames.size(); i++) { | ||
operands[2 + i] = info.fieldNames.get(i); | ||
} | ||
SqlBasicCall lateralTableAs = new SqlBasicCall(asOp, operands, SqlParserPos.ZERO); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can directly return new SqlBasicCall(asOp, operands, SqlParserPos.ZERO);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed! Thanks for you review!
tableFunctionInfo.node = (SqlBasicCall) udtfNode; | ||
tableFunctionInfo.selectIndex = i; | ||
tableFunctionInfo.fieldNames = (SqlNodeList) aliasNode; | ||
tableFunctionInfo.tableName = "_table_function_" + nextTableFunctionNameId++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make "_table_function_"
a constant string may be better like
public static final String TABLE_FUNCTION_PREFIX = "_table_function_"
The global variables nextTableFunctionNameId
once use once in this function is a little odd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you than make "table_function" as constant. But nextTableFunctionNameId
should be a global variable in SqlValidatorImpl
, as we may reuse the SqlValidatorImpl
to validator different SqlNode
. It is better to differentiate the table function in different SqlNode
.
86684b8
to
48942ba
Compare
18fd91c
to
486c3c2
Compare
@pengzhiwei2018 Could you take a look at the conflicts here? |
d4704e9
to
d649921
Compare
Thanks for start this review! Done for it! |
b6a2dcc
to
41ae5d1
Compare
41ae5d1
to
893d69d
Compare
5a9d3d3
to
892ab01
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
a90cd98
to
2e176f0
Compare
2e176f0
to
86f26ae
Compare
31bba48
to
beaf125
Compare
final SqlIdentifier id; | ||
SqlIdentifier id; | ||
final List<SqlNode> ids = new ArrayList(); | ||
final Span s = span(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename ids
to columnAliases
and id
to columnAlias
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for you suggestions.
aliases.addAll(aliasList); | ||
|
||
String tableAlias = TABLE_FUNCTION_PREFIX + nextGeneratedId++; | ||
// Expand the table function alias |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just use the function name as the alias prefix, the TABLE_FUNCTION_PREFIX
seems unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your suggestion. done!
scopes.put(functionCall, tableScope); | ||
// Associate the select with the table function | ||
selectTableFunctions.put(parentSelect, functionCall); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm skeptical about this member selectTableFunctions
, the SqlValidator never has such mapping, it handles all the states to the "Namespace" and "scope", i'm wondering if we can move this mapping into each scope, because each select has a scope. Thus, we can keep the validator code clean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think selectTableFunctions
is the same to the whereScopes
or groupByScopes
in the SqlValidatorImpl
.
@@ -294,6 +299,9 @@ | |||
// Flag saying if we enable the implicit type coercion. | |||
private boolean enableTypeCoercion; | |||
|
|||
// Maping the table function and the select node. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo -- "Mapping between select node and table function. "
<RPAREN> { | ||
if (!this.conformance.allowSelectTableFunction()) { | ||
throw SqlUtil.newContextException(getPos(), | ||
RESOURCE.notAllowTableFunctionInSelect()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indent: 4 spaces
throw SqlUtil.newContextException(getPos(), | ||
RESOURCE.notAllowTableFunctionInSelect()); | ||
} | ||
e = SqlStdOperatorTable.AS.createCall(s.end(e), e, new SqlNodeList(ids, s.end(e))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though less than 100 characters, but shall we break the line ?
assert asIdentifier instanceof SqlIdentifier | ||
|| (asIdentifier instanceof SqlNodeList | ||
&& validator.getConformance().allowSelectTableFunction()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused. In validateSelectList
, this change has already rewriten the select items by handleTableFunctionInSelect
, how is it possible that SqlAsOperator
does validation here ?
Can you explain or give a test that the assertion can be failed ?
SqlIdentifier id = (SqlIdentifier) ids.get(i); | ||
if (!id.isSimple()) { | ||
throw validator.newValidationError(id, | ||
RESOURCE.aliasMustBeSimpleIdentifier()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indent -- 4 spaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your suggestion.
@@ -408,6 +409,13 @@ | |||
* false otherwise. | |||
*/ | |||
boolean allowPluralTimeUnits(); | |||
|
|||
/** | |||
* Whether SELECT can contain a table function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about SELECT -> select list ?
SQL_SERVER_2008, | ||
|
||
/** Conformance value that instructs Calcite to use SQL semantics | ||
* consistent with Hive version. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the word of version
or specify the version.
beaf125
to
7d1a5bc
Compare
remove unused empty line remove test code & add comment add comment check for more than one table function in select fix test sql make _table_function_ as a constant support table function without from add comment fix conflict move rewrite to SqlToRelConverter fix code style modify comment fix doc issue remove used blank add more test case fix format fix some format issue fix compile failture fix compile error use SqlUtil#newContextException format code
27692d3
to
ed35496
Compare
80f411d
to
ca27fe9
Compare
Thanks @pengzhiwei2018 for the update, maybe i can find some time to review the latest change in this week ~ |
49cb002
to
8768a23
Compare
@pengzhiwei2018 , could you please resolve conflicts? I think it needs a final review and I would like to do that. |
Close because there is already another PR. |
No description provided.