use of org.apache.calcite.sql.SqlNodeList in project flink by apache.
the class SqlValidatorImpl method rewriteUpdateToMerge.
private SqlNode rewriteUpdateToMerge(SqlUpdate updateCall, SqlNode selfJoinSrcExpr) {
// Make sure target has an alias.
if (updateCall.getAlias() == null) {
updateCall.setAlias(new SqlIdentifier(UPDATE_TGT_ALIAS, SqlParserPos.ZERO));
}
SqlNode selfJoinTgtExpr = getSelfJoinExprForUpdate(updateCall.getTargetTable(), updateCall.getAlias().getSimple());
assert selfJoinTgtExpr != null;
// Create join condition between source and target exprs,
// creating a conjunction with the user-level WHERE
// clause if one was supplied
SqlNode condition = updateCall.getCondition();
SqlNode selfJoinCond = SqlStdOperatorTable.EQUALS.createCall(SqlParserPos.ZERO, selfJoinSrcExpr, selfJoinTgtExpr);
if (condition == null) {
condition = selfJoinCond;
} else {
condition = SqlStdOperatorTable.AND.createCall(SqlParserPos.ZERO, selfJoinCond, condition);
}
SqlNode target = updateCall.getTargetTable().clone(SqlParserPos.ZERO);
// For the source, we need to anonymize the fields, so
// that for a statement like UPDATE T SET I = I + 1,
// there's no ambiguity for the "I" in "I + 1";
// this is OK because the source and target have
// identical values due to the self-join.
// Note that we anonymize the source rather than the
// target because downstream, the optimizer rules
// don't want to see any projection on top of the target.
IdentifierNamespace ns = new IdentifierNamespace(this, target, null, null);
RelDataType rowType = ns.getRowType();
SqlNode source = updateCall.getTargetTable().clone(SqlParserPos.ZERO);
final SqlNodeList selectList = new SqlNodeList(SqlParserPos.ZERO);
int i = 1;
for (RelDataTypeField field : rowType.getFieldList()) {
SqlIdentifier col = new SqlIdentifier(field.getName(), SqlParserPos.ZERO);
selectList.add(SqlValidatorUtil.addAlias(col, UPDATE_ANON_PREFIX + i));
++i;
}
source = new SqlSelect(SqlParserPos.ZERO, null, selectList, source, null, null, null, null, null, null, null, null);
source = SqlValidatorUtil.addAlias(source, UPDATE_SRC_ALIAS);
SqlMerge mergeCall = new SqlMerge(updateCall.getParserPosition(), target, condition, source, updateCall, null, null, updateCall.getAlias());
rewriteMerge(mergeCall);
return mergeCall;
}
use of org.apache.calcite.sql.SqlNodeList 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()));
}
use of org.apache.calcite.sql.SqlNodeList in project calcite by apache.
the class SqlCase method createSwitched.
/**
* Creates a call to the switched form of the case operator, viz:
*
* <blockquote><code>CASE value<br>
* WHEN whenList[0] THEN thenList[0]<br>
* WHEN whenList[1] THEN thenList[1]<br>
* ...<br>
* ELSE elseClause<br>
* END</code></blockquote>
*/
public static SqlCase createSwitched(SqlParserPos pos, SqlNode value, SqlNodeList whenList, SqlNodeList thenList, SqlNode elseClause) {
if (null != value) {
List<SqlNode> list = whenList.getList();
for (int i = 0; i < list.size(); i++) {
SqlNode e = list.get(i);
final SqlCall call;
if (e instanceof SqlNodeList) {
call = SqlStdOperatorTable.IN.createCall(pos, value, e);
} else {
call = SqlStdOperatorTable.EQUALS.createCall(pos, value, e);
}
list.set(i, call);
}
}
if (null == elseClause) {
elseClause = SqlLiteral.createNull(pos);
}
return new SqlCase(pos, null, whenList, thenList, elseClause);
}
use of org.apache.calcite.sql.SqlNodeList in project calcite by apache.
the class SqlCaseOperator method checkOperandTypes.
public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
SqlCase caseCall = (SqlCase) callBinding.getCall();
SqlNodeList whenList = caseCall.getWhenOperands();
SqlNodeList thenList = caseCall.getThenOperands();
assert whenList.size() == thenList.size();
// checking that search conditions are ok...
for (SqlNode node : whenList) {
// should throw validation error if something wrong...
RelDataType type = callBinding.getValidator().deriveType(callBinding.getScope(), node);
if (!SqlTypeUtil.inBooleanFamily(type)) {
if (throwOnFailure) {
throw callBinding.newError(RESOURCE.expectedBoolean());
}
return false;
}
}
boolean foundNotNull = false;
for (SqlNode node : thenList) {
if (!SqlUtil.isNullLiteral(node, false)) {
foundNotNull = true;
}
}
if (!SqlUtil.isNullLiteral(caseCall.getElseOperand(), false)) {
foundNotNull = true;
}
if (!foundNotNull) {
// statements and the ELSE returning null
if (throwOnFailure) {
throw callBinding.newError(RESOURCE.mustNotNullInElse());
}
return false;
}
return true;
}
use of org.apache.calcite.sql.SqlNodeList in project calcite by apache.
the class SqlCaseOperator method validateCall.
// ~ Methods ----------------------------------------------------------------
public void validateCall(SqlCall call, SqlValidator validator, SqlValidatorScope scope, SqlValidatorScope operandScope) {
final SqlCase sqlCase = (SqlCase) call;
final SqlNodeList whenOperands = sqlCase.getWhenOperands();
final SqlNodeList thenOperands = sqlCase.getThenOperands();
final SqlNode elseOperand = sqlCase.getElseOperand();
for (SqlNode operand : whenOperands) {
operand.validateExpr(validator, operandScope);
}
for (SqlNode operand : thenOperands) {
operand.validateExpr(validator, operandScope);
}
if (elseOperand != null) {
elseOperand.validateExpr(validator, operandScope);
}
}
Aggregations