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 if (this.condition != null) { 217 this.condition.doParse(this, ESqlClause.joinCondition); 218 } 219 220 if (mergeSqlNode.getColumnList() != null){ 221 this.columnList = mergeSqlNode.getColumnList(); 222 TObjectName crf ; 223 for (int i=0;i< mergeSqlNode.getColumnList().size();i++){ 224 crf =mergeSqlNode.getColumnList().getObjectName(i); 225 // link this column to last 2 tables 226 crf.setLocation(ESqlClause.mergeInsert); 227 getTargetTable().getObjectNameReferences().addObjectName(crf); 228 getTargetTable().getLinkedColumns().addObjectName(crf); 229 crf.setSourceTable(getTargetTable()); 230 crf.setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM); 231 } 232 233 //insertNode.getColumnList().doParse(this,TBaseType.insertColumnClause); 234 } 235 236 this.whenClauses = mergeSqlNode.getWhenClauses(); 237 if (this.whenClauses != null){ 238 this.whenClauses.doParse(this,ESqlClause.unknown); 239 } 240 241 limitClause = mergeSqlNode.getLimitClause(); 242 if (limitClause != null){ 243 limitClause.doParse(this,ESqlClause.unknown); 244 } 245 returningClause = mergeSqlNode.getReturningClause(); 246 if (returningClause != null){ 247 returningClause.doParse(this,ESqlClause.unknown); 248 } 249 250 if (mergeSqlNode.getOutputClause() != null){ 251 mergeSqlNode.getOutputClause().doParse(this,ESqlClause.output); 252 this.setOutputClause(mergeSqlNode.getOutputClause()); 253 } 254 255 this.optionClause = mergeSqlNode.getOptionClause(); 256 257 errorLoggingClause = mergeSqlNode.getErrorLoggingClause(); 258 // tables.addTable(this.getTargetTable()); 259 260 return 0; 261 } 262 263 public void accept(TParseTreeVisitor v){ 264 v.preVisit(this); 265 v.postVisit(this); 266 } 267 268 public void acceptChildren(TParseTreeVisitor v){ 269 v.preVisit(this); 270 this.getTargetTable().acceptChildren(v); 271 usingTable.acceptChildren(v); 272 condition.acceptChildren(v); 273 if (columnList != null) columnList.acceptChildren(v); 274 if (whenClauses != null) whenClauses.acceptChildren(v); 275 if (getOutputClause() != null) getOutputClause().acceptChildren(v); 276 if (errorLoggingClause != null) errorLoggingClause.acceptChildren(v); 277 v.postVisit(this); 278 } 279 280 public void setErrorLoggingClause(TErrorLoggingClause errorLoggingClause) { 281 this.errorLoggingClause = errorLoggingClause; 282 } 283 284 public void setOptionClause(TOptionClause optionClause) { 285 this.optionClause = optionClause; 286 } 287 288 public void setMatchedSearchCondition(TExpression matchedSearchCondition) { 289 this.matchedSearchCondition = matchedSearchCondition; 290 } 291 292 public void setNotMatchedSearchCondition(TExpression notMatchedSearchCondition) { 293 this.notMatchedSearchCondition = notMatchedSearchCondition; 294 } 295 296 public void setColumnList(TObjectNameList columnList) { 297 this.columnList = columnList; 298 } 299 300 public void setUsingTable(TTable usingTable) { 301 this.usingTable = usingTable; 302 } 303 304 public void setCondition(TExpression condition) { 305 this.condition = condition; 306 } 307 308 public void setUpdateClause(TMergeUpdateClause updateClause) { 309 this.updateClause = updateClause; 310 } 311 312 public void setInsertClause(TMergeInsertClause insertClause) { 313 this.insertClause = insertClause; 314 } 315 316 public void setWhenClauses(TPTNodeList<TMergeWhenClause> whenClauses) { 317 this.whenClauses = whenClauses; 318 } 319 320 private TLimitClause limitClause; 321 322 public void setLimitClause(TLimitClause limitClause) { 323 this.limitClause = limitClause; 324 } 325 326 /** 327 * Couchbase, limit clause. 328 * @return Couchbase, limit clause. 329 */ 330 public TLimitClause getLimitClause() { 331 332 return limitClause; 333 } 334 335 private TReturningClause returningClause; 336 337 public void setReturningClause(TReturningClause returningClause) { 338 this.returningClause = returningClause; 339 } 340 341 /** 342 * Couchbase, returning clause. 343 * @return Couchbase, returning clause. 344 */ 345 public TReturningClause getReturningClause() { 346 347 return returningClause; 348 } 349}