001package gudusoft.gsqlparser.nodes; 002 003import gudusoft.gsqlparser.ESqlClause; 004import gudusoft.gsqlparser.TCustomSqlStatement; 005 006/** 007 * Represents a PostgreSQL INSERT ... ON CONFLICT clause (UPSERT). 008 * 009 * <p>PostgreSQL syntax: 010 * <pre> 011 * INSERT INTO table_name ... 012 * ON CONFLICT [ conflict_target ] conflict_action 013 * 014 * conflict_target: 015 * ( { index_column_name | ( index_expression ) } [, ...] ) [ WHERE index_predicate ] 016 * | ON CONSTRAINT constraint_name 017 * 018 * conflict_action: 019 * DO NOTHING 020 * | DO UPDATE SET { column_name = expression } [, ...] [ WHERE condition ] 021 * </pre> 022 * 023 * @see gudusoft.gsqlparser.stmt.TInsertSqlStatement#getOnConflictClause() 024 */ 025public class TOnConflictClause extends TParseTreeNode { 026 027 private EOnConflictActionType actionType; 028 029 /** 030 * Conflict target: index columns/expressions in parentheses. 031 * Each item is a TOrderByItem representing an index element. 032 * Null when ON CONSTRAINT is used or no conflict target is specified. 033 */ 034 private TOrderByItemList indexColumns; 035 036 /** 037 * Conflict target: constraint name when ON CONSTRAINT syntax is used. 038 * Null when column-based conflict target or no conflict target is specified. 039 */ 040 private TObjectName constraintName; 041 042 /** 043 * WHERE clause on the conflict target (partial unique index predicate). 044 * Only applicable when column-based conflict target is used. 045 */ 046 private TWhereClause indexWhereClause; 047 048 /** 049 * SET clause assignments for DO UPDATE action. 050 * Null when action is DO NOTHING. 051 */ 052 private TResultColumnList updateSetClause; 053 054 /** 055 * WHERE clause for DO UPDATE action. 056 * Null when action is DO NOTHING or no WHERE specified on the UPDATE. 057 */ 058 private TWhereClause updateWhereClause; 059 060 /** 061 * Returns the conflict action type: DO NOTHING or DO UPDATE. 062 * @return the action type 063 */ 064 public EOnConflictActionType getActionType() { 065 return actionType; 066 } 067 068 public void setActionType(EOnConflictActionType actionType) { 069 this.actionType = actionType; 070 } 071 072 /** 073 * Returns the list of index column names or expressions that form the conflict target. 074 * @return the index column list, or null if ON CONSTRAINT or no target specified 075 */ 076 public TOrderByItemList getIndexColumns() { 077 return indexColumns; 078 } 079 080 public void setIndexColumns(TOrderByItemList indexColumns) { 081 this.indexColumns = indexColumns; 082 } 083 084 /** 085 * Returns the constraint name when ON CONSTRAINT syntax is used. 086 * @return the constraint name, or null 087 */ 088 public TObjectName getConstraintName() { 089 return constraintName; 090 } 091 092 public void setConstraintName(TObjectName constraintName) { 093 this.constraintName = constraintName; 094 } 095 096 /** 097 * Returns the WHERE clause for the partial unique index predicate on the conflict target. 098 * @return the index WHERE clause, or null 099 */ 100 public TWhereClause getIndexWhereClause() { 101 return indexWhereClause; 102 } 103 104 public void setIndexWhereClause(TWhereClause indexWhereClause) { 105 this.indexWhereClause = indexWhereClause; 106 } 107 108 /** 109 * Returns the SET clause assignments for the DO UPDATE action. 110 * @return the SET clause result column list, or null if DO NOTHING 111 */ 112 public TResultColumnList getUpdateSetClause() { 113 return updateSetClause; 114 } 115 116 public void setUpdateSetClause(TResultColumnList updateSetClause) { 117 this.updateSetClause = updateSetClause; 118 } 119 120 /** 121 * Returns the WHERE clause for the DO UPDATE action. 122 * @return the update WHERE clause, or null 123 */ 124 public TWhereClause getUpdateWhereClause() { 125 return updateWhereClause; 126 } 127 128 public void setUpdateWhereClause(TWhereClause updateWhereClause) { 129 this.updateWhereClause = updateWhereClause; 130 } 131 132 /** 133 * Sets the conflict target from a TDummy node produced by the grammar. 134 * The TDummy carries: list1 = index columns (TOrderByItemList), 135 * node1 = index WHERE clause (TWhereClause), node2 = constraint name (TObjectName). 136 */ 137 public void setConflictTarget(TDummy dummy) { 138 if (dummy == null) return; 139 if (dummy.list1 != null) { 140 this.indexColumns = (TOrderByItemList) dummy.list1; 141 } 142 if (dummy.node1 != null) { 143 this.indexWhereClause = (TWhereClause) dummy.node1; 144 } 145 if (dummy.node2 != null) { 146 this.constraintName = (TObjectName) dummy.node2; 147 } 148 } 149 150 /** 151 * Parses the ON CONFLICT clause within the context of the parent statement. 152 */ 153 public void doParse(TCustomSqlStatement psql, ESqlClause clauseType) { 154 if (indexColumns != null) { 155 indexColumns.doParse(psql, clauseType); 156 } 157 if (constraintName != null) { 158 constraintName.doParse(psql, clauseType); 159 } 160 if (indexWhereClause != null) { 161 indexWhereClause.doParse(psql, clauseType); 162 } 163 if (updateSetClause != null) { 164 updateSetClause.doParse(psql, clauseType); 165 } 166 if (updateWhereClause != null) { 167 updateWhereClause.doParse(psql, clauseType); 168 } 169 } 170 171 public void acceptChildren(TParseTreeVisitor v) { 172 if (indexColumns != null) { 173 indexColumns.acceptChildren(v); 174 } 175 if (indexWhereClause != null) { 176 indexWhereClause.acceptChildren(v); 177 } 178 if (updateSetClause != null) { 179 updateSetClause.acceptChildren(v); 180 } 181 if (updateWhereClause != null) { 182 updateWhereClause.acceptChildren(v); 183 } 184 } 185}