Search in sources :

Example 36 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project flink by apache.

the class SqlValidatorImpl method deriveConstructorType.

public RelDataType deriveConstructorType(SqlValidatorScope scope, SqlCall call, SqlFunction unresolvedConstructor, SqlFunction resolvedConstructor, List<RelDataType> argTypes) {
    SqlIdentifier sqlIdentifier = unresolvedConstructor.getSqlIdentifier();
    assert sqlIdentifier != null;
    RelDataType type = catalogReader.getNamedType(sqlIdentifier);
    if (type == null) {
        // TODO jvs 12-Feb-2005:  proper type name formatting
        throw newValidationError(sqlIdentifier, RESOURCE.unknownDatatypeName(sqlIdentifier.toString()));
    }
    if (resolvedConstructor == null) {
        if (call.operandCount() > 0) {
            // no user-defined constructor could be found
            throw handleUnresolvedFunction(call, unresolvedConstructor, argTypes, null);
        }
    } else {
        SqlCall testCall = resolvedConstructor.createCall(call.getParserPosition(), call.getOperandList());
        RelDataType returnType = resolvedConstructor.validateOperands(this, scope, testCall);
        assert type == returnType;
    }
    if (config.identifierExpansion()) {
        if (resolvedConstructor != null) {
            ((SqlBasicCall) call).setOperator(resolvedConstructor);
        } else {
            // fake a fully-qualified call to the default constructor
            ((SqlBasicCall) call).setOperator(new SqlFunction(type.getSqlIdentifier(), ReturnTypes.explicit(type), null, null, null, SqlFunctionCategory.USER_DEFINED_CONSTRUCTOR));
        }
    }
    return type;
}
Also used : SqlBasicCall(org.apache.calcite.sql.SqlBasicCall) SqlCall(org.apache.calcite.sql.SqlCall) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlFunction(org.apache.calcite.sql.SqlFunction)

Example 37 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project drill by apache.

the class PreProcessLogicalRel method visit.

@Override
public RelNode visit(LogicalProject project) {
    final List<RexNode> projExpr = Lists.newArrayList();
    for (RexNode rexNode : project.getChildExps()) {
        projExpr.add(rexNode.accept(unwrappingExpressionVisitor));
    }
    project = project.copy(project.getTraitSet(), project.getInput(), projExpr, project.getRowType());
    List<RexNode> exprList = new ArrayList<>();
    boolean rewrite = false;
    for (RexNode rex : project.getChildExps()) {
        RexNode newExpr = rex;
        if (rex instanceof RexCall) {
            RexCall function = (RexCall) rex;
            String functionName = function.getOperator().getName();
            int nArgs = function.getOperands().size();
            // check if its a convert_from or convert_to function
            if (functionName.equalsIgnoreCase("convert_from") || functionName.equalsIgnoreCase("convert_to")) {
                String literal;
                if (nArgs == 2) {
                    if (function.getOperands().get(1) instanceof RexLiteral) {
                        try {
                            literal = ((NlsString) (((RexLiteral) function.getOperands().get(1)).getValue())).getValue();
                        } catch (final ClassCastException e) {
                            // Caused by user entering a value with a non-string literal
                            throw getConvertFunctionInvalidTypeException(function);
                        }
                    } else {
                        // caused by user entering a non-literal
                        throw getConvertFunctionInvalidTypeException(function);
                    }
                } else {
                    // Second operand is missing
                    throw UserException.parseError().message("'%s' expects a string literal as a second argument.", functionName).build(logger);
                }
                RexBuilder builder = new RexBuilder(factory);
                // construct the new function name based on the input argument
                String newFunctionName = functionName + literal;
                // Look up the new function name in the drill operator table
                List<SqlOperator> operatorList = table.getSqlOperator(newFunctionName);
                if (operatorList.size() == 0) {
                    // User typed in an invalid type name
                    throw getConvertFunctionException(functionName, literal);
                }
                SqlFunction newFunction = null;
                // Find the SqlFunction with the correct args
                for (SqlOperator op : operatorList) {
                    if (op.getOperandTypeChecker().getOperandCountRange().isValidCount(nArgs - 1)) {
                        newFunction = (SqlFunction) op;
                        break;
                    }
                }
                if (newFunction == null) {
                    // we are here because we found some dummy convert function. (See DummyConvertFrom and DummyConvertTo)
                    throw getConvertFunctionException(functionName, literal);
                }
                // create the new expression to be used in the rewritten project
                newExpr = builder.makeCall(newFunction, function.getOperands().subList(0, 1));
                rewrite = true;
            }
        }
        exprList.add(newExpr);
    }
    if (rewrite) {
        LogicalProject newProject = project.copy(project.getTraitSet(), project.getInput(0), exprList, project.getRowType());
        return visitChild(newProject, 0, project.getInput());
    }
    return visitChild(project, 0, project.getInput());
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) SqlOperator(org.apache.calcite.sql.SqlOperator) ArrayList(java.util.ArrayList) NlsString(org.apache.calcite.util.NlsString) RexCall(org.apache.calcite.rex.RexCall) RexBuilder(org.apache.calcite.rex.RexBuilder) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode) SqlFunction(org.apache.calcite.sql.SqlFunction)

Example 38 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project drill by apache.

the class DrillTableInfo method prepareTableMacroOperands.

/**
 * Returns list with operands for table function, obtained from specified call in the order
 * suitable to be used in table function and default values for absent arguments.
 * For example, for the following call:
 * <pre>
 *   `dfs`.`corrupted_dates`(`type` => 'parquet', `autoCorrectCorruptDates` => FALSE, `enableStringsSignedMinMax` => FALSE)
 * </pre>
 * will be returned the following list:
 * <pre>
 *   ['parquet', FALSE, FALSE, DEFAULT]
 * </pre>
 * whose elements correspond to the following parameters:
 * <pre>
 *   [type, autoCorrectCorruptDates, enableStringsSignedMinMax, schema]
 * </pre>
 *
 * @param call sql call whose arguments should be prepared
 * @return list with operands for table function
 */
private static List<SqlNode> prepareTableMacroOperands(SqlCall call) {
    Function<String, SqlNode> convertOperand = paramName -> call.getOperandList().stream().map(sqlNode -> (SqlCall) sqlNode).filter(sqlCall -> ((SqlIdentifier) sqlCall.operand(1)).getSimple().equals(paramName)).peek(sqlCall -> Preconditions.checkState(sqlCall.getKind() == SqlKind.ARGUMENT_ASSIGNMENT)).findFirst().map(sqlCall -> (SqlNode) sqlCall.operand(0)).orElse(SqlStdOperatorTable.DEFAULT.createCall(SqlParserPos.ZERO));
    SqlFunction operator = (SqlFunction) call.getOperator();
    return operator.getParamNames().stream().map(convertOperand).collect(Collectors.toList());
}
Also used : SqlParserPos(org.apache.calcite.sql.parser.SqlParserPos) SchemaUtilites(org.apache.drill.exec.planner.sql.SchemaUtilites) SqlKind(org.apache.calcite.sql.SqlKind) SqlUserDefinedTableMacro(org.apache.calcite.sql.validate.SqlUserDefinedTableMacro) Logger(org.slf4j.Logger) TranslatableTable(org.apache.calcite.schema.TranslatableTable) UserException(org.apache.drill.common.exceptions.UserException) LoggerFactory(org.slf4j.LoggerFactory) Table(org.apache.calcite.schema.Table) DrillTable(org.apache.drill.exec.planner.logical.DrillTable) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) SqlCall(org.apache.calcite.sql.SqlCall) List(java.util.List) SqlFunction(org.apache.calcite.sql.SqlFunction) SqlNode(org.apache.calcite.sql.SqlNode) SqlStdOperatorTable(org.apache.calcite.sql.fun.SqlStdOperatorTable) AbstractSchema(org.apache.drill.exec.store.AbstractSchema) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) Preconditions(org.apache.drill.shaded.guava.com.google.common.base.Preconditions) SqlOperator(org.apache.calcite.sql.SqlOperator) Util(org.apache.calcite.util.Util) DrillTranslatableTable(org.apache.drill.exec.planner.logical.DrillTranslatableTable) SqlCall(org.apache.calcite.sql.SqlCall) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode) SqlFunction(org.apache.calcite.sql.SqlFunction)

Example 39 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project drill by apache.

the class DrillOperatorTable method populateWrappedCalciteOperators.

private void populateWrappedCalciteOperators() {
    for (SqlOperator calciteOperator : inner.getOperatorList()) {
        final SqlOperator wrapper;
        if (calciteOperator instanceof SqlAggFunction) {
            wrapper = new DrillCalciteSqlAggFunctionWrapper((SqlAggFunction) calciteOperator, getFunctionListWithInference(calciteOperator.getName()));
        } else if (calciteOperator instanceof SqlFunction) {
            wrapper = new DrillCalciteSqlFunctionWrapper((SqlFunction) calciteOperator, getFunctionListWithInference(calciteOperator.getName()));
        } else if (calciteOperator instanceof SqlBetweenOperator) {
            // During the procedure of converting to RexNode,
            // StandardConvertletTable.convertBetween expects the SqlOperator to be a subclass of SqlBetweenOperator
            final SqlBetweenOperator sqlBetweenOperator = (SqlBetweenOperator) calciteOperator;
            wrapper = new DrillCalciteSqlBetweenOperatorWrapper(sqlBetweenOperator);
        } else {
            final String drillOpName;
            // Otherwise, Calcite will mix them up with binary operator subtract (-) or add (+)
            if (calciteOperator == SqlStdOperatorTable.UNARY_MINUS || calciteOperator == SqlStdOperatorTable.UNARY_PLUS) {
                drillOpName = calciteOperator.getName();
            } else {
                drillOpName = FunctionCallFactory.convertToDrillFunctionName(calciteOperator.getName());
            }
            final List<DrillFuncHolder> drillFuncHolders = getFunctionListWithInference(drillOpName);
            if (drillFuncHolders.isEmpty()) {
                continue;
            }
            wrapper = new DrillCalciteSqlOperatorWrapper(calciteOperator, drillOpName, drillFuncHolders);
        }
        calciteToWrapper.put(calciteOperator, wrapper);
    }
}
Also used : DrillFuncHolder(org.apache.drill.exec.expr.fn.DrillFuncHolder) SqlOperator(org.apache.calcite.sql.SqlOperator) SqlBetweenOperator(org.apache.calcite.sql.fun.SqlBetweenOperator) SqlAggFunction(org.apache.calcite.sql.SqlAggFunction) SqlFunction(org.apache.calcite.sql.SqlFunction)

Example 40 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project drill by axbaretto.

the class PreProcessLogicalRel method visit.

@Override
public RelNode visit(LogicalProject project) {
    final List<RexNode> projExpr = Lists.newArrayList();
    for (RexNode rexNode : project.getChildExps()) {
        projExpr.add(rexNode.accept(unwrappingExpressionVisitor));
    }
    project = project.copy(project.getTraitSet(), project.getInput(), projExpr, project.getRowType());
    List<RexNode> exprList = new ArrayList<>();
    boolean rewrite = false;
    for (RexNode rex : project.getChildExps()) {
        RexNode newExpr = rex;
        if (rex instanceof RexCall) {
            RexCall function = (RexCall) rex;
            String functionName = function.getOperator().getName();
            int nArgs = function.getOperands().size();
            // check if its a convert_from or convert_to function
            if (functionName.equalsIgnoreCase("convert_from") || functionName.equalsIgnoreCase("convert_to")) {
                String literal;
                if (nArgs == 2) {
                    if (function.getOperands().get(1) instanceof RexLiteral) {
                        try {
                            literal = ((NlsString) (((RexLiteral) function.getOperands().get(1)).getValue())).getValue();
                        } catch (final ClassCastException e) {
                            // Caused by user entering a value with a non-string literal
                            throw getConvertFunctionInvalidTypeException(function);
                        }
                    } else {
                        // caused by user entering a non-literal
                        throw getConvertFunctionInvalidTypeException(function);
                    }
                } else {
                    // Second operand is missing
                    throw UserException.parseError().message("'%s' expects a string literal as a second argument.", functionName).build(logger);
                }
                RexBuilder builder = new RexBuilder(factory);
                // construct the new function name based on the input argument
                String newFunctionName = functionName + literal;
                // Look up the new function name in the drill operator table
                List<SqlOperator> operatorList = table.getSqlOperator(newFunctionName);
                if (operatorList.size() == 0) {
                    // User typed in an invalid type name
                    throw getConvertFunctionException(functionName, literal);
                }
                SqlFunction newFunction = null;
                // Find the SqlFunction with the correct args
                for (SqlOperator op : operatorList) {
                    if (op.getOperandTypeChecker().getOperandCountRange().isValidCount(nArgs - 1)) {
                        newFunction = (SqlFunction) op;
                        break;
                    }
                }
                if (newFunction == null) {
                    // we are here because we found some dummy convert function. (See DummyConvertFrom and DummyConvertTo)
                    throw getConvertFunctionException(functionName, literal);
                }
                // create the new expression to be used in the rewritten project
                newExpr = builder.makeCall(newFunction, function.getOperands().subList(0, 1));
                rewrite = true;
            }
        }
        exprList.add(newExpr);
    }
    if (rewrite == true) {
        LogicalProject newProject = project.copy(project.getTraitSet(), project.getInput(0), exprList, project.getRowType());
        return visitChild(newProject, 0, project.getInput());
    }
    return visitChild(project, 0, project.getInput());
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) SqlOperator(org.apache.calcite.sql.SqlOperator) ArrayList(java.util.ArrayList) NlsString(org.apache.calcite.util.NlsString) RexCall(org.apache.calcite.rex.RexCall) RexBuilder(org.apache.calcite.rex.RexBuilder) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode) SqlFunction(org.apache.calcite.sql.SqlFunction)

Aggregations

SqlFunction (org.apache.calcite.sql.SqlFunction)57 SqlOperator (org.apache.calcite.sql.SqlOperator)26 ArrayList (java.util.ArrayList)13 RoundOperatorConversion (org.apache.druid.sql.calcite.expression.builtin.RoundOperatorConversion)12 Test (org.junit.Test)12 RexNode (org.apache.calcite.rex.RexNode)8 SqlCall (org.apache.calcite.sql.SqlCall)8 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)8 AssignableOperandTypeChecker (org.apache.calcite.sql.type.AssignableOperandTypeChecker)6 BitString (org.apache.calcite.util.BitString)6 ImmutableList (com.google.common.collect.ImmutableList)5 RelDataType (org.apache.calcite.rel.type.RelDataType)5 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)5 RexCall (org.apache.calcite.rex.RexCall)4 RexLiteral (org.apache.calcite.rex.RexLiteral)4 FunctionDefinition (org.apache.flink.table.functions.FunctionDefinition)4 ScalarFunctionDefinition (org.apache.flink.table.functions.ScalarFunctionDefinition)4 BigDecimal (java.math.BigDecimal)3 TimeUnitRange (org.apache.calcite.avatica.util.TimeUnitRange)3 SqlTypeName (org.apache.calcite.sql.type.SqlTypeName)3