001package gudusoft.gsqlparser.ir.logical.rel;
002
003import gudusoft.gsqlparser.ir.common.SourceAnchor;
004import gudusoft.gsqlparser.ir.logical.*;
005
006import java.util.Arrays;
007import java.util.Collections;
008import java.util.List;
009
010/**
011 * MERGE statement.
012 */
013public final class DmlMerge extends RelNode {
014    private final String targetTable;
015    private final RelNode source;
016    private final RexNode joinCondition;
017    private final List<MergeClause> clauses;
018
019    public DmlMerge(String targetTable, RelNode source, RexNode joinCondition,
020                    List<MergeClause> clauses, SourceAnchor anchor) {
021        super(RelNodeKind.DML_MERGE, anchor);
022        this.targetTable = targetTable;
023        this.source = source;
024        this.joinCondition = joinCondition;
025        this.clauses = clauses != null ? Collections.unmodifiableList(clauses) : Collections.<MergeClause>emptyList();
026    }
027
028    public String getTargetTable() { return targetTable; }
029    public RelNode getSource() { return source; }
030    public RexNode getJoinCondition() { return joinCondition; }
031    public List<MergeClause> getClauses() { return clauses; }
032
033    @Override
034    public List<RelNode> getInputs() {
035        return source != null ? Collections.singletonList(source) : Collections.<RelNode>emptyList();
036    }
037
038    @Override
039    public <R> R accept(RelNodeVisitor<R> visitor) { return visitor.visitDmlMerge(this); }
040
041    /**
042     * A WHEN MATCHED / NOT MATCHED clause in a MERGE.
043     */
044    public static final class MergeClause {
045        public enum Type { WHEN_MATCHED_UPDATE, WHEN_MATCHED_DELETE, WHEN_NOT_MATCHED_INSERT }
046
047        private final Type type;
048        private final RexNode condition;
049        private final List<RexNode> assignments;
050
051        public MergeClause(Type type, RexNode condition, List<RexNode> assignments) {
052            this.type = type;
053            this.condition = condition;
054            this.assignments = assignments != null ? Collections.unmodifiableList(assignments) : Collections.<RexNode>emptyList();
055        }
056
057        public Type getType() { return type; }
058        public RexNode getCondition() { return condition; }
059        public List<RexNode> getAssignments() { return assignments; }
060    }
061}