Search in sources :

Example 6 with SqlMerge

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;
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) SqlSelect(org.apache.calcite.sql.SqlSelect) SqlMerge(org.apache.calcite.sql.SqlMerge) SqlNodeList(org.apache.calcite.sql.SqlNodeList) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

SqlMerge (org.apache.calcite.sql.SqlMerge)6 SqlNode (org.apache.calcite.sql.SqlNode)6 SqlNodeList (org.apache.calcite.sql.SqlNodeList)6 SqlSelect (org.apache.calcite.sql.SqlSelect)6 SqlCall (org.apache.calcite.sql.SqlCall)4 SqlDelete (org.apache.calcite.sql.SqlDelete)4 SqlUpdate (org.apache.calcite.sql.SqlUpdate)4 ArrayList (java.util.ArrayList)2 Ord (org.apache.calcite.linq4j.Ord)2 RelDataType (org.apache.calcite.rel.type.RelDataType)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)2 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)2 SqlInsert (org.apache.calcite.sql.SqlInsert)2 SqlKind (org.apache.calcite.sql.SqlKind)2 SqlOperator (org.apache.calcite.sql.SqlOperator)2 SqlOrderBy (org.apache.calcite.sql.SqlOrderBy)2 SqlUnresolvedFunction (org.apache.calcite.sql.SqlUnresolvedFunction)2 SqlWith (org.apache.calcite.sql.SqlWith)2 BitString (org.apache.calcite.util.BitString)2