use of org.apache.calcite.sql.SqlMerge in project calcite 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);
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;
}
Aggregations