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.");
}
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());
}
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);
}
});
}
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()));
}
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);
}
Aggregations