001package gudusoft.gsqlparser.stmt; 002 003 004import gudusoft.gsqlparser.*; 005import gudusoft.gsqlparser.nodes.*; 006 007import java.util.EnumSet; 008 009/** 010 * Create trigger statement. 011 * 012 * supported databases: 013 * <ul> 014 * <li>DB2</li> 015 * <li>Hana</li> 016 * <li>Greenplum, represented by {@link gudusoft.gsqlparser.stmt.oracle.TPlsqlCreateTrigger}</li> 017 * <li>Informix</li> 018 * <li>MySQL</li> 019 * <li>Openedge</li> 020 * <li>Oracle, represented by {@link gudusoft.gsqlparser.stmt.oracle.TPlsqlCreateTrigger} 021 * support dml, non-dml and database trigger. 022 * </li> 023 * <li>PostgreSQL</li> 024 * <li>SQL Server, 025 * support dml, ddl trigger 026 * </li> 027 * <li>Sybase</li> 028 * <li>Teradata</li> 029 * </ul> 030 * 031 * @see TTriggeringClause 032 */ 033public class TCreateTriggerStmt extends TStoredProcedureSqlStatement { 034 public void setTriggeringClause(TTriggeringClause triggeringClause) { 035 this.triggeringClause = triggeringClause; 036 } 037 038 public TCreateTriggerStmt (EDbVendor dbvendor){ 039 super(dbvendor); 040 sqlstatementtype = ESqlStatementType.sstcreatetrigger ; 041 } 042 043 044 void buildsql() { 045 } 046 047 void clear() { 048 } 049 050 String getasprettytext() { 051 return ""; 052 } 053 054 void iterate(TVisitorAbs pvisitor) { 055 } 056 057 private TExpression whenCondition = null; 058 059 /** 060 * When condition 061 * @return when condition 062 */ 063 public TExpression getWhenCondition() { 064 return whenCondition; 065 } 066 067 private boolean alterTrigger; 068 069 public void setAlterTrigger(boolean alterTrigger) { 070 this.alterTrigger = alterTrigger; 071 } 072 073 public boolean isAlterTrigger() { 074 075 return alterTrigger; 076 } 077 @Override 078 public TObjectName getStoredProcedureName(){ 079 return triggerName; 080 } 081 082 private TTable onTable = null; 083 084 /** 085 * @deprecated As of v2.0.1.0, use {@link #getTriggeringClause()} instead 086 * 087 * @return onTable 088 */ 089 public TTable getOnTable() { 090 return onTable; 091 } 092 093 094 public TObjectName getTriggerName() { 095 return triggerName; 096 } 097 098 private TObjectName triggerName = null; 099 100 public void setTimingPoint(ETriggerTimingPoint timingPoint) { 101 this.timingPoint = timingPoint; 102 } 103 104 public void setDmlTypes(EnumSet<ETriggerDmlType> dmlTypes) { 105 this.dmlTypes = dmlTypes; 106 } 107 108 /** 109 * @deprecated As of v2.0.1.0, replaced by {@link #getTriggeringClause()} 110 * @return timing point 111 */ 112 public ETriggerTimingPoint getTimingPoint() { 113 114 return timingPoint; 115 } 116 117 /** 118 * @deprecated As of v2.0.1.0, replaced by {@link #getTriggeringClause()} 119 * @return dml 120 */ 121 public EnumSet<ETriggerDmlType> getDmlTypes() { 122 return dmlTypes; 123 } 124 125 private TFunctionCall functionCall;//postgresql 126 127 public void setFunctionCall(TFunctionCall functionCall) { 128 this.functionCall = functionCall; 129 } 130 131 /** 132 * Greenplum,postgresql executed function 133 * 134 * @return function call 135 */ 136 public TFunctionCall getFunctionCall() { 137 138 return functionCall; 139 } 140 141 public int doParseStatement(TCustomSqlStatement psql) { 142 if (rootNode == null) return -1; 143 if(!(rootNode instanceof TCreateTriggerSqlNode)) return -1; 144 TCreateTriggerSqlNode createTriggerNode = (TCreateTriggerSqlNode)rootNode; 145 146 super.doParseStatement(psql); 147 this.triggerName = createTriggerNode.getTriggerName(); 148 if (getSqlEnv().getDefaultCatalogName() != null){ 149 if (triggerName.getDatabaseToken() == null){ 150 triggerName.setDatabaseToken(new TSourceToken(getSqlEnv().getDefaultCatalogName())); 151 } 152 } 153 alterTrigger = createTriggerNode.isAlterTrigger(); 154 this.fireMode = createTriggerNode.getFireMode(); 155 timingPoint = createTriggerNode.getTimingPoint(); 156 triggeringClause = createTriggerNode.getTriggeringClause(); 157 triggeringClause.doParse(this,ESqlClause.unknown); 158 functionCall = createTriggerNode.getFunctionCall(); 159 160 onTable = tables.getTable(0); 161 162 switch (dbvendor){ 163 case dbvdb2: 164 TTriggerAction triggerAction = createTriggerNode.getTriggerAction(); 165 this.whenCondition = triggerAction.getWhenExpr(); 166 167 if (triggerAction.getStmtNode() != null){ 168 triggerAction.getStmtNode().doParse(this,ESqlClause.unknown); 169 this.getBodyStatements().add(triggerAction.getStmtNode().getStmt()); 170 }else if (triggerAction.getCompoundSqlNode() != null){ 171 TCompoundSqlNode compoundSqlNode = triggerAction.getCompoundSqlNode(); 172 if (compoundSqlNode.getDeclareStmts() != null){ 173 compoundSqlNode.getDeclareStmts().doParse(this,ESqlClause.unknown); 174 175 // push variable declare into symbolTable, and add to declareStatements 176 for(int i=0;i<compoundSqlNode.getDeclareStmts().size();i++){ 177 this.getTopStatement().getSymbolTable().push( new TSymbolTableItem(TObjectName.ttobjVariable,this,compoundSqlNode.getDeclareStmts().getStatementSqlNode(i).getStmt() )); 178 this.getDeclareStatements().add(compoundSqlNode.getDeclareStmts().getStatementSqlNode(i).getStmt()); 179 } 180 } 181 182 if (compoundSqlNode.getStmts() != null){ 183 compoundSqlNode.getStmts().doParse(this,ESqlClause.unknown); 184 185 for(int i= 0; i<compoundSqlNode.getStmts().size();i++){ 186 this.getBodyStatements().add(compoundSqlNode.getStmts().getStatementSqlNode(i).getStmt()); 187 } 188 } 189 190 if (compoundSqlNode.getDeclareStmts() != null){ 191 // pop variable declare from symbolTable 192 for(int i=0;i<compoundSqlNode.getDeclareStmts().size();i++){ 193 this.getTopStatement().getSymbolTable().pop(); 194 } 195 } 196 } 197 break; 198 case dbvmysql: 199 parseMySqlTriggerBody(createTriggerNode); 200 break; 201 case dbvoceanbase: 202 // MySQL/system tenant: the MySQL trigger body, one statement or a BEGIN ... END block 203 // (Mantis 4813, Codex review); Oracle tenant keeps the generic reading 204 if (isMySQLDialect()){ 205 parseMySqlTriggerBody(createTriggerNode); 206 }else{ 207 parseGenericTriggerBody(createTriggerNode); 208 } 209 break; 210 case dbvsqlite: 211 if (createTriggerNode.getWhenCondition() != null){ 212 this.whenCondition = createTriggerNode.getWhenCondition(); 213 } 214 if (createTriggerNode.getStmts() != null){ 215 createTriggerNode.getStmts().doParse(this,ESqlClause.unknown); 216 for(int i=0;i<createTriggerNode.getStmts().size();i++){ 217 this.getBodyStatements().add(createTriggerNode.getStmts().getStatementSqlNode(i).getStmt()); 218 } 219 } 220 break; 221 default: 222 parseGenericTriggerBody(createTriggerNode); 223 break; 224 } 225 226 227 return 0; 228 } 229 230 /** A MySQL trigger body: one statement, or the statements of a BEGIN ... END block. */ 231 private void parseMySqlTriggerBody(TCreateTriggerSqlNode createTriggerNode){ 232 if (createTriggerNode.getStmt() != null){ 233 createTriggerNode.getStmt().doParse(this,ESqlClause.unknown); 234 this.getBodyStatements().add(createTriggerNode.getStmt().getStmt()); 235 } 236 else if (createTriggerNode.getBlcok() != null){ 237 if (createTriggerNode.getBlcok().getStmts() != null){ 238 createTriggerNode.getBlcok().getStmts().doParse(this,ESqlClause.unknown); 239 240 for(int i=0;i<createTriggerNode.getBlcok().getStmts().size();i++){ 241 this.getBodyStatements().add(createTriggerNode.getBlcok().getStmts().getStatementSqlNode(i).getStmt()); 242 } 243 } 244 } 245 } 246 247 /** The trigger body of the other dialects: the node's statement list. */ 248 private void parseGenericTriggerBody(TCreateTriggerSqlNode createTriggerNode){ 249 if (createTriggerNode.getStmts() != null){ 250 createTriggerNode.getStmts().doParse(this,ESqlClause.unknown); 251 for(int i=0;i<createTriggerNode.getStmts().size();i++){ 252 this.getBodyStatements().add(createTriggerNode.getStmts().getStatementSqlNode(i).getStmt()); 253 } 254 } 255 } 256 257 private TTriggeringClause triggeringClause; 258 259 public TTriggeringClause getTriggeringClause() { 260 return triggeringClause; 261 } 262 263 private int fireMode = TBaseType.tfmFor; 264 private ETriggerTimingPoint timingPoint = ETriggerTimingPoint.ttpAfter; 265 private EnumSet <ETriggerDmlType> dmlTypes = EnumSet.noneOf(ETriggerDmlType.class); 266 267 /** 268 * @deprecated As of v1.7.2.5, replaced by {@link gudusoft.gsqlparser.ETriggerDmlType} 269 * @return insert/delete/update action 270 */ 271 public TSourceTokenList getDmlTpyes() { 272 if (this.dmlTpyes == null){ 273 this.dmlTpyes = new TSourceTokenList(); 274 } 275 return this.dmlTpyes; 276 } 277 278 private TSourceTokenList dmlTpyes = null; 279 280 /** 281 * @deprecated As of v1.7.2.5, replaced by {@link gudusoft.gsqlparser.ETriggerTimingPoint} 282 * @return trigger timing point 283 */ 284 public int getFireMode() { 285 return fireMode; 286 } 287 288 public void accept(TParseTreeVisitor v){ 289 v.preVisit(this); 290 291 v.postVisit(this); 292 } 293 public void acceptChildren(TParseTreeVisitor v){ 294 v.preVisit(this); 295 if (getBodyStatements().size() > 0) getBodyStatements().acceptChildren(v); 296 v.postVisit(this); 297 } 298 299 public void setOnTable(TTable onTable) { 300 this.onTable = onTable; 301 } 302 303 public void setTriggerName(TObjectName triggerName) { 304 this.triggerName = triggerName; 305 } 306 307 public void setFireMode(int fireMode) { 308 this.fireMode = fireMode; 309 } 310}