Search in sources :

Example 61 with SqlCall

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

the class SqlValidatorImpl method inferUnknownTypes.

protected void inferUnknownTypes(@Nonnull RelDataType inferredType, @Nonnull SqlValidatorScope scope, @Nonnull SqlNode node) {
    Objects.requireNonNull(inferredType);
    Objects.requireNonNull(scope);
    Objects.requireNonNull(node);
    final SqlValidatorScope newScope = scopes.get(node);
    if (newScope != null) {
        scope = newScope;
    }
    boolean isNullLiteral = SqlUtil.isNullLiteral(node, false);
    if ((node instanceof SqlDynamicParam) || isNullLiteral) {
        if (inferredType.equals(unknownType)) {
            if (isNullLiteral) {
                if (config.typeCoercionEnabled()) {
                    // derive type of null literal
                    deriveType(scope, node);
                    return;
                } else {
                    throw newValidationError(node, RESOURCE.nullIllegal());
                }
            } else {
                throw newValidationError(node, RESOURCE.dynamicParamIllegal());
            }
        }
        // REVIEW:  should dynamic parameter types always be nullable?
        RelDataType newInferredType = typeFactory.createTypeWithNullability(inferredType, true);
        if (SqlTypeUtil.inCharFamily(inferredType)) {
            newInferredType = typeFactory.createTypeWithCharsetAndCollation(newInferredType, inferredType.getCharset(), inferredType.getCollation());
        }
        setValidatedNodeType(node, newInferredType);
    } else if (node instanceof SqlNodeList) {
        SqlNodeList nodeList = (SqlNodeList) node;
        if (inferredType.isStruct()) {
            if (inferredType.getFieldCount() != nodeList.size()) {
                // bust out, and the error will be detected higher up
                return;
            }
        }
        int i = 0;
        for (SqlNode child : nodeList) {
            RelDataType type;
            if (inferredType.isStruct()) {
                type = inferredType.getFieldList().get(i).getType();
                ++i;
            } else {
                type = inferredType;
            }
            inferUnknownTypes(type, scope, child);
        }
    } else if (node instanceof SqlCase) {
        final SqlCase caseCall = (SqlCase) node;
        final RelDataType whenType = caseCall.getValueOperand() == null ? booleanType : unknownType;
        for (SqlNode sqlNode : caseCall.getWhenOperands().getList()) {
            inferUnknownTypes(whenType, scope, sqlNode);
        }
        RelDataType returnType = deriveType(scope, node);
        for (SqlNode sqlNode : caseCall.getThenOperands().getList()) {
            inferUnknownTypes(returnType, scope, sqlNode);
        }
        if (!SqlUtil.isNullLiteral(caseCall.getElseOperand(), false)) {
            inferUnknownTypes(returnType, scope, caseCall.getElseOperand());
        } else {
            setValidatedNodeType(caseCall.getElseOperand(), returnType);
        }
    } else if (node.getKind() == SqlKind.AS) {
        // For AS operator, only infer the operand not the alias
        inferUnknownTypes(inferredType, scope, ((SqlCall) node).operand(0));
    } else if (node instanceof SqlCall) {
        final SqlCall call = (SqlCall) node;
        final SqlOperandTypeInference operandTypeInference = call.getOperator().getOperandTypeInference();
        final SqlCallBinding callBinding = new SqlCallBinding(this, scope, call);
        final List<SqlNode> operands = callBinding.operands();
        final RelDataType[] operandTypes = new RelDataType[operands.size()];
        Arrays.fill(operandTypes, unknownType);
        // instead; for now just eat it
        if (operandTypeInference != null) {
            operandTypeInference.inferOperandTypes(callBinding, inferredType, operandTypes);
        }
        for (int i = 0; i < operands.size(); ++i) {
            final SqlNode operand = operands.get(i);
            if (operand != null) {
                inferUnknownTypes(operandTypes[i], scope, operand);
            }
        }
    }
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlOperandTypeInference(org.apache.calcite.sql.type.SqlOperandTypeInference) SqlDynamicParam(org.apache.calcite.sql.SqlDynamicParam) SqlCase(org.apache.calcite.sql.fun.SqlCase) SqlCallBinding(org.apache.calcite.sql.SqlCallBinding) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlNode(org.apache.calcite.sql.SqlNode)

Example 62 with SqlCall

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

the class SqlValidatorImpl method findTableColumnPair.

private Pair<String, String> findTableColumnPair(SqlIdentifier identifier, SqlValidatorScope scope) {
    final SqlCall call = makeNullaryCall(identifier);
    if (call != null) {
        return null;
    }
    SqlQualified qualified = scope.fullyQualify(identifier);
    List<String> names = qualified.identifier.names;
    if (names.size() < 2) {
        return null;
    }
    return new Pair<>(names.get(names.size() - 2), Util.last(names));
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) BitString(org.apache.calcite.util.BitString) IdPair(org.apache.calcite.sql.util.IdPair) Pair(org.apache.calcite.util.Pair)

Example 63 with SqlCall

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

the class Expander method expanded.

/**
 * Expands identifiers in a given SQL string, returning a {@link Expanded}.
 */
public Expanded expanded(String ori) {
    final Map<SqlParserPos, SqlIdentifier> identifiers = new HashMap<>();
    final Map<String, SqlIdentifier> funcNameToId = new HashMap<>();
    final SqlNode oriNode = planner.parser().parse(ori);
    // parse again because validation is stateful, that means the node tree was probably
    // mutated.
    final SqlNode validated = planner.validate(planner.parser().parse(ori));
    validated.accept(new SqlBasicVisitor<Void>() {

        @Override
        public Void visit(SqlCall call) {
            SqlOperator operator = call.getOperator();
            if (operator instanceof BridgingSqlFunction) {
                final SqlIdentifier functionID = ((BridgingSqlFunction) operator).getSqlIdentifier();
                if (!functionID.isSimple()) {
                    funcNameToId.put(Util.last(functionID.names), functionID);
                }
            }
            return super.visit(call);
        }

        @Override
        public Void visit(SqlIdentifier identifier) {
            // and we stop expanding all of them.
            if (!identifier.names.get(0).startsWith("EXPR$")) {
                identifiers.putIfAbsent(identifier.getParserPosition(), identifier);
            }
            return null;
        }
    });
    return new Expanded(oriNode, identifiers, funcNameToId);
}
Also used : SqlParserPos(org.apache.calcite.sql.parser.SqlParserPos) HashMap(java.util.HashMap) SqlCall(org.apache.calcite.sql.SqlCall) SqlOperator(org.apache.calcite.sql.SqlOperator) BridgingSqlFunction(org.apache.flink.table.planner.functions.bridging.BridgingSqlFunction) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode)

Example 64 with SqlCall

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

the class SqlValidatorImpl method registerSubQueries.

private void registerSubQueries(SqlValidatorScope parentScope, SqlNode node) {
    if (node == null) {
        return;
    }
    if (node.getKind().belongsTo(SqlKind.QUERY) || node.getKind() == SqlKind.MULTISET_QUERY_CONSTRUCTOR || node.getKind() == SqlKind.MULTISET_VALUE_CONSTRUCTOR) {
        registerQuery(parentScope, null, node, node, null, false);
    } else if (node instanceof SqlCall) {
        validateNodeFeature(node);
        SqlCall call = (SqlCall) node;
        for (int i = 0; i < call.operandCount(); i++) {
            registerOperandSubQueries(parentScope, call, i);
        }
    } else if (node instanceof SqlNodeList) {
        SqlNodeList list = (SqlNodeList) node;
        for (int i = 0, count = list.size(); i < count; i++) {
            SqlNode listNode = list.get(i);
            if (listNode.getKind().belongsTo(SqlKind.QUERY)) {
                listNode = SqlStdOperatorTable.SCALAR_QUERY.createCall(listNode.getParserPosition(), listNode);
                list.set(i, listNode);
            }
            registerSubQueries(parentScope, listNode);
        }
    } else {
    // atomic node -- can be ignored
    }
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlNode(org.apache.calcite.sql.SqlNode)

Example 65 with SqlCall

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

the class SqlValidatorImpl method validateExpr.

/**
 * Validates an expression.
 *
 * @param expr Expression
 * @param scope Scope in which expression occurs
 */
private void validateExpr(SqlNode expr, SqlValidatorScope scope) {
    if (expr instanceof SqlCall) {
        final SqlOperator op = ((SqlCall) expr).getOperator();
        if (op.isAggregator() && op.requiresOver()) {
            throw newValidationError(expr, RESOURCE.absentOverClause());
        }
        if (op instanceof SqlTableFunction) {
            throw RESOURCE.cannotCallTableFunctionHere(op.getName()).ex();
        }
    }
    // Call on the expression to validate itself.
    expr.validateExpr(this, scope);
    // Perform any validation specific to the scope. For example, an
    // aggregating scope requires that expressions are valid aggregations.
    scope.validateExpr(expr);
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) SqlOperator(org.apache.calcite.sql.SqlOperator) SqlTableFunction(org.apache.calcite.sql.SqlTableFunction)

Aggregations

SqlCall (org.apache.calcite.sql.SqlCall)108 SqlNode (org.apache.calcite.sql.SqlNode)81 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)32 SqlNodeList (org.apache.calcite.sql.SqlNodeList)32 RelDataType (org.apache.calcite.rel.type.RelDataType)30 SqlOperator (org.apache.calcite.sql.SqlOperator)26 BitString (org.apache.calcite.util.BitString)19 ArrayList (java.util.ArrayList)18 SqlSelect (org.apache.calcite.sql.SqlSelect)17 RexNode (org.apache.calcite.rex.RexNode)13 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)12 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)11 SqlLiteral (org.apache.calcite.sql.SqlLiteral)11 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)9 SqlKind (org.apache.calcite.sql.SqlKind)9 SqlParserPos (org.apache.calcite.sql.parser.SqlParserPos)9 List (java.util.List)8 SqlCallBinding (org.apache.calcite.sql.SqlCallBinding)8 Pair (org.apache.calcite.util.Pair)8 RelNode (org.apache.calcite.rel.RelNode)7