Uploaded image for project: 'Calcite'
  1. Calcite
  2. CALCITE-1882

Can't obtain the user defined aggregate function such as sum,avg by calcite

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical
    • Resolution: Cannot Reproduce
    • Affects Version/s: 1.12.0
    • Fix Version/s: 1.21.0
    • Component/s: None

      Description

      If we want to register a sum or avg aggregate function to deal with different data type such as sum(double) ,we implement a SqlUserDefinedAggFunction and register with name sum,but when we execute a sql like:

      select id,sum(payment) from table test group by id
      

      in fact,it always give the SqlSumAggFunction function which builtin by calcite,never find the exactly function which we register by ourself.

      During sql parse process,method createCall in SqlAbstractParserImpl will be called,

        protected SqlCall createCall(
            SqlIdentifier funName,
            SqlParserPos pos,
            SqlFunctionCategory funcType,
            SqlLiteral functionQualifier,
            SqlNode[] operands) {
          SqlOperator fun = null;
      
          // First, try a half-hearted resolution as a builtin function.
          // If we find one, use it; this will guarantee that we
          // preserve the correct syntax (i.e. don't quote builtin function
          /// name when regenerating SQL).
          if (funName.isSimple()) {
            final List<SqlOperator> list = Lists.newArrayList();
            opTab.lookupOperatorOverloads(funName, funcType, SqlSyntax.FUNCTION, list);//we lookup in SqlStdOperatorTable,and always find buidin function for sum ,avg .eg
            if (list.size() == 1) {
              fun = list.get(0);
            }
          }
      
          // Otherwise, just create a placeholder function.  Later, during
          // validation, it will be resolved into a real function reference.
          if (fun == null) {
            fun = new SqlUnresolvedFunction(funName, null, null, null, null,
                funcType);
          }
      
          return fun.createCall(functionQualifier, pos, operands);
        }
      

      but the problem will be appear in deriveType,because of we get the SqlSumAggFunction previously,and the sqlKind of SqlSumAggFunction is AVG,but the sqlKind of sql user defined agg function (sum) which we register by ourself is OTHER_FUNCTION,so it filter out our sum function.

        private static Iterator<SqlOperator>
        filterOperatorRoutinesByKind(Iterator<SqlOperator> routines,
            final SqlKind sqlKind) {
          return Iterators.filter(routines,
              new PredicateImpl<SqlOperator>() {
                public boolean test(SqlOperator input) {
                  return input.getKind() == sqlKind;
                }
              });
        }
      

      that cause we never obtain sum function which registered by user .

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                yuemeng yuemeng
                Reporter:
                yuemeng yuemeng
              • Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 20m
                  20m