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  }