001package gudusoft.gsqlparser.stmt; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.nodes.*; 005import gudusoft.gsqlparser.nodes.mssql.TOptionClause; 006import gudusoft.gsqlparser.nodes.oracle.TErrorLoggingClause; 007 008/** 009 * Merge SQL statement. 010 * <br> 011 * <br>{@link #getTargetTable()} returns the target table. 012 * <br>{@link #getUsingTable()} returns the source table in the using clause. 013 * <br>{@link #getCondition()} returns the merge search condition. 014 * <br>{@link #getWhenClauses()} returns when MATCHED/NOT MATCHED clauses. 015 * 016 * <pre> 017 * merge into target_table [column_list] 018 * using source_table|subquery 019 * on merge_search_condition 020 * [when matched [and search_conditions ] then update set {col_name = expression} | delete] 021 * [when not matched [and search_conditions ] then insert [(column_list)] values (value_list)] 022 * </pre> 023 * 024 * <p> call {@link #getTargetTable()} to return a value for target_table. 025 * <p> column_list can be fetched from {@link #getColumnList()} if any. 026 * <p> source_table in using clause can be fetched via {@link #getUsingTable()}, 027 * subquery treated as a table as well. 028 * <p> call {@link #getCondition()} to return merge_search_condition. 029 * <p> when [not] matched clause is available by calling {@link #getWhenClauses()} 030 * which is a list of type {@link TMergeWhenClause}. 031 * 032 * @see TMergeWhenClause 033 * @see TMergeUpdateClause 034 * @see TMergeDeleteClause 035 * @see TMergeInsertClause 036 */ 037public class TMergeSqlStatement extends TCustomSqlStatement { 038 039 private TErrorLoggingClause errorLoggingClause; 040 041 /** 042 * Oracle error logging clause. 043 * @return Oracle error logging clause. 044 */ 045 public TErrorLoggingClause getErrorLoggingClause() { 046 return errorLoggingClause; 047 } 048 049 private TOptionClause optionClause; 050 051 /** 052 * sql server option clause 053 * @return option clause 054 * 055 * @see gudusoft.gsqlparser.nodes.mssql.TOptionClause 056 */ 057 public TOptionClause getOptionClause() { 058 return optionClause; 059 } 060 061 public TMergeSqlStatement(EDbVendor dbvendor) { 062 super(dbvendor); 063 sqlstatementtype = ESqlStatementType.sstmerge; 064 } 065 066 void buildsql() { 067 } 068 069 void clear() { 070 } 071 072 String getasprettytext() { 073 return ""; 074 } 075 076 void iterate(TVisitorAbs pvisitor) { 077 } 078 079 private TExpression matchedSearchCondition = null; 080 private TExpression notMatchedSearchCondition = null; 081 private TObjectNameList columnList = null; 082 083 /** 084 * Columns in target table. 085 * @return Columns in target table. 086 */ 087 public TObjectNameList getColumnList() { 088 return columnList; 089 } 090 091 /** 092 * This method is not used, use {@link #getCondition()} instead. 093 * @return not used 094 */ 095 public TExpression getMatchedSearchCondition() { 096 return matchedSearchCondition; 097 } 098 099 /** 100 * This method is not used, use {@link #getCondition()} instead. 101 * @return not used 102 */ 103 public TExpression getNotMatchedSearchCondition() { 104 return notMatchedSearchCondition; 105 } 106 107 private TTable usingTable; 108 109 /** 110 * Source table in the using clause. 111 * @return Source table in the using clause. 112 */ 113 public TTable getUsingTable() { 114 return usingTable; 115 } 116 117 private TExpression condition; 118 119 /** 120 * merge search condition. 121 * @return merge search condition. 122 */ 123 public TExpression getCondition() { 124 return condition; 125 } 126 127 128 private TMergeUpdateClause updateClause; 129 private TMergeInsertClause insertClause; 130 131 /** 132 * This method is not used, use {@link #getWhenClauses()} instead. 133 * @return 134 */ 135 public TMergeUpdateClause getUpdateClause() { 136 return updateClause; 137 } 138 139 /** 140 * This method is not used, use {@link #getWhenClauses()} instead. 141 * @return 142 */ 143 public TMergeInsertClause getInsertClause() { 144 return insertClause; 145 } 146 147 private TPTNodeList <TMergeWhenClause> whenClauses; 148 149 /** 150 * when matched/not matched clauses. 151 * @return when matched/not matched clauses. 152 */ 153 public TPTNodeList<TMergeWhenClause> getWhenClauses() { 154 return whenClauses; 155 } 156 157 public int doParseStatement(TCustomSqlStatement psql) { 158 if (rootNode == null) return -1; 159 TMergeSqlNode mergeSqlNode = (TMergeSqlNode)rootNode; 160 super.doParseStatement(psql); 161 162 if (mergeSqlNode.cteList != null){ 163 this.setCteList( mergeSqlNode.cteList); 164 this.getCteList().doParse(this, ESqlClause.cte); 165 } 166 167 TTable lcTable; 168 lcTable = analyzeFromTable(mergeSqlNode.getTargetTable(),true); 169 lcTable.setEffectType(ETableEffectType.tetMerge); 170 setTargetTable(lcTable); 171 this.getRelations().add(lcTable); 172 173 //tables.addTable(this.getTargetTable()); 174// TFromTable lcFromTable = mergeSqlNode.getUsingTable(); 175// TJoin lcJoin; 176// if (lcFromTable.getFromtableType() != ETableSource.join){ 177// lcJoin = new TJoin(); 178// lcTable = analyzeFromTable(lcFromTable,true); 179// lcTable.setEffectType(ETableEffectType.tetSelect); 180// lcJoin.setTable(lcTable); 181// lcJoin.setStartToken(lcJoin.getTable().getStartToken()); 182// lcJoin.setEndToken(lcJoin.getTable().getEndToken()); 183// lcJoin.setGsqlparser(getGsqlparser()); 184// this.fromSourceTable = lcTable; 185// this.getRelations().add(lcTable); 186// }else{ 187// this.fromSourceJoin = lcFromTable.getJoinExpr(); 188// 189// this.fromSourceTable = new TTable(); 190// this.fromSourceTable.setTableType(ETableSource.join); 191// this.fromSourceTable.setAliasClause(lcFromTable.getJoinExpr().getAliasClause()); 192// this.fromSourceTable.setStartToken(lcFromTable.getStartToken()); 193// this.fromSourceTable.setEndToken(lcFromTable.getEndToken()); 194// this.fromSourceTable.setGsqlparser(lcFromTable.getGsqlparser()); 195// this.fromSourceTable.setJoinExpr(this.fromSourceJoin); 196// this.getRelations().add(this.fromSourceTable); 197// 198// lcJoin = analyzeJoin(lcFromTable.getJoinExpr(),null,true); 199// lcJoin.doParse(this, ESqlClause.join); 200// 201// if (lcFromTable.getLateralViewList() != null){ 202// for(TLateralView lateralView:lcFromTable.getLateralViewList()){ 203// addToTables(lateralView.createATable(this)); 204// } 205// } 206// } 207 208 analyzeTableOrJoin(mergeSqlNode.getUsingTable()); 209 this.usingTable = this.fromSourceTable;//analyzeFromTable(mergeSqlNode.getUsingTable(),true); 210 //usingTable.setEffectType(ETableEffectType.tetSelect); 211 this.getRelations().add(usingTable); 212 213 //tables.addTable(this.usingTable); 214 215 this.condition = mergeSqlNode.getCondition(); 216 this.condition.doParse(this, ESqlClause.joinCondition); 217 218 if (mergeSqlNode.getColumnList() != null){ 219 this.columnList = mergeSqlNode.getColumnList(); 220 TObjectName crf ; 221 for (int i=0;i< mergeSqlNode.getColumnList().size();i++){ 222 crf =mergeSqlNode.getColumnList().getObjectName(i); 223 // link this column to last 2 tables 224 crf.setLocation(ESqlClause.mergeInsert); 225 getTargetTable().getObjectNameReferences().addObjectName(crf); 226 getTargetTable().getLinkedColumns().addObjectName(crf); 227 crf.setSourceTable(getTargetTable()); 228 crf.setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM); 229 } 230 231 //insertNode.getColumnList().doParse(this,TBaseType.insertColumnClause); 232 } 233 234 this.whenClauses = mergeSqlNode.getWhenClauses(); 235 if (this.whenClauses != null){ 236 this.whenClauses.doParse(this,ESqlClause.unknown); 237 } 238 239 limitClause = mergeSqlNode.getLimitClause(); 240 if (limitClause != null){ 241 limitClause.doParse(this,ESqlClause.unknown); 242 } 243 returningClause = mergeSqlNode.getReturningClause(); 244 if (returningClause != null){ 245 returningClause.doParse(this,ESqlClause.unknown); 246 } 247 248 if (mergeSqlNode.getOutputClause() != null){ 249 mergeSqlNode.getOutputClause().doParse(this,ESqlClause.output); 250 this.setOutputClause(mergeSqlNode.getOutputClause()); 251 } 252 253 this.optionClause = mergeSqlNode.getOptionClause(); 254 255 errorLoggingClause = mergeSqlNode.getErrorLoggingClause(); 256 // tables.addTable(this.getTargetTable()); 257 258 return 0; 259 } 260 261 public void accept(TParseTreeVisitor v){ 262 v.preVisit(this); 263 v.postVisit(this); 264 } 265 266 public void acceptChildren(TParseTreeVisitor v){ 267 v.preVisit(this); 268 this.getTargetTable().acceptChildren(v); 269 usingTable.acceptChildren(v); 270 condition.acceptChildren(v); 271 if (columnList != null) columnList.acceptChildren(v); 272 if (whenClauses != null) whenClauses.acceptChildren(v); 273 if (getOutputClause() != null) getOutputClause().acceptChildren(v); 274 if (errorLoggingClause != null) errorLoggingClause.acceptChildren(v); 275 v.postVisit(this); 276 } 277 278 public void setErrorLoggingClause(TErrorLoggingClause errorLoggingClause) { 279 this.errorLoggingClause = errorLoggingClause; 280 } 281 282 public void setOptionClause(TOptionClause optionClause) { 283 this.optionClause = optionClause; 284 } 285 286 public void setMatchedSearchCondition(TExpression matchedSearchCondition) { 287 this.matchedSearchCondition = matchedSearchCondition; 288 } 289 290 public void setNotMatchedSearchCondition(TExpression notMatchedSearchCondition) { 291 this.notMatchedSearchCondition = notMatchedSearchCondition; 292 } 293 294 public void setColumnList(TObjectNameList columnList) { 295 this.columnList = columnList; 296 } 297 298 public void setUsingTable(TTable usingTable) { 299 this.usingTable = usingTable; 300 } 301 302 public void setCondition(TExpression condition) { 303 this.condition = condition; 304 } 305 306 public void setUpdateClause(TMergeUpdateClause updateClause) { 307 this.updateClause = updateClause; 308 } 309 310 public void setInsertClause(TMergeInsertClause insertClause) { 311 this.insertClause = insertClause; 312 } 313 314 public void setWhenClauses(TPTNodeList<TMergeWhenClause> whenClauses) { 315 this.whenClauses = whenClauses; 316 } 317 318 private TLimitClause limitClause; 319 320 public void setLimitClause(TLimitClause limitClause) { 321 this.limitClause = limitClause; 322 } 323 324 /** 325 * Couchbase, limit clause. 326 * @return Couchbase, limit clause. 327 */ 328 public TLimitClause getLimitClause() { 329 330 return limitClause; 331 } 332 333 private TReturningClause returningClause; 334 335 public void setReturningClause(TReturningClause returningClause) { 336 this.returningClause = returningClause; 337 } 338 339 /** 340 * Couchbase, returning clause. 341 * @return Couchbase, returning clause. 342 */ 343 public TReturningClause getReturningClause() { 344 345 return returningClause; 346 } 347}