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

Reply via email to