001package gudusoft.gsqlparser.stmt.mssql; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.compiler.TSymbolTableManager; 005import gudusoft.gsqlparser.compiler.TVariable; 006import gudusoft.gsqlparser.nodes.*; 007import gudusoft.gsqlparser.nodes.mssql.TExecuteOption; 008import gudusoft.gsqlparser.stmt.TCreateFunctionStmt; 009import gudusoft.gsqlparser.stmt.TCreateProcedureStmt; 010import gudusoft.gsqlparser.stmt.TRoutine; 011import gudusoft.gsqlparser.stmt.TStoredProcedureSqlStatement; 012 013/** 014 * Execute a stored procedure or function, 015 * or Execute a character string 016 */ 017public class TMssqlExecute extends TCustomSqlStatement { 018 public TMssqlExecute (EDbVendor dbvendor){ 019 super(dbvendor); 020 sqlstatementtype = ESqlStatementType.sstmssqlexec ; 021 } 022 023 void buildsql() { 024 } 025 026 void clear() { 027 } 028 029 String getasprettytext() { 030 return ""; 031 } 032 033 void iterate(TVisitorAbs pvisitor) { 034 } 035 036 037 private String sqlText = null; 038 039 private TObjectName moduleName = null; 040 private TObjectName returnStatus = null; 041 private TExecParameterList parameters = null; 042 043 public String getSqlText() { 044 return sqlText; 045 } 046 047 public TObjectName getModuleName() { 048 return moduleName; 049 } 050 051 public TExecParameterList getParameters() { 052 return parameters; 053 } 054 055 public TObjectName getReturnStatus() { 056 return returnStatus; 057 } 058 059 public TExpressionList getStringValues() { 060 return stringValues; 061 } 062 063 public int getExecType() { 064 return execType; 065 } 066 067 private TExpressionList stringValues = null; 068 private int execType = TBaseType.metExecSp; 069 070 public TExpression getPreparedValue() { 071 return preparedValue; 072 } 073 074 private TExpression preparedValue;//couchbase 075 076 private boolean isValidProcedureCall(TSourceTokenList stList,TSyntaxError err){ 077 boolean ret = false; 078 079 if (stList.size() <= 1) return false; 080 TSourceToken st = stList.get(0); 081 if (st.tokencode == TBaseType.rrw_drop){ 082 TSourceToken nextst = stList.nextsolidtoken(st,1,false); 083 err.hint = "Unknown object type in drop statement"; 084 if (nextst != null){ 085 err.tokentext = nextst.toString(); 086 err.lineNo = nextst.lineNo; 087 err.columnNo = nextst.columnNo; 088 } 089 090 return false; 091 } 092 if (stList.get(1).tokentype == ETokenType.ttperiod) return true; 093 if (st.toString().toLowerCase().startsWith("sp")) return true; 094 if (st.toString().toLowerCase().startsWith("select")) return false; 095 if (st.toString().toLowerCase().startsWith("del")) return false; 096 if (st.toString().toLowerCase().startsWith("update")) return false; 097 if (st.toString().toLowerCase().startsWith("insert")) return false; 098 if (st.toString().toLowerCase().startsWith("create")) return false; 099 100 return ret; 101 } 102 private TExecuteOption executeOption; 103 104 public TExecuteOption getExecuteOption() { 105 return executeOption; 106 } 107 108 public EExecType getExecuteType() { 109 return executeType; 110 } 111 112 private EExecType executeType = EExecType.unknown; 113 114 private TObjectName intoVariable; 115 private TExpressionList usingVariables; 116 117 public TObjectName getIntoVariable() { 118 return intoVariable; 119 } 120 121 public TExpressionList getUsingVariables() { 122 return usingVariables; 123 } 124 125 public int doParseStatement(TCustomSqlStatement psql) { 126 if (rootNode == null) return -1; 127 if (!(rootNode instanceof TExecuteSqlNode)){ 128 if (this.sourcetokenlist.size() > 0){ 129 TSourceToken st1 = this.sourcetokenlist.get(0); 130 TSyntaxError err = new TSyntaxError(st1.toString(),st1.lineNo,st1.columnNo,"syntax error",EErrorType.sperror 131 ,TBaseType.MSG_ERROR_SYNTAX_ERROR 132 ,this,st1.posinlist); 133 if (!isValidProcedureCall(this.sourcetokenlist,err)) 134 this.parseerrormessagehandle(err); 135 } 136 return -1; 137 } 138 TExecuteSqlNode node = (TExecuteSqlNode)rootNode; 139 this.execType = node.getExecType(); 140 this.executeType = node.getExecuteType(); 141 this.preparedValue = node.getPreparedValue(); 142 this.intoVariable = node.getIntoVariable(); 143 this.usingVariables = node.getUsingVariables(); 144 145 this.executeOption = node.getExecuteOption(); 146 super.doParseStatement(psql); 147 148 149 if ((node.getExecType() == TBaseType.metExecSp)){ 150 this.moduleName = node.getModuleName(); 151 this.parameters = node.getParameters(); 152 this.returnStatus = node.getReturnStatus(); 153 this.linkServerName = node.getLinkServerName(); 154 if ((this.moduleName != null)&&(this.moduleName.toString().equalsIgnoreCase("sp_executesql")) 155 && (this.parameters != null) && (this.parameters.size() > 0)){ 156 TExecParameter parameter = this.parameters.getExecParameter(0); 157 if (parameter.getParameterValue().getExpressionType() == EExpressionType.simple_object_name_t){ 158 TObjectName var = parameter.getParameterValue().getObjectOperand(); 159 if (var.getDbObjectType() == EDbObjectType.variable){ 160 TVariable symbolVariable = TSymbolTableManager.searchSymbolVariable(this.getFrameStack(),var.toString()); 161 if (symbolVariable != null){ 162 this.sqlText = symbolVariable.getVariableStr(); 163 //System.out.println(this.sqlText); 164 } 165 } 166 }else{ 167 parameter.getParameterValue().evaluate(this.getFrameStack(),this); 168 this.sqlText = parameter.getParameterValue().getPlainText(); 169 } 170 }else { 171 // exec a procedure with parameter, put the parameter as a variable into scope 172 TVariable variable = null; 173 int i=0; 174 175 //System.out.println(this.moduleName.toString()); 176 if (this.parameters != null){ 177 if (this.parameters.size() > 0){ 178 for(TExecParameter p:this.parameters){ 179 TObjectName variableName = TObjectName.createObjectName (this.dbvendor, EDbObjectType.variable, new TSourceToken("$"+i)); 180 variable = new TVariable(variableName,p,this.moduleName); 181 variable.setVariableStr(TBaseType.getStringInsideLiteral(p.getParameterValue().toString())); 182 if ((psql != null) && (psql.getStmtScope() != null)) { 183 psql.getStmtScope().addSymbol(variable); 184 }else{ 185 //TODO: execute 中的变量应该放在gloabl scope中吗? 186 this.getGlobalScope().addSymbol(variable); 187 } 188 189 i++; 190 //System.out.println(p.getParameterValue().toString()); 191 } 192 } 193 } 194 }; 195 }else if (node.getExecType() == TBaseType.metExecStringCmd){ 196 this.stringValues = node.getStringValues(); 197 if (this.stringValues.getExpression(0).getExpressionType() == EExpressionType.simple_object_name_t){ 198 TObjectName var = this.stringValues.getExpression(0).getObjectOperand(); 199 if (var.getDbObjectType() == EDbObjectType.variable){ 200 TVariable symbolVariable = TSymbolTableManager.searchSymbolVariable(this.getFrameStack(),var.toString()); 201 if (symbolVariable != null){ 202 //this.getSqlEnv().getVariableValue(symbolVariable.getQualifiedName(),symbolVariable.getVariableStr()); 203 this.sqlText = symbolVariable.getVariableStr(); 204 //System.out.println(this.sqlText); 205 } 206 } 207 } 208 this.linkServerName = node.getLinkServerName(); 209 this.executeAsUser = node.getExecuteAsUser(); 210 this.executeAsLogin = node.getExecuteAsLogin(); 211 }else if (node.getExecType() == TBaseType.metNoExecKeyword){ 212 //the first statement in a batch or an osql or sqlcmd script, EXEC is not required. 213 //dbo.uspGetEmployeeManagers @BusinessEntityID = 6; 214 if (this.sourcetokenlist.size() > 0){ 215 TSourceToken st1 = this.sourcetokenlist.get(0); 216 String errMsg = "syntax error"; 217 TSourceToken errToken = st1; 218 TSyntaxError err = new TSyntaxError(st1.toString(),st1.lineNo,st1.columnNo,"syntax error",EErrorType.sperror 219 ,TBaseType.MSG_ERROR_SYNTAX_ERROR,this,st1.posinlist); 220 if (!isValidProcedureCall(this.sourcetokenlist,err)) 221 this.parseerrormessagehandle( err); 222 223 // moduleName = (TObjectName)this.parser.getNf().createNode(ENodeType.T_ObjectName.getId()); //new TObjectName(); 224 moduleName = new TObjectName(); 225 moduleName.setGsqlparser(this.getGsqlparser()); 226 int j = 0; 227 for(int i=0;i<this.sourcetokenlist.size();i++){ 228 if ((this.sourcetokenlist.get(i).tokentype == ETokenType.ttwhitespace) 229 || (this.sourcetokenlist.get(i).tokentype == ETokenType.ttreturn) 230 ||(this.sourcetokenlist.get(i).tokentype == ETokenType.ttsemicolon) 231 ){ 232 break; 233 } 234 j++; 235 } 236 switch(j){ 237 case 1: 238 moduleName.init(this.sourcetokenlist.get(0)); 239 break; 240 case 3: 241 moduleName.init(this.sourcetokenlist.get(0),this.sourcetokenlist.get(2)); 242 break; 243 case 5: 244 moduleName.init(this.sourcetokenlist.get(0),this.sourcetokenlist.get(2),this.sourcetokenlist.get(4)); 245 break; 246 case 7: 247 moduleName.init(this.sourcetokenlist.get(0),this.sourcetokenlist.get(2),this.sourcetokenlist.get(4),this.sourcetokenlist.get(6)); 248 break; 249 default: 250 moduleName = null; 251 break; 252 } 253 254 if (moduleName != null){ 255 //moduleName.setObjectType(TObjectName.ttobjProcedureName); 256 moduleName.setDbObjectType(EDbObjectType.procedure); 257 } 258 259 } 260 261 } 262 return 0; 263 } 264 265 public TObjectName getLinkServerName() { 266 return linkServerName; 267 } 268 269 private TObjectName linkServerName; 270 271 private TObjectName executeAsUser; 272 private TObjectName executeAsLogin; 273 274 public TObjectName getExecuteAsUser() { 275 return executeAsUser; 276 } 277 278 public TObjectName getExecuteAsLogin() { 279 return executeAsLogin; 280 } 281 282 public void accept(TParseTreeVisitor v){ 283 v.preVisit(this); 284 v.postVisit(this); 285 } 286 public void acceptChildren(TParseTreeVisitor v){ 287 v.preVisit(this); 288 v.postVisit(this); 289 } 290 291 public void setModuleName(TObjectName moduleName) { 292 this.moduleName = moduleName; 293 } 294 295 public void setReturnStatus(TObjectName returnStatus) { 296 this.returnStatus = returnStatus; 297 } 298 299 public void setParameters(TExecParameterList parameters) { 300 this.parameters = parameters; 301 } 302 303 public void setStringValues(TExpressionList stringValues) { 304 this.stringValues = stringValues; 305 } 306 307 public void setExecType(int execType) { 308 this.execType = execType; 309 } 310}