001package gudusoft.gsqlparser.stmt; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.compiler.TSymbolTableManager; 005import gudusoft.gsqlparser.compiler.TVariable; 006import gudusoft.gsqlparser.nodes.*; 007 008 009/** 010 * execute statement 011 * 012 * db: couchbase, netezza,greenplum,mysql, postgresql,redshift 013 * 014 * @TODO: 2024/2/7 {@link gudusoft.gsqlparser.stmt.mssql.TMssqlExecute}, {@link TExecImmeStmt} should merge into this class 015 */ 016public class TExecuteSqlStatement extends TCustomSqlStatement { 017 018 private String preparedSqlText; 019 020 public void setPreparedSqlText(String preparedSqlText) { 021 this.preparedSqlText = preparedSqlText; 022 } 023 024 public String getPreparedSqlText() { 025 return preparedSqlText; 026 } 027 028 private EExecType executeType = EExecType.unknown; 029 030 public EExecType getExecuteType() { 031 return executeType; 032 } 033 034 private TCustomSqlStatement stmt; 035 036 public TCustomSqlStatement getStmt() { 037 return stmt; 038 } 039 040 public TExecuteSqlStatement(){ 041 this(EDbVendor.dbvpostgresql); 042 } 043 044 public TExecuteSqlStatement(EDbVendor dbvendor) { 045 super(dbvendor); 046 sqlstatementtype = ESqlStatementType.sstExecute; 047 } 048 049 public int doParseStatement(TCustomSqlStatement psql) { 050 051 if (rootNode == null) return -1; 052 super.doParseStatement(psql); 053 054 TExecuteSqlNode sqlNode = (TExecuteSqlNode)rootNode; 055 this.executeType = sqlNode.getExecuteType(); 056 057 switch (dbvendor){ 058 case dbvpostgresql: 059 this.stmtString = sqlNode.getStmtString(); 060 this.intoVariable = sqlNode.getIntoVariable(); 061 this.usingVariables = sqlNode.getUsingVariables(); 062 063 sqlText = stmtString.toString(); 064 if (stmtString.getExpressionType() == EExpressionType.function_t){ 065 if (stmtString.toString().startsWith("format")){ 066 //postgresql format function 067 TFunctionCall functionCall = stmtString.getFunctionCall(); 068 sqlText = functionCall.getArgs().getExpression(0).toString(); 069 sqlText = sqlText.replaceAll("%s","PLACEHOLDER"); 070 } 071 } 072 // System.out.println(sqlText); 073 074 this.moduleName = sqlNode.getModuleName(); 075 this.statementName = sqlNode.getModuleName(); 076 this.parameters = sqlNode.getStringValues(); 077 078 break; 079 case dbvsnowflake: 080 this.stmtString = sqlNode.getStmtString(); 081 //System.out.println(stmtString.toString()); 082 TSourceToken st = stmtString.getStartToken(); 083 if (st.toString().startsWith("$$")){ 084 TGSqlParser parser = new TGSqlParser(EDbVendor.dbvsnowflake); 085 parser.sqltext = TBaseType.stringBlock((int)st.lineNo - 1,(int)st.columnNo)+ TBaseType.getStringInsideLiteral(st.toString()); 086 int ret = parser.parse(); 087 if (ret == 0){ 088 stmt = parser.sqlstatements.get(0); 089 }else{ 090 for(int j=0;j<parser.getErrorCount();j++){ 091 this.parseerrormessagehandle(parser.getSyntaxErrors().get(j)); 092 } 093 } 094 } 095 096 break; 097 case dbvnetezza: 098 this.moduleName = sqlNode.getModuleName(); 099 this.statementName = sqlNode.getModuleName(); 100 this.parameters = sqlNode.getStringValues(); 101 preparedValue = sqlNode.getPreparedValue(); 102 if (preparedValue != null){ 103 preparedValue.doParse(this, ESqlClause.unknown); 104 } 105 106 switch (executeType){ 107 case expr: 108 if (sqlNode.getPreparedValue().getExpressionType() == EExpressionType.function_t){ 109 TFunctionCall functionCall = sqlNode.getPreparedValue().getFunctionCall(); 110 this.moduleName = functionCall.getFunctionName(); 111 this.parameters = functionCall.getArgs(); 112 this.executeType = EExecType.module; 113 } 114 break; 115 default: 116 break; 117 } 118 119 break; 120 case dbvredshift: 121 this.moduleName = sqlNode.getModuleName(); 122 this.statementName = sqlNode.getModuleName(); 123 this.parameters = sqlNode.getStringValues(); 124 preparedValue = sqlNode.getPreparedValue(); 125 if (preparedValue != null){ 126 preparedValue.doParse(this, ESqlClause.unknown); 127 128 if (this.preparedValue.getExpressionType() == EExpressionType.simple_object_name_t){ 129 TObjectName var = this.preparedValue.getObjectOperand(); 130 // if (var.getDbObjectType() == EDbObjectType.variable){ 131 TVariable symbolVariable = TSymbolTableManager.searchSymbolVariable(this.getFrameStack(),var.toString()); 132 if (symbolVariable != null){ 133 this.sqlText = symbolVariable.getVariableStr(); 134 //System.out.println(this.sqlText); 135 } 136 // } 137 } 138 139 } 140 break; 141 default: 142 this.moduleName = sqlNode.getModuleName(); 143 this.statementName = sqlNode.getModuleName(); 144 this.parameters = sqlNode.getStringValues(); 145 preparedValue = sqlNode.getPreparedValue(); 146 if (preparedValue != null){ 147 preparedValue.doParse(this, ESqlClause.unknown); 148 } 149 150 // available in TMssqlExecute currently, maybe will be moved to here in later version 151 //this.stringValues = sqlNode.getStringValues(); 152 //this.linkServerName = sqlNode.getLinkServerName(); 153 154 break; 155 } 156 return 0; 157 } 158 159 static TGSqlParser sqlparser = null; 160 static { 161 // Todo: hardcode to redshift, need to change according to dbvendor 162 sqlparser = new TGSqlParser(EDbVendor.dbvredshift); 163 } 164 165 private TStatementList dynamicStatements = null; 166 167 /** 168 * 169 * @return sql statement instance that generated dynamically based on {@link #sqlText} 170 */ 171 public synchronized TStatementList getDynamicStatements() { 172 if (this.dynamicStatements != null) return this.dynamicStatements; 173 if (this.sqlText == null) return null; 174 175 176 String query = this.sqlText; 177 if((this.preparedValue != null) && (this.preparedValue.getPlainTextLineNo() != -1)){ 178 long lineNo = this.preparedValue.getPlainTextLineNo(); 179 long columnNo = this.preparedValue.getPlainTextColumnNo(); 180 query = TBaseType.stringBlock((int)lineNo - 1,(int)columnNo)+ this.sqlText; 181 } 182 183 184 sqlparser.sqltext = query; 185 int ret = sqlparser.parse(); 186 187 if ( ret != 0){ 188 for(int j=0;j<sqlparser.getErrorCount();j++){ 189 this.parseerrormessagehandle(sqlparser.getSyntaxErrors().get(j)); 190 } 191 192 return null; 193 } 194 195 this.dynamicStatements = new TStatementList(); 196 for(int i=0;i<sqlparser.sqlstatements.size();i++){ 197 if (this.getParentStmt() == null){ 198 sqlparser.sqlstatements.get(i).setParentStmt(this); 199 }else{ 200 sqlparser.sqlstatements.get(i).setParentStmt(this.getParentStmt()); 201 } 202 203 this.dynamicStatements.add(sqlparser.sqlstatements.get(i)); 204 } 205 return dynamicStatements; 206 } 207 208 public TObjectName getLinkServerName() { 209 return linkServerName; 210 } 211 212 private TObjectName linkServerName; 213 private TExpressionList stringValues = null; 214 215 public TExpressionList getStringValues() { 216 return stringValues; 217 } 218 219 private TObjectName moduleName; 220 221 public TObjectName getModuleName() { 222 return moduleName; 223 } 224 225 private TExpression stmtString; 226 private TObjectName intoVariable; 227 private TExpressionList usingVariables; 228 229 private TObjectName statementName; 230 private TExpressionList parameters; 231 private TExpression preparedValue;//couchbase 232 233 public void setSqlText(String sqlText) { 234 this.sqlText = sqlText; 235 } 236 237 private String sqlText = null; 238 239 public String getSqlText() { 240 return sqlText; 241 } 242 243 public void init(Object arg1){ 244 stmtString = (TExpression)arg1; 245 sqlText = stmtString.toString(); 246 switch (stmtString.getExpressionType()){ 247 case simple_object_name_t: 248 moduleName = stmtString.getObjectOperand(); 249 //moduleName.setObjectType(TObjectName.ttobjProcedureName); 250 moduleName.setDbObjectType(EDbObjectType.procedure); 251 break; 252 case function_t: 253 if (stmtString.toString().startsWith("format")){ 254 //postgresql format function 255 TFunctionCall functionCall = stmtString.getFunctionCall(); 256 sqlText = functionCall.getArgs().getExpression(0).toString(); 257 sqlText = sqlText.replaceAll("%s","PLACEHOLDER"); 258 } 259 break; 260 } 261 262 } 263 public void init(Object arg1,Object arg2){ 264 init(arg1); 265 intoVariable = (TObjectName)arg2; 266 267 } 268 269 public TObjectName getIntoVariable() { 270 return intoVariable; 271 } 272 273 public TExpression getStmtString() { 274 return stmtString; 275 } 276 277 public TExpressionList getUsingVariables() { 278 return usingVariables; 279 } 280 281 public void init(Object arg1,Object arg2, Object arg3){ 282 init(arg1,arg2); 283 usingVariables = (TExpressionList)arg3; 284 285 } 286 287 public void accept(TParseTreeVisitor v){ 288 v.preVisit(this); 289 v.postVisit(this); 290 } 291 292 public void acceptChildren(TParseTreeVisitor v){ 293 v.preVisit(this); 294 v.postVisit(this); 295 } 296 297 public void setStmtString(TExpression stmtString) { 298 this.stmtString = stmtString; 299 } 300 301 public void setIntoVariable(TObjectName intoVariable) { 302 this.intoVariable = intoVariable; 303 } 304 305 public void setUsingVariables(TExpressionList usingVariables) { 306 this.usingVariables = usingVariables; 307 } 308 309 public TObjectName getStatementName() { 310 return statementName; 311 } 312 public TExpressionList getParameters() { 313 return parameters; 314 } 315 public void setStatementName(TObjectName statementName) { 316 this.statementName = statementName; 317 } 318 public void setParameters(TExpressionList parameters) { 319 this.parameters = parameters; 320 } 321 public TExpression getPreparedValue() { 322 return preparedValue; 323 } 324 325}