github.com/matrixorigin/matrixone@v0.7.0/pkg/frontend/status_stmt.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package frontend 16 17 import ( 18 "context" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 "github.com/matrixorigin/matrixone/pkg/container/batch" 22 "github.com/matrixorigin/matrixone/pkg/logutil" 23 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 24 "github.com/matrixorigin/matrixone/pkg/vm/process" 25 ) 26 27 // statusStmtExecutor represents the execution without outputting result set to the client 28 type statusStmtExecutor struct { 29 *baseStmtExecutor 30 } 31 32 type BeginTxnExecutor struct { 33 *statusStmtExecutor 34 bt *tree.BeginTransaction 35 } 36 37 func (bte *BeginTxnExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 38 err := ses.TxnBegin() 39 if err != nil { 40 return err 41 } 42 RecordStatementTxnID(ctx, ses) 43 return err 44 } 45 46 type CommitTxnExecutor struct { 47 *statusStmtExecutor 48 ct *tree.CommitTransaction 49 } 50 51 func (cte *CommitTxnExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 52 return ses.TxnCommit() 53 } 54 55 type RollbackTxnExecutor struct { 56 *statusStmtExecutor 57 rt *tree.RollbackTransaction 58 } 59 60 func (rte *RollbackTxnExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 61 return ses.TxnRollback() 62 } 63 64 type SetRoleExecutor struct { 65 *statusStmtExecutor 66 sr *tree.SetRole 67 } 68 69 func (sre *SetRoleExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 70 return doSwitchRole(ctx, ses, sre.sr) 71 } 72 73 type UseExecutor struct { 74 *statusStmtExecutor 75 u *tree.Use 76 } 77 78 func (ue *UseExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 79 return doUse(ctx, ses, ue.u.Name) 80 } 81 82 type DropDatabaseExecutor struct { 83 *statusStmtExecutor 84 dd *tree.DropDatabase 85 } 86 87 func (dde *DropDatabaseExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 88 // if the droped database is the same as the one in use, database must be reseted to empty. 89 if string(dde.dd.Name) == ses.GetDatabaseName() { 90 ses.SetDatabaseName("") 91 } 92 return dde.statusStmtExecutor.ExecuteImpl(ctx, ses) 93 } 94 95 type ImportExecutor struct { 96 *statusStmtExecutor 97 i *tree.Import 98 result *LoadResult 99 } 100 101 func (ie *ImportExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 102 var err error 103 ie.result, err = doLoadData(ctx, ses, ie.GetProcess(), ie.i) 104 return err 105 } 106 107 func (ie *ImportExecutor) ResponseAfterExec(ctx context.Context, ses *Session) error { 108 var err error 109 result := ie.result 110 info := moerr.NewLoadInfo(ctx, result.Records, result.Deleted, result.Skipped, result.Warnings, result.WriteTimeout).Error() 111 resp := NewOkResponse(result.Records, 0, uint16(result.Warnings), 0, int(COM_QUERY), info) 112 if err = ses.GetMysqlProtocol().SendResponse(ctx, resp); err != nil { 113 return moerr.NewInternalError(ctx, "routine send response failed. error:%v ", err) 114 } 115 return nil 116 } 117 118 func (ie *ImportExecutor) CommitOrRollbackTxn(ctx context.Context, ses *Session) error { 119 stmt := ie.GetAst() 120 tenant := ie.tenantName 121 incStatementCounter(tenant, stmt) 122 if ie.GetStatus() == stmtExecSuccess { 123 logStatementStatus(ctx, ses, stmt, success, nil) 124 } else { 125 incStatementErrorsCounter(tenant, stmt) 126 /* 127 Cases | set Autocommit = 1/0 | BEGIN statement | 128 --------------------------------------------------- 129 Case1 1 Yes 130 Case2 1 No 131 Case3 0 Yes 132 Case4 0 No 133 --------------------------------------------------- 134 update error message in Case1,Case3,Case4. 135 */ 136 if ses.InMultiStmtTransactionMode() && ses.InActiveTransaction() { 137 ses.SetOptionBits(OPTION_ATTACH_ABORT_TRANSACTION_ERROR) 138 } 139 logutil.Error(ie.err.Error()) 140 logStatementStatus(ctx, ses, stmt, fail, ie.err) 141 } 142 return nil 143 } 144 145 type PrepareStmtExecutor struct { 146 *statusStmtExecutor 147 ps *tree.PrepareStmt 148 prepareStmt *PrepareStmt 149 } 150 151 func (pse *PrepareStmtExecutor) ResponseAfterExec(ctx context.Context, ses *Session) error { 152 var err2, retErr error 153 if ses.GetCmd() == COM_STMT_PREPARE { 154 if err2 = ses.GetMysqlProtocol().SendPrepareResponse(ctx, pse.prepareStmt); err2 != nil { 155 retErr = moerr.NewInternalError(ctx, "routine send response failed. error:%v ", err2) 156 logStatementStatus(ctx, ses, pse.GetAst(), fail, retErr) 157 return retErr 158 } 159 } else { 160 resp := NewOkResponse(pse.GetAffectedRows(), 0, 0, 0, int(COM_QUERY), "") 161 if err2 = ses.GetMysqlProtocol().SendResponse(ctx, resp); err2 != nil { 162 retErr = moerr.NewInternalError(ctx, "routine send response failed. error:%v ", err2) 163 logStatementStatus(ctx, ses, pse.GetAst(), fail, retErr) 164 return retErr 165 } 166 } 167 return nil 168 } 169 170 func (pse *PrepareStmtExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 171 var err error 172 pse.prepareStmt, err = doPrepareStmt(ctx, ses, pse.ps) 173 if err != nil { 174 return err 175 } 176 return authenticateUserCanExecutePrepareOrExecute(ctx, ses, pse.prepareStmt.PrepareStmt, pse.prepareStmt.PreparePlan.GetDcl().GetPrepare().GetPlan()) 177 } 178 179 type PrepareStringExecutor struct { 180 *statusStmtExecutor 181 ps *tree.PrepareString 182 prepareStmt *PrepareStmt 183 } 184 185 func (pse *PrepareStringExecutor) ResponseAfterExec(ctx context.Context, ses *Session) error { 186 var err2, retErr error 187 if ses.GetCmd() == COM_STMT_PREPARE { 188 if err2 = ses.GetMysqlProtocol().SendPrepareResponse(ctx, pse.prepareStmt); err2 != nil { 189 retErr = moerr.NewInternalError(ctx, "routine send response failed. error:%v ", err2) 190 logStatementStatus(ctx, ses, pse.GetAst(), fail, retErr) 191 return retErr 192 } 193 } else { 194 resp := NewOkResponse(pse.GetAffectedRows(), 0, 0, 0, int(COM_QUERY), "") 195 if err2 = ses.GetMysqlProtocol().SendResponse(ctx, resp); err2 != nil { 196 retErr = moerr.NewInternalError(ctx, "routine send response failed. error:%v ", err2) 197 logStatementStatus(ctx, ses, pse.GetAst(), fail, retErr) 198 return retErr 199 } 200 } 201 return nil 202 } 203 204 func (pse *PrepareStringExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 205 var err error 206 pse.prepareStmt, err = doPrepareString(ctx, ses, pse.ps) 207 if err != nil { 208 return err 209 } 210 return authenticateUserCanExecutePrepareOrExecute(ctx, ses, pse.prepareStmt.PrepareStmt, pse.prepareStmt.PreparePlan.GetDcl().GetPrepare().GetPlan()) 211 } 212 213 // TODO: DeallocateExecutor has no response like QUIT COMMAND ? 214 type DeallocateExecutor struct { 215 *statusStmtExecutor 216 d *tree.Deallocate 217 } 218 219 func (de *DeallocateExecutor) ResponseAfterExec(ctx context.Context, ses *Session) error { 220 var err2, retErr error 221 //we will not send response in COM_STMT_CLOSE command 222 if ses.GetCmd() != COM_STMT_CLOSE { 223 resp := NewOkResponse(de.GetAffectedRows(), 0, 0, 0, int(COM_QUERY), "") 224 if err2 = ses.GetMysqlProtocol().SendResponse(ctx, resp); err2 != nil { 225 retErr = moerr.NewInternalError(ctx, "routine send response failed. error:%v ", err2) 226 logStatementStatus(ctx, ses, de.GetAst(), fail, retErr) 227 return retErr 228 } 229 } 230 return nil 231 } 232 233 func (de *DeallocateExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 234 return doDeallocate(ctx, ses, de.d) 235 } 236 237 type ExecuteExecutor struct { 238 *baseStmtExecutor 239 actualStmtExec StmtExecutor 240 ses *Session 241 proc *process.Process 242 e *tree.Execute 243 } 244 245 func (ee *ExecuteExecutor) Compile(requestCtx context.Context, u interface{}, fill func(interface{}, *batch.Batch) error) (interface{}, error) { 246 var err error 247 var ret interface{} 248 ret, err = ee.baseStmtExecutor.Compile(requestCtx, u, fill) 249 if err != nil { 250 return nil, err 251 } 252 253 ee.actualStmtExec, err = getStmtExecutor(ee.ses, ee.proc, ee.baseStmtExecutor, ee.GetAst()) 254 if err != nil { 255 return nil, err 256 } 257 return ret, err 258 } 259 260 func (ee *ExecuteExecutor) ResponseBeforeExec(ctx context.Context, ses *Session) error { 261 return ee.actualStmtExec.ResponseBeforeExec(ctx, ses) 262 } 263 264 func (ee *ExecuteExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 265 return ee.actualStmtExec.ExecuteImpl(ctx, ses) 266 } 267 268 func (ee *ExecuteExecutor) ResponseAfterExec(ctx context.Context, ses *Session) error { 269 return ee.actualStmtExec.ResponseAfterExec(ctx, ses) 270 } 271 272 func (ee *ExecuteExecutor) CommitOrRollbackTxn(ctx context.Context, ses *Session) error { 273 return ee.actualStmtExec.CommitOrRollbackTxn(ctx, ses) 274 } 275 276 func (ee *ExecuteExecutor) Close(ctx context.Context, ses *Session) error { 277 return ee.actualStmtExec.Close(ctx, ses) 278 } 279 280 type SetVarExecutor struct { 281 *statusStmtExecutor 282 sv *tree.SetVar 283 } 284 285 func (sve *SetVarExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 286 return doSetVar(ctx, ses, sve.sv) 287 } 288 289 type DeleteExecutor struct { 290 *statusStmtExecutor 291 d *tree.Delete 292 } 293 294 func (de *DeleteExecutor) Setup(ctx context.Context, ses *Session) error { 295 err := de.baseStmtExecutor.Setup(ctx, ses) 296 if err != nil { 297 return err 298 } 299 ses.GetTxnCompileCtx().SetQueryType(TXN_DELETE) 300 return nil 301 } 302 303 type UpdateExecutor struct { 304 *statusStmtExecutor 305 u *tree.Update 306 } 307 308 func (de *UpdateExecutor) Setup(ctx context.Context, ses *Session) error { 309 err := de.baseStmtExecutor.Setup(ctx, ses) 310 if err != nil { 311 return err 312 } 313 ses.GetTxnCompileCtx().SetQueryType(TXN_UPDATE) 314 return nil 315 } 316 317 type CreateAccountExecutor struct { 318 *statusStmtExecutor 319 ca *tree.CreateAccount 320 } 321 322 func (cae *CreateAccountExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 323 return InitGeneralTenant(ctx, ses, cae.ca) 324 } 325 326 type DropAccountExecutor struct { 327 *statusStmtExecutor 328 da *tree.DropAccount 329 } 330 331 func (dae *DropAccountExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 332 return doDropAccount(ctx, ses, dae.da) 333 } 334 335 type AlterAccountExecutor struct { 336 *statusStmtExecutor 337 aa *tree.AlterAccount 338 } 339 340 type CreateUserExecutor struct { 341 *statusStmtExecutor 342 cu *tree.CreateUser 343 } 344 345 func (cue *CreateUserExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 346 tenant := ses.GetTenantInfo() 347 return InitUser(ctx, ses, tenant, cue.cu) 348 } 349 350 type DropUserExecutor struct { 351 *statusStmtExecutor 352 du *tree.DropUser 353 } 354 355 func (due *DropUserExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 356 return doDropUser(ctx, ses, due.du) 357 } 358 359 type AlterUserExecutor struct { 360 *statusStmtExecutor 361 au *tree.AlterUser 362 } 363 364 type CreateRoleExecutor struct { 365 *statusStmtExecutor 366 cr *tree.CreateRole 367 } 368 369 func (cre *CreateRoleExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 370 tenant := ses.GetTenantInfo() 371 372 //step1 : create the role 373 return InitRole(ctx, ses, tenant, cre.cr) 374 } 375 376 type DropRoleExecutor struct { 377 *statusStmtExecutor 378 dr *tree.DropRole 379 } 380 381 func (dre *DropRoleExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 382 return doDropRole(ctx, ses, dre.dr) 383 } 384 385 type GrantExecutor struct { 386 *statusStmtExecutor 387 g *tree.Grant 388 } 389 390 func (ge *GrantExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 391 switch ge.g.Typ { 392 case tree.GrantTypeRole: 393 return doGrantRole(ctx, ses, &ge.g.GrantRole) 394 case tree.GrantTypePrivilege: 395 return doGrantPrivilege(ctx, ses, &ge.g.GrantPrivilege) 396 } 397 return moerr.NewInternalError(ctx, "no such grant type %v", ge.g.Typ) 398 } 399 400 type RevokeExecutor struct { 401 *statusStmtExecutor 402 r *tree.Revoke 403 } 404 405 func (re *RevokeExecutor) ExecuteImpl(ctx context.Context, ses *Session) error { 406 switch re.r.Typ { 407 case tree.RevokeTypeRole: 408 return doRevokeRole(ctx, ses, &re.r.RevokeRole) 409 case tree.RevokeTypePrivilege: 410 return doRevokePrivilege(ctx, ses, &re.r.RevokePrivilege) 411 } 412 return moerr.NewInternalError(ctx, "no such revoke type %v", re.r.Typ) 413 } 414 415 type CreateTableExecutor struct { 416 *statusStmtExecutor 417 ct *tree.CreateTable 418 } 419 420 type DropTableExecutor struct { 421 *statusStmtExecutor 422 dt *tree.DropTable 423 } 424 425 type CreateDatabaseExecutor struct { 426 *statusStmtExecutor 427 cd *tree.CreateDatabase 428 } 429 430 type CreateIndexExecutor struct { 431 *statusStmtExecutor 432 ci *tree.CreateIndex 433 } 434 435 type DropIndexExecutor struct { 436 *statusStmtExecutor 437 di *tree.DropIndex 438 } 439 440 type CreateViewExecutor struct { 441 *statusStmtExecutor 442 cv *tree.CreateView 443 } 444 445 type AlterViewExecutor struct { 446 *statusStmtExecutor 447 av *tree.AlterView 448 } 449 450 type DropViewExecutor struct { 451 *statusStmtExecutor 452 dv *tree.DropView 453 } 454 455 type InsertExecutor struct { 456 *statusStmtExecutor 457 i *tree.Insert 458 } 459 460 func (ie *InsertExecutor) ResponseAfterExec(ctx context.Context, ses *Session) error { 461 var err, retErr error 462 if ie.GetStatus() == stmtExecSuccess { 463 resp := NewOkResponse(ie.GetAffectedRows(), 0, 0, 0, int(COM_QUERY), "") 464 resp.lastInsertId = 1 465 if err = ses.GetMysqlProtocol().SendResponse(ctx, resp); err != nil { 466 retErr = moerr.NewInternalError(ctx, "routine send response failed. error:%v ", err) 467 logStatementStatus(ctx, ses, ie.GetAst(), fail, retErr) 468 return retErr 469 } 470 } 471 return nil 472 } 473 474 type LoadExecutor struct { 475 *statusStmtExecutor 476 l *tree.Load 477 } 478 479 func (le *LoadExecutor) CommitOrRollbackTxn(ctx context.Context, ses *Session) error { 480 stmt := le.GetAst() 481 tenant := le.tenantName 482 incStatementCounter(tenant, stmt) 483 if le.GetStatus() == stmtExecSuccess { 484 logStatementStatus(ctx, ses, stmt, success, nil) 485 } else { 486 incStatementErrorsCounter(tenant, stmt) 487 /* 488 Cases | set Autocommit = 1/0 | BEGIN statement | 489 --------------------------------------------------- 490 Case1 1 Yes 491 Case2 1 No 492 Case3 0 Yes 493 Case4 0 No 494 --------------------------------------------------- 495 update error message in Case1,Case3,Case4. 496 */ 497 if ses.InMultiStmtTransactionMode() && ses.InActiveTransaction() { 498 ses.SetOptionBits(OPTION_ATTACH_ABORT_TRANSACTION_ERROR) 499 } 500 logutil.Error(le.err.Error()) 501 logStatementStatus(ctx, ses, stmt, fail, le.err) 502 } 503 return nil 504 } 505 506 type SetDefaultRoleExecutor struct { 507 *statusStmtExecutor 508 sdr *tree.SetDefaultRole 509 } 510 511 type SetPasswordExecutor struct { 512 *statusStmtExecutor 513 sp *tree.SetPassword 514 } 515 516 type TruncateTableExecutor struct { 517 *statusStmtExecutor 518 tt *tree.TruncateTable 519 }