Search in sources :

Example 51 with SqlNodeList

use of org.apache.calcite.sql.SqlNodeList in project hazelcast by hazelcast.

the class HazelcastSqlToRelConverter method convertIn.

/**
 * This method overrides Apache Calcite's approach for IN operator.
 *
 * @see org.apache.calcite.sql2rel.SqlToRelConverter##substituteSubQuery
 * @see org.apache.calcite.sql2rel.SqlToRelConverter##convertInToOr
 */
private RexNode convertIn(SqlCall call, Blackboard blackboard) {
    assert call.getOperandList().size() == 2;
    final SqlNode lhs = call.operand(0);
    final List<RexNode> leftKeys;
    if (lhs.getKind() == SqlKind.ROW) {
        leftKeys = new ArrayList<>();
        for (SqlNode sqlExpr : ((SqlBasicCall) lhs).getOperandList()) {
            leftKeys.add(blackboard.convertExpression(sqlExpr));
        }
    } else {
        leftKeys = ImmutableList.of(blackboard.convertExpression(lhs));
    }
    final SqlNode rhs = call.operand(1);
    if (rhs instanceof SqlNodeList) {
        SqlNodeList valueList = (SqlNodeList) rhs;
        return convertInToOr(blackboard, leftKeys, valueList, (SqlInOperator) call.getOperator());
    }
    throw QueryException.error(SqlErrorCode.GENERIC, "Sub-queries are not supported for IN operator.");
}
Also used : SqlBasicCall(org.apache.calcite.sql.SqlBasicCall) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlNode(org.apache.calcite.sql.SqlNode) RexNode(org.apache.calcite.rex.RexNode)

Example 52 with SqlNodeList

use of org.apache.calcite.sql.SqlNodeList in project hazelcast by hazelcast.

the class QueryParser method parse0.

private QueryParseResult parse0(String sql) throws SqlParseException {
    SqlParser parser = SqlParser.create(sql, CONFIG);
    SqlNodeList statements = parser.parseStmtList();
    if (statements.size() != 1) {
        throw QueryException.error(SqlErrorCode.PARSING, "The command must contain a single statement");
    }
    SqlNode topNode = statements.get(0);
    SqlNode node = validator.validate(topNode);
    SqlVisitor<Void> visitor = new UnsupportedOperationVisitor();
    node.accept(visitor);
    return new QueryParseResult(node, new QueryParameterMetadata(validator.getParameterConverters(node)), validator.isInfiniteRows());
}
Also used : UnsupportedOperationVisitor(com.hazelcast.jet.sql.impl.validate.UnsupportedOperationVisitor) HazelcastSqlParser(com.hazelcast.jet.sql.impl.calcite.parser.HazelcastSqlParser) SqlParser(org.apache.calcite.sql.parser.SqlParser) SqlNodeList(org.apache.calcite.sql.SqlNodeList) QueryParameterMetadata(com.hazelcast.sql.impl.QueryParameterMetadata) SqlNode(org.apache.calcite.sql.SqlNode)

Example 53 with SqlNodeList

use of org.apache.calcite.sql.SqlNodeList in project hazelcast by hazelcast.

the class HazelcastSqlValidator method validateUpdate.

@Override
public void validateUpdate(SqlUpdate update) {
    super.validateUpdate(update);
    // hack around Calcite deficiency of not deriving types for fields in sourceExpressionList...
    // see HazelcastTypeCoercion.coerceSourceRowType()
    SqlNodeList selectList = update.getSourceSelect().getSelectList();
    SqlNodeList sourceExpressionList = update.getSourceExpressionList();
    for (int i = 0; i < sourceExpressionList.size(); i++) {
        update.getSourceExpressionList().set(i, selectList.get(selectList.size() - sourceExpressionList.size() + i));
    }
    // UPDATE FROM SELECT is transformed into join (which is not supported yet):
    // UPDATE m1 SET __key = m2.this FROM m2 WHERE m1.__key = m2.__key
    // UPDATE m1 SET __key = (SELECT this FROM m2) WHERE __key = 1
    // UPDATE m1 SET __key = (SELECT m2.this FROM m2 WHERE m1.__key = m2.__key)
    update.getSourceSelect().getSelectList().accept(new SqlBasicVisitor<Void>() {

        @Override
        public Void visit(SqlCall call) {
            if (call.getKind() == SqlKind.SELECT) {
                throw newValidationError(update, RESOURCE.updateFromSelectNotSupported());
            }
            return call.getOperator().acceptCall(this, call);
        }
    });
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) SqlNodeList(org.apache.calcite.sql.SqlNodeList)

Example 54 with SqlNodeList

use of org.apache.calcite.sql.SqlNodeList in project hazelcast by hazelcast.

the class HazelcastInOperator method deriveType.

@Override
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 (SqlNode node : nodeList) {
            if (node instanceof SqlLiteral) {
                SqlLiteral lit = (SqlLiteral) node;
                // We are not supporting raw NULL literals within IN right-hand side list.
                if (lit.getValue() == null) {
                    throw validator.newValidationError(right, HZRESOURCE.noRawNullsAllowed());
                }
            }
            RelDataType nodeType = validator.deriveType(scope, node);
            rightTypeList.add(nodeType);
        }
        rightType = typeFactory.leastRestrictive(rightTypeList);
        // Same rules as the VALUES operator (per SQL:2003 Part 2 Section 8.4, <in predicate>).
        if (null == rightType && validator.config().typeCoercionEnabled()) {
            // Do implicit type cast if it is allowed to.
            rightType = validator.getTypeCoercion().getWiderTypeFor(rightTypeList, false);
        }
        if (null == rightType) {
            throw validator.newValidationError(right, RESOURCE.incompatibleTypesInList());
        }
        // Record the RHS type for use by SqlToRelConverter.
        validator.setValidatedNodeType(nodeList, rightType);
    } else {
        // We do not support sub-querying for IN operator.
        throw validator.newValidationError(call, HZRESOURCE.noSubQueryAllowed());
    }
    HazelcastCallBinding hazelcastCallBinding = prepareBinding(new SqlCallBinding(validator, scope, call));
    // Coerce type first.
    if (hazelcastCallBinding.isTypeCoercionEnabled()) {
        boolean coerced = hazelcastCallBinding.getValidator().getTypeCoercion().inOperationCoercion(hazelcastCallBinding);
        if (coerced) {
            // Update the node data type if we coerced any type.
            leftType = validator.deriveType(scope, call.operand(0));
            rightType = validator.deriveType(scope, call.operand(1));
        }
    }
    // 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(hazelcastCallBinding, ImmutableList.of(leftRowType, rightRowType)), hazelcastCallBinding)) {
        throw validator.newValidationError(call, RESOURCE.incompatibleValueType(SqlStdOperatorTable.IN.getName()));
    }
    return typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BOOLEAN), anyNullable(leftRowType.getFieldList()) || anyNullable(rightRowType.getFieldList()));
}
Also used : ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) ExplicitOperatorBinding(org.apache.calcite.sql.ExplicitOperatorBinding) ComparableOperandTypeChecker(org.apache.calcite.sql.type.ComparableOperandTypeChecker) HazelcastCallBinding(com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) SqlCallBinding(org.apache.calcite.sql.SqlCallBinding) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlLiteral(org.apache.calcite.sql.SqlLiteral) SqlNode(org.apache.calcite.sql.SqlNode)

Example 55 with SqlNodeList

use of org.apache.calcite.sql.SqlNodeList in project hazelcast by hazelcast.

the class HazelcastCaseOperator method checkOperandTypes.

@Override
@SuppressWarnings("checkstyle:MethodLength")
public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
    HazelcastSqlValidator validator = (HazelcastSqlValidator) callBinding.getValidator();
    HazelcastSqlCase sqlCall = (HazelcastSqlCase) callBinding.getCall();
    // at this point `CASE x WHEN y ...` is already converted to `CASE WHEN x=y ...`
    assert sqlCall.getValueOperand() == null;
    SqlNodeList whenList = sqlCall.getWhenOperands();
    SqlNodeList thenList = sqlCall.getThenOperands();
    SqlNode elseOperand = sqlCall.getElseOperand();
    assert whenList.size() > 0 : "no WHEN clause";
    assert whenList.size() == thenList.size();
    SqlValidatorScope scope = callBinding.getScope();
    if (!typeCheckWhen(scope, validator, whenList)) {
        if (throwOnFailure) {
            throw callBinding.newError(RESOURCE.expectedBoolean());
        }
        return false;
    }
    List<RelDataType> argTypes = new ArrayList<>(thenList.size() + 1);
    for (SqlNode node : thenList) {
        argTypes.add(validator.deriveType(scope, node));
    }
    argTypes.add(validator.deriveType(scope, elseOperand));
    // noinspection OptionalGetWithoutIsPresent
    RelDataType caseReturnType = argTypes.stream().reduce(HazelcastTypeUtils::withHigherPrecedence).get();
    Supplier<CalciteContextException> exceptionSupplier = () -> validator.newValidationError(sqlCall, HazelcastResources.RESOURCES.cannotInferCaseResult(argTypes.toString(), "CASE"));
    for (int i = 0; i < thenList.size(); i++) {
        int finalI = i;
        if (!coerceItem(validator, scope, thenList.get(i), caseReturnType, sqlNode -> thenList.getList().set(finalI, sqlNode), throwOnFailure, exceptionSupplier)) {
            return false;
        }
    }
    return coerceItem(validator, scope, elseOperand, caseReturnType, sqlNode -> sqlCall.setOperand(ELSE_BRANCH_OPERAND_INDEX, sqlNode), throwOnFailure, exceptionSupplier);
}
Also used : SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope) SqlSyntax(org.apache.calcite.sql.SqlSyntax) SqlCaseOperator(org.apache.calcite.sql.fun.SqlCaseOperator) CalciteContextException(org.apache.calcite.runtime.CalciteContextException) HazelcastReturnTypeInference.wrap(com.hazelcast.jet.sql.impl.validate.operators.typeinference.HazelcastReturnTypeInference.wrap) SqlOperandCountRanges(org.apache.calcite.sql.type.SqlOperandCountRanges) SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope) HazelcastResources(com.hazelcast.jet.sql.impl.validate.HazelcastResources) Supplier(java.util.function.Supplier) RESOURCE(org.apache.calcite.util.Static.RESOURCE) ArrayList(java.util.ArrayList) SqlCall(org.apache.calcite.sql.SqlCall) SqlLiteral(org.apache.calcite.sql.SqlLiteral) SqlNode(org.apache.calcite.sql.SqlNode) Pair(org.apache.calcite.util.Pair) SqlValidator(org.apache.calcite.sql.validate.SqlValidator) SqlOperator(org.apache.calcite.sql.SqlOperator) SqlOperatorBinding(org.apache.calcite.sql.SqlOperatorBinding) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlParserPos(org.apache.calcite.sql.parser.SqlParserPos) HazelcastSqlValidator(com.hazelcast.jet.sql.impl.validate.HazelcastSqlValidator) SqlKind(org.apache.calcite.sql.SqlKind) SqlWriter(org.apache.calcite.sql.SqlWriter) HazelcastTypeUtils(com.hazelcast.jet.sql.impl.validate.types.HazelcastTypeUtils) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) SqlCallBinding(org.apache.calcite.sql.SqlCallBinding) SqlTypeUtil(org.apache.calcite.sql.type.SqlTypeUtil) HazelcastSqlCase(com.hazelcast.jet.sql.impl.validate.operators.special.HazelcastSqlCase) Consumer(java.util.function.Consumer) SqlReturnTypeInference(org.apache.calcite.sql.type.SqlReturnTypeInference) List(java.util.List) SqlOperandCountRange(org.apache.calcite.sql.SqlOperandCountRange) SqlNodeList(org.apache.calcite.sql.SqlNodeList) CalciteContextException(org.apache.calcite.runtime.CalciteContextException) HazelcastSqlCase(com.hazelcast.jet.sql.impl.validate.operators.special.HazelcastSqlCase) ArrayList(java.util.ArrayList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) HazelcastSqlValidator(com.hazelcast.jet.sql.impl.validate.HazelcastSqlValidator) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

SqlNodeList (org.apache.calcite.sql.SqlNodeList)123 SqlNode (org.apache.calcite.sql.SqlNode)97 ArrayList (java.util.ArrayList)45 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)43 RelDataType (org.apache.calcite.rel.type.RelDataType)39 SqlCall (org.apache.calcite.sql.SqlCall)30 SqlSelect (org.apache.calcite.sql.SqlSelect)29 BitString (org.apache.calcite.util.BitString)23 RexNode (org.apache.calcite.rex.RexNode)13 SqlLiteral (org.apache.calcite.sql.SqlLiteral)11 ImmutableList (com.google.common.collect.ImmutableList)10 List (java.util.List)10 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)10 NlsString (org.apache.calcite.util.NlsString)9 RelNode (org.apache.calcite.rel.RelNode)8 SqlUpdate (org.apache.calcite.sql.SqlUpdate)8 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)7 SqlWriter (org.apache.calcite.sql.SqlWriter)7 SqlParserPos (org.apache.calcite.sql.parser.SqlParserPos)7 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)6