001package gudusoft.gsqlparser.stmt.snowflake; 002 003import gudusoft.gsqlparser.EDbObjectType; 004import gudusoft.gsqlparser.EDbVendor; 005import gudusoft.gsqlparser.ESqlStatementType; 006import gudusoft.gsqlparser.TBaseType; 007import gudusoft.gsqlparser.TCustomSqlStatement; 008import gudusoft.gsqlparser.TSourceToken; 009import gudusoft.gsqlparser.nodes.TObjectName; 010import gudusoft.gsqlparser.nodes.TParseTreeVisitor; 011import gudusoft.gsqlparser.nodes.TDummy; 012 013 014public class TDropTaskStmt extends TCustomSqlStatement { 015 016 private TObjectName taskName; 017 private boolean ifExists = false; 018 private boolean cascade = false; 019 private boolean restrict = false; 020 021 public TDropTaskStmt(EDbVendor dbvendor) { 022 super(dbvendor); 023 sqlstatementtype = ESqlStatementType.sstDropTask; 024 } 025 026 public int doParseStatement(TCustomSqlStatement psql) { 027 // When grammar parser provides rootNode, use it 028 if (rootNode != null) { 029 super.doParseStatement(psql); 030 TDummy node = (TDummy)rootNode; 031 taskName = (TObjectName) node.node1; 032 taskName.setDbObjectType(EDbObjectType.task); 033 } 034 // Otherwise taskName was set in dochecksyntax 035 return 0; 036 } 037 038 /** 039 * Override dochecksyntax to parse DROP TASK statement directly from tokens. 040 * This bypasses the grammar parser which may not have the DROP TASK rule. 041 * Syntax: DROP TASK [IF EXISTS] <qualified_name> [CASCADE | RESTRICT] 042 */ 043 @Override 044 protected int dochecksyntax(TCustomSqlStatement psql) { 045 isparsed = true; 046 047 // Parse tokens: DROP TASK [IF EXISTS] name [CASCADE|RESTRICT] 048 int index = 0; 049 050 // Helper to skip non-solid tokens (whitespace, comments) 051 while (index < sourcetokenlist.size() && !sourcetokenlist.get(index).issolidtoken()) { 052 index++; 053 } 054 055 // Skip DROP token 056 if (index < sourcetokenlist.size() && sourcetokenlist.get(index).tokencode == TBaseType.rrw_drop) { 057 index++; 058 } 059 060 // Skip non-solid tokens 061 while (index < sourcetokenlist.size() && !sourcetokenlist.get(index).issolidtoken()) { 062 index++; 063 } 064 065 // Skip TASK token (it's an identifier, not a reserved word) 066 if (index < sourcetokenlist.size()) { 067 TSourceToken taskToken = sourcetokenlist.get(index); 068 if (taskToken.toString().equalsIgnoreCase("TASK")) { 069 index++; 070 } 071 } 072 073 // Skip non-solid tokens 074 while (index < sourcetokenlist.size() && !sourcetokenlist.get(index).issolidtoken()) { 075 index++; 076 } 077 078 // Check for IF EXISTS 079 if (index < sourcetokenlist.size()) { 080 TSourceToken token = sourcetokenlist.get(index); 081 if (token.tokencode == TBaseType.rrw_if) { 082 index++; 083 // Skip non-solid tokens 084 while (index < sourcetokenlist.size() && !sourcetokenlist.get(index).issolidtoken()) { 085 index++; 086 } 087 // Check for EXISTS 088 if (index < sourcetokenlist.size() && sourcetokenlist.get(index).toString().equalsIgnoreCase("EXISTS")) { 089 ifExists = true; 090 index++; 091 } 092 // Skip non-solid tokens 093 while (index < sourcetokenlist.size() && !sourcetokenlist.get(index).issolidtoken()) { 094 index++; 095 } 096 } 097 } 098 099 // Now parse the qualified name (task name) 100 // Collect tokens until we hit semicolon, CASCADE, RESTRICT, or end 101 TSourceToken startToken = null; 102 TSourceToken endToken = null; 103 104 while (index < sourcetokenlist.size()) { 105 TSourceToken token = sourcetokenlist.get(index); 106 107 // Skip non-solid tokens 108 if (!token.issolidtoken()) { 109 index++; 110 continue; 111 } 112 113 // Stop at semicolon 114 if (token.tokencode == ';' || token.toString().equals(";")) { 115 break; 116 } 117 118 // Check for CASCADE or RESTRICT 119 String tokenStr = token.toString().toUpperCase(); 120 if (tokenStr.equals("CASCADE")) { 121 cascade = true; 122 index++; 123 continue; 124 } 125 if (tokenStr.equals("RESTRICT")) { 126 restrict = true; 127 index++; 128 continue; 129 } 130 131 // Part of the qualified name 132 if (startToken == null) { 133 startToken = token; 134 } 135 endToken = token; 136 index++; 137 } 138 139 // Create TObjectName from the tokens 140 if (startToken != null) { 141 taskName = new TObjectName(); 142 taskName.setStartToken(startToken); 143 taskName.setEndToken(endToken != null ? endToken : startToken); 144 taskName.setDbObjectType(EDbObjectType.task); 145 } 146 147 return 0; 148 } 149 150 public TObjectName getTaskName() { 151 return taskName; 152 } 153 154 155 public boolean isIfExists() { 156 return ifExists; 157 } 158 159 public void setIfExists(boolean ifExists) { 160 this.ifExists = ifExists; 161 } 162 163 public boolean isCascade() { 164 return cascade; 165 } 166 167 public void setCascade(boolean cascade) { 168 this.cascade = cascade; 169 } 170 171 public boolean isRestrict() { 172 return restrict; 173 } 174 175 public void setRestrict(boolean restrict) { 176 this.restrict = restrict; 177 } 178 179 public void accept(TParseTreeVisitor v){ 180 v.preVisit(this); 181 v.postVisit(this); 182 } 183 184 public void acceptChildren(TParseTreeVisitor v){ 185 v.preVisit(this); 186 v.postVisit(this); 187 } 188}