[ 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)