Search in sources :

Example 11 with SqlValidatorImpl

use of org.apache.calcite.sql.validate.SqlValidatorImpl in project calcite by apache.

the class SqlInOperator method deriveType.

public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) {
    final List<SqlNode> operands = call.getOperandList();
    assert operands.size() == 2;
    final SqlNode left = operands.get(0);
    final SqlNode right = operands.get(1);
    final RelDataTypeFactory typeFactory = validator.getTypeFactory();
    RelDataType leftType = validator.deriveType(scope, left);
    RelDataType rightType;
    // Derive type for RHS.
    if (right instanceof SqlNodeList) {
        // Handle the 'IN (expr, ...)' form.
        List<RelDataType> rightTypeList = new ArrayList<>();
        SqlNodeList nodeList = (SqlNodeList) right;
        for (int i = 0; i < nodeList.size(); i++) {
            SqlNode node = nodeList.get(i);
            RelDataType nodeType = validator.deriveType(scope, node);
            rightTypeList.add(nodeType);
        }
        rightType = typeFactory.leastRestrictive(rightTypeList);
        // SQL:2003 Part 2 Section 8.4, <in predicate>).
        if (null == rightType) {
            throw validator.newValidationError(right, RESOURCE.incompatibleTypesInList());
        }
        // Record the RHS type for use by SqlToRelConverter.
        ((SqlValidatorImpl) validator).setValidatedNodeType(nodeList, rightType);
    } else {
        // Handle the 'IN (query)' form.
        rightType = validator.deriveType(scope, right);
    }
    // Now check that the left expression is compatible with the
    // type of the list. Same strategy as the '=' operator.
    // Normalize the types on both sides to be row types
    // for the purposes of compatibility-checking.
    RelDataType leftRowType = SqlTypeUtil.promoteToRowType(typeFactory, leftType, null);
    RelDataType rightRowType = SqlTypeUtil.promoteToRowType(typeFactory, rightType, null);
    final ComparableOperandTypeChecker checker = (ComparableOperandTypeChecker) OperandTypes.COMPARABLE_UNORDERED_COMPARABLE_UNORDERED;
    if (!checker.checkOperandTypes(new ExplicitOperatorBinding(new SqlCallBinding(validator, scope, call), ImmutableList.of(leftRowType, rightRowType)))) {
        throw validator.newValidationError(call, RESOURCE.incompatibleValueType(SqlStdOperatorTable.IN.getName()));
    }
    // on either side.
    return typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BOOLEAN), anyNullable(leftRowType.getFieldList()) || anyNullable(rightRowType.getFieldList()));
}
Also used : ComparableOperandTypeChecker(org.apache.calcite.sql.type.ComparableOperandTypeChecker) SqlValidatorImpl(org.apache.calcite.sql.validate.SqlValidatorImpl) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) ArrayList(java.util.ArrayList) SqlCallBinding(org.apache.calcite.sql.SqlCallBinding) SqlNodeList(org.apache.calcite.sql.SqlNodeList) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlNode(org.apache.calcite.sql.SqlNode) ExplicitOperatorBinding(org.apache.calcite.sql.ExplicitOperatorBinding)

Example 12 with SqlValidatorImpl

use of org.apache.calcite.sql.validate.SqlValidatorImpl in project calcite by apache.

the class SqlCaseOperator method inferTypeFromValidator.

private RelDataType inferTypeFromValidator(SqlCallBinding callBinding) {
    SqlCase caseCall = (SqlCase) callBinding.getCall();
    SqlNodeList thenList = caseCall.getThenOperands();
    ArrayList<SqlNode> nullList = new ArrayList<SqlNode>();
    List<RelDataType> argTypes = new ArrayList<RelDataType>();
    for (SqlNode node : thenList) {
        argTypes.add(callBinding.getValidator().deriveType(callBinding.getScope(), node));
        if (SqlUtil.isNullLiteral(node, false)) {
            nullList.add(node);
        }
    }
    SqlNode elseOp = caseCall.getElseOperand();
    argTypes.add(callBinding.getValidator().deriveType(callBinding.getScope(), caseCall.getElseOperand()));
    if (SqlUtil.isNullLiteral(elseOp, false)) {
        nullList.add(elseOp);
    }
    RelDataType ret = callBinding.getTypeFactory().leastRestrictive(argTypes);
    if (null == ret) {
        throw callBinding.newValidationError(RESOURCE.illegalMixingOfTypes());
    }
    final SqlValidatorImpl validator = (SqlValidatorImpl) callBinding.getValidator();
    for (SqlNode node : nullList) {
        validator.setValidatedNodeType(node, ret);
    }
    return ret;
}
Also used : SqlValidatorImpl(org.apache.calcite.sql.validate.SqlValidatorImpl) ArrayList(java.util.ArrayList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlNode(org.apache.calcite.sql.SqlNode)

Example 13 with SqlValidatorImpl

use of org.apache.calcite.sql.validate.SqlValidatorImpl in project calcite by apache.

the class SqlToRelConverter method convertMultisets.

private RelNode convertMultisets(final List<SqlNode> operands, Blackboard bb) {
    // NOTE: Wael 2/04/05: this implementation is not the most efficient in
    // terms of planning since it generates XOs that can be reduced.
    final List<Object> joinList = new ArrayList<>();
    List<SqlNode> lastList = new ArrayList<>();
    for (int i = 0; i < operands.size(); i++) {
        SqlNode operand = operands.get(i);
        if (!(operand instanceof SqlCall)) {
            lastList.add(operand);
            continue;
        }
        final SqlCall call = (SqlCall) operand;
        final RelNode input;
        switch(call.getKind()) {
            case MULTISET_VALUE_CONSTRUCTOR:
            case ARRAY_VALUE_CONSTRUCTOR:
                final SqlNodeList list = new SqlNodeList(call.getOperandList(), call.getParserPosition());
                CollectNamespace nss = (CollectNamespace) validator.getNamespace(call);
                Blackboard usedBb;
                if (null != nss) {
                    usedBb = createBlackboard(nss.getScope(), null, false);
                } else {
                    usedBb = createBlackboard(new ListScope(bb.scope) {

                        public SqlNode getNode() {
                            return call;
                        }
                    }, null, false);
                }
                RelDataType multisetType = validator.getValidatedNodeType(call);
                ((SqlValidatorImpl) validator).setValidatedNodeType(list, multisetType.getComponentType());
                input = convertQueryOrInList(usedBb, list, null);
                break;
            case MULTISET_QUERY_CONSTRUCTOR:
            case ARRAY_QUERY_CONSTRUCTOR:
                final RelRoot root = convertQuery(call.operand(0), false, true);
                input = root.rel;
                break;
            default:
                lastList.add(operand);
                continue;
        }
        if (lastList.size() > 0) {
            joinList.add(lastList);
        }
        lastList = new ArrayList<>();
        Collect collect = new Collect(cluster, cluster.traitSetOf(Convention.NONE), input, validator.deriveAlias(call, i));
        joinList.add(collect);
    }
    if (joinList.size() == 0) {
        joinList.add(lastList);
    }
    for (int i = 0; i < joinList.size(); i++) {
        Object o = joinList.get(i);
        if (o instanceof List) {
            @SuppressWarnings("unchecked") List<SqlNode> projectList = (List<SqlNode>) o;
            final List<RexNode> selectList = new ArrayList<>();
            final List<String> fieldNameList = new ArrayList<>();
            for (int j = 0; j < projectList.size(); j++) {
                SqlNode operand = projectList.get(j);
                selectList.add(bb.convertExpression(operand));
                // REVIEW angel 5-June-2005: Use deriveAliasFromOrdinal
                // instead of deriveAlias to match field names from
                // SqlRowOperator. Otherwise, get error   Type
                // 'RecordType(INTEGER EMPNO)' has no field 'EXPR$0' when
                // doing   select * from unnest(     select multiset[empno]
                // from sales.emps);
                fieldNameList.add(SqlUtil.deriveAliasFromOrdinal(j));
            }
            relBuilder.push(LogicalValues.createOneRow(cluster)).projectNamed(selectList, fieldNameList, true);
            joinList.set(i, relBuilder.build());
        }
    }
    RelNode ret = (RelNode) joinList.get(0);
    for (int i = 1; i < joinList.size(); i++) {
        RelNode relNode = (RelNode) joinList.get(i);
        ret = RelFactories.DEFAULT_JOIN_FACTORY.createJoin(ret, relNode, rexBuilder.makeLiteral(true), ImmutableSet.<CorrelationId>of(), JoinRelType.INNER, false);
    }
    return ret;
}
Also used : Collect(org.apache.calcite.rel.core.Collect) SqlCall(org.apache.calcite.sql.SqlCall) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) RelRoot(org.apache.calcite.rel.RelRoot) NlsString(org.apache.calcite.util.NlsString) SqlValidatorImpl(org.apache.calcite.sql.validate.SqlValidatorImpl) RelNode(org.apache.calcite.rel.RelNode) SqlNodeList(org.apache.calcite.sql.SqlNodeList) ArrayList(java.util.ArrayList) AbstractList(java.util.AbstractList) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) CorrelationId(org.apache.calcite.rel.core.CorrelationId) CollectNamespace(org.apache.calcite.sql.validate.CollectNamespace) ListScope(org.apache.calcite.sql.validate.ListScope) SqlNode(org.apache.calcite.sql.SqlNode) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

SqlValidatorImpl (org.apache.calcite.sql.validate.SqlValidatorImpl)13 RelDataType (org.apache.calcite.rel.type.RelDataType)11 SqlNode (org.apache.calcite.sql.SqlNode)6 ArrayList (java.util.ArrayList)4 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)4 SqlCallBinding (org.apache.calcite.sql.SqlCallBinding)4 SqlNodeList (org.apache.calcite.sql.SqlNodeList)4 ImmutableList (com.google.common.collect.ImmutableList)2 List (java.util.List)2 RexNode (org.apache.calcite.rex.RexNode)2 SqlCall (org.apache.calcite.sql.SqlCall)2 SqlDynamicParam (org.apache.calcite.sql.SqlDynamicParam)2 SqlLiteral (org.apache.calcite.sql.SqlLiteral)2 SqlValidatorScope (org.apache.calcite.sql.validate.SqlValidatorScope)2 SQLException (java.sql.SQLException)1 AbstractList (java.util.AbstractList)1 Strong (org.apache.calcite.plan.Strong)1 RelNode (org.apache.calcite.rel.RelNode)1 RelRoot (org.apache.calcite.rel.RelRoot)1 Collect (org.apache.calcite.rel.core.Collect)1