[
https://issues.apache.org/jira/browse/CALCITE-2282?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16820939#comment-16820939
]
Lai Zhou edited comment on CALCITE-2282 at 4/18/19 10:22 AM:
-------------------------------------------------------------
[~julianhyde], I think we should let the validator to resolve operators , the
parser only need to parse the sql . After the parser parsed the sql, we just
have unresolved functions.
I'm working to bridge the hive functions to calcite these days.
Since implementing a whole function list for a DB is an amount of work and
boring,I just want to make the parser and the functions compatible with hive
,so I hope to reuse the built-in functions of Calcite as possible.
I made some extensions to reach it:
# introduce a HiveSqlOperatorTable which extends ReflectiveSqlOperatorTable to
lookupOperatorOverloads, so I can plugin some new operators or replace the
built-in operators of Calcite. For example, I want to implement a Hive DIVIDE
operator, then I redefined it:
{code:java}
/**
* replace the DIVIDE FUNCTION in Parser.jj, Inferring type is not right by
* {@link SqlStdOperatorTable#DIVIDE}
*/
public static final SqlBinaryOperator DIVIDE =
new SqlBinaryOperator(
"/",
SqlKind.DIVIDE,
60,
true,
HiveSqlUDFReturnTypeInference.INSTANCE,
null,
HiveSqlFunction.ArgChecker.INSTANCE);
{code}
2.introduce a post processor for RexImpTable, to define Implementors . Here is
some part of the code :
{code:java}
private void defineImplementors() {
//define implementors for hive operator
final List<SqlOperator> operatorList = getOperatorList();
RexImpTable.INSTANCE.defineImplementors((map, aggMap, winAggMap) -> {
for (SqlOperator sqlOperator : operatorList) {
if (sqlOperator instanceof HiveSqlAggFunction) {
HiveSqlAggFunction aggFunction = (HiveSqlAggFunction) sqlOperator;
aggMap.put(aggFunction, () -> new HiveUDAFImplementor(aggFunction));
} else {
/**since SqlOperator is identified by name and kind ,see
* {@link SqlOperator#equals(Object)} and
* {@link SqlOperator#hashCode()},
* we can override implementors of operators that declared in
* SqlStdOperatorTable
* */
CallImplementor callImplementor;
if (sqlOperator.getName().equals("NOT RLIKE")) {
callImplementor =
RexImpTable.createImplementor(
RexImpTable.NotImplementor.of(
new HiveUDFImplementor()), NullPolicy.STRICT, false);
} else {
callImplementor =
RexImpTable.createImplementor(
new HiveUDFImplementor(), NullPolicy.NONE, false);
}
map.put(sqlOperator, callImplementor);
}
}
// directly override some implementors of SqlOperator that declared in
// SqlStdOperatorTable
map.put(SqlStdOperatorTable.ITEM,
new RexImpTable.ItemImplementor(true));
});
{code}
The way to achieve my goal might be quick and dirty , if Calcite can be more
pluggable, it will be friendly to people who wants to use calcite to make a new
sql engine.
was (Author: hhlai1990):
[~julianhyde], I think we should let the validator to resolve operators , the
parser only need to parse the sql . After the parser parsed the sql, we just
have unresolved functions.
I'm working to bridge the hive functions to calcite these days.
Since implementing a whole function list for a DB is an amount of work and
boring,I just want to make the parser and the functions compatible with hive
,so I hope to reuse the built-in functions of Calcite as possible.
I made some extensions to reach it:
# introduce a HiveSqlOperatorTable which extends ReflectiveSqlOperatorTable to
lookupOperatorOverloads, so I can plugin some new operators or replace the
built-in operators of Calcite. For example, I want to implement a Hive DIVIDE
operator, then I redefined it:
{code:java}
/**
* replace the DIVIDE FUNCTION in Parser.jj, Inferring type is not right by
* {@link SqlStdOperatorTable#DIVIDE}
*/
public static final SqlBinaryOperator DIVIDE =
new SqlBinaryOperator(
"/",
SqlKind.DIVIDE,
60,
true,
HiveSqlUDFReturnTypeInference.INSTANCE,
null,
HiveSqlFunction.ArgChecker.INSTANCE);
{code}
2.introduce a post processor for RexImpTable, to define Implementors . Here is
some part of the code :
{code:java}
private void defineImplementors() {
//define implementors for hive operator
final List<SqlOperator> operatorList = getOperatorList();
RexImpTable.INSTANCE.defineImplementors((map, aggMap, winAggMap) -> {
for (SqlOperator sqlOperator : operatorList) {
if (sqlOperator instanceof HiveSqlAggFunction) {
HiveSqlAggFunction aggFunction = (HiveSqlAggFunction) sqlOperator;
aggMap.put(aggFunction, () -> new HiveUDAFImplementor(aggFunction));
} else {
/**since SqlOperator is identified by name and kind ,see
* {@link SqlOperator#equals(Object)} and
* {@link SqlOperator#hashCode()},
* we can override implementors of operators that declared in
* SqlStdOperatorTable
* */
CallImplementor callImplementor;
if (sqlOperator.getName().equals("NOT RLIKE")) {
callImplementor =
RexImpTable.createImplementor(
RexImpTable.NotImplementor.of(
new HiveUDFImplementor()), NullPolicy.STRICT, false);
} else {
callImplementor =
RexImpTable.createImplementor(
new HiveUDFImplementor(), NullPolicy.NONE, false);
}
map.put(sqlOperator, callImplementor);
}
}
// directly override some implementors of SqlOperator that declared in
// SqlStdOperatorTable
map.put(SqlStdOperatorTable.ITEM,
new RexImpTable.ItemImplementor(true));
});
{code}
The way to achieve my goal might be quick and dirty , but I think it will be
friendly to people who wants to use calcite to make a new sql engine.
> Allow OperatorTable to be pluggable in the parser
> -------------------------------------------------
>
> Key: CALCITE-2282
> URL: https://issues.apache.org/jira/browse/CALCITE-2282
> Project: Calcite
> Issue Type: Bug
> Components: core
> Reporter: Sudheesh Katkam
> Priority: Major
> Attachments: CALCITE-2282.patch.txt
>
>
> SqlAbstractParserImpl [hardcodes OperatorTable to
> SqlStdOperatorTable|https://github.com/apache/calcite/blob/8327e674e7f0a768d124fa37fd75cda4b8a35bb6/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java#L334|https://github.com/apache/calcite/blob/8327e674e7f0a768d124fa37fd75cda4b8a35bb6/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java#L334].
> Make this pluggable via a protected method.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)