github.com/matrixorigin/matrixone@v1.2.0/pkg/frontend/authenticate_test.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  	"bytes"
    19  	"context"
    20  	"fmt"
    21  	"go/constant"
    22  	"reflect"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/BurntSushi/toml"
    28  	"github.com/fagongzi/goetty/v2"
    29  	"github.com/stretchr/testify/assert"
    30  
    31  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    32  	"github.com/matrixorigin/matrixone/pkg/fileservice"
    33  
    34  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    35  
    36  	"github.com/fagongzi/goetty/v2/buf"
    37  	"github.com/golang/mock/gomock"
    38  	"github.com/prashantv/gostub"
    39  	"github.com/smartystreets/goconvey/convey"
    40  	"github.com/stretchr/testify/require"
    41  
    42  	"github.com/matrixorigin/matrixone/pkg/container/types"
    43  	"github.com/matrixorigin/matrixone/pkg/queryservice"
    44  	"github.com/matrixorigin/matrixone/pkg/testutil"
    45  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    46  
    47  	"github.com/matrixorigin/matrixone/pkg/config"
    48  	"github.com/matrixorigin/matrixone/pkg/defines"
    49  	mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test"
    50  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    51  	"github.com/matrixorigin/matrixone/pkg/pb/timestamp"
    52  	"github.com/matrixorigin/matrixone/pkg/pb/txn"
    53  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    54  	plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan"
    55  )
    56  
    57  func TestGetTenantInfo(t *testing.T) {
    58  	convey.Convey("tenant", t, func() {
    59  		type input struct {
    60  			input   string
    61  			output  string
    62  			wantErr bool
    63  		}
    64  		args := []input{
    65  			{"u1", "{account sys:u1: -- 0:0:0}", false},
    66  			{"tenant1:u1", "{account tenant1:u1: -- 0:0:0}", false},
    67  			{"tenant1:u1:r1", "{account tenant1:u1:r1 -- 0:0:0}", false},
    68  			{":u1:r1", "{account tenant1:u1:r1 -- 0:0:0}", true},
    69  			{"tenant1:u1:", "{account tenant1:u1:moadmin -- 0:0:0}", true},
    70  			{"tenant1::r1", "{account tenant1::r1 -- 0:0:0}", true},
    71  			{"tenant1:    :r1", "{account tenant1:    :r1 -- 0:0:0}", false},
    72  			{"     : :r1", "{account      : :r1 -- 0:0:0}", false},
    73  			{"   tenant1   :   u1   :   r1    ", "{account    tenant1   :   u1   :   r1     -- 0:0:0}", false},
    74  			{"u1", "{account sys:u1: -- 0:0:0}", false},
    75  			{"tenant1#u1", "{account tenant1#u1# -- 0#0#0}", false},
    76  			{"tenant1#u1#r1", "{account tenant1#u1#r1 -- 0#0#0}", false},
    77  			{"#u1#r1", "{account tenant1#u1#r1 -- 0#0#0}", true},
    78  			{"tenant1#u1#", "{account tenant1#u1#moadmin -- 0#0#0}", true},
    79  			{"tenant1##r1", "{account tenant1##r1 -- 0#0#0}", true},
    80  			{"tenant1#    #r1", "{account tenant1#    #r1 -- 0#0#0}", false},
    81  			{"     # #r1", "{account      # #r1 -- 0#0#0}", false},
    82  			{"   tenant1   #   u1   #   r1    ", "{account    tenant1   #   u1   #   r1     -- 0#0#0}", false},
    83  		}
    84  
    85  		for _, arg := range args {
    86  			ti, err := GetTenantInfo(context.TODO(), arg.input)
    87  			if arg.wantErr {
    88  				convey.So(err, convey.ShouldNotBeNil)
    89  			} else {
    90  				convey.So(err, convey.ShouldBeNil)
    91  				tis := ti.String()
    92  				convey.So(tis, convey.ShouldEqual, arg.output)
    93  			}
    94  		}
    95  	})
    96  
    97  	convey.Convey("tenant op", t, func() {
    98  		ti := &TenantInfo{}
    99  		convey.So(ti.GetTenant(), convey.ShouldBeEmpty)
   100  		convey.So(ti.GetTenantID(), convey.ShouldBeZeroValue)
   101  		convey.So(ti.GetUser(), convey.ShouldBeEmpty)
   102  		convey.So(ti.GetUserID(), convey.ShouldBeZeroValue)
   103  		convey.So(ti.GetDefaultRole(), convey.ShouldBeEmpty)
   104  		convey.So(ti.GetDefaultRoleID(), convey.ShouldBeZeroValue)
   105  
   106  		ti.SetTenantID(10)
   107  		convey.So(ti.GetTenantID(), convey.ShouldEqual, 10)
   108  		ti.SetUserID(10)
   109  		convey.So(ti.GetUserID(), convey.ShouldEqual, 10)
   110  		ti.SetDefaultRoleID(10)
   111  		convey.So(ti.GetDefaultRoleID(), convey.ShouldEqual, 10)
   112  
   113  		convey.So(ti.IsSysTenant(), convey.ShouldBeFalse)
   114  		convey.So(ti.IsDefaultRole(), convey.ShouldBeFalse)
   115  		convey.So(ti.IsMoAdminRole(), convey.ShouldBeFalse)
   116  
   117  		convey.So(GetDefaultTenant(), convey.ShouldEqual, sysAccountName)
   118  		convey.So(GetDefaultRole(), convey.ShouldEqual, moAdminRoleName)
   119  	})
   120  }
   121  
   122  func TestPrivilegeType_Scope(t *testing.T) {
   123  	convey.Convey("scope", t, func() {
   124  		pss := []struct {
   125  			ps PrivilegeScope
   126  			s  string
   127  		}{
   128  			{PrivilegeScopeSys, "sys"},
   129  			{PrivilegeScopeAccount, "account"},
   130  			{PrivilegeScopeUser, "user"},
   131  			{PrivilegeScopeRole, "role"},
   132  			{PrivilegeScopeDatabase, "database"},
   133  			{PrivilegeScopeTable, "table"},
   134  			{PrivilegeScopeRoutine, "routine"},
   135  			{PrivilegeScopeSys | PrivilegeScopeRole | PrivilegeScopeRoutine, "sys,role,routine"},
   136  			{PrivilegeScopeSys | PrivilegeScopeDatabase | PrivilegeScopeTable, "sys,database,table"},
   137  		}
   138  		for _, scope := range pss {
   139  			convey.So(scope.ps.String(), convey.ShouldEqual, scope.s)
   140  		}
   141  	})
   142  }
   143  
   144  func TestPrivilegeType(t *testing.T) {
   145  	convey.Convey("privilege type", t, func() {
   146  		type arg struct {
   147  			pt PrivilegeType
   148  			s  string
   149  			sc PrivilegeScope
   150  		}
   151  		args := []arg{}
   152  		for i := PrivilegeTypeCreateAccount; i <= PrivilegeTypeExecute; i++ {
   153  			args = append(args, arg{pt: i, s: i.String(), sc: i.Scope()})
   154  		}
   155  		for _, a := range args {
   156  			convey.So(a.pt.String(), convey.ShouldEqual, a.s)
   157  			convey.So(a.pt.Scope(), convey.ShouldEqual, a.sc)
   158  		}
   159  	})
   160  }
   161  
   162  func TestFormSql(t *testing.T) {
   163  	convey.Convey("form sql", t, func() {
   164  		sql, _ := getSqlForCheckTenant(context.TODO(), "a")
   165  		convey.So(sql, convey.ShouldEqual, fmt.Sprintf(checkTenantFormat, "a"))
   166  		sql, _ = getSqlForPasswordOfUser(context.TODO(), "u")
   167  		convey.So(sql, convey.ShouldEqual, fmt.Sprintf(getPasswordOfUserFormat, "u"))
   168  		sql, _ = getSqlForCheckRoleExists(context.TODO(), 0, "r")
   169  		convey.So(sql, convey.ShouldEqual, fmt.Sprintf(checkRoleExistsFormat, 0, "r"))
   170  		sql, _ = getSqlForRoleIdOfRole(context.TODO(), "r")
   171  		convey.So(sql, convey.ShouldEqual, fmt.Sprintf(roleIdOfRoleFormat, "r"))
   172  		sql, _ = getSqlForRoleOfUser(context.TODO(), 0, "r")
   173  		convey.So(sql, convey.ShouldEqual, fmt.Sprintf(getRoleOfUserFormat, 0, "r"))
   174  	})
   175  }
   176  
   177  func Test_checkSysExistsOrNot(t *testing.T) {
   178  	convey.Convey("check sys tenant exists or not", t, func() {
   179  		ctrl := gomock.NewController(t)
   180  		defer ctrl.Finish()
   181  
   182  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
   183  		pu.SV.SetDefaultValues()
   184  
   185  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   186  
   187  		bh := mock_frontend.NewMockBackgroundExec(ctrl)
   188  		bh.EXPECT().Close().Return().AnyTimes()
   189  		bh.EXPECT().Exec(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   190  		bh.EXPECT().ClearExecResultSet().Return().AnyTimes()
   191  
   192  		mrs1 := mock_frontend.NewMockExecResult(ctrl)
   193  		dbs := make([]string, 0)
   194  		for k := range sysWantedDatabases {
   195  			dbs = append(dbs, k)
   196  		}
   197  		mrs1.EXPECT().GetRowCount().Return(uint64(len(sysWantedDatabases))).AnyTimes()
   198  		mrs1.EXPECT().GetString(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx2 context.Context, r uint64, c uint64) (string, error) {
   199  			return dbs[r], nil
   200  		}).AnyTimes()
   201  
   202  		mrs2 := mock_frontend.NewMockExecResult(ctrl)
   203  		tables := make([]string, 0)
   204  		for k := range sysWantedTables {
   205  			tables = append(tables, k)
   206  		}
   207  
   208  		mrs2.EXPECT().GetRowCount().Return(uint64(len(sysWantedTables))).AnyTimes()
   209  		mrs2.EXPECT().GetString(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx2 context.Context, r uint64, c uint64) (string, error) {
   210  			return tables[r], nil
   211  		}).AnyTimes()
   212  
   213  		rs := []ExecResult{
   214  			mrs1,
   215  			mrs2,
   216  		}
   217  
   218  		cnt := 0
   219  		bh.EXPECT().GetExecResultSet().DoAndReturn(func() []interface{} {
   220  			old := cnt
   221  			cnt++
   222  			if cnt >= len(rs) {
   223  				cnt = 0
   224  			}
   225  			return []interface{}{rs[old]}
   226  		}).AnyTimes()
   227  
   228  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   229  		defer bhStub.Reset()
   230  
   231  		exists, err := checkSysExistsOrNot(ctx, bh)
   232  		convey.So(exists, convey.ShouldBeTrue)
   233  		convey.So(err, convey.ShouldBeNil)
   234  
   235  		// A mock autoIncrCaches.
   236  		aicm := &defines.AutoIncrCacheManager{}
   237  		finalVersion := "1.2.0"
   238  		err = InitSysTenantOld(ctx, aicm, finalVersion)
   239  		convey.So(err, convey.ShouldBeNil)
   240  	})
   241  }
   242  
   243  func Test_checkTenantExistsOrNot(t *testing.T) {
   244  	convey.Convey("check tenant exists or not", t, func() {
   245  		ctrl := gomock.NewController(t)
   246  		defer ctrl.Finish()
   247  
   248  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
   249  		pu.SV.SetDefaultValues()
   250  		setGlobalPu(pu)
   251  
   252  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   253  
   254  		bh := mock_frontend.NewMockBackgroundExec(ctrl)
   255  		bh.EXPECT().Close().Return().AnyTimes()
   256  		bh.EXPECT().Exec(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   257  
   258  		mrs1 := mock_frontend.NewMockExecResult(ctrl)
   259  		mrs1.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes()
   260  
   261  		bh.EXPECT().GetExecResultSet().Return([]interface{}{mrs1}).AnyTimes()
   262  		bh.EXPECT().ClearExecResultSet().Return().AnyTimes()
   263  
   264  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   265  		defer bhStub.Reset()
   266  
   267  		exists, err := checkTenantExistsOrNot(ctx, bh, "test")
   268  		convey.So(exists, convey.ShouldBeTrue)
   269  		convey.So(err, convey.ShouldBeNil)
   270  
   271  		tenant := &TenantInfo{
   272  			Tenant:        sysAccountName,
   273  			User:          rootName,
   274  			DefaultRole:   moAdminRoleName,
   275  			TenantID:      sysAccountID,
   276  			UserID:        rootID,
   277  			DefaultRoleID: moAdminRoleID,
   278  		}
   279  
   280  		ses := newSes(nil, ctrl)
   281  		ses.tenant = tenant
   282  
   283  		err = InitGeneralTenant(ctx, ses, &createAccount{
   284  			Name:        "test",
   285  			IfNotExists: true,
   286  			AdminName:   "root",
   287  			IdentTyp:    tree.AccountIdentifiedByPassword,
   288  			IdentStr:    "123456",
   289  		})
   290  		convey.So(err, convey.ShouldBeNil)
   291  	})
   292  }
   293  
   294  func Test_checkDatabaseExistsOrNot(t *testing.T) {
   295  	convey.Convey("check databse exists or not", t, func() {
   296  		ctrl := gomock.NewController(t)
   297  		defer ctrl.Finish()
   298  
   299  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
   300  		pu.SV.SetDefaultValues()
   301  
   302  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   303  
   304  		bh := mock_frontend.NewMockBackgroundExec(ctrl)
   305  		bh.EXPECT().Close().Return().AnyTimes()
   306  		bh.EXPECT().Exec(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   307  
   308  		mrs1 := mock_frontend.NewMockExecResult(ctrl)
   309  		mrs1.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes()
   310  
   311  		bh.EXPECT().GetExecResultSet().Return([]interface{}{mrs1}).AnyTimes()
   312  		bh.EXPECT().ClearExecResultSet().Return().AnyTimes()
   313  
   314  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   315  		defer bhStub.Reset()
   316  
   317  		exists, err := checkDatabaseExistsOrNot(ctx, bh, "test")
   318  		convey.So(exists, convey.ShouldBeTrue)
   319  		convey.So(err, convey.ShouldBeNil)
   320  	})
   321  }
   322  
   323  func Test_createTablesInMoCatalogOfGeneralTenant(t *testing.T) {
   324  	convey.Convey("createTablesInMoCatalog", t, func() {
   325  		ctrl := gomock.NewController(t)
   326  		defer ctrl.Finish()
   327  
   328  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
   329  		pu.SV.SetDefaultValues()
   330  
   331  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   332  
   333  		bh := mock_frontend.NewMockBackgroundExec(ctrl)
   334  		bh.EXPECT().Close().Return().AnyTimes()
   335  		bh.EXPECT().Exec(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   336  		bh.EXPECT().ClearExecResultSet().Return().AnyTimes()
   337  		msr := newMrsForCheckTenant([][]interface{}{
   338  			{1, "test"},
   339  		})
   340  		bh.EXPECT().GetExecResultSet().Return([]interface{}{msr}).AnyTimes()
   341  
   342  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   343  		defer bhStub.Reset()
   344  
   345  		//tenant := &TenantInfo{
   346  		//	Tenant:        sysAccountName,
   347  		//	User:          rootName,
   348  		//	DefaultRole:   moAdminRoleName,
   349  		//	TenantID:      sysAccountID,
   350  		//	UserID:        rootID,
   351  		//	DefaultRoleID: moAdminRoleID,
   352  		//}
   353  
   354  		ca := &createAccount{
   355  			Name:        "test",
   356  			IfNotExists: true,
   357  			AdminName:   "test_root",
   358  			IdentTyp:    tree.AccountIdentifiedByPassword,
   359  			IdentStr:    "123",
   360  			Comment:     tree.AccountComment{Exist: true, Comment: "test acccount"},
   361  		}
   362  		finalVersion := "1.2.0"
   363  		_, _, err := createTablesInMoCatalogOfGeneralTenant(ctx, bh, finalVersion, ca)
   364  		convey.So(err, convey.ShouldBeNil)
   365  
   366  		err = createTablesInInformationSchemaOfGeneralTenant(ctx, bh)
   367  		convey.So(err, convey.ShouldBeNil)
   368  	})
   369  }
   370  
   371  func Test_initFunction(t *testing.T) {
   372  	convey.Convey("init function", t, func() {
   373  		ctrl := gomock.NewController(t)
   374  		defer ctrl.Finish()
   375  
   376  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
   377  		pu.SV.SetDefaultValues()
   378  		setGlobalPu(pu)
   379  
   380  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   381  
   382  		bh := mock_frontend.NewMockBackgroundExec(ctrl)
   383  		bh.EXPECT().ClearExecResultSet().AnyTimes()
   384  		bh.EXPECT().Close().Return().AnyTimes()
   385  		bh.EXPECT().Exec(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   386  		rs := mock_frontend.NewMockExecResult(ctrl)
   387  		rs.EXPECT().GetRowCount().Return(uint64(0)).AnyTimes()
   388  		bh.EXPECT().GetExecResultSet().Return([]interface{}{rs}).AnyTimes()
   389  
   390  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   391  		defer bhStub.Reset()
   392  
   393  		locale := ""
   394  
   395  		cu := &tree.CreateFunction{
   396  			Name: tree.NewFuncName("testFunc",
   397  				tree.ObjectNamePrefix{
   398  					SchemaName:      tree.Identifier("db"),
   399  					CatalogName:     tree.Identifier(""),
   400  					ExplicitSchema:  true,
   401  					ExplicitCatalog: false,
   402  				},
   403  			),
   404  			Args: nil,
   405  			ReturnType: tree.NewReturnType(&tree.T{
   406  				InternalType: tree.InternalType{
   407  					Family:       tree.IntFamily,
   408  					FamilyString: "INT",
   409  					Width:        24,
   410  					Locale:       &locale,
   411  					Oid:          uint32(defines.MYSQL_TYPE_INT24),
   412  				},
   413  			}),
   414  			Body:     "",
   415  			Language: "sql",
   416  		}
   417  
   418  		tenant := &TenantInfo{
   419  			Tenant:        sysAccountName,
   420  			User:          rootName,
   421  			DefaultRole:   moAdminRoleName,
   422  			TenantID:      sysAccountID,
   423  			UserID:        rootID,
   424  			DefaultRoleID: moAdminRoleID,
   425  		}
   426  
   427  		ses := &Session{
   428  			feSessionImpl: feSessionImpl{
   429  				tenant: tenant,
   430  			},
   431  		}
   432  		err := InitFunction(ses, newTestExecCtx(ctx, ctrl), tenant, cu)
   433  		convey.So(err, convey.ShouldNotBeNil)
   434  	})
   435  }
   436  
   437  func Test_initUser(t *testing.T) {
   438  	convey.Convey("init user", t, func() {
   439  		ctrl := gomock.NewController(t)
   440  		defer ctrl.Finish()
   441  
   442  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
   443  		pu.SV.SetDefaultValues()
   444  
   445  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   446  		sql2result := make(map[string]ExecResult)
   447  
   448  		cu := &createUser{
   449  			IfNotExists: true,
   450  			Users: []*user{
   451  				{
   452  					Username:  "u1",
   453  					AuthExist: true,
   454  					IdentTyp:  tree.AccountIdentifiedByPassword,
   455  					IdentStr:  "123",
   456  				},
   457  				{
   458  					Username:  "u2",
   459  					AuthExist: true,
   460  					IdentTyp:  tree.AccountIdentifiedByPassword,
   461  					IdentStr:  "123",
   462  				},
   463  			},
   464  			Role:    &tree.Role{UserName: "test_role"},
   465  			MiscOpt: &tree.UserMiscOptionAccountUnlock{},
   466  		}
   467  
   468  		mrs := newMrsForRoleIdOfRole([][]interface{}{
   469  			{10},
   470  		})
   471  
   472  		sql, _ := getSqlForRoleIdOfRole(context.TODO(), cu.Role.UserName)
   473  		sql2result[sql] = mrs
   474  
   475  		for _, user := range cu.Users {
   476  			sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
   477  			mrs = newMrsForPasswordOfUser([][]interface{}{})
   478  			sql2result[sql] = mrs
   479  
   480  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
   481  			mrs = newMrsForRoleIdOfRole([][]interface{}{})
   482  			sql2result[sql] = mrs
   483  		}
   484  
   485  		bh := newBh(ctrl, sql2result)
   486  
   487  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   488  		defer bhStub.Reset()
   489  
   490  		tenant := &TenantInfo{
   491  			Tenant:        sysAccountName,
   492  			User:          rootName,
   493  			DefaultRole:   moAdminRoleName,
   494  			TenantID:      sysAccountID,
   495  			UserID:        rootID,
   496  			DefaultRoleID: moAdminRoleID,
   497  		}
   498  
   499  		ses := &Session{}
   500  		err := InitUser(ctx, ses, tenant, cu)
   501  		convey.So(err, convey.ShouldBeError)
   502  	})
   503  }
   504  
   505  func Test_initRole(t *testing.T) {
   506  	convey.Convey("init role", t, func() {
   507  		ctrl := gomock.NewController(t)
   508  		defer ctrl.Finish()
   509  
   510  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
   511  		pu.SV.SetDefaultValues()
   512  
   513  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   514  
   515  		bh := mock_frontend.NewMockBackgroundExec(ctrl)
   516  		bh.EXPECT().ClearExecResultSet().AnyTimes()
   517  		bh.EXPECT().Close().Return().AnyTimes()
   518  		bh.EXPECT().Exec(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   519  		rs := mock_frontend.NewMockExecResult(ctrl)
   520  		rs.EXPECT().GetRowCount().Return(uint64(0)).AnyTimes()
   521  		bh.EXPECT().GetExecResultSet().Return([]interface{}{rs}).AnyTimes()
   522  
   523  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   524  		defer bhStub.Reset()
   525  
   526  		tenant := &TenantInfo{
   527  			Tenant:        sysAccountName,
   528  			User:          rootName,
   529  			DefaultRole:   moAdminRoleName,
   530  			TenantID:      sysAccountID,
   531  			UserID:        rootID,
   532  			DefaultRoleID: moAdminRoleID,
   533  		}
   534  
   535  		cr := &tree.CreateRole{
   536  			IfNotExists: true,
   537  			Roles: []*tree.Role{
   538  				{UserName: "r1"},
   539  				{UserName: "r2"},
   540  			},
   541  		}
   542  		ses := &Session{}
   543  
   544  		err := InitRole(ctx, ses, tenant, cr)
   545  		convey.So(err, convey.ShouldBeNil)
   546  	})
   547  }
   548  
   549  func Test_determinePrivilege(t *testing.T) {
   550  	type arg struct {
   551  		stmt tree.Statement
   552  		priv *privilege
   553  	}
   554  
   555  	args := []arg{
   556  		{stmt: &tree.CreateAccount{}},
   557  		{stmt: &tree.DropAccount{}},
   558  		{stmt: &tree.AlterAccount{}},
   559  		{stmt: &tree.CreateUser{}},
   560  		{stmt: &tree.DropUser{}},
   561  		{stmt: &tree.AlterUser{}},
   562  		{stmt: &tree.CreateRole{}},
   563  		{stmt: &tree.DropRole{}},
   564  		{stmt: &tree.GrantRole{}},
   565  		{stmt: &tree.RevokeRole{}},
   566  		{stmt: &tree.GrantPrivilege{}},
   567  		{stmt: &tree.RevokePrivilege{}},
   568  		{stmt: &tree.CreateDatabase{}},
   569  		{stmt: &tree.DropDatabase{}},
   570  		{stmt: &tree.ShowDatabases{}},
   571  		{stmt: &tree.ShowCreateDatabase{}},
   572  		{stmt: &tree.Use{}},
   573  		{stmt: &tree.ShowTables{}},
   574  		{stmt: &tree.ShowCreateTable{}},
   575  		{stmt: &tree.ShowColumns{}},
   576  		{stmt: &tree.ShowCreateView{}},
   577  		{stmt: &tree.CreateTable{}},
   578  		{stmt: &tree.CreateView{}},
   579  		{stmt: &tree.DropTable{}},
   580  		{stmt: &tree.DropView{}},
   581  		{stmt: &tree.Select{}},
   582  		{stmt: &tree.Insert{}},
   583  		{stmt: &tree.Load{}},
   584  		{stmt: &tree.Update{}},
   585  		{stmt: &tree.Delete{}},
   586  		{stmt: &tree.CreateIndex{}},
   587  		{stmt: &tree.DropIndex{}},
   588  		{stmt: &tree.ShowIndex{}},
   589  		{stmt: &tree.ShowProcessList{}},
   590  		{stmt: &tree.ShowErrors{}},
   591  		{stmt: &tree.ShowWarnings{}},
   592  		{stmt: &tree.ShowVariables{}},
   593  		{stmt: &tree.ShowStatus{}},
   594  		{stmt: &tree.ExplainFor{}},
   595  		{stmt: &tree.ExplainAnalyze{}},
   596  		{stmt: &tree.ExplainStmt{}},
   597  		{stmt: &tree.BeginTransaction{}},
   598  		{stmt: &tree.CommitTransaction{}},
   599  		{stmt: &tree.RollbackTransaction{}},
   600  		{stmt: &tree.SetVar{}},
   601  		{stmt: &tree.SetDefaultRole{}},
   602  		{stmt: &tree.SetRole{}},
   603  		{stmt: &tree.SetPassword{}},
   604  		{stmt: &tree.PrepareStmt{}},
   605  		{stmt: &tree.PrepareString{}},
   606  		{stmt: &tree.Deallocate{}},
   607  		{stmt: &tree.ShowBackendServers{}},
   608  	}
   609  
   610  	for i := 0; i < len(args); i++ {
   611  		args[i].priv = determinePrivilegeSetOfStatement(args[i].stmt)
   612  	}
   613  
   614  	convey.Convey("privilege of statement", t, func() {
   615  		for i := 0; i < len(args); i++ {
   616  			priv := determinePrivilegeSetOfStatement(args[i].stmt)
   617  			convey.So(priv, convey.ShouldResemble, args[i].priv)
   618  		}
   619  	})
   620  }
   621  
   622  func Test_determineCreateAccount(t *testing.T) {
   623  	convey.Convey("create/drop/alter account succ", t, func() {
   624  		ctrl := gomock.NewController(t)
   625  		defer ctrl.Finish()
   626  
   627  		stmt := &tree.CreateAccount{}
   628  		priv := determinePrivilegeSetOfStatement(stmt)
   629  		ses := newSes(priv, ctrl)
   630  
   631  		rowsOfMoUserGrant := [][]interface{}{
   632  			{0, false},
   633  		}
   634  		roleIdsInMoRolePrivs := []int{0}
   635  		rowsOfMoRolePrivs := [][]interface{}{
   636  			{0, true},
   637  		}
   638  
   639  		sql2result := makeSql2ExecResult(0, rowsOfMoUserGrant,
   640  			roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs,
   641  			nil, nil)
   642  
   643  		bh := newBh(ctrl, sql2result)
   644  
   645  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   646  		defer bhStub.Reset()
   647  
   648  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
   649  		convey.So(err, convey.ShouldBeNil)
   650  		convey.So(ok, convey.ShouldBeTrue)
   651  	})
   652  
   653  	convey.Convey("create/drop/alter account fail", t, func() {
   654  		ctrl := gomock.NewController(t)
   655  		defer ctrl.Finish()
   656  
   657  		stmt := &tree.CreateAccount{}
   658  		priv := determinePrivilegeSetOfStatement(stmt)
   659  		ses := newSes(priv, ctrl)
   660  
   661  		rowsOfMoUserGrant := [][]interface{}{
   662  			{0, false},
   663  		}
   664  		roleIdsInMoRolePrivs := []int{0, 1}
   665  		rowsOfMoRolePrivs := [][]interface{}{}
   666  
   667  		//actually no role dependency loop
   668  		roleIdsInMoRoleGrant := []int{0, 1}
   669  		rowsOfMoRoleGrant := [][]interface{}{
   670  			{1, true},
   671  		}
   672  
   673  		sql2result := makeSql2ExecResult(0, rowsOfMoUserGrant,
   674  			roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs,
   675  			roleIdsInMoRoleGrant, rowsOfMoRoleGrant)
   676  
   677  		bh := newBh(ctrl, sql2result)
   678  
   679  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   680  		defer bhStub.Reset()
   681  
   682  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
   683  		convey.So(err, convey.ShouldBeNil)
   684  		convey.So(ok, convey.ShouldBeFalse)
   685  	})
   686  }
   687  
   688  func Test_determineCreateUser(t *testing.T) {
   689  	convey.Convey("create user succ", t, func() {
   690  		ctrl := gomock.NewController(t)
   691  		defer ctrl.Finish()
   692  
   693  		stmt := &tree.CreateUser{}
   694  		priv := determinePrivilegeSetOfStatement(stmt)
   695  		ses := newSes(priv, ctrl)
   696  
   697  		rowsOfMoUserGrant := [][]interface{}{
   698  			{0, false},
   699  		}
   700  		roleIdsInMoRolePrivs := []int{0}
   701  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
   702  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
   703  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
   704  		}
   705  
   706  		//without privilege create user, all
   707  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
   708  		rowsOfMoRolePrivs[0][1] = [][]interface{}{
   709  			{0, true},
   710  		}
   711  
   712  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
   713  
   714  		bh := newBh(ctrl, sql2result)
   715  
   716  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   717  		defer bhStub.Reset()
   718  
   719  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
   720  		convey.So(err, convey.ShouldBeNil)
   721  		convey.So(ok, convey.ShouldBeTrue)
   722  	})
   723  	convey.Convey("create user succ 2", t, func() {
   724  		ctrl := gomock.NewController(t)
   725  		defer ctrl.Finish()
   726  
   727  		stmt := &tree.CreateUser{}
   728  		priv := determinePrivilegeSetOfStatement(stmt)
   729  		ses := newSes(priv, ctrl)
   730  
   731  		rowsOfMoUserGrant := [][]interface{}{
   732  			{0, false},
   733  		}
   734  		roleIdsInMoRolePrivs := []int{0, 1}
   735  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
   736  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
   737  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
   738  		}
   739  
   740  		//role 0 without privilege create user, all, ownership
   741  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
   742  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
   743  
   744  		//role 1 with privilege create user
   745  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
   746  			{1, true},
   747  		}
   748  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
   749  
   750  		//grant role 1 to role 0
   751  		roleIdsInMoRoleGrant := []int{0}
   752  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
   753  		rowsOfMoRoleGrant[0] = [][]interface{}{
   754  			{1, true},
   755  		}
   756  
   757  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
   758  
   759  		bh := newBh(ctrl, sql2result)
   760  
   761  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   762  		defer bhStub.Reset()
   763  
   764  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
   765  		convey.So(err, convey.ShouldBeNil)
   766  		convey.So(ok, convey.ShouldBeTrue)
   767  	})
   768  	convey.Convey("create user fail", t, func() {
   769  		ctrl := gomock.NewController(t)
   770  		defer ctrl.Finish()
   771  
   772  		stmt := &tree.CreateUser{}
   773  		priv := determinePrivilegeSetOfStatement(stmt)
   774  		ses := newSes(priv, ctrl)
   775  
   776  		rowsOfMoUserGrant := [][]interface{}{
   777  			{0, false},
   778  		}
   779  		roleIdsInMoRolePrivs := []int{0, 1, 2}
   780  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
   781  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
   782  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
   783  		}
   784  
   785  		//role 0 without privilege create user, all, ownership
   786  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
   787  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
   788  
   789  		//role 1 without privilege create user, all, ownership
   790  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
   791  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
   792  
   793  		//role 2 without privilege create user, all, ownership
   794  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
   795  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
   796  
   797  		roleIdsInMoRoleGrant := []int{0, 1, 2}
   798  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
   799  		//grant role 1 to role 0
   800  		rowsOfMoRoleGrant[0] = [][]interface{}{
   801  			{1, true},
   802  		}
   803  		//grant role 2 to role 1
   804  		rowsOfMoRoleGrant[1] = [][]interface{}{
   805  			{2, true},
   806  		}
   807  		rowsOfMoRoleGrant[2] = [][]interface{}{}
   808  
   809  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
   810  
   811  		bh := newBh(ctrl, sql2result)
   812  
   813  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   814  		defer bhStub.Reset()
   815  
   816  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
   817  		convey.So(err, convey.ShouldBeNil)
   818  		convey.So(ok, convey.ShouldBeFalse)
   819  	})
   820  }
   821  
   822  func Test_determineDropUser(t *testing.T) {
   823  	convey.Convey("drop/alter user succ", t, func() {
   824  		ctrl := gomock.NewController(t)
   825  		defer ctrl.Finish()
   826  
   827  		stmt := &tree.DropUser{}
   828  		priv := determinePrivilegeSetOfStatement(stmt)
   829  		ses := newSes(priv, ctrl)
   830  
   831  		rowsOfMoUserGrant := [][]interface{}{
   832  			{0, false},
   833  		}
   834  		roleIdsInMoRolePrivs := []int{0}
   835  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
   836  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
   837  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
   838  		}
   839  
   840  		//with privilege drop user
   841  		rowsOfMoRolePrivs[0][0] = [][]interface{}{
   842  			{0, true},
   843  		}
   844  		//without privilege all
   845  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
   846  
   847  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
   848  
   849  		bh := newBh(ctrl, sql2result)
   850  
   851  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   852  		defer bhStub.Reset()
   853  
   854  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
   855  		convey.So(err, convey.ShouldBeNil)
   856  		convey.So(ok, convey.ShouldBeTrue)
   857  	})
   858  	convey.Convey("drop/alter user succ 2", t, func() {
   859  		ctrl := gomock.NewController(t)
   860  		defer ctrl.Finish()
   861  
   862  		stmt := &tree.DropUser{}
   863  		priv := determinePrivilegeSetOfStatement(stmt)
   864  		ses := newSes(priv, ctrl)
   865  
   866  		rowsOfMoUserGrant := [][]interface{}{
   867  			{0, false},
   868  		}
   869  		roleIdsInMoRolePrivs := []int{0, 1}
   870  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
   871  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
   872  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
   873  		}
   874  
   875  		//role 0 without privilege drop user, all, account/user ownership
   876  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
   877  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
   878  
   879  		//role 1 with privilege drop user
   880  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
   881  			{1, true},
   882  		}
   883  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
   884  
   885  		//grant role 1 to role 0
   886  		roleIdsInMoRoleGrant := []int{0}
   887  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
   888  		rowsOfMoRoleGrant[0] = [][]interface{}{
   889  			{1, true},
   890  		}
   891  
   892  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
   893  
   894  		bh := newBh(ctrl, sql2result)
   895  
   896  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   897  		defer bhStub.Reset()
   898  
   899  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
   900  		convey.So(err, convey.ShouldBeNil)
   901  		convey.So(ok, convey.ShouldBeTrue)
   902  	})
   903  	convey.Convey("drop/alter user fail", t, func() {
   904  		ctrl := gomock.NewController(t)
   905  		defer ctrl.Finish()
   906  
   907  		stmt := &tree.DropUser{}
   908  		priv := determinePrivilegeSetOfStatement(stmt)
   909  		ses := newSes(priv, ctrl)
   910  
   911  		rowsOfMoUserGrant := [][]interface{}{
   912  			{0, false},
   913  		}
   914  		roleIdsInMoRolePrivs := []int{0, 1, 2}
   915  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
   916  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
   917  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
   918  		}
   919  
   920  		//role 0 without privilege drop user, all, ownership
   921  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
   922  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
   923  
   924  		//role 1 without privilege drop user, all, ownership
   925  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
   926  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
   927  
   928  		//role 2 without privilege drop user, all, ownership
   929  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
   930  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
   931  
   932  		roleIdsInMoRoleGrant := []int{0, 1, 2}
   933  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
   934  		//grant role 1 to role 0
   935  		rowsOfMoRoleGrant[0] = [][]interface{}{
   936  			{1, true},
   937  		}
   938  		//grant role 2 to role 1
   939  		rowsOfMoRoleGrant[1] = [][]interface{}{
   940  			{2, true},
   941  		}
   942  		rowsOfMoRoleGrant[2] = [][]interface{}{}
   943  
   944  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
   945  
   946  		bh := newBh(ctrl, sql2result)
   947  
   948  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   949  		defer bhStub.Reset()
   950  
   951  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
   952  		convey.So(err, convey.ShouldBeNil)
   953  		convey.So(ok, convey.ShouldBeFalse)
   954  	})
   955  }
   956  
   957  func Test_determineCreateRole(t *testing.T) {
   958  	convey.Convey("create role succ", t, func() {
   959  		ctrl := gomock.NewController(t)
   960  		defer ctrl.Finish()
   961  
   962  		stmt := &tree.CreateRole{}
   963  		priv := determinePrivilegeSetOfStatement(stmt)
   964  		ses := newSes(priv, ctrl)
   965  
   966  		rowsOfMoUserGrant := [][]interface{}{
   967  			{0, false},
   968  		}
   969  		roleIdsInMoRolePrivs := []int{0}
   970  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
   971  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
   972  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
   973  		}
   974  
   975  		//with privilege create role
   976  		rowsOfMoRolePrivs[0][0] = [][]interface{}{
   977  			{0, true},
   978  		}
   979  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
   980  
   981  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
   982  
   983  		bh := newBh(ctrl, sql2result)
   984  
   985  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
   986  		defer bhStub.Reset()
   987  
   988  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
   989  		convey.So(err, convey.ShouldBeNil)
   990  		convey.So(ok, convey.ShouldBeTrue)
   991  	})
   992  	convey.Convey("create role succ 2", t, func() {
   993  		ctrl := gomock.NewController(t)
   994  		defer ctrl.Finish()
   995  
   996  		stmt := &tree.CreateRole{}
   997  		priv := determinePrivilegeSetOfStatement(stmt)
   998  		ses := newSes(priv, ctrl)
   999  
  1000  		rowsOfMoUserGrant := [][]interface{}{
  1001  			{0, false},
  1002  		}
  1003  		roleIdsInMoRolePrivs := []int{0, 1}
  1004  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1005  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1006  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1007  		}
  1008  
  1009  		//role 0 without privilege create role, all, ownership
  1010  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1011  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1012  
  1013  		//role 1 with privilege create role
  1014  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  1015  			{1, true},
  1016  		}
  1017  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1018  
  1019  		//grant role 1 to role 0
  1020  		roleIdsInMoRoleGrant := []int{0}
  1021  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1022  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1023  			{1, true},
  1024  		}
  1025  
  1026  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  1027  
  1028  		bh := newBh(ctrl, sql2result)
  1029  
  1030  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1031  		defer bhStub.Reset()
  1032  
  1033  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1034  		convey.So(err, convey.ShouldBeNil)
  1035  		convey.So(ok, convey.ShouldBeTrue)
  1036  	})
  1037  	convey.Convey("create role fail", t, func() {
  1038  		ctrl := gomock.NewController(t)
  1039  		defer ctrl.Finish()
  1040  
  1041  		stmt := &tree.CreateRole{}
  1042  		priv := determinePrivilegeSetOfStatement(stmt)
  1043  		ses := newSes(priv, ctrl)
  1044  
  1045  		rowsOfMoUserGrant := [][]interface{}{
  1046  			{0, false},
  1047  		}
  1048  		roleIdsInMoRolePrivs := []int{0, 1, 2}
  1049  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1050  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1051  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1052  		}
  1053  
  1054  		//role 0 without privilege create role, all, ownership
  1055  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1056  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1057  
  1058  		//role 1 without privilege create role, all, ownership
  1059  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  1060  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1061  
  1062  		//role 2 without privilege create role, all, ownership
  1063  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  1064  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  1065  
  1066  		roleIdsInMoRoleGrant := []int{0, 1, 2}
  1067  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1068  		//grant role 1 to role 0
  1069  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1070  			{1, true},
  1071  		}
  1072  		//grant role 2 to role 1
  1073  		rowsOfMoRoleGrant[1] = [][]interface{}{
  1074  			{2, true},
  1075  		}
  1076  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  1077  
  1078  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  1079  
  1080  		bh := newBh(ctrl, sql2result)
  1081  
  1082  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1083  		defer bhStub.Reset()
  1084  
  1085  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1086  		convey.So(err, convey.ShouldBeNil)
  1087  		convey.So(ok, convey.ShouldBeFalse)
  1088  	})
  1089  }
  1090  
  1091  func Test_determineDropRole(t *testing.T) {
  1092  	convey.Convey("drop/alter role succ", t, func() {
  1093  		ctrl := gomock.NewController(t)
  1094  		defer ctrl.Finish()
  1095  
  1096  		stmt := &tree.DropRole{}
  1097  		priv := determinePrivilegeSetOfStatement(stmt)
  1098  		ses := newSes(priv, ctrl)
  1099  
  1100  		rowsOfMoUserGrant := [][]interface{}{
  1101  			{0, false},
  1102  		}
  1103  		roleIdsInMoRolePrivs := []int{0}
  1104  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1105  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1106  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1107  		}
  1108  
  1109  		//with privilege drop role
  1110  		rowsOfMoRolePrivs[0][0] = [][]interface{}{
  1111  			{0, true},
  1112  		}
  1113  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1114  
  1115  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
  1116  
  1117  		bh := newBh(ctrl, sql2result)
  1118  
  1119  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1120  		defer bhStub.Reset()
  1121  
  1122  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1123  		convey.So(err, convey.ShouldBeNil)
  1124  		convey.So(ok, convey.ShouldBeTrue)
  1125  	})
  1126  	convey.Convey("drop/alter role succ 2", t, func() {
  1127  		ctrl := gomock.NewController(t)
  1128  		defer ctrl.Finish()
  1129  
  1130  		stmt := &tree.DropRole{}
  1131  		priv := determinePrivilegeSetOfStatement(stmt)
  1132  		ses := newSes(priv, ctrl)
  1133  
  1134  		rowsOfMoUserGrant := [][]interface{}{
  1135  			{0, false},
  1136  		}
  1137  		roleIdsInMoRolePrivs := []int{0, 1}
  1138  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1139  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1140  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1141  		}
  1142  
  1143  		//role 0 without privilege drop role, all, ownership
  1144  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1145  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1146  
  1147  		//role 1 with privilege drop role
  1148  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  1149  			{1, true},
  1150  		}
  1151  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1152  
  1153  		//grant role 1 to role 0
  1154  		roleIdsInMoRoleGrant := []int{0}
  1155  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1156  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1157  			{1, true},
  1158  		}
  1159  
  1160  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  1161  
  1162  		bh := newBh(ctrl, sql2result)
  1163  
  1164  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1165  		defer bhStub.Reset()
  1166  
  1167  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1168  		convey.So(err, convey.ShouldBeNil)
  1169  		convey.So(ok, convey.ShouldBeTrue)
  1170  	})
  1171  	convey.Convey("drop/alter role fail", t, func() {
  1172  		ctrl := gomock.NewController(t)
  1173  		defer ctrl.Finish()
  1174  
  1175  		stmt := &tree.DropRole{}
  1176  		priv := determinePrivilegeSetOfStatement(stmt)
  1177  		ses := newSes(priv, ctrl)
  1178  
  1179  		rowsOfMoUserGrant := [][]interface{}{
  1180  			{0, false},
  1181  		}
  1182  		roleIdsInMoRolePrivs := []int{0, 1, 2}
  1183  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1184  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1185  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1186  		}
  1187  
  1188  		//role 0 without privilege drop role, all, ownership
  1189  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1190  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1191  
  1192  		//role 1 without privilege drop role, all, ownership
  1193  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  1194  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1195  
  1196  		//role 2 without privilege drop role, all, ownership
  1197  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  1198  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  1199  
  1200  		roleIdsInMoRoleGrant := []int{0, 1, 2}
  1201  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1202  		//grant role 1 to role 0
  1203  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1204  			{1, true},
  1205  		}
  1206  		//grant role 2 to role 1
  1207  		rowsOfMoRoleGrant[1] = [][]interface{}{
  1208  			{2, true},
  1209  		}
  1210  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  1211  
  1212  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  1213  
  1214  		bh := newBh(ctrl, sql2result)
  1215  
  1216  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1217  		defer bhStub.Reset()
  1218  
  1219  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1220  		convey.So(err, convey.ShouldBeNil)
  1221  		convey.So(ok, convey.ShouldBeFalse)
  1222  	})
  1223  }
  1224  
  1225  func Test_determineGrantRole(t *testing.T) {
  1226  	convey.Convey("grant role succ", t, func() {
  1227  		ctrl := gomock.NewController(t)
  1228  		defer ctrl.Finish()
  1229  
  1230  		stmt := &tree.GrantRole{}
  1231  		priv := determinePrivilegeSetOfStatement(stmt)
  1232  		ses := newSes(priv, ctrl)
  1233  
  1234  		rowsOfMoUserGrant := [][]interface{}{
  1235  			{0, false},
  1236  		}
  1237  		roleIdsInMoRolePrivs := []int{0}
  1238  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1239  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1240  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1241  		}
  1242  
  1243  		//with privilege manage grants
  1244  		rowsOfMoRolePrivs[0][0] = [][]interface{}{
  1245  			{0, true},
  1246  		}
  1247  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1248  
  1249  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant,
  1250  			roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs,
  1251  			nil, nil, nil, nil)
  1252  
  1253  		bh := newBh(ctrl, sql2result)
  1254  
  1255  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1256  		defer bhStub.Reset()
  1257  
  1258  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1259  		convey.So(err, convey.ShouldBeNil)
  1260  		convey.So(ok, convey.ShouldBeTrue)
  1261  	})
  1262  
  1263  	convey.Convey("grant role succ 2", t, func() {
  1264  		ctrl := gomock.NewController(t)
  1265  		defer ctrl.Finish()
  1266  
  1267  		stmt := &tree.GrantRole{}
  1268  		priv := determinePrivilegeSetOfStatement(stmt)
  1269  		ses := newSes(priv, ctrl)
  1270  
  1271  		rowsOfMoUserGrant := [][]interface{}{
  1272  			{0, false},
  1273  		}
  1274  		roleIdsInMoRolePrivs := []int{0, 1}
  1275  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1276  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1277  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1278  		}
  1279  
  1280  		//role 0 without privilege manage grants, all, ownership
  1281  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1282  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1283  
  1284  		//role 1 with privilege manage grants
  1285  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  1286  			{1, true},
  1287  		}
  1288  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1289  
  1290  		//grant role 1 to role 0
  1291  		roleIdsInMoRoleGrant := []int{0}
  1292  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1293  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1294  			{1, true},
  1295  		}
  1296  
  1297  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant,
  1298  			roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs,
  1299  			roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  1300  		bh := newBh(ctrl, sql2result)
  1301  
  1302  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1303  		defer bhStub.Reset()
  1304  
  1305  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1306  		convey.So(err, convey.ShouldBeNil)
  1307  		convey.So(ok, convey.ShouldBeTrue)
  1308  	})
  1309  
  1310  	convey.Convey("grant role succ 3 (mo_role_grant + with_grant_option)", t, func() {
  1311  		ctrl := gomock.NewController(t)
  1312  		defer ctrl.Finish()
  1313  
  1314  		roleNames := []string{
  1315  			"r1",
  1316  			"r2",
  1317  			"r3",
  1318  		}
  1319  
  1320  		g := &tree.Grant{
  1321  			Typ: tree.GrantTypeRole,
  1322  		}
  1323  		gr := &g.GrantRole
  1324  		for _, name := range roleNames {
  1325  			gr.Roles = append(gr.Roles, &tree.Role{UserName: name})
  1326  		}
  1327  		priv := determinePrivilegeSetOfStatement(g)
  1328  		ses := newSes(priv, ctrl)
  1329  
  1330  		rowsOfMoUserGrant := [][]interface{}{
  1331  			{0, false},
  1332  		}
  1333  		roleIdsInMoRolePrivs := []int{0, 1, 5, 6, 7}
  1334  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1335  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1336  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1337  		}
  1338  
  1339  		//role 0 without privilege manage grants, all, ownership
  1340  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1341  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1342  
  1343  		//role 1 without privilege manage grants
  1344  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  1345  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1346  
  1347  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  1348  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  1349  
  1350  		rowsOfMoRolePrivs[3][0] = [][]interface{}{}
  1351  		rowsOfMoRolePrivs[3][1] = [][]interface{}{}
  1352  
  1353  		rowsOfMoRolePrivs[4][0] = [][]interface{}{}
  1354  		rowsOfMoRolePrivs[4][1] = [][]interface{}{}
  1355  
  1356  		//grant role 1,5,6,7 to role 0
  1357  		roleIdsInMoRoleGrant := []int{0, 1, 5, 6, 7}
  1358  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1359  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1360  			{1, true},
  1361  			{5, true},
  1362  			{6, true},
  1363  			{7, true},
  1364  		}
  1365  		rowsOfMoRoleGrant[1] = [][]interface{}{}
  1366  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  1367  		rowsOfMoRoleGrant[3] = [][]interface{}{}
  1368  		rowsOfMoRoleGrant[4] = [][]interface{}{}
  1369  
  1370  		grantedIds := []int{0, 1, 5, 6, 7}
  1371  		granteeRows := make([][][]interface{}, len(grantedIds))
  1372  		granteeRows[0] = [][]interface{}{}
  1373  		granteeRows[1] = [][]interface{}{}
  1374  		granteeRows[2] = [][]interface{}{
  1375  			{0},
  1376  		}
  1377  		granteeRows[3] = [][]interface{}{
  1378  			{0},
  1379  		}
  1380  		granteeRows[4] = [][]interface{}{
  1381  			{0},
  1382  		}
  1383  
  1384  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant,
  1385  			roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs,
  1386  			roleIdsInMoRoleGrant, rowsOfMoRoleGrant,
  1387  			grantedIds, granteeRows)
  1388  
  1389  		//fill mo_role
  1390  		rowsOfMoRole := make([][][]interface{}, len(roleNames))
  1391  		rowsOfMoRole[0] = [][]interface{}{
  1392  			{5},
  1393  		}
  1394  		rowsOfMoRole[1] = [][]interface{}{
  1395  			{6},
  1396  		}
  1397  		rowsOfMoRole[2] = [][]interface{}{
  1398  			{7},
  1399  		}
  1400  		makeRowsOfMoRole(sql2result, roleNames, rowsOfMoRole)
  1401  
  1402  		bh := newBh(ctrl, sql2result)
  1403  
  1404  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1405  		defer bhStub.Reset()
  1406  
  1407  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, g)
  1408  		convey.So(err, convey.ShouldBeNil)
  1409  		convey.So(ok, convey.ShouldBeTrue)
  1410  	})
  1411  
  1412  	convey.Convey("grant role succ 4 (mo_user_grant + with_grant_option)", t, func() {
  1413  		ctrl := gomock.NewController(t)
  1414  		defer ctrl.Finish()
  1415  
  1416  		roleNames := []string{
  1417  			"r1",
  1418  			"r2",
  1419  			"r3",
  1420  		}
  1421  
  1422  		g := &tree.Grant{
  1423  			Typ: tree.GrantTypeRole,
  1424  		}
  1425  		gr := &g.GrantRole
  1426  		for _, name := range roleNames {
  1427  			gr.Roles = append(gr.Roles, &tree.Role{UserName: name})
  1428  		}
  1429  		priv := determinePrivilegeSetOfStatement(g)
  1430  		ses := newSes(priv, ctrl)
  1431  
  1432  		rowsOfMoUserGrant := [][]interface{}{
  1433  			{0, false},
  1434  			{5, true},
  1435  			{6, true},
  1436  			{7, true},
  1437  		}
  1438  		roleIdsInMoRolePrivs := []int{0, 1, 5, 6, 7}
  1439  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1440  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1441  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1442  		}
  1443  
  1444  		//role 0 without privilege manage grants, all, ownership
  1445  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1446  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1447  
  1448  		//role 1 without privilege manage grants
  1449  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  1450  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1451  
  1452  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  1453  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  1454  
  1455  		rowsOfMoRolePrivs[3][0] = [][]interface{}{}
  1456  		rowsOfMoRolePrivs[3][1] = [][]interface{}{}
  1457  
  1458  		rowsOfMoRolePrivs[4][0] = [][]interface{}{}
  1459  		rowsOfMoRolePrivs[4][1] = [][]interface{}{}
  1460  
  1461  		//grant role 1,5,6,7 to role 0
  1462  		roleIdsInMoRoleGrant := []int{0, 1, 5, 6, 7}
  1463  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1464  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1465  			{1, true},
  1466  		}
  1467  		rowsOfMoRoleGrant[1] = [][]interface{}{}
  1468  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  1469  		rowsOfMoRoleGrant[3] = [][]interface{}{}
  1470  		rowsOfMoRoleGrant[4] = [][]interface{}{}
  1471  
  1472  		grantedIds := []int{0, 1, 5, 6, 7}
  1473  		granteeRows := make([][][]interface{}, len(grantedIds))
  1474  		granteeRows[0] = [][]interface{}{}
  1475  		granteeRows[1] = [][]interface{}{}
  1476  		granteeRows[2] = [][]interface{}{
  1477  			{0},
  1478  		}
  1479  		granteeRows[3] = [][]interface{}{
  1480  			{0},
  1481  		}
  1482  		granteeRows[4] = [][]interface{}{
  1483  			{0},
  1484  		}
  1485  
  1486  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant,
  1487  			roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs,
  1488  			roleIdsInMoRoleGrant, rowsOfMoRoleGrant,
  1489  			grantedIds, granteeRows)
  1490  
  1491  		//fill mo_role
  1492  		rowsOfMoRole := make([][][]interface{}, len(roleNames))
  1493  		rowsOfMoRole[0] = [][]interface{}{
  1494  			{5},
  1495  		}
  1496  		rowsOfMoRole[1] = [][]interface{}{
  1497  			{6},
  1498  		}
  1499  		rowsOfMoRole[2] = [][]interface{}{
  1500  			{7},
  1501  		}
  1502  		makeRowsOfMoRole(sql2result, roleNames, rowsOfMoRole)
  1503  
  1504  		bh := newBh(ctrl, sql2result)
  1505  
  1506  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1507  		defer bhStub.Reset()
  1508  
  1509  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, g)
  1510  		convey.So(err, convey.ShouldBeNil)
  1511  		convey.So(ok, convey.ShouldBeTrue)
  1512  	})
  1513  
  1514  	convey.Convey("grant role fail 1 (mo_user_grant + with_grant_option)", t, func() {
  1515  		ctrl := gomock.NewController(t)
  1516  		defer ctrl.Finish()
  1517  
  1518  		roleNames := []string{
  1519  			"r1",
  1520  			"r2",
  1521  			"r3",
  1522  		}
  1523  
  1524  		g := &tree.Grant{
  1525  			Typ: tree.GrantTypeRole,
  1526  		}
  1527  		gr := &g.GrantRole
  1528  		for _, name := range roleNames {
  1529  			gr.Roles = append(gr.Roles, &tree.Role{UserName: name})
  1530  		}
  1531  		priv := determinePrivilegeSetOfStatement(g)
  1532  		ses := newSes(priv, ctrl)
  1533  
  1534  		rowsOfMoUserGrant := [][]interface{}{
  1535  			{0, false},
  1536  			{5, true},
  1537  			{6, false},
  1538  			{7, true},
  1539  		}
  1540  		roleIdsInMoRolePrivs := []int{0, 1, 5, 6, 7}
  1541  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1542  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1543  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1544  		}
  1545  
  1546  		//role 0 without privilege manage grants, all, ownership
  1547  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1548  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1549  
  1550  		//role 1 without privilege manage grants
  1551  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  1552  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1553  
  1554  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  1555  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  1556  
  1557  		rowsOfMoRolePrivs[3][0] = [][]interface{}{}
  1558  		rowsOfMoRolePrivs[3][1] = [][]interface{}{}
  1559  
  1560  		rowsOfMoRolePrivs[4][0] = [][]interface{}{}
  1561  		rowsOfMoRolePrivs[4][1] = [][]interface{}{}
  1562  
  1563  		//grant role 1,5,6,7 to role 0
  1564  		roleIdsInMoRoleGrant := []int{0, 1, 5, 6, 7}
  1565  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1566  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1567  			{1, true},
  1568  		}
  1569  		rowsOfMoRoleGrant[1] = [][]interface{}{}
  1570  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  1571  		rowsOfMoRoleGrant[3] = [][]interface{}{}
  1572  		rowsOfMoRoleGrant[4] = [][]interface{}{}
  1573  
  1574  		grantedIds := []int{0, 1, 5, 6, 7}
  1575  		granteeRows := make([][][]interface{}, len(grantedIds))
  1576  		granteeRows[0] = [][]interface{}{}
  1577  		granteeRows[1] = [][]interface{}{}
  1578  		granteeRows[2] = [][]interface{}{
  1579  			{0},
  1580  		}
  1581  		granteeRows[3] = [][]interface{}{}
  1582  		granteeRows[4] = [][]interface{}{
  1583  			{0},
  1584  		}
  1585  
  1586  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant,
  1587  			roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs,
  1588  			roleIdsInMoRoleGrant, rowsOfMoRoleGrant, grantedIds, granteeRows)
  1589  
  1590  		//fill mo_role
  1591  		rowsOfMoRole := make([][][]interface{}, len(roleNames))
  1592  		rowsOfMoRole[0] = [][]interface{}{
  1593  			{5},
  1594  		}
  1595  		rowsOfMoRole[1] = [][]interface{}{
  1596  			{6},
  1597  		}
  1598  		rowsOfMoRole[2] = [][]interface{}{
  1599  			{7},
  1600  		}
  1601  		makeRowsOfMoRole(sql2result, roleNames, rowsOfMoRole)
  1602  
  1603  		bh := newBh(ctrl, sql2result)
  1604  
  1605  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1606  		defer bhStub.Reset()
  1607  
  1608  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, g)
  1609  		convey.So(err, convey.ShouldBeNil)
  1610  		convey.So(ok, convey.ShouldBeFalse)
  1611  	})
  1612  
  1613  	convey.Convey("grant role fail 2 (mo_role_grant + with_grant_option)", t, func() {
  1614  		ctrl := gomock.NewController(t)
  1615  		defer ctrl.Finish()
  1616  
  1617  		roleNames := []string{
  1618  			"r1",
  1619  			"r2",
  1620  			"r3",
  1621  		}
  1622  
  1623  		g := &tree.Grant{
  1624  			Typ: tree.GrantTypeRole,
  1625  		}
  1626  		gr := &g.GrantRole
  1627  		for _, name := range roleNames {
  1628  			gr.Roles = append(gr.Roles, &tree.Role{UserName: name})
  1629  		}
  1630  		priv := determinePrivilegeSetOfStatement(g)
  1631  		ses := newSes(priv, ctrl)
  1632  
  1633  		rowsOfMoUserGrant := [][]interface{}{
  1634  			{0, false},
  1635  		}
  1636  		roleIdsInMoRolePrivs := []int{0, 1, 5, 6, 7}
  1637  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1638  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1639  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1640  		}
  1641  
  1642  		//role 0 without privilege manage grants, all, ownership
  1643  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1644  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1645  
  1646  		//role 1 without privilege manage grants
  1647  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  1648  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1649  
  1650  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  1651  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  1652  
  1653  		rowsOfMoRolePrivs[3][0] = [][]interface{}{}
  1654  		rowsOfMoRolePrivs[3][1] = [][]interface{}{}
  1655  
  1656  		rowsOfMoRolePrivs[4][0] = [][]interface{}{}
  1657  		rowsOfMoRolePrivs[4][1] = [][]interface{}{}
  1658  
  1659  		//grant role 1,5,6,7 to role 0
  1660  		roleIdsInMoRoleGrant := []int{0, 1, 5, 6, 7}
  1661  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1662  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1663  			{1, true},
  1664  			{5, true},
  1665  			{6, false},
  1666  			{7, true},
  1667  		}
  1668  		rowsOfMoRoleGrant[1] = [][]interface{}{}
  1669  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  1670  		rowsOfMoRoleGrant[3] = [][]interface{}{}
  1671  		rowsOfMoRoleGrant[4] = [][]interface{}{}
  1672  
  1673  		grantedIds := []int{0, 1, 5, 6, 7}
  1674  		granteeRows := make([][][]interface{}, len(grantedIds))
  1675  		granteeRows[0] = [][]interface{}{}
  1676  		granteeRows[1] = [][]interface{}{}
  1677  		granteeRows[2] = [][]interface{}{
  1678  			{0},
  1679  		}
  1680  		granteeRows[3] = [][]interface{}{
  1681  			{0},
  1682  		}
  1683  		granteeRows[4] = [][]interface{}{}
  1684  
  1685  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant,
  1686  			roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs,
  1687  			roleIdsInMoRoleGrant, rowsOfMoRoleGrant,
  1688  			grantedIds, granteeRows)
  1689  
  1690  		//fill mo_role
  1691  		rowsOfMoRole := make([][][]interface{}, len(roleNames))
  1692  		rowsOfMoRole[0] = [][]interface{}{
  1693  			{5},
  1694  		}
  1695  		rowsOfMoRole[1] = [][]interface{}{
  1696  			{6},
  1697  		}
  1698  		rowsOfMoRole[2] = [][]interface{}{
  1699  			{7},
  1700  		}
  1701  		makeRowsOfMoRole(sql2result, roleNames, rowsOfMoRole)
  1702  
  1703  		bh := newBh(ctrl, sql2result)
  1704  
  1705  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1706  		defer bhStub.Reset()
  1707  
  1708  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, g)
  1709  		convey.So(err, convey.ShouldBeNil)
  1710  		convey.So(ok, convey.ShouldBeFalse)
  1711  	})
  1712  }
  1713  
  1714  func Test_determineRevokeRole(t *testing.T) {
  1715  	convey.Convey("revoke role succ", t, func() {
  1716  		ctrl := gomock.NewController(t)
  1717  		defer ctrl.Finish()
  1718  
  1719  		stmt := &tree.RevokeRole{}
  1720  		priv := determinePrivilegeSetOfStatement(stmt)
  1721  		ses := newSes(priv, ctrl)
  1722  
  1723  		rowsOfMoUserGrant := [][]interface{}{
  1724  			{0, false},
  1725  		}
  1726  		roleIdsInMoRolePrivs := []int{0}
  1727  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1728  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1729  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1730  		}
  1731  
  1732  		//with privilege manage grants
  1733  		rowsOfMoRolePrivs[0][0] = [][]interface{}{
  1734  			{0, true},
  1735  		}
  1736  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1737  
  1738  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
  1739  
  1740  		bh := newBh(ctrl, sql2result)
  1741  
  1742  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1743  		defer bhStub.Reset()
  1744  
  1745  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1746  		convey.So(err, convey.ShouldBeNil)
  1747  		convey.So(ok, convey.ShouldBeTrue)
  1748  	})
  1749  
  1750  	convey.Convey("revoke role succ 2", t, func() {
  1751  		ctrl := gomock.NewController(t)
  1752  		defer ctrl.Finish()
  1753  
  1754  		stmt := &tree.RevokeRole{}
  1755  		priv := determinePrivilegeSetOfStatement(stmt)
  1756  		ses := newSes(priv, ctrl)
  1757  
  1758  		rowsOfMoUserGrant := [][]interface{}{
  1759  			{0, false},
  1760  		}
  1761  		roleIdsInMoRolePrivs := []int{0, 1}
  1762  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1763  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1764  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1765  		}
  1766  
  1767  		//role 0 without privilege manage grants, all, ownership
  1768  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1769  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1770  
  1771  		//role 1 with privilege manage grants
  1772  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  1773  			{1, true},
  1774  		}
  1775  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1776  
  1777  		//grant role 1 to role 0
  1778  		roleIdsInMoRoleGrant := []int{0}
  1779  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1780  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1781  			{1, true},
  1782  		}
  1783  
  1784  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  1785  
  1786  		bh := newBh(ctrl, sql2result)
  1787  
  1788  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1789  		defer bhStub.Reset()
  1790  
  1791  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1792  		convey.So(err, convey.ShouldBeNil)
  1793  		convey.So(ok, convey.ShouldBeTrue)
  1794  	})
  1795  
  1796  	convey.Convey("revoke role fail", t, func() {
  1797  		ctrl := gomock.NewController(t)
  1798  		defer ctrl.Finish()
  1799  
  1800  		stmt := &tree.RevokeRole{}
  1801  		priv := determinePrivilegeSetOfStatement(stmt)
  1802  		ses := newSes(priv, ctrl)
  1803  
  1804  		rowsOfMoUserGrant := [][]interface{}{
  1805  			{0, false},
  1806  		}
  1807  		roleIdsInMoRolePrivs := []int{0, 1, 2}
  1808  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  1809  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  1810  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  1811  		}
  1812  
  1813  		//role 0 without privilege drop role, all, ownership
  1814  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  1815  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  1816  
  1817  		//role 1 without privilege drop role, all, ownership
  1818  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  1819  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  1820  
  1821  		//role 2 without privilege drop role, all, ownership
  1822  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  1823  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  1824  
  1825  		roleIdsInMoRoleGrant := []int{0, 1, 2}
  1826  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  1827  		//grant role 1 to role 0
  1828  		rowsOfMoRoleGrant[0] = [][]interface{}{
  1829  			{1, true},
  1830  		}
  1831  		//grant role 2 to role 1
  1832  		rowsOfMoRoleGrant[1] = [][]interface{}{
  1833  			{2, true},
  1834  		}
  1835  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  1836  
  1837  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  1838  
  1839  		bh := newBh(ctrl, sql2result)
  1840  
  1841  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1842  		defer bhStub.Reset()
  1843  
  1844  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  1845  		convey.So(err, convey.ShouldBeNil)
  1846  		convey.So(ok, convey.ShouldBeFalse)
  1847  	})
  1848  }
  1849  
  1850  func Test_determineGrantPrivilege(t *testing.T) {
  1851  	convey.Convey("convert ast privilege", t, func() {
  1852  		type arg struct {
  1853  			pt   tree.PrivilegeType
  1854  			want PrivilegeType
  1855  		}
  1856  
  1857  		args := []arg{
  1858  			{tree.PRIVILEGE_TYPE_STATIC_SELECT, PrivilegeTypeSelect},
  1859  		}
  1860  
  1861  		for _, a := range args {
  1862  			w, err := convertAstPrivilegeTypeToPrivilegeType(context.TODO(), a.pt, tree.OBJECT_TYPE_TABLE)
  1863  			convey.So(err, convey.ShouldBeNil)
  1864  			convey.So(w, convey.ShouldEqual, a.want)
  1865  		}
  1866  	})
  1867  
  1868  	convey.Convey("grant privilege [ObjectType: Table] AdminRole succ", t, func() {
  1869  		ctrl := gomock.NewController(t)
  1870  		defer ctrl.Finish()
  1871  
  1872  		stmts := []*tree.GrantPrivilege{
  1873  			{
  1874  				Privileges: []*tree.Privilege{
  1875  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  1876  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  1877  				},
  1878  				ObjType: tree.OBJECT_TYPE_TABLE,
  1879  				Level: &tree.PrivilegeLevel{
  1880  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  1881  				},
  1882  			},
  1883  		}
  1884  
  1885  		for _, stmt := range stmts {
  1886  			priv := determinePrivilegeSetOfStatement(stmt)
  1887  			ses := newSes(priv, ctrl)
  1888  			ses.SetDatabaseName("db")
  1889  
  1890  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  1891  			convey.So(err, convey.ShouldBeNil)
  1892  			convey.So(ok, convey.ShouldBeTrue)
  1893  		}
  1894  	})
  1895  
  1896  	convey.Convey("grant privilege [ObjectType: Table] succ", t, func() {
  1897  		ctrl := gomock.NewController(t)
  1898  		defer ctrl.Finish()
  1899  
  1900  		bh := &backgroundExecTest{}
  1901  		bh.init()
  1902  
  1903  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  1904  		defer bhStub.Reset()
  1905  
  1906  		stmts := []*tree.GrantPrivilege{
  1907  			{
  1908  				Privileges: []*tree.Privilege{
  1909  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  1910  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  1911  				},
  1912  				ObjType: tree.OBJECT_TYPE_TABLE,
  1913  				Level: &tree.PrivilegeLevel{
  1914  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  1915  				},
  1916  			},
  1917  			{
  1918  				Privileges: []*tree.Privilege{
  1919  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  1920  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  1921  				},
  1922  				ObjType: tree.OBJECT_TYPE_TABLE,
  1923  				Level: &tree.PrivilegeLevel{
  1924  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR_STAR,
  1925  				},
  1926  			},
  1927  			{
  1928  				Privileges: []*tree.Privilege{
  1929  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  1930  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  1931  				},
  1932  				ObjType: tree.OBJECT_TYPE_TABLE,
  1933  				Level: &tree.PrivilegeLevel{
  1934  					Level: tree.PRIVILEGE_LEVEL_TYPE_DATABASE_STAR,
  1935  				},
  1936  			},
  1937  			{
  1938  				Privileges: []*tree.Privilege{
  1939  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  1940  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  1941  				},
  1942  				ObjType: tree.OBJECT_TYPE_TABLE,
  1943  				Level: &tree.PrivilegeLevel{
  1944  					Level: tree.PRIVILEGE_LEVEL_TYPE_DATABASE_TABLE,
  1945  				},
  1946  			},
  1947  			{
  1948  				Privileges: []*tree.Privilege{
  1949  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  1950  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  1951  				},
  1952  				ObjType: tree.OBJECT_TYPE_TABLE,
  1953  				Level: &tree.PrivilegeLevel{
  1954  					Level: tree.PRIVILEGE_LEVEL_TYPE_TABLE,
  1955  				},
  1956  			},
  1957  		}
  1958  
  1959  		for _, stmt := range stmts {
  1960  			priv := determinePrivilegeSetOfStatement(stmt)
  1961  			ses := newSes(priv, ctrl)
  1962  			ses.tenant = &TenantInfo{
  1963  				Tenant:        "xxx",
  1964  				User:          "xxx",
  1965  				DefaultRole:   "xxx",
  1966  				TenantID:      1001,
  1967  				UserID:        1001,
  1968  				DefaultRoleID: 1001,
  1969  			}
  1970  			ses.SetDatabaseName("db")
  1971  			//TODO: make sql2result
  1972  			bh.init()
  1973  			for _, p := range stmt.Privileges {
  1974  				sql, err := formSqlFromGrantPrivilege(context.TODO(), ses, stmt, p)
  1975  				convey.So(err, convey.ShouldBeNil)
  1976  				makeRowsOfWithGrantOptionPrivilege(bh.sql2result, sql, [][]interface{}{
  1977  					{1, true},
  1978  				})
  1979  
  1980  				var privType PrivilegeType
  1981  				privType, err = convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  1982  				convey.So(err, convey.ShouldBeNil)
  1983  				sql = getSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(privType)
  1984  
  1985  				rows := [][]interface{}{
  1986  					{ses.GetTenantInfo().GetDefaultRoleID()},
  1987  				}
  1988  
  1989  				bh.sql2result[sql] = newMrsForPrivilegeWGO(rows)
  1990  			}
  1991  
  1992  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  1993  			convey.So(err, convey.ShouldBeNil)
  1994  			convey.So(ok, convey.ShouldBeTrue)
  1995  		}
  1996  	})
  1997  
  1998  	convey.Convey("grant privilege [ObjectType: Table] fail", t, func() {
  1999  		ctrl := gomock.NewController(t)
  2000  		defer ctrl.Finish()
  2001  
  2002  		bh := &backgroundExecTest{}
  2003  		bh.init()
  2004  
  2005  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2006  		defer bhStub.Reset()
  2007  
  2008  		stmts := []*tree.GrantPrivilege{
  2009  			{
  2010  				Privileges: []*tree.Privilege{
  2011  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2012  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2013  				},
  2014  				ObjType: tree.OBJECT_TYPE_TABLE,
  2015  				Level: &tree.PrivilegeLevel{
  2016  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  2017  				},
  2018  			},
  2019  			{
  2020  				Privileges: []*tree.Privilege{
  2021  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2022  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2023  				},
  2024  				ObjType: tree.OBJECT_TYPE_TABLE,
  2025  				Level: &tree.PrivilegeLevel{
  2026  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR_STAR,
  2027  				},
  2028  			},
  2029  			{
  2030  				Privileges: []*tree.Privilege{
  2031  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2032  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2033  				},
  2034  				ObjType: tree.OBJECT_TYPE_TABLE,
  2035  				Level: &tree.PrivilegeLevel{
  2036  					Level: tree.PRIVILEGE_LEVEL_TYPE_DATABASE_STAR,
  2037  				},
  2038  			},
  2039  			{
  2040  				Privileges: []*tree.Privilege{
  2041  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2042  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2043  				},
  2044  				ObjType: tree.OBJECT_TYPE_TABLE,
  2045  				Level: &tree.PrivilegeLevel{
  2046  					Level: tree.PRIVILEGE_LEVEL_TYPE_DATABASE_TABLE,
  2047  				},
  2048  			},
  2049  			{
  2050  				Privileges: []*tree.Privilege{
  2051  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2052  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2053  				},
  2054  				ObjType: tree.OBJECT_TYPE_TABLE,
  2055  				Level: &tree.PrivilegeLevel{
  2056  					Level: tree.PRIVILEGE_LEVEL_TYPE_TABLE,
  2057  				},
  2058  			},
  2059  		}
  2060  
  2061  		for _, stmt := range stmts {
  2062  			priv := determinePrivilegeSetOfStatement(stmt)
  2063  			ses := newSes(priv, ctrl)
  2064  			ses.tenant = &TenantInfo{
  2065  				Tenant:        "xxx",
  2066  				User:          "xxx",
  2067  				DefaultRole:   "xxx",
  2068  				TenantID:      1001,
  2069  				UserID:        1001,
  2070  				DefaultRoleID: 1001,
  2071  			}
  2072  			ses.SetDatabaseName("db")
  2073  			//TODO: make sql2result
  2074  			bh.init()
  2075  			var privType PrivilegeType
  2076  			for i, p := range stmt.Privileges {
  2077  				sql, err := formSqlFromGrantPrivilege(context.TODO(), ses, stmt, p)
  2078  				convey.So(err, convey.ShouldBeNil)
  2079  				var rows [][]interface{}
  2080  				if i == 0 {
  2081  					rows = [][]interface{}{}
  2082  				} else {
  2083  					rows = [][]interface{}{
  2084  						{1, true},
  2085  					}
  2086  				}
  2087  				makeRowsOfWithGrantOptionPrivilege(bh.sql2result, sql, rows)
  2088  
  2089  				privType, err = convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  2090  				convey.So(err, convey.ShouldBeNil)
  2091  				sql = getSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(privType)
  2092  				if i == 0 {
  2093  					rows = [][]interface{}{}
  2094  				} else {
  2095  					rows = [][]interface{}{
  2096  						{ses.GetTenantInfo().GetDefaultRoleID()},
  2097  					}
  2098  				}
  2099  
  2100  				bh.sql2result[sql] = newMrsForPrivilegeWGO(rows)
  2101  			}
  2102  
  2103  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  2104  			convey.So(err, convey.ShouldBeNil)
  2105  			convey.So(ok, convey.ShouldBeFalse)
  2106  		}
  2107  	})
  2108  
  2109  	convey.Convey("grant privilege [ObjectType: Database] succ", t, func() {
  2110  		ctrl := gomock.NewController(t)
  2111  		defer ctrl.Finish()
  2112  
  2113  		bh := &backgroundExecTest{}
  2114  		bh.init()
  2115  
  2116  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2117  		defer bhStub.Reset()
  2118  
  2119  		stmts := []*tree.GrantPrivilege{
  2120  			{
  2121  				Privileges: []*tree.Privilege{
  2122  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2123  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2124  				},
  2125  				ObjType: tree.OBJECT_TYPE_DATABASE,
  2126  				Level: &tree.PrivilegeLevel{
  2127  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  2128  				},
  2129  			},
  2130  			{
  2131  				Privileges: []*tree.Privilege{
  2132  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2133  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2134  				},
  2135  				ObjType: tree.OBJECT_TYPE_DATABASE,
  2136  				Level: &tree.PrivilegeLevel{
  2137  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR_STAR,
  2138  				},
  2139  			},
  2140  			{
  2141  				Privileges: []*tree.Privilege{
  2142  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2143  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2144  				},
  2145  				ObjType: tree.OBJECT_TYPE_DATABASE,
  2146  				Level: &tree.PrivilegeLevel{
  2147  					Level: tree.PRIVILEGE_LEVEL_TYPE_DATABASE,
  2148  				},
  2149  			},
  2150  		}
  2151  
  2152  		var privType PrivilegeType
  2153  		for _, stmt := range stmts {
  2154  			priv := determinePrivilegeSetOfStatement(stmt)
  2155  			ses := newSes(priv, ctrl)
  2156  			ses.tenant = &TenantInfo{
  2157  				Tenant:        "xxx",
  2158  				User:          "xxx",
  2159  				DefaultRole:   "xxx",
  2160  				TenantID:      1001,
  2161  				UserID:        1001,
  2162  				DefaultRoleID: 1001,
  2163  			}
  2164  			ses.SetDatabaseName("db")
  2165  			//TODO: make sql2result
  2166  			bh.init()
  2167  			for _, p := range stmt.Privileges {
  2168  				sql, err := formSqlFromGrantPrivilege(context.TODO(), ses, stmt, p)
  2169  				convey.So(err, convey.ShouldBeNil)
  2170  				makeRowsOfWithGrantOptionPrivilege(bh.sql2result, sql, [][]interface{}{
  2171  					{1, true},
  2172  				})
  2173  
  2174  				privType, err = convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  2175  				convey.So(err, convey.ShouldBeNil)
  2176  				sql = getSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(privType)
  2177  
  2178  				rows := [][]interface{}{
  2179  					{ses.GetTenantInfo().GetDefaultRoleID()},
  2180  				}
  2181  
  2182  				bh.sql2result[sql] = newMrsForPrivilegeWGO(rows)
  2183  			}
  2184  
  2185  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  2186  			convey.So(err, convey.ShouldBeNil)
  2187  			convey.So(ok, convey.ShouldBeTrue)
  2188  		}
  2189  	})
  2190  
  2191  	convey.Convey("grant privilege [ObjectType: Database] fail", t, func() {
  2192  		ctrl := gomock.NewController(t)
  2193  		defer ctrl.Finish()
  2194  
  2195  		bh := &backgroundExecTest{}
  2196  		bh.init()
  2197  
  2198  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2199  		defer bhStub.Reset()
  2200  
  2201  		stmts := []*tree.GrantPrivilege{
  2202  			{
  2203  				Privileges: []*tree.Privilege{
  2204  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2205  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2206  				},
  2207  				ObjType: tree.OBJECT_TYPE_DATABASE,
  2208  				Level: &tree.PrivilegeLevel{
  2209  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  2210  				},
  2211  			},
  2212  			{
  2213  				Privileges: []*tree.Privilege{
  2214  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2215  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2216  				},
  2217  				ObjType: tree.OBJECT_TYPE_DATABASE,
  2218  				Level: &tree.PrivilegeLevel{
  2219  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR_STAR,
  2220  				},
  2221  			},
  2222  			{
  2223  				Privileges: []*tree.Privilege{
  2224  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2225  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2226  				},
  2227  				ObjType: tree.OBJECT_TYPE_DATABASE,
  2228  				Level: &tree.PrivilegeLevel{
  2229  					Level: tree.PRIVILEGE_LEVEL_TYPE_DATABASE,
  2230  				},
  2231  			},
  2232  		}
  2233  
  2234  		for _, stmt := range stmts {
  2235  			priv := determinePrivilegeSetOfStatement(stmt)
  2236  			ses := newSes(priv, ctrl)
  2237  			ses.tenant = &TenantInfo{
  2238  				Tenant:        "xxx",
  2239  				User:          "xxx",
  2240  				DefaultRole:   "xxx",
  2241  				TenantID:      1001,
  2242  				UserID:        1001,
  2243  				DefaultRoleID: 1001,
  2244  			}
  2245  			ses.SetDatabaseName("db")
  2246  			//TODO: make sql2result
  2247  			bh.init()
  2248  			for i, p := range stmt.Privileges {
  2249  				sql, err := formSqlFromGrantPrivilege(context.TODO(), ses, stmt, p)
  2250  				convey.So(err, convey.ShouldBeNil)
  2251  				var rows [][]interface{}
  2252  				if i == 0 {
  2253  					rows = [][]interface{}{}
  2254  				} else {
  2255  					rows = [][]interface{}{
  2256  						{1, true},
  2257  					}
  2258  				}
  2259  				makeRowsOfWithGrantOptionPrivilege(bh.sql2result, sql, rows)
  2260  
  2261  				var privType PrivilegeType
  2262  				privType, err = convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  2263  				convey.So(err, convey.ShouldBeNil)
  2264  				sql = getSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(privType)
  2265  
  2266  				if i == 0 {
  2267  					rows = [][]interface{}{}
  2268  				} else {
  2269  					rows = [][]interface{}{
  2270  						{ses.GetTenantInfo().GetDefaultRoleID()},
  2271  					}
  2272  				}
  2273  
  2274  				bh.sql2result[sql] = newMrsForPrivilegeWGO(rows)
  2275  			}
  2276  
  2277  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  2278  			convey.So(err, convey.ShouldBeNil)
  2279  			convey.So(ok, convey.ShouldBeFalse)
  2280  		}
  2281  	})
  2282  
  2283  	convey.Convey("grant privilege [ObjectType: Account] succ", t, func() {
  2284  		ctrl := gomock.NewController(t)
  2285  		defer ctrl.Finish()
  2286  
  2287  		bh := &backgroundExecTest{}
  2288  		bh.init()
  2289  
  2290  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2291  		defer bhStub.Reset()
  2292  
  2293  		stmts := []*tree.GrantPrivilege{
  2294  			{
  2295  				Privileges: []*tree.Privilege{
  2296  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2297  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2298  				},
  2299  				ObjType: tree.OBJECT_TYPE_ACCOUNT,
  2300  				Level: &tree.PrivilegeLevel{
  2301  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  2302  				},
  2303  			},
  2304  		}
  2305  
  2306  		for _, stmt := range stmts {
  2307  			priv := determinePrivilegeSetOfStatement(stmt)
  2308  			ses := newSes(priv, ctrl)
  2309  			ses.tenant = &TenantInfo{
  2310  				Tenant:        "xxx",
  2311  				User:          "xxx",
  2312  				DefaultRole:   "xxx",
  2313  				TenantID:      1001,
  2314  				UserID:        1001,
  2315  				DefaultRoleID: 1001,
  2316  			}
  2317  			ses.SetDatabaseName("db")
  2318  			//TODO: make sql2result
  2319  			bh.init()
  2320  			for _, p := range stmt.Privileges {
  2321  				sql, err := formSqlFromGrantPrivilege(context.TODO(), ses, stmt, p)
  2322  				convey.So(err, convey.ShouldBeNil)
  2323  				makeRowsOfWithGrantOptionPrivilege(bh.sql2result, sql, [][]interface{}{
  2324  					{1, true},
  2325  				})
  2326  
  2327  				var privType PrivilegeType
  2328  				privType, err = convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  2329  				convey.So(err, convey.ShouldBeNil)
  2330  				sql = getSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(privType)
  2331  				rows := [][]interface{}{
  2332  					{ses.GetTenantInfo().GetDefaultRoleID()},
  2333  				}
  2334  
  2335  				bh.sql2result[sql] = newMrsForPrivilegeWGO(rows)
  2336  			}
  2337  
  2338  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  2339  			convey.So(err, convey.ShouldBeNil)
  2340  			convey.So(ok, convey.ShouldBeTrue)
  2341  		}
  2342  	})
  2343  
  2344  	convey.Convey("grant privilege [ObjectType: Account] fail", t, func() {
  2345  		ctrl := gomock.NewController(t)
  2346  		defer ctrl.Finish()
  2347  
  2348  		bh := &backgroundExecTest{}
  2349  		bh.init()
  2350  
  2351  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2352  		defer bhStub.Reset()
  2353  
  2354  		stmts := []*tree.GrantPrivilege{
  2355  			{
  2356  				Privileges: []*tree.Privilege{
  2357  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  2358  					{Type: tree.PRIVILEGE_TYPE_STATIC_INSERT},
  2359  				},
  2360  				ObjType: tree.OBJECT_TYPE_ACCOUNT,
  2361  				Level: &tree.PrivilegeLevel{
  2362  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  2363  				},
  2364  			},
  2365  		}
  2366  
  2367  		for _, stmt := range stmts {
  2368  			priv := determinePrivilegeSetOfStatement(stmt)
  2369  			ses := newSes(priv, ctrl)
  2370  			ses.tenant = &TenantInfo{
  2371  				Tenant:        "xxx",
  2372  				User:          "xxx",
  2373  				DefaultRole:   "xxx",
  2374  				TenantID:      1001,
  2375  				UserID:        1001,
  2376  				DefaultRoleID: 1001,
  2377  			}
  2378  			ses.SetDatabaseName("db")
  2379  			//TODO: make sql2result
  2380  			bh.init()
  2381  			for i, p := range stmt.Privileges {
  2382  				sql, err := formSqlFromGrantPrivilege(context.TODO(), ses, stmt, p)
  2383  				convey.So(err, convey.ShouldBeNil)
  2384  				var rows [][]interface{}
  2385  				if i == 0 {
  2386  					rows = [][]interface{}{}
  2387  				} else {
  2388  					rows = [][]interface{}{
  2389  						{1, true},
  2390  					}
  2391  				}
  2392  				makeRowsOfWithGrantOptionPrivilege(bh.sql2result, sql, rows)
  2393  
  2394  				var privType PrivilegeType
  2395  				privType, err = convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  2396  				convey.So(err, convey.ShouldBeNil)
  2397  				sql = getSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(privType)
  2398  
  2399  				if i == 0 {
  2400  					rows = [][]interface{}{}
  2401  				} else {
  2402  					rows = [][]interface{}{
  2403  						{ses.GetTenantInfo().GetDefaultRoleID()},
  2404  					}
  2405  				}
  2406  
  2407  				bh.sql2result[sql] = newMrsForPrivilegeWGO(rows)
  2408  			}
  2409  
  2410  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  2411  			convey.So(err, convey.ShouldBeNil)
  2412  			convey.So(ok, convey.ShouldBeFalse)
  2413  		}
  2414  	})
  2415  }
  2416  
  2417  func Test_determineRevokePrivilege(t *testing.T) {
  2418  	convey.Convey("revoke privilege [ObjectType: Table] AdminRole succ", t, func() {
  2419  		ctrl := gomock.NewController(t)
  2420  		defer ctrl.Finish()
  2421  		var stmts []*tree.RevokePrivilege
  2422  
  2423  		for _, stmt := range stmts {
  2424  			priv := determinePrivilegeSetOfStatement(stmt)
  2425  			ses := newSes(priv, ctrl)
  2426  
  2427  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  2428  			convey.So(err, convey.ShouldBeNil)
  2429  			convey.So(ok, convey.ShouldBeTrue)
  2430  		}
  2431  	})
  2432  	convey.Convey("revoke privilege [ObjectType: Table] not AdminRole fail", t, func() {
  2433  		ctrl := gomock.NewController(t)
  2434  		defer ctrl.Finish()
  2435  		var stmts []*tree.RevokePrivilege
  2436  
  2437  		for _, stmt := range stmts {
  2438  			priv := determinePrivilegeSetOfStatement(stmt)
  2439  			ses := newSes(priv, ctrl)
  2440  			ses.tenant = &TenantInfo{
  2441  				Tenant:        "xxx",
  2442  				User:          "xxx",
  2443  				DefaultRole:   "xxx",
  2444  				TenantID:      1001,
  2445  				UserID:        1001,
  2446  				DefaultRoleID: 1001,
  2447  			}
  2448  
  2449  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  2450  			convey.So(err, convey.ShouldBeNil)
  2451  			convey.So(ok, convey.ShouldBeFalse)
  2452  		}
  2453  	})
  2454  }
  2455  
  2456  func TestBackUpStatementPrivilege(t *testing.T) {
  2457  	convey.Convey("backup success", t, func() {
  2458  		ctrl := gomock.NewController(t)
  2459  		defer ctrl.Finish()
  2460  		stmt := &tree.BackupStart{}
  2461  		priv := determinePrivilegeSetOfStatement(stmt)
  2462  		ses := newSes(priv, ctrl)
  2463  		tenant := &TenantInfo{
  2464  			Tenant:        sysAccountName,
  2465  			User:          rootName,
  2466  			DefaultRole:   moAdminRoleName,
  2467  			TenantID:      sysAccountID,
  2468  			UserID:        rootID,
  2469  			DefaultRoleID: moAdminRoleID,
  2470  		}
  2471  		ses.SetTenantInfo(tenant)
  2472  
  2473  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  2474  		convey.So(err, convey.ShouldBeNil)
  2475  		convey.So(ok, convey.ShouldBeTrue)
  2476  	})
  2477  
  2478  	convey.Convey("backup fail", t, func() {
  2479  		ctrl := gomock.NewController(t)
  2480  		defer ctrl.Finish()
  2481  		stmt := &tree.BackupStart{}
  2482  		priv := determinePrivilegeSetOfStatement(stmt)
  2483  		ses := newSes(priv, ctrl)
  2484  		tenant := &TenantInfo{
  2485  			Tenant:        "test_account",
  2486  			User:          "test_user",
  2487  			DefaultRole:   "role1",
  2488  			TenantID:      3001,
  2489  			UserID:        3,
  2490  			DefaultRoleID: 5,
  2491  		}
  2492  		ses.SetTenantInfo(tenant)
  2493  
  2494  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeNone(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  2495  		convey.So(err, convey.ShouldBeNil)
  2496  		convey.So(ok, convey.ShouldBeFalse)
  2497  	})
  2498  }
  2499  
  2500  func Test_determineCreateDatabase(t *testing.T) {
  2501  	convey.Convey("create database succ", t, func() {
  2502  		ctrl := gomock.NewController(t)
  2503  		defer ctrl.Finish()
  2504  
  2505  		stmt := &tree.CreateDatabase{}
  2506  		priv := determinePrivilegeSetOfStatement(stmt)
  2507  		ses := newSes(priv, ctrl)
  2508  
  2509  		rowsOfMoUserGrant := [][]interface{}{
  2510  			{0, false},
  2511  		}
  2512  		roleIdsInMoRolePrivs := []int{0}
  2513  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2514  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2515  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2516  		}
  2517  
  2518  		//without privilege create database, all
  2519  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  2520  		rowsOfMoRolePrivs[0][1] = [][]interface{}{
  2521  			{0, true},
  2522  		}
  2523  
  2524  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
  2525  
  2526  		bh := newBh(ctrl, sql2result)
  2527  
  2528  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2529  		defer bhStub.Reset()
  2530  
  2531  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2532  		convey.So(err, convey.ShouldBeNil)
  2533  		convey.So(ok, convey.ShouldBeTrue)
  2534  	})
  2535  	convey.Convey("create database succ 2", t, func() {
  2536  		ctrl := gomock.NewController(t)
  2537  		defer ctrl.Finish()
  2538  
  2539  		stmt := &tree.CreateDatabase{}
  2540  		priv := determinePrivilegeSetOfStatement(stmt)
  2541  		ses := newSes(priv, ctrl)
  2542  
  2543  		rowsOfMoUserGrant := [][]interface{}{
  2544  			{0, false},
  2545  		}
  2546  		roleIdsInMoRolePrivs := []int{0, 1}
  2547  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2548  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2549  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2550  		}
  2551  
  2552  		//role 0 without privilege create database, all, ownership
  2553  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  2554  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2555  
  2556  		//role 1 with privilege create database
  2557  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  2558  			{1, true},
  2559  		}
  2560  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  2561  
  2562  		//grant role 1 to role 0
  2563  		roleIdsInMoRoleGrant := []int{0}
  2564  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  2565  		rowsOfMoRoleGrant[0] = [][]interface{}{
  2566  			{1, true},
  2567  		}
  2568  
  2569  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  2570  
  2571  		bh := newBh(ctrl, sql2result)
  2572  
  2573  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2574  		defer bhStub.Reset()
  2575  
  2576  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2577  		convey.So(err, convey.ShouldBeNil)
  2578  		convey.So(ok, convey.ShouldBeTrue)
  2579  	})
  2580  	convey.Convey("create database fail", t, func() {
  2581  		ctrl := gomock.NewController(t)
  2582  		defer ctrl.Finish()
  2583  
  2584  		stmt := &tree.CreateDatabase{}
  2585  		priv := determinePrivilegeSetOfStatement(stmt)
  2586  		ses := newSes(priv, ctrl)
  2587  
  2588  		rowsOfMoUserGrant := [][]interface{}{
  2589  			{0, false},
  2590  		}
  2591  		roleIdsInMoRolePrivs := []int{0, 1, 2}
  2592  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2593  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2594  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2595  		}
  2596  
  2597  		//role 0 without privilege create database, all, ownership
  2598  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  2599  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2600  
  2601  		//role 1 without privilege create database, all, ownership
  2602  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  2603  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  2604  
  2605  		//role 2 without privilege create database, all, ownership
  2606  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  2607  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  2608  
  2609  		roleIdsInMoRoleGrant := []int{0, 1, 2}
  2610  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  2611  		//grant role 1 to role 0
  2612  		rowsOfMoRoleGrant[0] = [][]interface{}{
  2613  			{1, true},
  2614  		}
  2615  		//grant role 2 to role 1
  2616  		rowsOfMoRoleGrant[1] = [][]interface{}{
  2617  			{2, true},
  2618  		}
  2619  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  2620  
  2621  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  2622  
  2623  		bh := newBh(ctrl, sql2result)
  2624  
  2625  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2626  		defer bhStub.Reset()
  2627  
  2628  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2629  		convey.So(err, convey.ShouldBeNil)
  2630  		convey.So(ok, convey.ShouldBeFalse)
  2631  	})
  2632  }
  2633  
  2634  func Test_determineDropDatabase(t *testing.T) {
  2635  	convey.Convey("drop/alter database succ", t, func() {
  2636  		ctrl := gomock.NewController(t)
  2637  		defer ctrl.Finish()
  2638  
  2639  		stmt := &tree.DropDatabase{}
  2640  		priv := determinePrivilegeSetOfStatement(stmt)
  2641  		ses := newSes(priv, ctrl)
  2642  
  2643  		rowsOfMoUserGrant := [][]interface{}{
  2644  			{0, false},
  2645  		}
  2646  		roleIdsInMoRolePrivs := []int{0}
  2647  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2648  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2649  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2650  		}
  2651  
  2652  		//with privilege drop database
  2653  		rowsOfMoRolePrivs[0][0] = [][]interface{}{
  2654  			{0, true},
  2655  		}
  2656  		//without privilege all
  2657  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2658  
  2659  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
  2660  
  2661  		bh := newBh(ctrl, sql2result)
  2662  
  2663  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2664  		defer bhStub.Reset()
  2665  
  2666  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2667  		convey.So(err, convey.ShouldBeNil)
  2668  		convey.So(ok, convey.ShouldBeTrue)
  2669  	})
  2670  	convey.Convey("drop/alter database succ 2", t, func() {
  2671  		ctrl := gomock.NewController(t)
  2672  		defer ctrl.Finish()
  2673  
  2674  		stmt := &tree.DropDatabase{}
  2675  		priv := determinePrivilegeSetOfStatement(stmt)
  2676  		ses := newSes(priv, ctrl)
  2677  
  2678  		rowsOfMoUserGrant := [][]interface{}{
  2679  			{0, false},
  2680  		}
  2681  		roleIdsInMoRolePrivs := []int{0, 1}
  2682  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2683  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2684  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2685  		}
  2686  
  2687  		//role 0 without privilege drop database, all, account/user ownership
  2688  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  2689  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2690  
  2691  		//role 1 with privilege drop database
  2692  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  2693  			{1, true},
  2694  		}
  2695  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  2696  
  2697  		//grant role 1 to role 0
  2698  		roleIdsInMoRoleGrant := []int{0}
  2699  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  2700  		rowsOfMoRoleGrant[0] = [][]interface{}{
  2701  			{1, true},
  2702  		}
  2703  
  2704  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  2705  
  2706  		bh := newBh(ctrl, sql2result)
  2707  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2708  		defer bhStub.Reset()
  2709  
  2710  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2711  		convey.So(err, convey.ShouldBeNil)
  2712  		convey.So(ok, convey.ShouldBeTrue)
  2713  	})
  2714  	convey.Convey("drop/alter database fail", t, func() {
  2715  		ctrl := gomock.NewController(t)
  2716  		defer ctrl.Finish()
  2717  
  2718  		stmt := &tree.DropDatabase{}
  2719  		priv := determinePrivilegeSetOfStatement(stmt)
  2720  		ses := newSes(priv, ctrl)
  2721  
  2722  		rowsOfMoUserGrant := [][]interface{}{
  2723  			{0, false},
  2724  		}
  2725  		roleIdsInMoRolePrivs := []int{0, 1, 2}
  2726  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2727  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2728  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2729  		}
  2730  
  2731  		//role 0 without privilege drop database, all, ownership
  2732  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  2733  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2734  
  2735  		//role 1 without privilege drop database, all, ownership
  2736  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  2737  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  2738  
  2739  		//role 2 without privilege drop database, all, ownership
  2740  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  2741  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  2742  
  2743  		roleIdsInMoRoleGrant := []int{0, 1, 2}
  2744  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  2745  		//grant role 1 to role 0
  2746  		rowsOfMoRoleGrant[0] = [][]interface{}{
  2747  			{1, true},
  2748  		}
  2749  		//grant role 2 to role 1
  2750  		rowsOfMoRoleGrant[1] = [][]interface{}{
  2751  			{2, true},
  2752  		}
  2753  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  2754  
  2755  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  2756  		bh := newBh(ctrl, sql2result)
  2757  
  2758  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2759  		defer bhStub.Reset()
  2760  
  2761  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2762  		convey.So(err, convey.ShouldBeNil)
  2763  		convey.So(ok, convey.ShouldBeFalse)
  2764  	})
  2765  }
  2766  
  2767  func Test_determineShowDatabase(t *testing.T) {
  2768  	convey.Convey("show database succ", t, func() {
  2769  		ctrl := gomock.NewController(t)
  2770  		defer ctrl.Finish()
  2771  
  2772  		stmt := &tree.ShowDatabases{}
  2773  		priv := determinePrivilegeSetOfStatement(stmt)
  2774  		ses := newSes(priv, ctrl)
  2775  
  2776  		rowsOfMoUserGrant := [][]interface{}{
  2777  			{0, false},
  2778  		}
  2779  		roleIdsInMoRolePrivs := []int{0}
  2780  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2781  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2782  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2783  		}
  2784  
  2785  		//with privilege show databases
  2786  		rowsOfMoRolePrivs[0][0] = [][]interface{}{
  2787  			{0, true},
  2788  		}
  2789  		//without privilege all
  2790  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2791  
  2792  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
  2793  
  2794  		bh := newBh(ctrl, sql2result)
  2795  
  2796  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2797  		defer bhStub.Reset()
  2798  
  2799  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2800  		convey.So(err, convey.ShouldBeNil)
  2801  		convey.So(ok, convey.ShouldBeTrue)
  2802  	})
  2803  	convey.Convey("show database succ 2", t, func() {
  2804  		ctrl := gomock.NewController(t)
  2805  		defer ctrl.Finish()
  2806  
  2807  		stmt := &tree.ShowDatabases{}
  2808  		priv := determinePrivilegeSetOfStatement(stmt)
  2809  		ses := newSes(priv, ctrl)
  2810  
  2811  		rowsOfMoUserGrant := [][]interface{}{
  2812  			{0, false},
  2813  		}
  2814  		roleIdsInMoRolePrivs := []int{0, 1}
  2815  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2816  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2817  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2818  		}
  2819  
  2820  		//role 0 without privilege show databases, all, account/user ownership
  2821  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  2822  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2823  
  2824  		//role 1 with privilege show databases
  2825  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  2826  			{1, true},
  2827  		}
  2828  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  2829  
  2830  		//grant role 1 to role 0
  2831  		roleIdsInMoRoleGrant := []int{0}
  2832  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  2833  		rowsOfMoRoleGrant[0] = [][]interface{}{
  2834  			{1, true},
  2835  		}
  2836  
  2837  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  2838  
  2839  		bh := newBh(ctrl, sql2result)
  2840  
  2841  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2842  		defer bhStub.Reset()
  2843  
  2844  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2845  		convey.So(err, convey.ShouldBeNil)
  2846  		convey.So(ok, convey.ShouldBeTrue)
  2847  	})
  2848  	convey.Convey("show database fail", t, func() {
  2849  		ctrl := gomock.NewController(t)
  2850  		defer ctrl.Finish()
  2851  
  2852  		stmt := &tree.ShowDatabases{}
  2853  		priv := determinePrivilegeSetOfStatement(stmt)
  2854  		ses := newSes(priv, ctrl)
  2855  
  2856  		rowsOfMoUserGrant := [][]interface{}{
  2857  			{0, false},
  2858  		}
  2859  		roleIdsInMoRolePrivs := []int{0, 1, 2}
  2860  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2861  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2862  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2863  		}
  2864  
  2865  		//role 0 without privilege show databases, all, ownership
  2866  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  2867  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2868  
  2869  		//role 1 without privilege show databases, all, ownership
  2870  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  2871  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  2872  
  2873  		//role 2 without privilege show databases, all, ownership
  2874  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  2875  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  2876  
  2877  		roleIdsInMoRoleGrant := []int{0, 1, 2}
  2878  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  2879  		//grant role 1 to role 0
  2880  		rowsOfMoRoleGrant[0] = [][]interface{}{
  2881  			{1, true},
  2882  		}
  2883  		//grant role 2 to role 1
  2884  		rowsOfMoRoleGrant[1] = [][]interface{}{
  2885  			{2, true},
  2886  		}
  2887  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  2888  
  2889  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  2890  
  2891  		bh := newBh(ctrl, sql2result)
  2892  
  2893  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2894  		defer bhStub.Reset()
  2895  
  2896  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2897  		convey.So(err, convey.ShouldBeNil)
  2898  		convey.So(ok, convey.ShouldBeFalse)
  2899  	})
  2900  }
  2901  
  2902  func Test_determineUseDatabase(t *testing.T) {
  2903  	convey.Convey("use database succ", t, func() {
  2904  		ctrl := gomock.NewController(t)
  2905  		defer ctrl.Finish()
  2906  
  2907  		stmt := &tree.Use{
  2908  			Name: tree.NewCStr("db", 1),
  2909  		}
  2910  		priv := determinePrivilegeSetOfStatement(stmt)
  2911  		ses := newSes(priv, ctrl)
  2912  
  2913  		rowsOfMoUserGrant := [][]interface{}{
  2914  			{0, false},
  2915  		}
  2916  		roleIdsInMoRolePrivs := []int{0}
  2917  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2918  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2919  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2920  		}
  2921  
  2922  		//with privilege show databases
  2923  		rowsOfMoRolePrivs[0][0] = [][]interface{}{
  2924  			{0, true},
  2925  		}
  2926  		//without privilege all
  2927  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2928  
  2929  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
  2930  
  2931  		bh := newBh(ctrl, sql2result)
  2932  
  2933  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2934  		defer bhStub.Reset()
  2935  
  2936  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2937  		convey.So(err, convey.ShouldBeNil)
  2938  		convey.So(ok, convey.ShouldBeTrue)
  2939  	})
  2940  	convey.Convey("use database succ 2", t, func() {
  2941  		ctrl := gomock.NewController(t)
  2942  		defer ctrl.Finish()
  2943  
  2944  		stmt := &tree.Use{
  2945  			Name: tree.NewCStr("db", 1),
  2946  		}
  2947  		priv := determinePrivilegeSetOfStatement(stmt)
  2948  		ses := newSes(priv, ctrl)
  2949  
  2950  		rowsOfMoUserGrant := [][]interface{}{
  2951  			{0, false},
  2952  		}
  2953  		roleIdsInMoRolePrivs := []int{0, 1}
  2954  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  2955  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  2956  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  2957  		}
  2958  
  2959  		//role 0 without privilege show databases, all, account/user ownership
  2960  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  2961  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  2962  
  2963  		//role 1 with privilege show databases
  2964  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  2965  			{1, true},
  2966  		}
  2967  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  2968  
  2969  		//grant role 1 to role 0
  2970  		roleIdsInMoRoleGrant := []int{0}
  2971  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  2972  		rowsOfMoRoleGrant[0] = [][]interface{}{
  2973  			{1, true},
  2974  		}
  2975  
  2976  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  2977  
  2978  		bh := newBh(ctrl, sql2result)
  2979  
  2980  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  2981  		defer bhStub.Reset()
  2982  
  2983  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  2984  		convey.So(err, convey.ShouldBeNil)
  2985  		convey.So(ok, convey.ShouldBeTrue)
  2986  	})
  2987  	convey.Convey("use database fail", t, func() {
  2988  		ctrl := gomock.NewController(t)
  2989  		defer ctrl.Finish()
  2990  
  2991  		stmt := &tree.Use{
  2992  			Name: tree.NewCStr("db", 1),
  2993  		}
  2994  		priv := determinePrivilegeSetOfStatement(stmt)
  2995  		ses := newSes(priv, ctrl)
  2996  
  2997  		rowsOfMoUserGrant := [][]interface{}{
  2998  			{0, false},
  2999  		}
  3000  		roleIdsInMoRolePrivs := []int{0, 1, 2}
  3001  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  3002  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  3003  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  3004  		}
  3005  
  3006  		//role 0 without privilege show databases, all, ownership
  3007  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  3008  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  3009  
  3010  		//role 1 without privilege show databases, all, ownership
  3011  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  3012  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  3013  
  3014  		//role 2 without privilege show databases, all, ownership
  3015  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  3016  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  3017  
  3018  		roleIdsInMoRoleGrant := []int{0, 1, 2}
  3019  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  3020  		//grant role 1 to role 0
  3021  		rowsOfMoRoleGrant[0] = [][]interface{}{
  3022  			{1, true},
  3023  		}
  3024  		//grant role 2 to role 1
  3025  		rowsOfMoRoleGrant[1] = [][]interface{}{
  3026  			{2, true},
  3027  		}
  3028  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  3029  
  3030  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  3031  
  3032  		bh := newBh(ctrl, sql2result)
  3033  
  3034  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3035  		defer bhStub.Reset()
  3036  
  3037  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  3038  		convey.So(err, convey.ShouldBeNil)
  3039  		convey.So(ok, convey.ShouldBeFalse)
  3040  	})
  3041  }
  3042  
  3043  func Test_determineUseRole(t *testing.T) {
  3044  	//TODO:add ut
  3045  }
  3046  
  3047  func Test_determineCreateTable(t *testing.T) {
  3048  	convey.Convey("create table succ", t, func() {
  3049  		ctrl := gomock.NewController(t)
  3050  		defer ctrl.Finish()
  3051  
  3052  		stmt := &tree.CreateTable{}
  3053  		priv := determinePrivilegeSetOfStatement(stmt)
  3054  		ses := newSes(priv, ctrl)
  3055  
  3056  		rowsOfMoUserGrant := [][]interface{}{
  3057  			{0, false},
  3058  		}
  3059  		roleIdsInMoRolePrivs := []int{0}
  3060  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  3061  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  3062  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  3063  		}
  3064  
  3065  		//without privilege create table, all
  3066  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  3067  		rowsOfMoRolePrivs[0][1] = [][]interface{}{
  3068  			{0, true},
  3069  		}
  3070  
  3071  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
  3072  
  3073  		var rows [][]interface{}
  3074  		roles := []int{0}
  3075  		for _, entry := range priv.entries {
  3076  			pls, err := getPrivilegeLevelsOfObjectType(context.TODO(), entry.objType)
  3077  			convey.So(err, convey.ShouldBeNil)
  3078  			for _, pl := range pls {
  3079  				for _, roleId := range roles {
  3080  					sql, err := getSqlForPrivilege(context.TODO(), int64(roleId), entry, pl)
  3081  					convey.So(err, convey.ShouldBeNil)
  3082  					if entry.privilegeId == PrivilegeTypeCreateTable {
  3083  						rows = [][]interface{}{
  3084  							{0, true},
  3085  						}
  3086  					} else {
  3087  						rows = [][]interface{}{}
  3088  					}
  3089  					sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3090  				}
  3091  			}
  3092  		}
  3093  
  3094  		sql := getSqlForInheritedRoleIdOfRoleId(0)
  3095  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{})
  3096  
  3097  		bh := newBh(ctrl, sql2result)
  3098  
  3099  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3100  		defer bhStub.Reset()
  3101  
  3102  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  3103  		convey.So(err, convey.ShouldBeNil)
  3104  		convey.So(ok, convey.ShouldBeTrue)
  3105  	})
  3106  
  3107  	convey.Convey("create table succ 2", t, func() {
  3108  		ctrl := gomock.NewController(t)
  3109  		defer ctrl.Finish()
  3110  
  3111  		stmt := &tree.CreateTable{}
  3112  		priv := determinePrivilegeSetOfStatement(stmt)
  3113  		ses := newSes(priv, ctrl)
  3114  
  3115  		rowsOfMoUserGrant := [][]interface{}{
  3116  			{0, false},
  3117  		}
  3118  		roleIdsInMoRolePrivs := []int{0, 1}
  3119  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  3120  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  3121  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  3122  		}
  3123  
  3124  		//role 0 without privilege create table, all, ownership
  3125  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  3126  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  3127  
  3128  		//role 1 with privilege create table
  3129  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  3130  			{1, true},
  3131  		}
  3132  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  3133  
  3134  		//grant role 1 to role 0
  3135  		roleIdsInMoRoleGrant := []int{0}
  3136  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  3137  		rowsOfMoRoleGrant[0] = [][]interface{}{
  3138  			{1, true},
  3139  		}
  3140  
  3141  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  3142  
  3143  		var rows [][]interface{}
  3144  		roles := []int{0, 1}
  3145  		for _, entry := range priv.entries {
  3146  			pls, err := getPrivilegeLevelsOfObjectType(context.TODO(), entry.objType)
  3147  			convey.So(err, convey.ShouldBeNil)
  3148  			for _, pl := range pls {
  3149  				for _, roleId := range roles {
  3150  					sql, err := getSqlForPrivilege(context.TODO(), int64(roleId), entry, pl)
  3151  					convey.So(err, convey.ShouldBeNil)
  3152  					if roleId == 1 && entry.privilegeId == PrivilegeTypeCreateTable {
  3153  						rows = [][]interface{}{
  3154  							{1, true},
  3155  						}
  3156  					} else {
  3157  						rows = [][]interface{}{}
  3158  					}
  3159  					sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3160  				}
  3161  			}
  3162  		}
  3163  
  3164  		sql := getSqlForInheritedRoleIdOfRoleId(0)
  3165  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{
  3166  			{1, true},
  3167  		})
  3168  		sql = getSqlForInheritedRoleIdOfRoleId(1)
  3169  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{})
  3170  
  3171  		bh := newBh(ctrl, sql2result)
  3172  
  3173  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3174  		defer bhStub.Reset()
  3175  
  3176  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  3177  		convey.So(err, convey.ShouldBeNil)
  3178  		convey.So(ok, convey.ShouldBeTrue)
  3179  	})
  3180  
  3181  	convey.Convey("create table fail", t, func() {
  3182  		ctrl := gomock.NewController(t)
  3183  		defer ctrl.Finish()
  3184  
  3185  		stmt := &tree.CreateTable{}
  3186  		priv := determinePrivilegeSetOfStatement(stmt)
  3187  		ses := newSes(priv, ctrl)
  3188  
  3189  		rowsOfMoUserGrant := [][]interface{}{
  3190  			{0, false},
  3191  		}
  3192  		roleIdsInMoRolePrivs := []int{0, 1, 2}
  3193  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  3194  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  3195  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  3196  		}
  3197  
  3198  		//role 0 without privilege create table, all, ownership
  3199  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  3200  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  3201  
  3202  		//role 1 without privilege create table, all, ownership
  3203  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  3204  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  3205  
  3206  		//role 2 without privilege create table, all, ownership
  3207  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  3208  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  3209  
  3210  		roleIdsInMoRoleGrant := []int{0, 1, 2}
  3211  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  3212  		//grant role 1 to role 0
  3213  		rowsOfMoRoleGrant[0] = [][]interface{}{
  3214  			{1, true},
  3215  		}
  3216  		//grant role 2 to role 1
  3217  		rowsOfMoRoleGrant[1] = [][]interface{}{
  3218  			{2, true},
  3219  		}
  3220  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  3221  
  3222  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  3223  
  3224  		var rows [][]interface{}
  3225  		roles := []int{0, 1, 2}
  3226  		for _, entry := range priv.entries {
  3227  			pls, err := getPrivilegeLevelsOfObjectType(context.TODO(), entry.objType)
  3228  			convey.So(err, convey.ShouldBeNil)
  3229  			for _, pl := range pls {
  3230  				for _, roleId := range roles {
  3231  					sql, err := getSqlForPrivilege(context.TODO(), int64(roleId), entry, pl)
  3232  					convey.So(err, convey.ShouldBeNil)
  3233  					rows = [][]interface{}{}
  3234  					sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3235  				}
  3236  			}
  3237  		}
  3238  
  3239  		sql := getSqlForInheritedRoleIdOfRoleId(0)
  3240  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{
  3241  			{1, true},
  3242  		})
  3243  		sql = getSqlForInheritedRoleIdOfRoleId(1)
  3244  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{
  3245  			{2, true},
  3246  		})
  3247  		sql = getSqlForInheritedRoleIdOfRoleId(2)
  3248  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{})
  3249  
  3250  		bh := newBh(ctrl, sql2result)
  3251  
  3252  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3253  		defer bhStub.Reset()
  3254  
  3255  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  3256  		convey.So(err, convey.ShouldBeNil)
  3257  		convey.So(ok, convey.ShouldBeFalse)
  3258  	})
  3259  }
  3260  
  3261  func Test_determineDropTable(t *testing.T) {
  3262  	convey.Convey("drop/alter table succ", t, func() {
  3263  		ctrl := gomock.NewController(t)
  3264  		defer ctrl.Finish()
  3265  
  3266  		stmt := &tree.DropTable{}
  3267  		priv := determinePrivilegeSetOfStatement(stmt)
  3268  		ses := newSes(priv, ctrl)
  3269  
  3270  		rowsOfMoUserGrant := [][]interface{}{
  3271  			{0, false},
  3272  		}
  3273  		roleIdsInMoRolePrivs := []int{0}
  3274  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  3275  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  3276  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  3277  		}
  3278  
  3279  		//with privilege drop table
  3280  		rowsOfMoRolePrivs[0][0] = [][]interface{}{
  3281  			{0, true},
  3282  		}
  3283  		//without privilege all
  3284  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  3285  
  3286  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, nil, nil, nil, nil)
  3287  
  3288  		var rows [][]interface{}
  3289  		roles := []int{0}
  3290  		for _, entry := range priv.entries {
  3291  			pls, err := getPrivilegeLevelsOfObjectType(context.TODO(), entry.objType)
  3292  			convey.So(err, convey.ShouldBeNil)
  3293  			for _, pl := range pls {
  3294  				for _, roleId := range roles {
  3295  					sql, err := getSqlForPrivilege(context.TODO(), int64(roleId), entry, pl)
  3296  					convey.So(err, convey.ShouldBeNil)
  3297  					if entry.privilegeId == PrivilegeTypeDropTable {
  3298  						rows = [][]interface{}{
  3299  							{0, true},
  3300  						}
  3301  					} else {
  3302  						rows = [][]interface{}{}
  3303  					}
  3304  					sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3305  				}
  3306  			}
  3307  		}
  3308  
  3309  		sql := getSqlForInheritedRoleIdOfRoleId(0)
  3310  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{})
  3311  
  3312  		bh := newBh(ctrl, sql2result)
  3313  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3314  		defer bhStub.Reset()
  3315  
  3316  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  3317  		convey.So(err, convey.ShouldBeNil)
  3318  		convey.So(ok, convey.ShouldBeTrue)
  3319  	})
  3320  
  3321  	convey.Convey("drop/alter table succ 2", t, func() {
  3322  		ctrl := gomock.NewController(t)
  3323  		defer ctrl.Finish()
  3324  
  3325  		stmt := &tree.DropTable{}
  3326  		priv := determinePrivilegeSetOfStatement(stmt)
  3327  		ses := newSes(priv, ctrl)
  3328  
  3329  		rowsOfMoUserGrant := [][]interface{}{
  3330  			{0, false},
  3331  		}
  3332  		roleIdsInMoRolePrivs := []int{0, 1}
  3333  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  3334  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  3335  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  3336  		}
  3337  
  3338  		//role 0 without privilege drop table, all, account/user ownership
  3339  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  3340  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  3341  
  3342  		//role 1 with privilege drop table
  3343  		rowsOfMoRolePrivs[1][0] = [][]interface{}{
  3344  			{1, true},
  3345  		}
  3346  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  3347  
  3348  		//grant role 1 to role 0
  3349  		roleIdsInMoRoleGrant := []int{0}
  3350  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  3351  		rowsOfMoRoleGrant[0] = [][]interface{}{
  3352  			{1, true},
  3353  		}
  3354  
  3355  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  3356  
  3357  		var rows [][]interface{}
  3358  		roles := []int{0, 1}
  3359  		for _, entry := range priv.entries {
  3360  			pls, err := getPrivilegeLevelsOfObjectType(context.TODO(), entry.objType)
  3361  			convey.So(err, convey.ShouldBeNil)
  3362  			for _, pl := range pls {
  3363  				for _, roleId := range roles {
  3364  					sql, err := getSqlForPrivilege(context.TODO(), int64(roleId), entry, pl)
  3365  					convey.So(err, convey.ShouldBeNil)
  3366  					if roleId == 1 && entry.privilegeId == PrivilegeTypeDropTable {
  3367  						rows = [][]interface{}{
  3368  							{1, true},
  3369  						}
  3370  					} else {
  3371  						rows = [][]interface{}{}
  3372  					}
  3373  					sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3374  				}
  3375  			}
  3376  		}
  3377  
  3378  		sql := getSqlForInheritedRoleIdOfRoleId(0)
  3379  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{
  3380  			{1, true},
  3381  		})
  3382  		sql = getSqlForInheritedRoleIdOfRoleId(1)
  3383  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{})
  3384  
  3385  		bh := newBh(ctrl, sql2result)
  3386  
  3387  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3388  		defer bhStub.Reset()
  3389  
  3390  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  3391  		convey.So(err, convey.ShouldBeNil)
  3392  		convey.So(ok, convey.ShouldBeTrue)
  3393  	})
  3394  
  3395  	convey.Convey("drop/alter table fail", t, func() {
  3396  		ctrl := gomock.NewController(t)
  3397  		defer ctrl.Finish()
  3398  
  3399  		stmt := &tree.DropTable{}
  3400  		priv := determinePrivilegeSetOfStatement(stmt)
  3401  		ses := newSes(priv, ctrl)
  3402  
  3403  		rowsOfMoUserGrant := [][]interface{}{
  3404  			{0, false},
  3405  		}
  3406  		roleIdsInMoRolePrivs := []int{0, 1, 2}
  3407  		rowsOfMoRolePrivs := make([][][][]interface{}, len(roleIdsInMoRolePrivs))
  3408  		for i := 0; i < len(roleIdsInMoRolePrivs); i++ {
  3409  			rowsOfMoRolePrivs[i] = make([][][]interface{}, len(priv.entries))
  3410  		}
  3411  
  3412  		//role 0 without privilege drop table, all, ownership
  3413  		rowsOfMoRolePrivs[0][0] = [][]interface{}{}
  3414  		rowsOfMoRolePrivs[0][1] = [][]interface{}{}
  3415  
  3416  		//role 1 without privilege drop table, all, ownership
  3417  		rowsOfMoRolePrivs[1][0] = [][]interface{}{}
  3418  		rowsOfMoRolePrivs[1][1] = [][]interface{}{}
  3419  
  3420  		//role 2 without privilege drop table, all, ownership
  3421  		rowsOfMoRolePrivs[2][0] = [][]interface{}{}
  3422  		rowsOfMoRolePrivs[2][1] = [][]interface{}{}
  3423  
  3424  		roleIdsInMoRoleGrant := []int{0, 1, 2}
  3425  		rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  3426  		//grant role 1 to role 0
  3427  		rowsOfMoRoleGrant[0] = [][]interface{}{
  3428  			{1, true},
  3429  		}
  3430  		//grant role 2 to role 1
  3431  		rowsOfMoRoleGrant[1] = [][]interface{}{
  3432  			{2, true},
  3433  		}
  3434  		rowsOfMoRoleGrant[2] = [][]interface{}{}
  3435  
  3436  		sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, roleIdsInMoRolePrivs, priv.entries, rowsOfMoRolePrivs, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  3437  
  3438  		var rows [][]interface{}
  3439  		roles := []int{0, 1, 2}
  3440  		for _, entry := range priv.entries {
  3441  			pls, err := getPrivilegeLevelsOfObjectType(context.TODO(), entry.objType)
  3442  			convey.So(err, convey.ShouldBeNil)
  3443  			for _, pl := range pls {
  3444  				for _, roleId := range roles {
  3445  					sql, err := getSqlForPrivilege(context.TODO(), int64(roleId), entry, pl)
  3446  					convey.So(err, convey.ShouldBeNil)
  3447  					rows = [][]interface{}{}
  3448  					sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3449  				}
  3450  			}
  3451  		}
  3452  
  3453  		sql := getSqlForInheritedRoleIdOfRoleId(0)
  3454  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{
  3455  			{1, true},
  3456  		})
  3457  		sql = getSqlForInheritedRoleIdOfRoleId(1)
  3458  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{
  3459  			{2, true},
  3460  		})
  3461  		sql = getSqlForInheritedRoleIdOfRoleId(2)
  3462  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{})
  3463  
  3464  		bh := newBh(ctrl, sql2result)
  3465  
  3466  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3467  		defer bhStub.Reset()
  3468  
  3469  		ok, err := authenticateUserCanExecuteStatementWithObjectTypeAccountAndDatabase(ses.GetTxnHandler().GetTxnCtx(), ses, nil)
  3470  		convey.So(err, convey.ShouldBeNil)
  3471  		convey.So(ok, convey.ShouldBeFalse)
  3472  	})
  3473  }
  3474  
  3475  func Test_determineDML(t *testing.T) {
  3476  	type arg struct {
  3477  		stmt tree.Statement
  3478  		p    *plan2.Plan
  3479  	}
  3480  
  3481  	args := []arg{
  3482  		{
  3483  			stmt: &tree.Select{},
  3484  			p: &plan2.Plan{
  3485  				Plan: &plan2.Plan_Query{
  3486  					Query: &plan2.Query{
  3487  						Nodes: []*plan2.Node{
  3488  							{NodeType: plan.Node_TABLE_SCAN, ObjRef: &plan2.ObjectRef{SchemaName: "t", ObjName: "a"}},
  3489  							{NodeType: plan.Node_TABLE_SCAN, ObjRef: &plan2.ObjectRef{SchemaName: "s", ObjName: "b"}},
  3490  						},
  3491  					},
  3492  				},
  3493  			},
  3494  		},
  3495  		{
  3496  			stmt: &tree.Update{},
  3497  			p: &plan2.Plan{
  3498  				Plan: &plan2.Plan_Query{
  3499  					Query: &plan2.Query{
  3500  						Nodes: []*plan2.Node{
  3501  							{NodeType: plan.Node_TABLE_SCAN, ObjRef: &plan2.ObjectRef{SchemaName: "t", ObjName: "a"}},
  3502  							{NodeType: plan.Node_TABLE_SCAN, ObjRef: &plan2.ObjectRef{SchemaName: "s", ObjName: "b"}},
  3503  							{NodeType: plan.Node_INSERT},
  3504  						},
  3505  					},
  3506  				},
  3507  			},
  3508  		},
  3509  		{
  3510  			stmt: &tree.Delete{},
  3511  			p: &plan2.Plan{
  3512  				Plan: &plan2.Plan_Query{
  3513  					Query: &plan2.Query{
  3514  						Nodes: []*plan2.Node{
  3515  							{NodeType: plan.Node_TABLE_SCAN, ObjRef: &plan2.ObjectRef{SchemaName: "t", ObjName: "a"}},
  3516  							{NodeType: plan.Node_TABLE_SCAN, ObjRef: &plan2.ObjectRef{SchemaName: "s", ObjName: "b"}},
  3517  							{NodeType: plan.Node_DELETE},
  3518  						},
  3519  					},
  3520  				},
  3521  			},
  3522  		},
  3523  		{ //insert into select
  3524  			stmt: &tree.Insert{},
  3525  			p: &plan2.Plan{
  3526  				Plan: &plan2.Plan_Query{
  3527  					Query: &plan2.Query{
  3528  						Nodes: []*plan2.Node{
  3529  							{NodeType: plan.Node_TABLE_SCAN, ObjRef: &plan2.ObjectRef{SchemaName: "t", ObjName: "a"}},
  3530  							{NodeType: plan.Node_TABLE_SCAN, ObjRef: &plan2.ObjectRef{SchemaName: "s", ObjName: "b"}},
  3531  							{NodeType: plan.Node_INSERT, ObjRef: &plan2.ObjectRef{SchemaName: "s", ObjName: "b"}},
  3532  						},
  3533  					},
  3534  				},
  3535  			},
  3536  		},
  3537  	}
  3538  
  3539  	convey.Convey("select/update/delete/insert succ", t, func() {
  3540  		ctrl := gomock.NewController(t)
  3541  		defer ctrl.Finish()
  3542  
  3543  		for _, a := range args {
  3544  			priv := determinePrivilegeSetOfStatement(a.stmt)
  3545  			ses := newSes(priv, ctrl)
  3546  
  3547  			rowsOfMoUserGrant := [][]interface{}{
  3548  				{0, false},
  3549  			}
  3550  
  3551  			sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, nil, nil, nil, nil, nil, nil, nil)
  3552  
  3553  			arr := extractPrivilegeTipsFromPlan(a.p)
  3554  			convertPrivilegeTipsToPrivilege(priv, arr)
  3555  
  3556  			roleIds := []int{
  3557  				int(ses.GetTenantInfo().GetDefaultRoleID()),
  3558  			}
  3559  
  3560  			for _, roleId := range roleIds {
  3561  				for _, entry := range priv.entries {
  3562  					sql, _ := getSqlForCheckRoleHasTableLevelPrivilege(context.TODO(), int64(roleId), entry.privilegeId, entry.databaseName, entry.tableName)
  3563  					sql2result[sql] = newMrsForWithGrantOptionPrivilege([][]interface{}{
  3564  						{entry.privilegeId, true},
  3565  					})
  3566  				}
  3567  			}
  3568  
  3569  			var rows [][]interface{}
  3570  			makeSql := func(entry privilegeEntry) {
  3571  				pls, err := getPrivilegeLevelsOfObjectType(context.TODO(), entry.objType)
  3572  				convey.So(err, convey.ShouldBeNil)
  3573  				for i, pl := range pls {
  3574  					for _, roleId := range roleIds {
  3575  						sql, err := getSqlForPrivilege(context.TODO(), int64(roleId), entry, pl)
  3576  						convey.So(err, convey.ShouldBeNil)
  3577  						if i == 0 {
  3578  							rows = [][]interface{}{
  3579  								{0, true},
  3580  							}
  3581  						} else {
  3582  							rows = [][]interface{}{}
  3583  						}
  3584  						sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3585  					}
  3586  				}
  3587  			}
  3588  			for _, entry := range priv.entries {
  3589  				if entry.privilegeEntryTyp == privilegeEntryTypeGeneral {
  3590  					makeSql(entry)
  3591  				} else if entry.privilegeEntryTyp == privilegeEntryTypeCompound {
  3592  					for _, mi := range entry.compound.items {
  3593  						tempEntry := privilegeEntriesMap[mi.privilegeTyp]
  3594  						tempEntry.databaseName = mi.dbName
  3595  						tempEntry.tableName = mi.tableName
  3596  						tempEntry.privilegeEntryTyp = privilegeEntryTypeGeneral
  3597  						tempEntry.compound = nil
  3598  						makeSql(tempEntry)
  3599  					}
  3600  				}
  3601  			}
  3602  
  3603  			sql := getSqlForInheritedRoleIdOfRoleId(0)
  3604  			sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{})
  3605  
  3606  			bh := newBh(ctrl, sql2result)
  3607  			bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3608  			defer bhStub.Reset()
  3609  
  3610  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeDatabaseAndTable(ses.GetTxnHandler().GetTxnCtx(), ses, a.stmt, a.p)
  3611  			convey.So(err, convey.ShouldBeNil)
  3612  			convey.So(ok, convey.ShouldBeTrue)
  3613  		}
  3614  
  3615  	})
  3616  
  3617  	convey.Convey("select/update/delete/insert succ 2", t, func() {
  3618  		ctrl := gomock.NewController(t)
  3619  		defer ctrl.Finish()
  3620  
  3621  		for _, a := range args {
  3622  			priv := determinePrivilegeSetOfStatement(a.stmt)
  3623  			ses := newSes(priv, ctrl)
  3624  
  3625  			rowsOfMoUserGrant := [][]interface{}{
  3626  				{0, false},
  3627  			}
  3628  
  3629  			//grant role 1 to role 0
  3630  			roleIdsInMoRoleGrant := []int{0}
  3631  			rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  3632  			rowsOfMoRoleGrant[0] = [][]interface{}{
  3633  				{1, true},
  3634  			}
  3635  
  3636  			sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, nil, nil, nil, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  3637  
  3638  			arr := extractPrivilegeTipsFromPlan(a.p)
  3639  			convertPrivilegeTipsToPrivilege(priv, arr)
  3640  
  3641  			//role 0 does not have the select
  3642  			//role 1 has the select
  3643  			roleIds := []int{
  3644  				int(ses.GetTenantInfo().GetDefaultRoleID()), 1,
  3645  			}
  3646  
  3647  			for _, roleId := range roleIds {
  3648  				for _, entry := range priv.entries {
  3649  					sql, _ := getSqlFromPrivilegeEntry(context.TODO(), int64(roleId), entry)
  3650  					var rows [][]interface{}
  3651  					if roleId == 1 {
  3652  						rows = [][]interface{}{
  3653  							{entry.privilegeId, true},
  3654  						}
  3655  					}
  3656  					sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3657  				}
  3658  			}
  3659  
  3660  			var rows [][]interface{}
  3661  			roles := []int{0, 1}
  3662  			makeSql := func(entry privilegeEntry) {
  3663  				pls, err := getPrivilegeLevelsOfObjectType(context.TODO(), entry.objType)
  3664  				convey.So(err, convey.ShouldBeNil)
  3665  				for _, pl := range pls {
  3666  					for _, roleId := range roles {
  3667  						sql, err := getSqlForPrivilege(context.TODO(), int64(roleId), entry, pl)
  3668  						convey.So(err, convey.ShouldBeNil)
  3669  						if roleId == 1 {
  3670  							rows = [][]interface{}{
  3671  								{1, true},
  3672  							}
  3673  						} else {
  3674  							rows = [][]interface{}{}
  3675  						}
  3676  						sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3677  					}
  3678  				}
  3679  			}
  3680  
  3681  			for _, entry := range priv.entries {
  3682  				if entry.privilegeEntryTyp == privilegeEntryTypeGeneral {
  3683  					makeSql(entry)
  3684  				} else if entry.privilegeEntryTyp == privilegeEntryTypeCompound {
  3685  					for _, mi := range entry.compound.items {
  3686  						tempEntry := privilegeEntriesMap[mi.privilegeTyp]
  3687  						tempEntry.databaseName = mi.dbName
  3688  						tempEntry.tableName = mi.tableName
  3689  						tempEntry.privilegeEntryTyp = privilegeEntryTypeGeneral
  3690  						tempEntry.compound = nil
  3691  						makeSql(tempEntry)
  3692  					}
  3693  				}
  3694  			}
  3695  
  3696  			sql := getSqlForInheritedRoleIdOfRoleId(0)
  3697  			sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{
  3698  				{1, true},
  3699  			})
  3700  			sql = getSqlForInheritedRoleIdOfRoleId(1)
  3701  			sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{})
  3702  
  3703  			bh := newBh(ctrl, sql2result)
  3704  
  3705  			bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3706  			defer bhStub.Reset()
  3707  
  3708  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeDatabaseAndTable(ses.GetTxnHandler().GetTxnCtx(), ses, a.stmt, a.p)
  3709  			convey.So(err, convey.ShouldBeNil)
  3710  			convey.So(ok, convey.ShouldBeTrue)
  3711  		}
  3712  	})
  3713  
  3714  	convey.Convey("select/update/delete/insert fail", t, func() {
  3715  		ctrl := gomock.NewController(t)
  3716  		defer ctrl.Finish()
  3717  
  3718  		for _, a := range args {
  3719  			priv := determinePrivilegeSetOfStatement(a.stmt)
  3720  			ses := newSes(priv, ctrl)
  3721  
  3722  			rowsOfMoUserGrant := [][]interface{}{
  3723  				{0, false},
  3724  			}
  3725  
  3726  			//grant role 1 to role 0
  3727  			roleIdsInMoRoleGrant := []int{0, 1}
  3728  			rowsOfMoRoleGrant := make([][][]interface{}, len(roleIdsInMoRoleGrant))
  3729  			rowsOfMoRoleGrant[0] = [][]interface{}{
  3730  				{1, true},
  3731  			}
  3732  			rowsOfMoRoleGrant[0] = [][]interface{}{}
  3733  
  3734  			sql2result := makeSql2ExecResult2(0, rowsOfMoUserGrant, nil, nil, nil, roleIdsInMoRoleGrant, rowsOfMoRoleGrant, nil, nil)
  3735  
  3736  			arr := extractPrivilegeTipsFromPlan(a.p)
  3737  			convertPrivilegeTipsToPrivilege(priv, arr)
  3738  
  3739  			//role 0,1 does not have the select
  3740  			roleIds := []int{
  3741  				int(ses.GetTenantInfo().GetDefaultRoleID()), 1,
  3742  			}
  3743  
  3744  			for _, roleId := range roleIds {
  3745  				for _, entry := range priv.entries {
  3746  					sql, _ := getSqlFromPrivilegeEntry(context.TODO(), int64(roleId), entry)
  3747  					rows := make([][]interface{}, 0)
  3748  					sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3749  				}
  3750  			}
  3751  
  3752  			var rows [][]interface{}
  3753  			roles := []int{0, 1, 2}
  3754  			makeSql := func(entry privilegeEntry) {
  3755  				pls, err := getPrivilegeLevelsOfObjectType(context.TODO(), entry.objType)
  3756  				convey.So(err, convey.ShouldBeNil)
  3757  				for _, pl := range pls {
  3758  					for _, roleId := range roles {
  3759  						sql, err := getSqlForPrivilege(context.TODO(), int64(roleId), entry, pl)
  3760  						convey.So(err, convey.ShouldBeNil)
  3761  						rows = [][]interface{}{}
  3762  						sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  3763  					}
  3764  				}
  3765  			}
  3766  
  3767  			for _, entry := range priv.entries {
  3768  				if entry.privilegeEntryTyp == privilegeEntryTypeGeneral {
  3769  					makeSql(entry)
  3770  				} else if entry.privilegeEntryTyp == privilegeEntryTypeCompound {
  3771  					for _, mi := range entry.compound.items {
  3772  						tempEntry := privilegeEntriesMap[mi.privilegeTyp]
  3773  						tempEntry.databaseName = mi.dbName
  3774  						tempEntry.tableName = mi.tableName
  3775  						tempEntry.privilegeEntryTyp = privilegeEntryTypeGeneral
  3776  						tempEntry.compound = nil
  3777  						makeSql(tempEntry)
  3778  					}
  3779  				}
  3780  			}
  3781  
  3782  			sql := getSqlForInheritedRoleIdOfRoleId(0)
  3783  			sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{
  3784  				{1, true},
  3785  			})
  3786  			sql = getSqlForInheritedRoleIdOfRoleId(1)
  3787  			sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{
  3788  				{2, true},
  3789  			})
  3790  			sql = getSqlForInheritedRoleIdOfRoleId(2)
  3791  			sql2result[sql] = newMrsForInheritedRoleIdOfRoleId([][]interface{}{})
  3792  
  3793  			bh := newBh(ctrl, sql2result)
  3794  
  3795  			bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3796  			defer bhStub.Reset()
  3797  
  3798  			ok, err := authenticateUserCanExecuteStatementWithObjectTypeDatabaseAndTable(ses.GetTxnHandler().GetTxnCtx(), ses, a.stmt, a.p)
  3799  			convey.So(err, convey.ShouldBeNil)
  3800  			convey.So(ok, convey.ShouldBeFalse)
  3801  		}
  3802  	})
  3803  }
  3804  
  3805  func Test_doGrantRole(t *testing.T) {
  3806  	convey.Convey("grant role to role succ", t, func() {
  3807  		ctrl := gomock.NewController(t)
  3808  		defer ctrl.Finish()
  3809  
  3810  		bh := &backgroundExecTest{}
  3811  		bh.init()
  3812  
  3813  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3814  		defer bhStub.Reset()
  3815  
  3816  		stmt := &tree.GrantRole{
  3817  			Roles: []*tree.Role{
  3818  				{UserName: "r1"},
  3819  				{UserName: "r2"},
  3820  				{UserName: "r3"},
  3821  			},
  3822  			Users: []*tree.User{
  3823  				{Username: "r4"},
  3824  				{Username: "r5"},
  3825  				{Username: "r6"},
  3826  			},
  3827  		}
  3828  		priv := determinePrivilegeSetOfStatement(stmt)
  3829  		ses := newSes(priv, ctrl)
  3830  
  3831  		//no result set
  3832  		bh.sql2result["begin;"] = nil
  3833  		bh.sql2result["commit;"] = nil
  3834  		bh.sql2result["rollback;"] = nil
  3835  
  3836  		//init from roles
  3837  		for i, role := range stmt.Roles {
  3838  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  3839  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  3840  				{i},
  3841  			})
  3842  			bh.sql2result[sql] = mrs
  3843  		}
  3844  
  3845  		//init to roles
  3846  		for i, user := range stmt.Users {
  3847  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  3848  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  3849  				{i + len(stmt.Roles)},
  3850  			})
  3851  
  3852  			bh.sql2result[sql] = mrs
  3853  		}
  3854  
  3855  		//has "ro roles", need init mo_role_grant (assume empty)
  3856  		sql := getSqlForGetAllStuffRoleGrantFormat()
  3857  		mrs := newMrsForGetAllStuffRoleGrant([][]interface{}{})
  3858  
  3859  		bh.sql2result[sql] = mrs
  3860  
  3861  		//loop on from ... to
  3862  		for fromId := range stmt.Roles {
  3863  			for toId := range stmt.Users {
  3864  				toId = toId + len(stmt.Roles)
  3865  				sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  3866  				mrs = newMrsForCheckRoleGrant([][]interface{}{})
  3867  				bh.sql2result[sql] = mrs
  3868  			}
  3869  		}
  3870  
  3871  		err := doGrantRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  3872  		convey.So(err, convey.ShouldBeNil)
  3873  	})
  3874  
  3875  	convey.Convey("grant role to user succ", t, func() {
  3876  		ctrl := gomock.NewController(t)
  3877  		defer ctrl.Finish()
  3878  
  3879  		bh := &backgroundExecTest{}
  3880  		bh.init()
  3881  
  3882  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3883  		defer bhStub.Reset()
  3884  
  3885  		stmt := &tree.GrantRole{
  3886  			Roles: []*tree.Role{
  3887  				{UserName: "r1"},
  3888  				{UserName: "r2"},
  3889  				{UserName: "r3"},
  3890  			},
  3891  			Users: []*tree.User{
  3892  				{Username: "u4"},
  3893  				{Username: "u5"},
  3894  				{Username: "u6"},
  3895  			},
  3896  		}
  3897  		priv := determinePrivilegeSetOfStatement(stmt)
  3898  		ses := newSes(priv, ctrl)
  3899  
  3900  		//no result set
  3901  		bh.sql2result["begin;"] = nil
  3902  		bh.sql2result["commit;"] = nil
  3903  		bh.sql2result["rollback;"] = nil
  3904  
  3905  		//init from roles
  3906  		for i, role := range stmt.Roles {
  3907  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  3908  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  3909  				{i},
  3910  			})
  3911  			bh.sql2result[sql] = mrs
  3912  		}
  3913  
  3914  		//init to empty roles,
  3915  		//init to users
  3916  		for i, user := range stmt.Users {
  3917  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  3918  			mrs := newMrsForRoleIdOfRole([][]interface{}{})
  3919  
  3920  			bh.sql2result[sql] = mrs
  3921  
  3922  			sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  3923  			mrs = newMrsForPasswordOfUser([][]interface{}{
  3924  				{i, "111", i},
  3925  			})
  3926  			bh.sql2result[sql] = mrs
  3927  
  3928  			sql, _ = getSqlForRoleOfUser(context.TODO(), int64(i), moAdminRoleName)
  3929  			bh.sql2result[sql] = newMrsForRoleOfUser([][]interface{}{})
  3930  		}
  3931  
  3932  		//has "ro roles", need init mo_role_grant (assume empty)
  3933  		sql := getSqlForGetAllStuffRoleGrantFormat()
  3934  		mrs := newMrsForGetAllStuffRoleGrant([][]interface{}{})
  3935  
  3936  		bh.sql2result[sql] = mrs
  3937  
  3938  		//loop on from ... to
  3939  		for fromId := range stmt.Roles {
  3940  			for toId := range stmt.Users {
  3941  				sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  3942  				mrs = newMrsForCheckRoleGrant([][]interface{}{})
  3943  				bh.sql2result[sql] = mrs
  3944  
  3945  				sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  3946  				mrs = newMrsForCheckUserGrant([][]interface{}{})
  3947  				bh.sql2result[sql] = mrs
  3948  			}
  3949  		}
  3950  
  3951  		err := doGrantRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  3952  		convey.So(err, convey.ShouldBeNil)
  3953  	})
  3954  
  3955  	convey.Convey("grant role to role+user succ", t, func() {
  3956  		ctrl := gomock.NewController(t)
  3957  		defer ctrl.Finish()
  3958  
  3959  		bh := &backgroundExecTest{}
  3960  		bh.init()
  3961  
  3962  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  3963  		defer bhStub.Reset()
  3964  
  3965  		stmt := &tree.GrantRole{
  3966  			Roles: []*tree.Role{
  3967  				{UserName: "r1"},
  3968  				{UserName: "r2"},
  3969  				{UserName: "r3"},
  3970  			},
  3971  			Users: []*tree.User{
  3972  				{Username: "u4"},
  3973  				{Username: "u5"},
  3974  				{Username: "u6"},
  3975  			},
  3976  		}
  3977  		priv := determinePrivilegeSetOfStatement(stmt)
  3978  		ses := newSes(priv, ctrl)
  3979  
  3980  		//no result set
  3981  		bh.sql2result["begin;"] = nil
  3982  		bh.sql2result["commit;"] = nil
  3983  		bh.sql2result["rollback;"] = nil
  3984  
  3985  		//init from roles
  3986  		for i, role := range stmt.Roles {
  3987  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  3988  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  3989  				{i},
  3990  			})
  3991  			bh.sql2result[sql] = mrs
  3992  		}
  3993  
  3994  		//init to 2 roles,
  3995  		//init to 1 users
  3996  		for i, user := range stmt.Users {
  3997  			if i < 2 { //roles
  3998  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  3999  				mrs := newMrsForRoleIdOfRole([][]interface{}{
  4000  					{i + len(stmt.Roles)},
  4001  				})
  4002  
  4003  				bh.sql2result[sql] = mrs
  4004  
  4005  				sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4006  				mrs = newMrsForPasswordOfUser([][]interface{}{})
  4007  				bh.sql2result[sql] = mrs
  4008  			} else { //users
  4009  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4010  				mrs := newMrsForRoleIdOfRole([][]interface{}{})
  4011  
  4012  				bh.sql2result[sql] = mrs
  4013  
  4014  				sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4015  				mrs = newMrsForPasswordOfUser([][]interface{}{
  4016  					{i, "111", i},
  4017  				})
  4018  				bh.sql2result[sql] = mrs
  4019  
  4020  				sql, _ = getSqlForRoleOfUser(context.TODO(), int64(i), moAdminRoleName)
  4021  				bh.sql2result[sql] = newMrsForRoleOfUser([][]interface{}{})
  4022  			}
  4023  
  4024  		}
  4025  
  4026  		//has "ro roles", need init mo_role_grant (assume empty)
  4027  		sql := getSqlForGetAllStuffRoleGrantFormat()
  4028  		mrs := newMrsForGetAllStuffRoleGrant([][]interface{}{})
  4029  
  4030  		bh.sql2result[sql] = mrs
  4031  
  4032  		//loop on from ... to
  4033  		for fromId := range stmt.Roles {
  4034  			for toId := range stmt.Users {
  4035  				if toId < 2 { //roles
  4036  					toId = toId + len(stmt.Roles)
  4037  					sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4038  					mrs = newMrsForCheckRoleGrant([][]interface{}{})
  4039  					bh.sql2result[sql] = mrs
  4040  
  4041  					sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  4042  					mrs = newMrsForCheckUserGrant([][]interface{}{})
  4043  					bh.sql2result[sql] = mrs
  4044  				} else { //users
  4045  					sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4046  					mrs = newMrsForCheckRoleGrant([][]interface{}{})
  4047  					bh.sql2result[sql] = mrs
  4048  
  4049  					sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  4050  					mrs = newMrsForCheckUserGrant([][]interface{}{})
  4051  					bh.sql2result[sql] = mrs
  4052  				}
  4053  
  4054  			}
  4055  		}
  4056  
  4057  		err := doGrantRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4058  		convey.So(err, convey.ShouldBeNil)
  4059  	})
  4060  
  4061  	convey.Convey("grant role to role+user 2 (insert) succ", t, func() {
  4062  		ctrl := gomock.NewController(t)
  4063  		defer ctrl.Finish()
  4064  
  4065  		bh := &backgroundExecTest{}
  4066  		bh.init()
  4067  
  4068  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4069  		defer bhStub.Reset()
  4070  
  4071  		stmt := &tree.GrantRole{
  4072  			Roles: []*tree.Role{
  4073  				{UserName: "r1"},
  4074  				{UserName: "r2"},
  4075  				{UserName: "r3"},
  4076  			},
  4077  			Users: []*tree.User{
  4078  				{Username: "u4"},
  4079  				{Username: "u5"},
  4080  				{Username: "u6"},
  4081  			},
  4082  		}
  4083  		priv := determinePrivilegeSetOfStatement(stmt)
  4084  		ses := newSes(priv, ctrl)
  4085  
  4086  		//no result set
  4087  		bh.sql2result["begin;"] = nil
  4088  		bh.sql2result["commit;"] = nil
  4089  		bh.sql2result["rollback;"] = nil
  4090  
  4091  		//init from roles
  4092  		for i, role := range stmt.Roles {
  4093  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4094  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4095  				{i},
  4096  			})
  4097  			bh.sql2result[sql] = mrs
  4098  		}
  4099  
  4100  		//init to 2 roles,
  4101  		//init to 1 users
  4102  		for i, user := range stmt.Users {
  4103  			if i < 2 { //roles
  4104  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4105  				mrs := newMrsForRoleIdOfRole([][]interface{}{
  4106  					{i + len(stmt.Roles)},
  4107  				})
  4108  
  4109  				bh.sql2result[sql] = mrs
  4110  
  4111  				sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4112  				mrs = newMrsForPasswordOfUser([][]interface{}{})
  4113  				bh.sql2result[sql] = mrs
  4114  			} else { //users
  4115  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4116  				mrs := newMrsForRoleIdOfRole([][]interface{}{})
  4117  
  4118  				bh.sql2result[sql] = mrs
  4119  
  4120  				sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4121  				mrs = newMrsForPasswordOfUser([][]interface{}{
  4122  					{i, "111", i},
  4123  				})
  4124  				bh.sql2result[sql] = mrs
  4125  
  4126  				sql, _ = getSqlForRoleOfUser(context.TODO(), int64(i), moAdminRoleName)
  4127  				bh.sql2result[sql] = newMrsForRoleOfUser([][]interface{}{})
  4128  			}
  4129  
  4130  		}
  4131  
  4132  		//has "ro roles", need init mo_role_grant (assume empty)
  4133  		sql := getSqlForGetAllStuffRoleGrantFormat()
  4134  		mrs := newMrsForGetAllStuffRoleGrant([][]interface{}{
  4135  			{0, 1, true},
  4136  			{1, 2, true},
  4137  			{3, 4, true},
  4138  		})
  4139  
  4140  		bh.sql2result[sql] = mrs
  4141  
  4142  		//loop on from ... to
  4143  		for fromId := range stmt.Roles {
  4144  			for toId := range stmt.Users {
  4145  				if toId < 2 { //roles
  4146  					toId = toId + len(stmt.Roles)
  4147  					sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4148  					mrs = newMrsForCheckRoleGrant([][]interface{}{})
  4149  					bh.sql2result[sql] = mrs
  4150  
  4151  					sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  4152  					mrs = newMrsForCheckUserGrant([][]interface{}{})
  4153  					bh.sql2result[sql] = mrs
  4154  				} else { //users
  4155  					sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4156  					mrs = newMrsForCheckRoleGrant([][]interface{}{})
  4157  					bh.sql2result[sql] = mrs
  4158  
  4159  					sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  4160  					mrs = newMrsForCheckUserGrant([][]interface{}{})
  4161  					bh.sql2result[sql] = mrs
  4162  				}
  4163  			}
  4164  		}
  4165  
  4166  		err := doGrantRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4167  		convey.So(err, convey.ShouldBeNil)
  4168  	})
  4169  
  4170  	convey.Convey("grant role to role+user 3 (update) succ", t, func() {
  4171  		ctrl := gomock.NewController(t)
  4172  		defer ctrl.Finish()
  4173  
  4174  		bh := &backgroundExecTest{}
  4175  		bh.init()
  4176  
  4177  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4178  		defer bhStub.Reset()
  4179  
  4180  		stmt := &tree.GrantRole{
  4181  			Roles: []*tree.Role{
  4182  				{UserName: "r1"},
  4183  				{UserName: "r2"},
  4184  				{UserName: "r3"},
  4185  			},
  4186  			Users: []*tree.User{
  4187  				{Username: "u4"},
  4188  				{Username: "u5"},
  4189  				{Username: "u6"},
  4190  			},
  4191  			GrantOption: true,
  4192  		}
  4193  		priv := determinePrivilegeSetOfStatement(stmt)
  4194  		ses := newSes(priv, ctrl)
  4195  
  4196  		//no result set
  4197  		bh.sql2result["begin;"] = nil
  4198  		bh.sql2result["commit;"] = nil
  4199  		bh.sql2result["rollback;"] = nil
  4200  
  4201  		//init from roles
  4202  		for i, role := range stmt.Roles {
  4203  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4204  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4205  				{i},
  4206  			})
  4207  			bh.sql2result[sql] = mrs
  4208  		}
  4209  
  4210  		//init to 2 roles,
  4211  		//init to 1 users
  4212  		for i, user := range stmt.Users {
  4213  			if i < 2 { //roles
  4214  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4215  				mrs := newMrsForRoleIdOfRole([][]interface{}{
  4216  					{i + len(stmt.Roles)},
  4217  				})
  4218  
  4219  				bh.sql2result[sql] = mrs
  4220  
  4221  				sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4222  				mrs = newMrsForPasswordOfUser([][]interface{}{})
  4223  				bh.sql2result[sql] = mrs
  4224  			} else { //users
  4225  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4226  				mrs := newMrsForRoleIdOfRole([][]interface{}{})
  4227  
  4228  				bh.sql2result[sql] = mrs
  4229  
  4230  				sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4231  				mrs = newMrsForPasswordOfUser([][]interface{}{
  4232  					{i, "111", i},
  4233  				})
  4234  				bh.sql2result[sql] = mrs
  4235  
  4236  				sql, _ = getSqlForRoleOfUser(context.TODO(), int64(i), moAdminRoleName)
  4237  				bh.sql2result[sql] = newMrsForRoleOfUser([][]interface{}{})
  4238  			}
  4239  
  4240  		}
  4241  
  4242  		//has "ro roles", need init mo_role_grant (assume empty)
  4243  		sql := getSqlForGetAllStuffRoleGrantFormat()
  4244  		mrs := newMrsForGetAllStuffRoleGrant([][]interface{}{
  4245  			{0, 1, true},
  4246  			{1, 2, true},
  4247  			{3, 4, true},
  4248  		})
  4249  
  4250  		bh.sql2result[sql] = mrs
  4251  
  4252  		//loop on from ... to
  4253  		for fromId := range stmt.Roles {
  4254  			for toId := range stmt.Users {
  4255  				if toId < 2 { //roles
  4256  					toId = toId + len(stmt.Roles)
  4257  					sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4258  					mrs = newMrsForCheckRoleGrant([][]interface{}{
  4259  						{fromId, toId, false},
  4260  					})
  4261  					bh.sql2result[sql] = mrs
  4262  
  4263  					//sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  4264  					//mrs = newMrsForCheckUserGrant([][]interface{}{})
  4265  					//bh.sql2result[sql] = mrs
  4266  				} else { //users
  4267  					//sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4268  					//mrs = newMrsForCheckRoleGrant([][]interface{}{})
  4269  					//bh.sql2result[sql] = mrs
  4270  
  4271  					sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  4272  					mrs = newMrsForCheckUserGrant([][]interface{}{
  4273  						{fromId, toId, false},
  4274  					})
  4275  					bh.sql2result[sql] = mrs
  4276  				}
  4277  
  4278  			}
  4279  		}
  4280  
  4281  		err := doGrantRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4282  		convey.So(err, convey.ShouldBeNil)
  4283  	})
  4284  
  4285  	convey.Convey("grant role to role fail direct loop", t, func() {
  4286  		ctrl := gomock.NewController(t)
  4287  		defer ctrl.Finish()
  4288  
  4289  		bh := &backgroundExecTest{}
  4290  		bh.init()
  4291  
  4292  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4293  		defer bhStub.Reset()
  4294  
  4295  		stmt := &tree.GrantRole{
  4296  			Roles: []*tree.Role{
  4297  				{UserName: "r1"},
  4298  			},
  4299  			Users: []*tree.User{
  4300  				{Username: "r1"},
  4301  			},
  4302  		}
  4303  		priv := determinePrivilegeSetOfStatement(stmt)
  4304  		ses := newSes(priv, ctrl)
  4305  
  4306  		//no result set
  4307  		bh.sql2result["begin;"] = nil
  4308  		bh.sql2result["commit;"] = nil
  4309  		bh.sql2result["rollback;"] = nil
  4310  
  4311  		//init from roles
  4312  		for i, role := range stmt.Roles {
  4313  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4314  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4315  				{i},
  4316  			})
  4317  			bh.sql2result[sql] = mrs
  4318  		}
  4319  
  4320  		//init to roles
  4321  		for i, user := range stmt.Users {
  4322  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4323  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4324  				{i + len(stmt.Roles)},
  4325  			})
  4326  
  4327  			bh.sql2result[sql] = mrs
  4328  		}
  4329  
  4330  		//has "ro roles", need init mo_role_grant (assume empty)
  4331  		sql := getSqlForGetAllStuffRoleGrantFormat()
  4332  		mrs := newMrsForGetAllStuffRoleGrant([][]interface{}{})
  4333  
  4334  		bh.sql2result[sql] = mrs
  4335  
  4336  		//loop on from ... to
  4337  		for fromId := range stmt.Roles {
  4338  			for toId := range stmt.Users {
  4339  				toId = toId + len(stmt.Roles)
  4340  				sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4341  				mrs = newMrsForCheckRoleGrant([][]interface{}{})
  4342  				bh.sql2result[sql] = mrs
  4343  			}
  4344  		}
  4345  
  4346  		err := doGrantRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4347  		convey.So(err, convey.ShouldBeError)
  4348  	})
  4349  
  4350  	convey.Convey("grant role to role+user fail indirect loop", t, func() {
  4351  		ctrl := gomock.NewController(t)
  4352  		defer ctrl.Finish()
  4353  
  4354  		bh := &backgroundExecTest{}
  4355  		bh.init()
  4356  
  4357  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4358  		defer bhStub.Reset()
  4359  
  4360  		stmt := &tree.GrantRole{
  4361  			Roles: []*tree.Role{
  4362  				{UserName: "r1"},
  4363  				{UserName: "r2"},
  4364  				{UserName: "r3"},
  4365  			},
  4366  			Users: []*tree.User{
  4367  				{Username: "r4"},
  4368  				{Username: "r5"},
  4369  				{Username: "u6"},
  4370  			},
  4371  			GrantOption: true,
  4372  		}
  4373  		priv := determinePrivilegeSetOfStatement(stmt)
  4374  		ses := newSes(priv, ctrl)
  4375  
  4376  		//no result set
  4377  		bh.sql2result["begin;"] = nil
  4378  		bh.sql2result["commit;"] = nil
  4379  		bh.sql2result["rollback;"] = nil
  4380  
  4381  		//init from roles
  4382  		for i, role := range stmt.Roles {
  4383  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4384  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4385  				{i},
  4386  			})
  4387  			bh.sql2result[sql] = mrs
  4388  		}
  4389  
  4390  		//init to 2 roles,
  4391  		//init to 1 users
  4392  		for i, user := range stmt.Users {
  4393  			if i < 2 { //roles
  4394  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4395  				mrs := newMrsForRoleIdOfRole([][]interface{}{
  4396  					{i + len(stmt.Roles)},
  4397  				})
  4398  
  4399  				bh.sql2result[sql] = mrs
  4400  
  4401  				sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4402  				mrs = newMrsForPasswordOfUser([][]interface{}{})
  4403  				bh.sql2result[sql] = mrs
  4404  			} else { //users
  4405  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4406  				mrs := newMrsForRoleIdOfRole([][]interface{}{})
  4407  
  4408  				bh.sql2result[sql] = mrs
  4409  
  4410  				sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4411  				mrs = newMrsForPasswordOfUser([][]interface{}{
  4412  					{i, "111", i},
  4413  				})
  4414  				bh.sql2result[sql] = mrs
  4415  
  4416  				sql, _ = getSqlForRoleOfUser(context.TODO(), int64(i), moAdminRoleName)
  4417  				bh.sql2result[sql] = newMrsForRoleOfUser([][]interface{}{})
  4418  			}
  4419  
  4420  		}
  4421  
  4422  		//has "ro roles", need init mo_role_grant (assume empty)
  4423  		sql := getSqlForGetAllStuffRoleGrantFormat()
  4424  		mrs := newMrsForGetAllStuffRoleGrant([][]interface{}{
  4425  			{1, 0, true},
  4426  			{2, 1, true},
  4427  			{3, 2, true},
  4428  			{4, 2, true},
  4429  		})
  4430  
  4431  		bh.sql2result[sql] = mrs
  4432  
  4433  		//loop on from ... to
  4434  		for fromId := range stmt.Roles {
  4435  			for toId := range stmt.Users {
  4436  				if toId < 2 { //roles
  4437  					toId = toId + len(stmt.Roles)
  4438  					sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4439  					mrs = newMrsForCheckRoleGrant([][]interface{}{
  4440  						{fromId, toId, false},
  4441  					})
  4442  					bh.sql2result[sql] = mrs
  4443  
  4444  					//sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  4445  					//mrs = newMrsForCheckUserGrant([][]interface{}{})
  4446  					//bh.sql2result[sql] = mrs
  4447  				} else { //users
  4448  					//sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4449  					//mrs = newMrsForCheckRoleGrant([][]interface{}{})
  4450  					//bh.sql2result[sql] = mrs
  4451  
  4452  					sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  4453  					mrs = newMrsForCheckUserGrant([][]interface{}{
  4454  						{fromId, toId, false},
  4455  					})
  4456  					bh.sql2result[sql] = mrs
  4457  				}
  4458  
  4459  			}
  4460  		}
  4461  
  4462  		err := doGrantRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4463  		convey.So(err, convey.ShouldBeError)
  4464  	})
  4465  
  4466  	convey.Convey("grant role to role fail no role", t, func() {
  4467  		ctrl := gomock.NewController(t)
  4468  		defer ctrl.Finish()
  4469  
  4470  		bh := &backgroundExecTest{}
  4471  		bh.init()
  4472  
  4473  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4474  		defer bhStub.Reset()
  4475  
  4476  		stmt := &tree.GrantRole{
  4477  			Roles: []*tree.Role{
  4478  				{UserName: "r1"},
  4479  				{UserName: "r2"},
  4480  				{UserName: "r3"},
  4481  			},
  4482  			Users: []*tree.User{
  4483  				{Username: "r4"},
  4484  				{Username: "r5"},
  4485  				{Username: "r6"},
  4486  			},
  4487  		}
  4488  		priv := determinePrivilegeSetOfStatement(stmt)
  4489  		ses := newSes(priv, ctrl)
  4490  
  4491  		//no result set
  4492  		bh.sql2result["begin;"] = nil
  4493  		bh.sql2result["commit;"] = nil
  4494  		bh.sql2result["rollback;"] = nil
  4495  
  4496  		//init from roles
  4497  		for _, role := range stmt.Roles {
  4498  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4499  			mrs := newMrsForRoleIdOfRole([][]interface{}{})
  4500  			bh.sql2result[sql] = mrs
  4501  		}
  4502  
  4503  		//init to roles
  4504  		for i, user := range stmt.Users {
  4505  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4506  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4507  				{i + len(stmt.Roles)},
  4508  			})
  4509  
  4510  			bh.sql2result[sql] = mrs
  4511  		}
  4512  
  4513  		//has "ro roles", need init mo_role_grant (assume empty)
  4514  		sql := getSqlForGetAllStuffRoleGrantFormat()
  4515  		mrs := newMrsForGetAllStuffRoleGrant([][]interface{}{})
  4516  
  4517  		bh.sql2result[sql] = mrs
  4518  
  4519  		//loop on from ... to
  4520  		for fromId := range stmt.Roles {
  4521  			for toId := range stmt.Users {
  4522  				toId = toId + len(stmt.Roles)
  4523  				sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4524  				mrs = newMrsForCheckRoleGrant([][]interface{}{})
  4525  				bh.sql2result[sql] = mrs
  4526  			}
  4527  		}
  4528  
  4529  		err := doGrantRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4530  		convey.So(err, convey.ShouldBeError)
  4531  	})
  4532  
  4533  	convey.Convey("grant role to user fail no user", t, func() {
  4534  		ctrl := gomock.NewController(t)
  4535  		defer ctrl.Finish()
  4536  
  4537  		bh := &backgroundExecTest{}
  4538  		bh.init()
  4539  
  4540  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4541  		defer bhStub.Reset()
  4542  
  4543  		stmt := &tree.GrantRole{
  4544  			Roles: []*tree.Role{
  4545  				{UserName: "r1"},
  4546  				{UserName: "r2"},
  4547  				{UserName: "r3"},
  4548  			},
  4549  			Users: []*tree.User{
  4550  				{Username: "u4"},
  4551  				{Username: "u5"},
  4552  				{Username: "u6"},
  4553  			},
  4554  		}
  4555  		priv := determinePrivilegeSetOfStatement(stmt)
  4556  		ses := newSes(priv, ctrl)
  4557  
  4558  		//no result set
  4559  		bh.sql2result["begin;"] = nil
  4560  		bh.sql2result["commit;"] = nil
  4561  		bh.sql2result["rollback;"] = nil
  4562  
  4563  		//init from roles
  4564  		for i, role := range stmt.Roles {
  4565  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4566  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4567  				{i},
  4568  			})
  4569  			bh.sql2result[sql] = mrs
  4570  		}
  4571  
  4572  		//init to empty roles,
  4573  		//init to users
  4574  		for _, user := range stmt.Users {
  4575  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4576  			mrs := newMrsForRoleIdOfRole([][]interface{}{})
  4577  
  4578  			bh.sql2result[sql] = mrs
  4579  
  4580  			sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4581  			mrs = newMrsForPasswordOfUser([][]interface{}{})
  4582  			bh.sql2result[sql] = mrs
  4583  		}
  4584  
  4585  		//has "ro roles", need init mo_role_grant (assume empty)
  4586  		sql := getSqlForGetAllStuffRoleGrantFormat()
  4587  		mrs := newMrsForGetAllStuffRoleGrant([][]interface{}{})
  4588  
  4589  		bh.sql2result[sql] = mrs
  4590  
  4591  		//loop on from ... to
  4592  		for fromId := range stmt.Roles {
  4593  			for toId := range stmt.Users {
  4594  				sql = getSqlForCheckRoleGrant(int64(fromId), int64(toId))
  4595  				mrs = newMrsForCheckRoleGrant([][]interface{}{})
  4596  				bh.sql2result[sql] = mrs
  4597  
  4598  				sql = getSqlForCheckUserGrant(int64(fromId), int64(toId))
  4599  				mrs = newMrsForCheckUserGrant([][]interface{}{})
  4600  				bh.sql2result[sql] = mrs
  4601  			}
  4602  		}
  4603  
  4604  		err := doGrantRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4605  		convey.So(err, convey.ShouldBeError)
  4606  	})
  4607  }
  4608  
  4609  func Test_doRevokeRole(t *testing.T) {
  4610  	convey.Convey("revoke role from role succ", t, func() {
  4611  		ctrl := gomock.NewController(t)
  4612  		defer ctrl.Finish()
  4613  
  4614  		bh := &backgroundExecTest{}
  4615  		bh.init()
  4616  
  4617  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4618  		defer bhStub.Reset()
  4619  
  4620  		stmt := &tree.RevokeRole{
  4621  			Roles: []*tree.Role{
  4622  				{UserName: "r1"},
  4623  				{UserName: "r2"},
  4624  				{UserName: "r3"},
  4625  			},
  4626  			Users: []*tree.User{
  4627  				{Username: "r4"},
  4628  				{Username: "r5"},
  4629  				{Username: "r6"},
  4630  			},
  4631  		}
  4632  		priv := determinePrivilegeSetOfStatement(stmt)
  4633  		ses := newSes(priv, ctrl)
  4634  
  4635  		//no result set
  4636  		bh.sql2result["begin;"] = nil
  4637  		bh.sql2result["commit;"] = nil
  4638  		bh.sql2result["rollback;"] = nil
  4639  
  4640  		//init from roles
  4641  		for i, role := range stmt.Roles {
  4642  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4643  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4644  				{i},
  4645  			})
  4646  			bh.sql2result[sql] = mrs
  4647  		}
  4648  
  4649  		//init to roles
  4650  		for i, user := range stmt.Users {
  4651  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4652  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4653  				{i + len(stmt.Roles)},
  4654  			})
  4655  
  4656  			bh.sql2result[sql] = mrs
  4657  		}
  4658  
  4659  		//loop on from ... to
  4660  		for fromId := range stmt.Roles {
  4661  			for toId := range stmt.Users {
  4662  				toId = toId + len(stmt.Roles)
  4663  				sql := getSqlForDeleteRoleGrant(int64(fromId), int64(toId))
  4664  				bh.sql2result[sql] = nil
  4665  			}
  4666  		}
  4667  
  4668  		err := doRevokeRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4669  		convey.So(err, convey.ShouldBeNil)
  4670  	})
  4671  
  4672  	convey.Convey("revoke role from role succ (if exists = true, miss role before FROM)", t, func() {
  4673  		ctrl := gomock.NewController(t)
  4674  		defer ctrl.Finish()
  4675  
  4676  		bh := &backgroundExecTest{}
  4677  		bh.init()
  4678  
  4679  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4680  		defer bhStub.Reset()
  4681  
  4682  		stmt := &tree.RevokeRole{
  4683  			IfExists: true,
  4684  			Roles: []*tree.Role{
  4685  				{UserName: "r1"},
  4686  				{UserName: "r2"},
  4687  				{UserName: "r3"},
  4688  			},
  4689  			Users: []*tree.User{
  4690  				{Username: "r4"},
  4691  				{Username: "r5"},
  4692  				{Username: "r6"},
  4693  			},
  4694  		}
  4695  		priv := determinePrivilegeSetOfStatement(stmt)
  4696  		ses := newSes(priv, ctrl)
  4697  
  4698  		//no result set
  4699  		bh.sql2result["begin;"] = nil
  4700  		bh.sql2result["commit;"] = nil
  4701  		bh.sql2result["rollback;"] = nil
  4702  
  4703  		//init from roles
  4704  		var mrs *MysqlResultSet
  4705  		for i, role := range stmt.Roles {
  4706  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4707  			mrs = newMrsForRoleIdOfRole([][]interface{}{
  4708  				{i},
  4709  			})
  4710  			bh.sql2result[sql] = mrs
  4711  		}
  4712  
  4713  		//init to roles
  4714  		for i, user := range stmt.Users {
  4715  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4716  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4717  				{i + len(stmt.Roles)},
  4718  			})
  4719  
  4720  			bh.sql2result[sql] = mrs
  4721  		}
  4722  
  4723  		//loop on from ... to
  4724  		for fromId := range stmt.Roles {
  4725  			for toId := range stmt.Users {
  4726  				toId = toId + len(stmt.Roles)
  4727  				sql := getSqlForDeleteRoleGrant(int64(fromId), int64(toId))
  4728  				bh.sql2result[sql] = nil
  4729  			}
  4730  		}
  4731  
  4732  		err := doRevokeRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4733  		convey.So(err, convey.ShouldBeNil)
  4734  	})
  4735  
  4736  	convey.Convey("revoke role from role fail (if exists = false,miss role before FROM)", t, func() {
  4737  		ctrl := gomock.NewController(t)
  4738  		defer ctrl.Finish()
  4739  
  4740  		bh := &backgroundExecTest{}
  4741  		bh.init()
  4742  
  4743  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4744  		defer bhStub.Reset()
  4745  
  4746  		stmt := &tree.RevokeRole{
  4747  			Roles: []*tree.Role{
  4748  				{UserName: "r1"},
  4749  				{UserName: "r2"},
  4750  				{UserName: "r3"},
  4751  			},
  4752  			Users: []*tree.User{
  4753  				{Username: "r4"},
  4754  				{Username: "r5"},
  4755  				{Username: "r6"},
  4756  			},
  4757  		}
  4758  		priv := determinePrivilegeSetOfStatement(stmt)
  4759  		ses := newSes(priv, ctrl)
  4760  
  4761  		//no result set
  4762  		bh.sql2result["begin;"] = nil
  4763  		bh.sql2result["commit;"] = nil
  4764  		bh.sql2result["rollback;"] = nil
  4765  
  4766  		//init from roles
  4767  		var mrs *MysqlResultSet
  4768  		for i, role := range stmt.Roles {
  4769  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4770  			if i == 0 {
  4771  				mrs = newMrsForRoleIdOfRole([][]interface{}{})
  4772  			} else {
  4773  				mrs = newMrsForRoleIdOfRole([][]interface{}{
  4774  					{i},
  4775  				})
  4776  			}
  4777  
  4778  			bh.sql2result[sql] = mrs
  4779  		}
  4780  
  4781  		//init to roles
  4782  		for i, user := range stmt.Users {
  4783  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4784  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4785  				{i + len(stmt.Roles)},
  4786  			})
  4787  
  4788  			bh.sql2result[sql] = mrs
  4789  		}
  4790  
  4791  		//loop on from ... to
  4792  		for fromId := range stmt.Roles {
  4793  			for toId := range stmt.Users {
  4794  				toId = toId + len(stmt.Roles)
  4795  				sql := getSqlForDeleteRoleGrant(int64(fromId), int64(toId))
  4796  				bh.sql2result[sql] = nil
  4797  			}
  4798  		}
  4799  
  4800  		err := doRevokeRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4801  		convey.So(err, convey.ShouldBeError)
  4802  	})
  4803  
  4804  	convey.Convey("revoke role from user fail (if exists = false,miss role after FROM)", t, func() {
  4805  		ctrl := gomock.NewController(t)
  4806  		defer ctrl.Finish()
  4807  
  4808  		bh := &backgroundExecTest{}
  4809  		bh.init()
  4810  
  4811  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4812  		defer bhStub.Reset()
  4813  
  4814  		stmt := &tree.RevokeRole{
  4815  			Roles: []*tree.Role{
  4816  				{UserName: "r1"},
  4817  				{UserName: "r2"},
  4818  				{UserName: "r3"},
  4819  			},
  4820  			Users: []*tree.User{
  4821  				{Username: "u1"},
  4822  				{Username: "u2"},
  4823  				{Username: "u3"},
  4824  			},
  4825  		}
  4826  		priv := determinePrivilegeSetOfStatement(stmt)
  4827  		ses := newSes(priv, ctrl)
  4828  
  4829  		//no result set
  4830  		bh.sql2result["begin;"] = nil
  4831  		bh.sql2result["commit;"] = nil
  4832  		bh.sql2result["rollback;"] = nil
  4833  
  4834  		//init from roles
  4835  		var mrs *MysqlResultSet
  4836  		for i, role := range stmt.Roles {
  4837  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4838  			mrs = newMrsForRoleIdOfRole([][]interface{}{
  4839  				{i},
  4840  			})
  4841  
  4842  			bh.sql2result[sql] = mrs
  4843  		}
  4844  
  4845  		//init to roles
  4846  		for i, user := range stmt.Users {
  4847  			//sql := sql, _ := getSqlForRoleIdOfRole(context.TODO(),user.Username)
  4848  			//mrs = newMrsForRoleIdOfRole([][]interface{}{})
  4849  
  4850  			sql, _ := getSqlForPasswordOfUser(context.TODO(), user.Username)
  4851  			//miss u2
  4852  			if i == 1 {
  4853  				mrs = newMrsForPasswordOfUser([][]interface{}{})
  4854  			} else {
  4855  				mrs = newMrsForPasswordOfUser([][]interface{}{
  4856  					{i + len(stmt.Roles)},
  4857  				})
  4858  			}
  4859  
  4860  			bh.sql2result[sql] = mrs
  4861  		}
  4862  
  4863  		//loop on from ... to
  4864  		for fromId := range stmt.Roles {
  4865  			for toId := range stmt.Users {
  4866  				toId = toId + len(stmt.Roles)
  4867  				sql := getSqlForDeleteUserGrant(int64(fromId), int64(toId))
  4868  				bh.sql2result[sql] = nil
  4869  			}
  4870  		}
  4871  
  4872  		err := doRevokeRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4873  		convey.So(err, convey.ShouldBeError)
  4874  	})
  4875  
  4876  	convey.Convey("revoke role from user succ", t, func() {
  4877  		ctrl := gomock.NewController(t)
  4878  		defer ctrl.Finish()
  4879  
  4880  		bh := &backgroundExecTest{}
  4881  		bh.init()
  4882  
  4883  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4884  		defer bhStub.Reset()
  4885  
  4886  		stmt := &tree.RevokeRole{
  4887  			Roles: []*tree.Role{
  4888  				{UserName: "r1"},
  4889  				{UserName: "r2"},
  4890  				{UserName: "r3"},
  4891  			},
  4892  			Users: []*tree.User{
  4893  				{Username: "u4"},
  4894  				{Username: "u5"},
  4895  				{Username: "u6"},
  4896  			},
  4897  		}
  4898  		priv := determinePrivilegeSetOfStatement(stmt)
  4899  		ses := newSes(priv, ctrl)
  4900  
  4901  		//no result set
  4902  		bh.sql2result["begin;"] = nil
  4903  		bh.sql2result["commit;"] = nil
  4904  		bh.sql2result["rollback;"] = nil
  4905  
  4906  		//init from roles
  4907  		for i, role := range stmt.Roles {
  4908  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4909  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4910  				{i},
  4911  			})
  4912  			bh.sql2result[sql] = mrs
  4913  		}
  4914  
  4915  		//init to roles
  4916  		for i, user := range stmt.Users {
  4917  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), user.Username)
  4918  			mrs := newMrsForRoleIdOfRole([][]interface{}{})
  4919  
  4920  			bh.sql2result[sql] = mrs
  4921  
  4922  			sql, _ = getSqlForPasswordOfUser(context.TODO(), user.Username)
  4923  			mrs = newMrsForPasswordOfUser([][]interface{}{
  4924  				{i},
  4925  			})
  4926  
  4927  			bh.sql2result[sql] = mrs
  4928  		}
  4929  
  4930  		//loop on from ... to
  4931  		for fromId := range stmt.Roles {
  4932  			for toId := range stmt.Users {
  4933  				toId = toId + len(stmt.Roles)
  4934  				sql := getSqlForDeleteRoleGrant(int64(fromId), int64(toId))
  4935  				bh.sql2result[sql] = nil
  4936  			}
  4937  		}
  4938  
  4939  		err := doRevokeRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4940  		convey.So(err, convey.ShouldBeNil)
  4941  	})
  4942  }
  4943  
  4944  func Test_doGrantPrivilege(t *testing.T) {
  4945  	convey.Convey("grant account, role succ", t, func() {
  4946  		ctrl := gomock.NewController(t)
  4947  		defer ctrl.Finish()
  4948  
  4949  		bh := &backgroundExecTest{}
  4950  		bh.init()
  4951  
  4952  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  4953  		defer bhStub.Reset()
  4954  
  4955  		stmt := &tree.GrantPrivilege{
  4956  			Privileges: []*tree.Privilege{
  4957  				{Type: tree.PRIVILEGE_TYPE_STATIC_CREATE_DATABASE},
  4958  			},
  4959  			ObjType: tree.OBJECT_TYPE_ACCOUNT,
  4960  			Level:   &tree.PrivilegeLevel{Level: tree.PRIVILEGE_LEVEL_TYPE_STAR},
  4961  			Roles: []*tree.Role{
  4962  				{UserName: "r1"},
  4963  			},
  4964  		}
  4965  		priv := determinePrivilegeSetOfStatement(stmt)
  4966  		ses := newSes(priv, ctrl)
  4967  
  4968  		//no result set
  4969  		bh.sql2result["begin;"] = nil
  4970  		bh.sql2result["commit;"] = nil
  4971  		bh.sql2result["rollback;"] = nil
  4972  
  4973  		//init from roles
  4974  		for i, role := range stmt.Roles {
  4975  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  4976  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  4977  				{i},
  4978  			})
  4979  			bh.sql2result[sql] = mrs
  4980  		}
  4981  
  4982  		for _, p := range stmt.Privileges {
  4983  			privType, err := convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, tree.OBJECT_TYPE_ACCOUNT)
  4984  			convey.So(err, convey.ShouldBeNil)
  4985  			for j := range stmt.Roles {
  4986  				sql := getSqlForCheckRoleHasPrivilege(int64(j), objectTypeAccount, objectIDAll, int64(privType))
  4987  				mrs := newMrsForCheckRoleHasPrivilege([][]interface{}{})
  4988  				bh.sql2result[sql] = mrs
  4989  			}
  4990  		}
  4991  
  4992  		err := doGrantPrivilege(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  4993  		convey.So(err, convey.ShouldBeNil)
  4994  	})
  4995  	convey.Convey("grant database, role succ", t, func() {
  4996  		ctrl := gomock.NewController(t)
  4997  		defer ctrl.Finish()
  4998  
  4999  		bh := &backgroundExecTest{}
  5000  		bh.init()
  5001  
  5002  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5003  		defer bhStub.Reset()
  5004  
  5005  		stmts := []*tree.GrantPrivilege{
  5006  			{
  5007  				Privileges: []*tree.Privilege{
  5008  					{Type: tree.PRIVILEGE_TYPE_STATIC_SHOW_TABLES},
  5009  				},
  5010  				ObjType: tree.OBJECT_TYPE_DATABASE,
  5011  				Level: &tree.PrivilegeLevel{
  5012  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  5013  				},
  5014  				Roles: []*tree.Role{
  5015  					{UserName: "r1"},
  5016  				},
  5017  			},
  5018  			{
  5019  				Privileges: []*tree.Privilege{
  5020  					{Type: tree.PRIVILEGE_TYPE_STATIC_SHOW_TABLES},
  5021  				},
  5022  				ObjType: tree.OBJECT_TYPE_DATABASE,
  5023  				Level: &tree.PrivilegeLevel{
  5024  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR_STAR,
  5025  				},
  5026  				Roles: []*tree.Role{
  5027  					{UserName: "r1"},
  5028  				},
  5029  			},
  5030  			{
  5031  				Privileges: []*tree.Privilege{
  5032  					{Type: tree.PRIVILEGE_TYPE_STATIC_SHOW_TABLES},
  5033  				},
  5034  				ObjType: tree.OBJECT_TYPE_DATABASE,
  5035  				Level: &tree.PrivilegeLevel{
  5036  					Level:  tree.PRIVILEGE_LEVEL_TYPE_DATABASE,
  5037  					DbName: "d",
  5038  				},
  5039  				Roles: []*tree.Role{
  5040  					{UserName: "r1"},
  5041  				},
  5042  			},
  5043  			{
  5044  				Privileges: []*tree.Privilege{
  5045  					{Type: tree.PRIVILEGE_TYPE_STATIC_SHOW_TABLES},
  5046  				},
  5047  				ObjType: tree.OBJECT_TYPE_DATABASE,
  5048  				Level: &tree.PrivilegeLevel{
  5049  					Level:   tree.PRIVILEGE_LEVEL_TYPE_TABLE,
  5050  					TabName: "d",
  5051  				},
  5052  				Roles: []*tree.Role{
  5053  					{UserName: "r1"},
  5054  				},
  5055  			},
  5056  		}
  5057  
  5058  		for _, stmt := range stmts {
  5059  			priv := determinePrivilegeSetOfStatement(stmt)
  5060  			ses := newSes(priv, ctrl)
  5061  
  5062  			//no result set
  5063  			bh.sql2result["begin;"] = nil
  5064  			bh.sql2result["commit;"] = nil
  5065  			bh.sql2result["rollback;"] = nil
  5066  
  5067  			//init from roles
  5068  			for i, role := range stmt.Roles {
  5069  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  5070  				mrs := newMrsForRoleIdOfRole([][]interface{}{
  5071  					{i},
  5072  				})
  5073  				bh.sql2result[sql] = mrs
  5074  			}
  5075  
  5076  			objType, err := convertAstObjectTypeToObjectType(context.TODO(), stmt.ObjType)
  5077  			convey.So(err, convey.ShouldBeNil)
  5078  
  5079  			if stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_DATABASE {
  5080  				sql, _ := getSqlForCheckDatabase(context.TODO(), stmt.Level.DbName)
  5081  				mrs := newMrsForCheckDatabase([][]interface{}{
  5082  					{0},
  5083  				})
  5084  				bh.sql2result[sql] = mrs
  5085  			} else if stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_TABLE {
  5086  				sql, _ := getSqlForCheckDatabase(context.TODO(), stmt.Level.TabName)
  5087  				mrs := newMrsForCheckDatabase([][]interface{}{
  5088  					{0},
  5089  				})
  5090  				bh.sql2result[sql] = mrs
  5091  			}
  5092  
  5093  			_, objId, err := checkPrivilegeObjectTypeAndPrivilegeLevel(context.TODO(), ses, bh, stmt.ObjType, *stmt.Level)
  5094  			convey.So(err, convey.ShouldBeNil)
  5095  
  5096  			for _, p := range stmt.Privileges {
  5097  				privType, err := convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  5098  				convey.So(err, convey.ShouldBeNil)
  5099  				for j := range stmt.Roles {
  5100  					sql := getSqlForCheckRoleHasPrivilege(int64(j), objType, objId, int64(privType))
  5101  					mrs := newMrsForCheckRoleHasPrivilege([][]interface{}{})
  5102  					bh.sql2result[sql] = mrs
  5103  				}
  5104  			}
  5105  
  5106  			err = doGrantPrivilege(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5107  			convey.So(err, convey.ShouldBeNil)
  5108  		}
  5109  	})
  5110  	convey.Convey("grant table, role succ", t, func() {
  5111  		ctrl := gomock.NewController(t)
  5112  		defer ctrl.Finish()
  5113  
  5114  		bh := &backgroundExecTest{}
  5115  		bh.init()
  5116  
  5117  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5118  		defer bhStub.Reset()
  5119  
  5120  		dbName := "d"
  5121  		tableName := "t"
  5122  		stmts := []*tree.GrantPrivilege{
  5123  			{
  5124  				Privileges: []*tree.Privilege{
  5125  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5126  				},
  5127  				ObjType: tree.OBJECT_TYPE_TABLE,
  5128  				Level: &tree.PrivilegeLevel{
  5129  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  5130  				},
  5131  				Roles: []*tree.Role{
  5132  					{UserName: "r1"},
  5133  				},
  5134  			},
  5135  			{
  5136  				Privileges: []*tree.Privilege{
  5137  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5138  				},
  5139  				ObjType: tree.OBJECT_TYPE_TABLE,
  5140  				Level: &tree.PrivilegeLevel{
  5141  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR_STAR,
  5142  				},
  5143  				Roles: []*tree.Role{
  5144  					{UserName: "r1"},
  5145  				},
  5146  			},
  5147  			{
  5148  				Privileges: []*tree.Privilege{
  5149  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5150  				},
  5151  				ObjType: tree.OBJECT_TYPE_TABLE,
  5152  				Level: &tree.PrivilegeLevel{
  5153  					Level:  tree.PRIVILEGE_LEVEL_TYPE_DATABASE_STAR,
  5154  					DbName: dbName,
  5155  				},
  5156  				Roles: []*tree.Role{
  5157  					{UserName: "r1"},
  5158  				},
  5159  			},
  5160  			{
  5161  				Privileges: []*tree.Privilege{
  5162  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5163  				},
  5164  				ObjType: tree.OBJECT_TYPE_TABLE,
  5165  				Level: &tree.PrivilegeLevel{
  5166  					Level:   tree.PRIVILEGE_LEVEL_TYPE_DATABASE_TABLE,
  5167  					DbName:  dbName,
  5168  					TabName: tableName,
  5169  				},
  5170  				Roles: []*tree.Role{
  5171  					{UserName: "r1"},
  5172  				},
  5173  			},
  5174  			{
  5175  				Privileges: []*tree.Privilege{
  5176  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5177  				},
  5178  				ObjType: tree.OBJECT_TYPE_TABLE,
  5179  				Level: &tree.PrivilegeLevel{
  5180  					Level:   tree.PRIVILEGE_LEVEL_TYPE_TABLE,
  5181  					TabName: tableName,
  5182  				},
  5183  				Roles: []*tree.Role{
  5184  					{UserName: "r1"},
  5185  				},
  5186  			},
  5187  		}
  5188  
  5189  		for _, stmt := range stmts {
  5190  			priv := determinePrivilegeSetOfStatement(stmt)
  5191  			ses := newSes(priv, ctrl)
  5192  			ses.SetDatabaseName("d")
  5193  
  5194  			//no result set
  5195  			bh.sql2result["begin;"] = nil
  5196  			bh.sql2result["commit;"] = nil
  5197  			bh.sql2result["rollback;"] = nil
  5198  
  5199  			//init from roles
  5200  			for i, role := range stmt.Roles {
  5201  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  5202  				mrs := newMrsForRoleIdOfRole([][]interface{}{
  5203  					{i},
  5204  				})
  5205  				bh.sql2result[sql] = mrs
  5206  			}
  5207  
  5208  			objType, err := convertAstObjectTypeToObjectType(context.TODO(), stmt.ObjType)
  5209  			convey.So(err, convey.ShouldBeNil)
  5210  
  5211  			if stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_STAR ||
  5212  				stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_DATABASE_STAR {
  5213  				sql, _ := getSqlForCheckDatabase(context.TODO(), dbName)
  5214  				mrs := newMrsForCheckDatabase([][]interface{}{
  5215  					{0},
  5216  				})
  5217  				bh.sql2result[sql] = mrs
  5218  			} else if stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_TABLE ||
  5219  				stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_DATABASE_TABLE {
  5220  				sql, _ := getSqlForCheckDatabaseTable(context.TODO(), dbName, tableName)
  5221  				mrs := newMrsForCheckDatabaseTable([][]interface{}{
  5222  					{0},
  5223  				})
  5224  				bh.sql2result[sql] = mrs
  5225  			}
  5226  
  5227  			_, objId, err := checkPrivilegeObjectTypeAndPrivilegeLevel(context.TODO(), ses, bh, stmt.ObjType, *stmt.Level)
  5228  			convey.So(err, convey.ShouldBeNil)
  5229  
  5230  			for _, p := range stmt.Privileges {
  5231  				privType, err := convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  5232  				convey.So(err, convey.ShouldBeNil)
  5233  				for j := range stmt.Roles {
  5234  					sql := getSqlForCheckRoleHasPrivilege(int64(j), objType, objId, int64(privType))
  5235  					mrs := newMrsForCheckRoleHasPrivilege([][]interface{}{})
  5236  					bh.sql2result[sql] = mrs
  5237  				}
  5238  			}
  5239  
  5240  			err = doGrantPrivilege(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5241  			convey.So(err, convey.ShouldBeNil)
  5242  		}
  5243  	})
  5244  }
  5245  
  5246  func Test_doRevokePrivilege(t *testing.T) {
  5247  	convey.Convey("revoke account, role succ", t, func() {
  5248  		ctrl := gomock.NewController(t)
  5249  		defer ctrl.Finish()
  5250  
  5251  		bh := &backgroundExecTest{}
  5252  		bh.init()
  5253  
  5254  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5255  		defer bhStub.Reset()
  5256  
  5257  		stmt := &tree.RevokePrivilege{
  5258  			Privileges: []*tree.Privilege{
  5259  				{Type: tree.PRIVILEGE_TYPE_STATIC_CREATE_DATABASE},
  5260  			},
  5261  			ObjType: tree.OBJECT_TYPE_ACCOUNT,
  5262  			Level:   &tree.PrivilegeLevel{Level: tree.PRIVILEGE_LEVEL_TYPE_STAR},
  5263  			Roles: []*tree.Role{
  5264  				{UserName: "r1"},
  5265  			},
  5266  		}
  5267  		priv := determinePrivilegeSetOfStatement(stmt)
  5268  		ses := newSes(priv, ctrl)
  5269  
  5270  		//no result set
  5271  		bh.sql2result["begin;"] = nil
  5272  		bh.sql2result["commit;"] = nil
  5273  		bh.sql2result["rollback;"] = nil
  5274  
  5275  		//init from roles
  5276  		for i, role := range stmt.Roles {
  5277  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  5278  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  5279  				{i},
  5280  			})
  5281  			bh.sql2result[sql] = mrs
  5282  		}
  5283  
  5284  		for _, p := range stmt.Privileges {
  5285  			privType, err := convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, tree.OBJECT_TYPE_ACCOUNT)
  5286  			convey.So(err, convey.ShouldBeNil)
  5287  			for j := range stmt.Roles {
  5288  				sql := getSqlForCheckRoleHasPrivilege(int64(j), objectTypeAccount, objectIDAll, int64(privType))
  5289  				mrs := newMrsForCheckRoleHasPrivilege([][]interface{}{})
  5290  				bh.sql2result[sql] = mrs
  5291  			}
  5292  		}
  5293  
  5294  		err := doRevokePrivilege(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5295  		convey.So(err, convey.ShouldBeNil)
  5296  	})
  5297  	convey.Convey("revoke database, role succ", t, func() {
  5298  		ctrl := gomock.NewController(t)
  5299  		defer ctrl.Finish()
  5300  
  5301  		bh := &backgroundExecTest{}
  5302  		bh.init()
  5303  
  5304  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5305  		defer bhStub.Reset()
  5306  
  5307  		stmts := []*tree.RevokePrivilege{
  5308  			{
  5309  				Privileges: []*tree.Privilege{
  5310  					{Type: tree.PRIVILEGE_TYPE_STATIC_SHOW_TABLES},
  5311  				},
  5312  				ObjType: tree.OBJECT_TYPE_DATABASE,
  5313  				Level: &tree.PrivilegeLevel{
  5314  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  5315  				},
  5316  				Roles: []*tree.Role{
  5317  					{UserName: "r1"},
  5318  				},
  5319  			},
  5320  			{
  5321  				Privileges: []*tree.Privilege{
  5322  					{Type: tree.PRIVILEGE_TYPE_STATIC_SHOW_TABLES},
  5323  				},
  5324  				ObjType: tree.OBJECT_TYPE_DATABASE,
  5325  				Level: &tree.PrivilegeLevel{
  5326  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR_STAR,
  5327  				},
  5328  				Roles: []*tree.Role{
  5329  					{UserName: "r1"},
  5330  				},
  5331  			},
  5332  			{
  5333  				Privileges: []*tree.Privilege{
  5334  					{Type: tree.PRIVILEGE_TYPE_STATIC_SHOW_TABLES},
  5335  				},
  5336  				ObjType: tree.OBJECT_TYPE_DATABASE,
  5337  				Level: &tree.PrivilegeLevel{
  5338  					Level:  tree.PRIVILEGE_LEVEL_TYPE_DATABASE,
  5339  					DbName: "d",
  5340  				},
  5341  				Roles: []*tree.Role{
  5342  					{UserName: "r1"},
  5343  				},
  5344  			},
  5345  			{
  5346  				Privileges: []*tree.Privilege{
  5347  					{Type: tree.PRIVILEGE_TYPE_STATIC_SHOW_TABLES},
  5348  				},
  5349  				ObjType: tree.OBJECT_TYPE_DATABASE,
  5350  				Level: &tree.PrivilegeLevel{
  5351  					Level:   tree.PRIVILEGE_LEVEL_TYPE_TABLE,
  5352  					TabName: "d",
  5353  				},
  5354  				Roles: []*tree.Role{
  5355  					{UserName: "r1"},
  5356  				},
  5357  			},
  5358  		}
  5359  
  5360  		for _, stmt := range stmts {
  5361  			priv := determinePrivilegeSetOfStatement(stmt)
  5362  			ses := newSes(priv, ctrl)
  5363  
  5364  			//no result set
  5365  			bh.sql2result["begin;"] = nil
  5366  			bh.sql2result["commit;"] = nil
  5367  			bh.sql2result["rollback;"] = nil
  5368  
  5369  			//init from roles
  5370  			for i, role := range stmt.Roles {
  5371  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  5372  				mrs := newMrsForRoleIdOfRole([][]interface{}{
  5373  					{i},
  5374  				})
  5375  				bh.sql2result[sql] = mrs
  5376  			}
  5377  
  5378  			objType, err := convertAstObjectTypeToObjectType(context.TODO(), stmt.ObjType)
  5379  			convey.So(err, convey.ShouldBeNil)
  5380  
  5381  			if stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_DATABASE {
  5382  				sql, _ := getSqlForCheckDatabase(context.TODO(), stmt.Level.DbName)
  5383  				mrs := newMrsForCheckDatabase([][]interface{}{
  5384  					{0},
  5385  				})
  5386  				bh.sql2result[sql] = mrs
  5387  			} else if stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_TABLE {
  5388  				sql, _ := getSqlForCheckDatabase(context.TODO(), stmt.Level.TabName)
  5389  				mrs := newMrsForCheckDatabase([][]interface{}{
  5390  					{0},
  5391  				})
  5392  				bh.sql2result[sql] = mrs
  5393  			}
  5394  
  5395  			_, objId, err := checkPrivilegeObjectTypeAndPrivilegeLevel(context.TODO(), ses, bh, stmt.ObjType, *stmt.Level)
  5396  			convey.So(err, convey.ShouldBeNil)
  5397  
  5398  			for _, p := range stmt.Privileges {
  5399  				privType, err := convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  5400  				convey.So(err, convey.ShouldBeNil)
  5401  				for j := range stmt.Roles {
  5402  					sql := getSqlForCheckRoleHasPrivilege(int64(j), objType, objId, int64(privType))
  5403  					mrs := newMrsForCheckRoleHasPrivilege([][]interface{}{})
  5404  					bh.sql2result[sql] = mrs
  5405  				}
  5406  			}
  5407  
  5408  			err = doRevokePrivilege(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5409  			convey.So(err, convey.ShouldBeNil)
  5410  		}
  5411  	})
  5412  	convey.Convey("revoke table, role succ", t, func() {
  5413  		ctrl := gomock.NewController(t)
  5414  		defer ctrl.Finish()
  5415  
  5416  		bh := &backgroundExecTest{}
  5417  		bh.init()
  5418  
  5419  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5420  		defer bhStub.Reset()
  5421  
  5422  		dbName := "d"
  5423  		tableName := "t"
  5424  		stmts := []*tree.RevokePrivilege{
  5425  			{
  5426  				Privileges: []*tree.Privilege{
  5427  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5428  				},
  5429  				ObjType: tree.OBJECT_TYPE_TABLE,
  5430  				Level: &tree.PrivilegeLevel{
  5431  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR,
  5432  				},
  5433  				Roles: []*tree.Role{
  5434  					{UserName: "r1"},
  5435  				},
  5436  			},
  5437  			{
  5438  				Privileges: []*tree.Privilege{
  5439  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5440  				},
  5441  				ObjType: tree.OBJECT_TYPE_TABLE,
  5442  				Level: &tree.PrivilegeLevel{
  5443  					Level: tree.PRIVILEGE_LEVEL_TYPE_STAR_STAR,
  5444  				},
  5445  				Roles: []*tree.Role{
  5446  					{UserName: "r1"},
  5447  				},
  5448  			},
  5449  			{
  5450  				Privileges: []*tree.Privilege{
  5451  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5452  				},
  5453  				ObjType: tree.OBJECT_TYPE_TABLE,
  5454  				Level: &tree.PrivilegeLevel{
  5455  					Level:  tree.PRIVILEGE_LEVEL_TYPE_DATABASE_STAR,
  5456  					DbName: dbName,
  5457  				},
  5458  				Roles: []*tree.Role{
  5459  					{UserName: "r1"},
  5460  				},
  5461  			},
  5462  			{
  5463  				Privileges: []*tree.Privilege{
  5464  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5465  				},
  5466  				ObjType: tree.OBJECT_TYPE_TABLE,
  5467  				Level: &tree.PrivilegeLevel{
  5468  					Level:   tree.PRIVILEGE_LEVEL_TYPE_DATABASE_TABLE,
  5469  					DbName:  dbName,
  5470  					TabName: tableName,
  5471  				},
  5472  				Roles: []*tree.Role{
  5473  					{UserName: "r1"},
  5474  				},
  5475  			},
  5476  			{
  5477  				Privileges: []*tree.Privilege{
  5478  					{Type: tree.PRIVILEGE_TYPE_STATIC_SELECT},
  5479  				},
  5480  				ObjType: tree.OBJECT_TYPE_TABLE,
  5481  				Level: &tree.PrivilegeLevel{
  5482  					Level:   tree.PRIVILEGE_LEVEL_TYPE_TABLE,
  5483  					TabName: tableName,
  5484  				},
  5485  				Roles: []*tree.Role{
  5486  					{UserName: "r1"},
  5487  				},
  5488  			},
  5489  		}
  5490  
  5491  		for _, stmt := range stmts {
  5492  			priv := determinePrivilegeSetOfStatement(stmt)
  5493  			ses := newSes(priv, ctrl)
  5494  			ses.SetDatabaseName("d")
  5495  
  5496  			//no result set
  5497  			bh.sql2result["begin;"] = nil
  5498  			bh.sql2result["commit;"] = nil
  5499  			bh.sql2result["rollback;"] = nil
  5500  
  5501  			//init from roles
  5502  			for i, role := range stmt.Roles {
  5503  				sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  5504  				mrs := newMrsForRoleIdOfRole([][]interface{}{
  5505  					{i},
  5506  				})
  5507  				bh.sql2result[sql] = mrs
  5508  			}
  5509  
  5510  			objType, err := convertAstObjectTypeToObjectType(context.TODO(), stmt.ObjType)
  5511  			convey.So(err, convey.ShouldBeNil)
  5512  
  5513  			if stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_STAR ||
  5514  				stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_DATABASE_STAR {
  5515  				sql, _ := getSqlForCheckDatabase(context.TODO(), dbName)
  5516  				mrs := newMrsForCheckDatabase([][]interface{}{
  5517  					{0},
  5518  				})
  5519  				bh.sql2result[sql] = mrs
  5520  			} else if stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_TABLE ||
  5521  				stmt.Level.Level == tree.PRIVILEGE_LEVEL_TYPE_DATABASE_TABLE {
  5522  				sql, _ := getSqlForCheckDatabaseTable(context.TODO(), dbName, tableName)
  5523  				mrs := newMrsForCheckDatabaseTable([][]interface{}{
  5524  					{0},
  5525  				})
  5526  				bh.sql2result[sql] = mrs
  5527  			}
  5528  
  5529  			_, objId, err := checkPrivilegeObjectTypeAndPrivilegeLevel(context.TODO(), ses, bh, stmt.ObjType, *stmt.Level)
  5530  			convey.So(err, convey.ShouldBeNil)
  5531  
  5532  			for _, p := range stmt.Privileges {
  5533  				privType, err := convertAstPrivilegeTypeToPrivilegeType(context.TODO(), p.Type, stmt.ObjType)
  5534  				convey.So(err, convey.ShouldBeNil)
  5535  				for j := range stmt.Roles {
  5536  					sql := getSqlForCheckRoleHasPrivilege(int64(j), objType, objId, int64(privType))
  5537  					mrs := newMrsForCheckRoleHasPrivilege([][]interface{}{})
  5538  					bh.sql2result[sql] = mrs
  5539  				}
  5540  			}
  5541  
  5542  			err = doRevokePrivilege(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5543  			convey.So(err, convey.ShouldBeNil)
  5544  		}
  5545  	})
  5546  }
  5547  
  5548  func Test_doDropFunctionWithDB(t *testing.T) {
  5549  	convey.Convey("drop function with db", t, func() {
  5550  		ctrl := gomock.NewController(t)
  5551  		defer ctrl.Finish()
  5552  
  5553  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  5554  		pu.SV.SetDefaultValues()
  5555  
  5556  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  5557  
  5558  		bh := &backgroundExecTest{}
  5559  		bh.init()
  5560  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5561  		defer bhStub.Reset()
  5562  
  5563  		stmt := &tree.DropDatabase{
  5564  			Name: tree.Identifier("abc"),
  5565  		}
  5566  
  5567  		ses := &Session{}
  5568  		sql := getSqlForCheckUdfWithDb(string(stmt.Name))
  5569  
  5570  		bh.sql2result[sql] = nil
  5571  		err := doDropFunctionWithDB(ctx, ses, stmt, nil)
  5572  		convey.So(err, convey.ShouldNotBeNil)
  5573  	})
  5574  }
  5575  
  5576  func Test_doDropFunction(t *testing.T) {
  5577  	convey.Convey("drop function", t, func() {
  5578  		ctrl := gomock.NewController(t)
  5579  		defer ctrl.Finish()
  5580  
  5581  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  5582  		pu.SV.SetDefaultValues()
  5583  
  5584  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  5585  
  5586  		bh := mock_frontend.NewMockBackgroundExec(ctrl)
  5587  		bh.EXPECT().ClearExecResultSet().AnyTimes()
  5588  		bh.EXPECT().Close().Return().AnyTimes()
  5589  		bh.EXPECT().Exec(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  5590  		rs := mock_frontend.NewMockExecResult(ctrl)
  5591  		rs.EXPECT().GetRowCount().Return(uint64(0)).AnyTimes()
  5592  		bh.EXPECT().GetExecResultSet().Return([]interface{}{rs}).AnyTimes()
  5593  
  5594  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5595  		defer bhStub.Reset()
  5596  
  5597  		cu := &tree.DropFunction{
  5598  			Name: tree.NewFuncName("testFunc",
  5599  				tree.ObjectNamePrefix{
  5600  					SchemaName:      tree.Identifier("db"),
  5601  					CatalogName:     tree.Identifier(""),
  5602  					ExplicitSchema:  true,
  5603  					ExplicitCatalog: false,
  5604  				},
  5605  			),
  5606  			Args: nil,
  5607  		}
  5608  
  5609  		ses := &Session{}
  5610  		err := doDropFunction(ctx, ses, cu, nil)
  5611  		convey.So(err, convey.ShouldNotBeNil)
  5612  	})
  5613  }
  5614  
  5615  func Test_doDropRole(t *testing.T) {
  5616  	convey.Convey("drop role succ", t, func() {
  5617  		ctrl := gomock.NewController(t)
  5618  		defer ctrl.Finish()
  5619  
  5620  		bh := &backgroundExecTest{}
  5621  		bh.init()
  5622  
  5623  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5624  		defer bhStub.Reset()
  5625  
  5626  		stmt := &tree.DropRole{
  5627  			Roles: []*tree.Role{
  5628  				{UserName: "r1"},
  5629  				{UserName: "r2"},
  5630  				{UserName: "r3"},
  5631  			},
  5632  		}
  5633  		priv := determinePrivilegeSetOfStatement(stmt)
  5634  		ses := newSes(priv, ctrl)
  5635  
  5636  		//no result set
  5637  		bh.sql2result["begin;"] = nil
  5638  		bh.sql2result["commit;"] = nil
  5639  		bh.sql2result["rollback;"] = nil
  5640  
  5641  		//init from roles
  5642  		for i, role := range stmt.Roles {
  5643  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  5644  			mrs := newMrsForRoleIdOfRole([][]interface{}{
  5645  				{i},
  5646  			})
  5647  			bh.sql2result[sql] = mrs
  5648  		}
  5649  
  5650  		for i := range stmt.Roles {
  5651  			sqls := getSqlForDeleteRole(int64(i))
  5652  			for _, sql := range sqls {
  5653  				bh.sql2result[sql] = nil
  5654  			}
  5655  		}
  5656  
  5657  		err := doDropRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5658  		convey.So(err, convey.ShouldBeNil)
  5659  	})
  5660  	convey.Convey("drop role succ (if exists)", t, func() {
  5661  		ctrl := gomock.NewController(t)
  5662  		defer ctrl.Finish()
  5663  
  5664  		bh := &backgroundExecTest{}
  5665  		bh.init()
  5666  
  5667  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5668  		defer bhStub.Reset()
  5669  
  5670  		stmt := &tree.DropRole{
  5671  			IfExists: true,
  5672  			Roles: []*tree.Role{
  5673  				{UserName: "r1"},
  5674  				{UserName: "r2"},
  5675  				{UserName: "r3"},
  5676  			},
  5677  		}
  5678  		priv := determinePrivilegeSetOfStatement(stmt)
  5679  		ses := newSes(priv, ctrl)
  5680  
  5681  		//no result set
  5682  		bh.sql2result["begin;"] = nil
  5683  		bh.sql2result["commit;"] = nil
  5684  		bh.sql2result["rollback;"] = nil
  5685  
  5686  		var mrs *MysqlResultSet
  5687  		//init from roles
  5688  		for i, role := range stmt.Roles {
  5689  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  5690  			if i == 0 {
  5691  				mrs = newMrsForRoleIdOfRole([][]interface{}{})
  5692  			} else {
  5693  				mrs = newMrsForRoleIdOfRole([][]interface{}{
  5694  					{i},
  5695  				})
  5696  			}
  5697  
  5698  			bh.sql2result[sql] = mrs
  5699  		}
  5700  
  5701  		for i := range stmt.Roles {
  5702  			sqls := getSqlForDeleteRole(int64(i))
  5703  			for _, sql := range sqls {
  5704  				bh.sql2result[sql] = nil
  5705  			}
  5706  		}
  5707  
  5708  		err := doDropRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5709  		convey.So(err, convey.ShouldBeNil)
  5710  	})
  5711  	convey.Convey("drop role fail", t, func() {
  5712  		ctrl := gomock.NewController(t)
  5713  		defer ctrl.Finish()
  5714  
  5715  		bh := &backgroundExecTest{}
  5716  		bh.init()
  5717  
  5718  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5719  		defer bhStub.Reset()
  5720  
  5721  		stmt := &tree.DropRole{
  5722  			IfExists: false,
  5723  			Roles: []*tree.Role{
  5724  				{UserName: "r1"},
  5725  				{UserName: "r2"},
  5726  				{UserName: "r3"},
  5727  			},
  5728  		}
  5729  		priv := determinePrivilegeSetOfStatement(stmt)
  5730  		ses := newSes(priv, ctrl)
  5731  
  5732  		//no result set
  5733  		bh.sql2result["begin;"] = nil
  5734  		bh.sql2result["commit;"] = nil
  5735  		bh.sql2result["rollback;"] = nil
  5736  
  5737  		var mrs *MysqlResultSet
  5738  		//init from roles
  5739  		for i, role := range stmt.Roles {
  5740  			sql, _ := getSqlForRoleIdOfRole(context.TODO(), role.UserName)
  5741  			if i == 0 {
  5742  				mrs = newMrsForRoleIdOfRole([][]interface{}{})
  5743  			} else {
  5744  				mrs = newMrsForRoleIdOfRole([][]interface{}{
  5745  					{i},
  5746  				})
  5747  			}
  5748  
  5749  			bh.sql2result[sql] = mrs
  5750  		}
  5751  
  5752  		for i := range stmt.Roles {
  5753  			sqls := getSqlForDeleteRole(int64(i))
  5754  			for _, sql := range sqls {
  5755  				bh.sql2result[sql] = nil
  5756  			}
  5757  		}
  5758  
  5759  		err := doDropRole(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5760  		convey.So(err, convey.ShouldBeError)
  5761  	})
  5762  }
  5763  
  5764  func Test_doDropUser(t *testing.T) {
  5765  	convey.Convey("drop user succ", t, func() {
  5766  		ctrl := gomock.NewController(t)
  5767  		defer ctrl.Finish()
  5768  
  5769  		bh := &backgroundExecTest{}
  5770  		bh.init()
  5771  
  5772  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5773  		defer bhStub.Reset()
  5774  
  5775  		stmt := &tree.DropUser{
  5776  			Users: []*tree.User{
  5777  				{Username: "u1"},
  5778  				{Username: "u2"},
  5779  				{Username: "u3"},
  5780  			},
  5781  		}
  5782  		priv := determinePrivilegeSetOfStatement(stmt)
  5783  		ses := newSes(priv, ctrl)
  5784  
  5785  		//no result set
  5786  		bh.sql2result["begin;"] = nil
  5787  		bh.sql2result["commit;"] = nil
  5788  		bh.sql2result["rollback;"] = nil
  5789  
  5790  		for i, user := range stmt.Users {
  5791  			sql, _ := getSqlForPasswordOfUser(context.TODO(), user.Username)
  5792  			mrs := newMrsForPasswordOfUser([][]interface{}{
  5793  				{i, "111", "public"},
  5794  			})
  5795  			bh.sql2result[sql] = mrs
  5796  
  5797  			sql, _ = getSqlForCheckUserHasRole(context.TODO(), user.Username, moAdminRoleID)
  5798  			mrs = newMrsForSqlForCheckUserHasRole([][]interface{}{})
  5799  			bh.sql2result[sql] = mrs
  5800  		}
  5801  
  5802  		for i := range stmt.Users {
  5803  			sqls := getSqlForDeleteUser(int64(i))
  5804  			for _, sql := range sqls {
  5805  				bh.sql2result[sql] = nil
  5806  			}
  5807  		}
  5808  
  5809  		err := doDropUser(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5810  		convey.So(err, convey.ShouldBeNil)
  5811  	})
  5812  
  5813  	convey.Convey("drop user succ (if exists)", t, func() {
  5814  		ctrl := gomock.NewController(t)
  5815  		defer ctrl.Finish()
  5816  
  5817  		bh := &backgroundExecTest{}
  5818  		bh.init()
  5819  
  5820  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5821  		defer bhStub.Reset()
  5822  
  5823  		stmt := &tree.DropUser{
  5824  			IfExists: true,
  5825  			Users: []*tree.User{
  5826  				{Username: "u1"},
  5827  				{Username: "u2"},
  5828  				{Username: "u3"},
  5829  			},
  5830  		}
  5831  		priv := determinePrivilegeSetOfStatement(stmt)
  5832  		ses := newSes(priv, ctrl)
  5833  
  5834  		//no result set
  5835  		bh.sql2result["begin;"] = nil
  5836  		bh.sql2result["commit;"] = nil
  5837  		bh.sql2result["rollback;"] = nil
  5838  
  5839  		var mrs *MysqlResultSet
  5840  		//init from roles
  5841  		for i, user := range stmt.Users {
  5842  			sql, _ := getSqlForPasswordOfUser(context.TODO(), user.Username)
  5843  			if i == 0 {
  5844  				mrs = newMrsForPasswordOfUser([][]interface{}{})
  5845  			} else {
  5846  				mrs = newMrsForPasswordOfUser([][]interface{}{
  5847  					{i, "111", "public"},
  5848  				})
  5849  			}
  5850  
  5851  			bh.sql2result[sql] = mrs
  5852  			sql, _ = getSqlForCheckUserHasRole(context.TODO(), user.Username, moAdminRoleID)
  5853  			mrs = newMrsForSqlForCheckUserHasRole([][]interface{}{})
  5854  			bh.sql2result[sql] = mrs
  5855  		}
  5856  
  5857  		for i := range stmt.Users {
  5858  			sqls := getSqlForDeleteUser(int64(i))
  5859  			for _, sql := range sqls {
  5860  				bh.sql2result[sql] = nil
  5861  			}
  5862  		}
  5863  
  5864  		err := doDropUser(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5865  		convey.So(err, convey.ShouldBeNil)
  5866  	})
  5867  
  5868  	convey.Convey("drop user fail", t, func() {
  5869  		ctrl := gomock.NewController(t)
  5870  		defer ctrl.Finish()
  5871  
  5872  		bh := &backgroundExecTest{}
  5873  		bh.init()
  5874  
  5875  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5876  		defer bhStub.Reset()
  5877  
  5878  		stmt := &tree.DropUser{
  5879  			IfExists: false,
  5880  			Users: []*tree.User{
  5881  				{Username: "u1"},
  5882  				{Username: "u2"},
  5883  				{Username: "u3"},
  5884  			},
  5885  		}
  5886  		priv := determinePrivilegeSetOfStatement(stmt)
  5887  		ses := newSes(priv, ctrl)
  5888  
  5889  		//no result set
  5890  		bh.sql2result["begin;"] = nil
  5891  		bh.sql2result["commit;"] = nil
  5892  		bh.sql2result["rollback;"] = nil
  5893  
  5894  		var mrs *MysqlResultSet
  5895  		//init from roles
  5896  		for i, user := range stmt.Users {
  5897  			sql, _ := getSqlForPasswordOfUser(context.TODO(), user.Username)
  5898  			if i == 0 {
  5899  				mrs = newMrsForPasswordOfUser([][]interface{}{})
  5900  			} else {
  5901  				mrs = newMrsForPasswordOfUser([][]interface{}{
  5902  					{i, "111", "public"},
  5903  				})
  5904  			}
  5905  
  5906  			bh.sql2result[sql] = mrs
  5907  
  5908  			sql, _ = getSqlForCheckUserHasRole(context.TODO(), user.Username, moAdminRoleID)
  5909  			mrs = newMrsForSqlForCheckUserHasRole([][]interface{}{})
  5910  			bh.sql2result[sql] = mrs
  5911  		}
  5912  
  5913  		for i := range stmt.Users {
  5914  			sqls := getSqlForDeleteUser(int64(i))
  5915  			for _, sql := range sqls {
  5916  				bh.sql2result[sql] = nil
  5917  			}
  5918  		}
  5919  
  5920  		err := doDropUser(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  5921  		convey.So(err, convey.ShouldBeError)
  5922  	})
  5923  }
  5924  
  5925  func Test_doInterpretCall(t *testing.T) {
  5926  	convey.Convey("call precedure (not exist)fail", t, func() {
  5927  		ctrl := gomock.NewController(t)
  5928  		defer ctrl.Finish()
  5929  
  5930  		bh := &backgroundExecTest{}
  5931  		bh.init()
  5932  
  5933  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5934  		defer bhStub.Reset()
  5935  		call := &tree.CallStmt{
  5936  			Name: tree.NewProcedureName("test_if_hit_elseif_first_elseif", tree.ObjectNamePrefix{}),
  5937  		}
  5938  
  5939  		priv := determinePrivilegeSetOfStatement(call)
  5940  		ses := newSes(priv, ctrl)
  5941  		proc := testutil.NewProcess()
  5942  		proc.FileService = getGlobalPu().FileService
  5943  		proc.SessionInfo = process.SessionInfo{Account: sysAccountName}
  5944  		ses.GetTxnCompileCtx().execCtx = &ExecCtx{
  5945  			proc: proc,
  5946  		}
  5947  		ses.SetDatabaseName("procedure_test")
  5948  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  5949  		pu.SV.SetDefaultValues()
  5950  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  5951  		rm, _ := NewRoutineManager(ctx)
  5952  		ses.rm = rm
  5953  
  5954  		//no result set
  5955  		bh.sql2result["begin;"] = nil
  5956  		bh.sql2result["commit;"] = nil
  5957  		bh.sql2result["rollback;"] = nil
  5958  
  5959  		sql, err := getSqlForSpBody(ses.GetTxnHandler().GetConnCtx(), string(call.Name.Name.ObjectName), ses.GetDatabaseName())
  5960  		convey.So(err, convey.ShouldBeNil)
  5961  		mrs := newMrsForPasswordOfUser([][]interface{}{})
  5962  		bh.sql2result[sql] = mrs
  5963  
  5964  		_, err = doInterpretCall(ctx, ses, call)
  5965  		convey.So(err, convey.ShouldNotBeNil)
  5966  	})
  5967  
  5968  	convey.Convey("call precedure (not support)fail", t, func() {
  5969  		ctrl := gomock.NewController(t)
  5970  		defer ctrl.Finish()
  5971  
  5972  		bh := &backgroundExecTest{}
  5973  		bh.init()
  5974  
  5975  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  5976  		defer bhStub.Reset()
  5977  		call := &tree.CallStmt{
  5978  			Name: tree.NewProcedureName("test_if_hit_elseif_first_elseif", tree.ObjectNamePrefix{}),
  5979  		}
  5980  
  5981  		priv := determinePrivilegeSetOfStatement(call)
  5982  		ses := newSes(priv, ctrl)
  5983  		proc := testutil.NewProcess()
  5984  		proc.FileService = getGlobalPu().FileService
  5985  		proc.SessionInfo = process.SessionInfo{Account: sysAccountName}
  5986  		ses.SetDatabaseName("procedure_test")
  5987  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  5988  		pu.SV.SetDefaultValues()
  5989  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  5990  		ses.GetTxnCompileCtx().execCtx = &ExecCtx{reqCtx: ctx, proc: proc, ses: ses}
  5991  		rm, _ := NewRoutineManager(ctx)
  5992  		ses.rm = rm
  5993  
  5994  		//no result set
  5995  		bh.sql2result["begin;"] = nil
  5996  		bh.sql2result["commit;"] = nil
  5997  		bh.sql2result["rollback;"] = nil
  5998  
  5999  		sql, err := getSqlForSpBody(ses.GetTxnHandler().GetConnCtx(), string(call.Name.Name.ObjectName), ses.GetDatabaseName())
  6000  		convey.So(err, convey.ShouldBeNil)
  6001  		mrs := newMrsForPasswordOfUser([][]interface{}{
  6002  			{"begin set sid = 1000; end", "{}"},
  6003  		})
  6004  		bh.sql2result[sql] = mrs
  6005  
  6006  		sql = getSystemVariablesWithAccount(uint64(ses.GetTenantInfo().GetTenantID()))
  6007  		mrs = newMrsForPasswordOfUser([][]interface{}{})
  6008  		bh.sql2result[sql] = mrs
  6009  
  6010  		sql = getSqlForGetSystemVariableValueWithDatabase("procedure_test", "version_compatibility")
  6011  		mrs = newMrsForPasswordOfUser([][]interface{}{
  6012  			{"0.7"},
  6013  		})
  6014  		bh.sql2result[sql] = mrs
  6015  
  6016  		_, err = doInterpretCall(ctx, ses, call)
  6017  		convey.So(err, convey.ShouldNotBeNil)
  6018  	})
  6019  
  6020  	convey.Convey("call precedure (not support)fail", t, func() {
  6021  		ctrl := gomock.NewController(t)
  6022  		defer ctrl.Finish()
  6023  
  6024  		bh := &backgroundExecTest{}
  6025  		bh.init()
  6026  
  6027  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6028  		defer bhStub.Reset()
  6029  		call := &tree.CallStmt{
  6030  			Name: tree.NewProcedureName("test_if_hit_elseif_first_elseif", tree.ObjectNamePrefix{}),
  6031  		}
  6032  
  6033  		priv := determinePrivilegeSetOfStatement(call)
  6034  		ses := newSes(priv, ctrl)
  6035  		proc := testutil.NewProcess()
  6036  		proc.FileService = getGlobalPu().FileService
  6037  		proc.SessionInfo = process.SessionInfo{Account: sysAccountName}
  6038  		ses.SetDatabaseName("procedure_test")
  6039  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  6040  		pu.SV.SetDefaultValues()
  6041  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  6042  		ses.GetTxnCompileCtx().execCtx = &ExecCtx{reqCtx: ctx, proc: proc,
  6043  			ses: ses}
  6044  		rm, _ := NewRoutineManager(ctx)
  6045  		ses.rm = rm
  6046  
  6047  		//no result set
  6048  		bh.sql2result["begin;"] = nil
  6049  		bh.sql2result["commit;"] = nil
  6050  		bh.sql2result["rollback;"] = nil
  6051  
  6052  		sql, err := getSqlForSpBody(ses.GetTxnHandler().GetConnCtx(), string(call.Name.Name.ObjectName), ses.GetDatabaseName())
  6053  		convey.So(err, convey.ShouldBeNil)
  6054  		mrs := newMrsForPasswordOfUser([][]interface{}{
  6055  			{"begin DECLARE v1 INT; SET v1 = 10; IF v1 > 5 THEN select * from tbh1; ELSEIF v1 = 5 THEN select * from tbh2; ELSEIF v1 = 4 THEN select * from tbh2 limit 1; ELSE select * from tbh3; END IF; end", "{}"},
  6056  		})
  6057  		bh.sql2result[sql] = mrs
  6058  
  6059  		sql = getSystemVariablesWithAccount(uint64(ses.GetTenantInfo().GetTenantID()))
  6060  		mrs = newMrsForPasswordOfUser([][]interface{}{})
  6061  		bh.sql2result[sql] = mrs
  6062  
  6063  		sql = getSqlForGetSystemVariableValueWithDatabase("procedure_test", "version_compatibility")
  6064  		mrs = newMrsForPasswordOfUser([][]interface{}{
  6065  			{"0.7"},
  6066  		})
  6067  		bh.sql2result[sql] = mrs
  6068  
  6069  		sql = "select v1 > 5"
  6070  		mrs = newMrsForPasswordOfUser([][]interface{}{
  6071  			{"1"},
  6072  		})
  6073  		bh.sql2result[sql] = mrs
  6074  
  6075  		sql = "select * from tbh1"
  6076  		mrs = newMrsForPasswordOfUser([][]interface{}{})
  6077  		bh.sql2result[sql] = mrs
  6078  
  6079  		_, err = doInterpretCall(ctx, ses, call)
  6080  		convey.So(err, convey.ShouldBeNil)
  6081  	})
  6082  }
  6083  
  6084  func Test_initProcedure(t *testing.T) {
  6085  	convey.Convey("init precedure fail", t, func() {
  6086  		ctrl := gomock.NewController(t)
  6087  		defer ctrl.Finish()
  6088  
  6089  		bh := &backgroundExecTest{}
  6090  		bh.init()
  6091  
  6092  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6093  		defer bhStub.Reset()
  6094  		cp := &tree.CreateProcedure{
  6095  			Name: tree.NewProcedureName("test_if_hit_elseif_first_elseif", tree.ObjectNamePrefix{}),
  6096  			Args: nil,
  6097  			Body: "'begin DECLARE v1 INT; SET v1 = 5; IF v1 > 5 THEN select * from tbh1; ELSEIF v1 = 5 THEN select * from tbh2; ELSEIF v1 = 4 THEN select * from tbh2 limit 1; ELSE select * from tbh3; END IF; end'",
  6098  		}
  6099  
  6100  		priv := determinePrivilegeSetOfStatement(cp)
  6101  		ses := newSes(priv, ctrl)
  6102  
  6103  		//no result set
  6104  		bh.sql2result["begin;"] = nil
  6105  		bh.sql2result["commit;"] = nil
  6106  		bh.sql2result["rollback;"] = nil
  6107  
  6108  		err := InitProcedure(ses.GetTxnHandler().GetConnCtx(), ses, ses.GetTenantInfo(), cp)
  6109  		convey.So(err, convey.ShouldNotBeNil)
  6110  	})
  6111  
  6112  	convey.Convey("init precedure succ", t, func() {
  6113  		ctrl := gomock.NewController(t)
  6114  		defer ctrl.Finish()
  6115  
  6116  		bh := &backgroundExecTest{}
  6117  		bh.init()
  6118  
  6119  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6120  		defer bhStub.Reset()
  6121  		cp := &tree.CreateProcedure{
  6122  			Name: tree.NewProcedureName("test_if_hit_elseif_first_elseif", tree.ObjectNamePrefix{}),
  6123  			Args: nil,
  6124  			Body: "'begin DECLARE v1 INT; SET v1 = 5; IF v1 > 5 THEN select * from tbh1; ELSEIF v1 = 5 THEN select * from tbh2; ELSEIF v1 = 4 THEN select * from tbh2 limit 1; ELSE select * from tbh3; END IF; end'",
  6125  		}
  6126  
  6127  		priv := determinePrivilegeSetOfStatement(cp)
  6128  		ses := newSes(priv, ctrl)
  6129  		ses.SetDatabaseName("test_procedure")
  6130  
  6131  		//no result set
  6132  		bh.sql2result["begin;"] = nil
  6133  		bh.sql2result["commit;"] = nil
  6134  		bh.sql2result["rollback;"] = nil
  6135  
  6136  		sql := getSqlForCheckProcedureExistence(string(cp.Name.Name.ObjectName), ses.GetDatabaseName())
  6137  		mrs := newMrsForPasswordOfUser([][]interface{}{})
  6138  		bh.sql2result[sql] = mrs
  6139  
  6140  		err := InitProcedure(ses.GetTxnHandler().GetConnCtx(), ses, ses.GetTenantInfo(), cp)
  6141  		convey.So(err, convey.ShouldBeNil)
  6142  	})
  6143  }
  6144  func TestDoSetSecondaryRoleAll(t *testing.T) {
  6145  	convey.Convey("do set secondary role succ", t, func() {
  6146  		ctrl := gomock.NewController(t)
  6147  		defer ctrl.Finish()
  6148  
  6149  		bh := &backgroundExecTest{}
  6150  		bh.init()
  6151  
  6152  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6153  		defer bhStub.Reset()
  6154  
  6155  		stmt := &tree.SetRole{
  6156  			SecondaryRole: false,
  6157  		}
  6158  
  6159  		priv := determinePrivilegeSetOfStatement(stmt)
  6160  		ses := newSes(priv, ctrl)
  6161  		tenant := &TenantInfo{
  6162  			Tenant:        "test_account",
  6163  			User:          "test_user",
  6164  			DefaultRole:   "role1",
  6165  			TenantID:      3001,
  6166  			UserID:        3,
  6167  			DefaultRoleID: 5,
  6168  		}
  6169  		ses.SetTenantInfo(tenant)
  6170  
  6171  		//no result set
  6172  		bh.sql2result["begin;"] = nil
  6173  		bh.sql2result["commit;"] = nil
  6174  		bh.sql2result["rollback;"] = nil
  6175  
  6176  		sql := getSqlForgetUserRolesExpectPublicRole(publicRoleID, ses.GetTenantInfo().UserID)
  6177  		mrs := newMrsForPasswordOfUser([][]interface{}{
  6178  			{"6", "role5"},
  6179  		})
  6180  		bh.sql2result[sql] = mrs
  6181  
  6182  		err := doSetSecondaryRoleAll(ses.GetTxnHandler().GetTxnCtx(), ses)
  6183  		convey.So(err, convey.ShouldBeNil)
  6184  	})
  6185  
  6186  	convey.Convey("do set secondary role succ", t, func() {
  6187  		ctrl := gomock.NewController(t)
  6188  		defer ctrl.Finish()
  6189  
  6190  		bh := &backgroundExecTest{}
  6191  		bh.init()
  6192  
  6193  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6194  		defer bhStub.Reset()
  6195  
  6196  		stmt := &tree.SetRole{
  6197  			SecondaryRole: false,
  6198  		}
  6199  
  6200  		priv := determinePrivilegeSetOfStatement(stmt)
  6201  		ses := newSes(priv, ctrl)
  6202  		tenant := &TenantInfo{
  6203  			Tenant:        "test_account",
  6204  			User:          "test_user",
  6205  			DefaultRole:   "role1",
  6206  			TenantID:      3001,
  6207  			UserID:        3,
  6208  			DefaultRoleID: 5,
  6209  		}
  6210  		ses.SetTenantInfo(tenant)
  6211  
  6212  		//no result set
  6213  		bh.sql2result["begin;"] = nil
  6214  		bh.sql2result["commit;"] = nil
  6215  		bh.sql2result["rollback;"] = nil
  6216  
  6217  		sql := getSqlForgetUserRolesExpectPublicRole(publicRoleID, ses.GetTenantInfo().UserID)
  6218  		mrs := newMrsForPasswordOfUser([][]interface{}{})
  6219  		bh.sql2result[sql] = mrs
  6220  
  6221  		err := doSetSecondaryRoleAll(ses.GetTxnHandler().GetTxnCtx(), ses)
  6222  		convey.So(err, convey.ShouldBeNil)
  6223  	})
  6224  }
  6225  
  6226  func TestDoGrantPrivilegeImplicitly(t *testing.T) {
  6227  	convey.Convey("do grant privilege implicitly for create database succ", t, func() {
  6228  		ctrl := gomock.NewController(t)
  6229  		defer ctrl.Finish()
  6230  
  6231  		bh := &backgroundExecTest{}
  6232  		bh.init()
  6233  
  6234  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6235  		defer bhStub.Reset()
  6236  
  6237  		stmt := &tree.CreateDatabase{
  6238  			Name: tree.Identifier("abc"),
  6239  		}
  6240  
  6241  		priv := determinePrivilegeSetOfStatement(stmt)
  6242  		ses := newSes(priv, ctrl)
  6243  		tenant := &TenantInfo{
  6244  			Tenant:        "test_account",
  6245  			User:          "test_user",
  6246  			DefaultRole:   "role1",
  6247  			TenantID:      3001,
  6248  			UserID:        3,
  6249  			DefaultRoleID: 5,
  6250  		}
  6251  		ses.SetTenantInfo(tenant)
  6252  
  6253  		//no result set
  6254  		bh.sql2result["begin;"] = nil
  6255  		bh.sql2result["commit;"] = nil
  6256  		bh.sql2result["rollback;"] = nil
  6257  
  6258  		sql := getSqlForGrantOwnershipOnDatabase(string(stmt.Name), ses.GetTenantInfo().GetDefaultRole())
  6259  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6260  		bh.sql2result[sql] = mrs
  6261  
  6262  		err := doGrantPrivilegeImplicitly(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  6263  		convey.So(err, convey.ShouldBeNil)
  6264  	})
  6265  
  6266  	convey.Convey("do grant privilege implicitly for create table succ", t, func() {
  6267  		ctrl := gomock.NewController(t)
  6268  		defer ctrl.Finish()
  6269  
  6270  		bh := &backgroundExecTest{}
  6271  		bh.init()
  6272  
  6273  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6274  		defer bhStub.Reset()
  6275  
  6276  		stmt := &tree.CreateTable{}
  6277  
  6278  		priv := determinePrivilegeSetOfStatement(stmt)
  6279  		ses := newSes(priv, ctrl)
  6280  		tenant := &TenantInfo{
  6281  			Tenant:        "test_account",
  6282  			User:          "test_user",
  6283  			DefaultRole:   "role1",
  6284  			TenantID:      3001,
  6285  			UserID:        3,
  6286  			DefaultRoleID: 5,
  6287  		}
  6288  		ses.SetTenantInfo(tenant)
  6289  
  6290  		//no result set
  6291  		bh.sql2result["begin;"] = nil
  6292  		bh.sql2result["commit;"] = nil
  6293  		bh.sql2result["rollback;"] = nil
  6294  
  6295  		sql := getSqlForGrantOwnershipOnTable("abd", "t1", ses.GetTenantInfo().GetDefaultRole())
  6296  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6297  		bh.sql2result[sql] = mrs
  6298  
  6299  		err := doGrantPrivilegeImplicitly(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  6300  		convey.So(err, convey.ShouldBeNil)
  6301  	})
  6302  	convey.Convey("do grant privilege implicitly for create database succ", t, func() {
  6303  		ctrl := gomock.NewController(t)
  6304  		defer ctrl.Finish()
  6305  
  6306  		bh := &backgroundExecTest{}
  6307  		bh.init()
  6308  
  6309  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6310  		defer bhStub.Reset()
  6311  
  6312  		stmt := &tree.CreateDatabase{
  6313  			Name: tree.Identifier("abc"),
  6314  		}
  6315  
  6316  		priv := determinePrivilegeSetOfStatement(stmt)
  6317  		ses := newSes(priv, ctrl)
  6318  		tenant := &TenantInfo{
  6319  			Tenant:        "test_account",
  6320  			User:          "test_user",
  6321  			DefaultRole:   "",
  6322  			TenantID:      3001,
  6323  			UserID:        3,
  6324  			DefaultRoleID: 5,
  6325  		}
  6326  		ses.SetTenantInfo(tenant)
  6327  
  6328  		//no result set
  6329  		bh.sql2result["begin;"] = nil
  6330  		bh.sql2result["commit;"] = nil
  6331  		bh.sql2result["rollback;"] = nil
  6332  
  6333  		sql := getSqlForGrantOwnershipOnDatabase(string(stmt.Name), ses.GetTenantInfo().GetDefaultRole())
  6334  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6335  		bh.sql2result[sql] = mrs
  6336  
  6337  		err := doGrantPrivilegeImplicitly(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  6338  		convey.So(err, convey.ShouldBeNil)
  6339  	})
  6340  
  6341  	convey.Convey("do grant privilege implicitly for create table succ", t, func() {
  6342  		ctrl := gomock.NewController(t)
  6343  		defer ctrl.Finish()
  6344  
  6345  		bh := &backgroundExecTest{}
  6346  		bh.init()
  6347  
  6348  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6349  		defer bhStub.Reset()
  6350  
  6351  		stmt := &tree.CreateTable{}
  6352  
  6353  		priv := determinePrivilegeSetOfStatement(stmt)
  6354  		ses := newSes(priv, ctrl)
  6355  		tenant := &TenantInfo{
  6356  			Tenant:        "test_account",
  6357  			User:          "test_user",
  6358  			DefaultRole:   "",
  6359  			TenantID:      3001,
  6360  			UserID:        3,
  6361  			DefaultRoleID: 5,
  6362  		}
  6363  		ses.SetTenantInfo(tenant)
  6364  
  6365  		//no result set
  6366  		bh.sql2result["begin;"] = nil
  6367  		bh.sql2result["commit;"] = nil
  6368  		bh.sql2result["rollback;"] = nil
  6369  
  6370  		sql := getSqlForGrantOwnershipOnTable("abd", "t1", ses.GetTenantInfo().GetDefaultRole())
  6371  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6372  		bh.sql2result[sql] = mrs
  6373  
  6374  		err := doGrantPrivilegeImplicitly(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  6375  		convey.So(err, convey.ShouldBeNil)
  6376  	})
  6377  }
  6378  
  6379  func TestDoRevokePrivilegeImplicitly(t *testing.T) {
  6380  	convey.Convey("do revoke privilege implicitly for drop database succ", t, func() {
  6381  		ctrl := gomock.NewController(t)
  6382  		defer ctrl.Finish()
  6383  
  6384  		bh := &backgroundExecTest{}
  6385  		bh.init()
  6386  
  6387  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6388  		defer bhStub.Reset()
  6389  
  6390  		stmt := &tree.DropDatabase{
  6391  			Name: tree.Identifier("abc"),
  6392  		}
  6393  
  6394  		priv := determinePrivilegeSetOfStatement(stmt)
  6395  		ses := newSes(priv, ctrl)
  6396  		tenant := &TenantInfo{
  6397  			Tenant:        "test_account",
  6398  			User:          "test_user",
  6399  			DefaultRole:   "role1",
  6400  			TenantID:      3001,
  6401  			UserID:        3,
  6402  			DefaultRoleID: 5,
  6403  		}
  6404  		ses.SetTenantInfo(tenant)
  6405  
  6406  		//no result set
  6407  		bh.sql2result["begin;"] = nil
  6408  		bh.sql2result["commit;"] = nil
  6409  		bh.sql2result["rollback;"] = nil
  6410  
  6411  		sql := getSqlForRevokeOwnershipFromDatabase(string(stmt.Name), ses.GetTenantInfo().GetDefaultRole())
  6412  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6413  		bh.sql2result[sql] = mrs
  6414  
  6415  		err := doRevokePrivilegeImplicitly(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  6416  		convey.So(err, convey.ShouldBeNil)
  6417  	})
  6418  
  6419  	convey.Convey("do grant privilege implicitly for drop table succ", t, func() {
  6420  		ctrl := gomock.NewController(t)
  6421  		defer ctrl.Finish()
  6422  
  6423  		bh := &backgroundExecTest{}
  6424  		bh.init()
  6425  
  6426  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6427  		defer bhStub.Reset()
  6428  
  6429  		stmt := &tree.DropTable{
  6430  			Names: tree.TableNames{
  6431  				tree.NewTableName(tree.Identifier("test1"), tree.ObjectNamePrefix{}, nil),
  6432  			},
  6433  		}
  6434  
  6435  		priv := determinePrivilegeSetOfStatement(stmt)
  6436  		ses := newSes(priv, ctrl)
  6437  		tenant := &TenantInfo{
  6438  			Tenant:        "test_account",
  6439  			User:          "test_user",
  6440  			DefaultRole:   "role1",
  6441  			TenantID:      3001,
  6442  			UserID:        3,
  6443  			DefaultRoleID: 5,
  6444  		}
  6445  		ses.SetTenantInfo(tenant)
  6446  
  6447  		//no result set
  6448  		bh.sql2result["begin;"] = nil
  6449  		bh.sql2result["commit;"] = nil
  6450  		bh.sql2result["rollback;"] = nil
  6451  
  6452  		sql := getSqlForRevokeOwnershipFromTable("abd", "t1", ses.GetTenantInfo().GetDefaultRole())
  6453  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6454  		bh.sql2result[sql] = mrs
  6455  
  6456  		err := doRevokePrivilegeImplicitly(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  6457  		convey.So(err, convey.ShouldBeNil)
  6458  	})
  6459  
  6460  	convey.Convey("do revoke privilege implicitly for drop database succ", t, func() {
  6461  		ctrl := gomock.NewController(t)
  6462  		defer ctrl.Finish()
  6463  
  6464  		bh := &backgroundExecTest{}
  6465  		bh.init()
  6466  
  6467  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6468  		defer bhStub.Reset()
  6469  
  6470  		stmt := &tree.DropDatabase{
  6471  			Name: tree.Identifier("abc"),
  6472  		}
  6473  
  6474  		priv := determinePrivilegeSetOfStatement(stmt)
  6475  		ses := newSes(priv, ctrl)
  6476  		tenant := &TenantInfo{
  6477  			Tenant:        "test_account",
  6478  			User:          "test_user",
  6479  			DefaultRole:   "",
  6480  			TenantID:      3001,
  6481  			UserID:        3,
  6482  			DefaultRoleID: 5,
  6483  		}
  6484  		ses.SetTenantInfo(tenant)
  6485  
  6486  		//no result set
  6487  		bh.sql2result["begin;"] = nil
  6488  		bh.sql2result["commit;"] = nil
  6489  		bh.sql2result["rollback;"] = nil
  6490  
  6491  		sql := getSqlForRevokeOwnershipFromDatabase(string(stmt.Name), ses.GetTenantInfo().GetDefaultRole())
  6492  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6493  		bh.sql2result[sql] = mrs
  6494  
  6495  		err := doRevokePrivilegeImplicitly(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  6496  		convey.So(err, convey.ShouldBeNil)
  6497  	})
  6498  
  6499  	convey.Convey("do grant privilege implicitly for drop table succ", t, func() {
  6500  		ctrl := gomock.NewController(t)
  6501  		defer ctrl.Finish()
  6502  
  6503  		bh := &backgroundExecTest{}
  6504  		bh.init()
  6505  
  6506  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6507  		defer bhStub.Reset()
  6508  
  6509  		stmt := &tree.DropTable{
  6510  			Names: tree.TableNames{
  6511  				tree.NewTableName(tree.Identifier("test1"), tree.ObjectNamePrefix{}, nil),
  6512  			},
  6513  		}
  6514  
  6515  		priv := determinePrivilegeSetOfStatement(stmt)
  6516  		ses := newSes(priv, ctrl)
  6517  		tenant := &TenantInfo{
  6518  			Tenant:        "test_account",
  6519  			User:          "test_user",
  6520  			DefaultRole:   "",
  6521  			TenantID:      3001,
  6522  			UserID:        3,
  6523  			DefaultRoleID: 5,
  6524  		}
  6525  		ses.SetTenantInfo(tenant)
  6526  
  6527  		//no result set
  6528  		bh.sql2result["begin;"] = nil
  6529  		bh.sql2result["commit;"] = nil
  6530  		bh.sql2result["rollback;"] = nil
  6531  
  6532  		sql := getSqlForRevokeOwnershipFromTable("abd", "t1", ses.GetTenantInfo().GetDefaultRole())
  6533  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6534  		bh.sql2result[sql] = mrs
  6535  
  6536  		err := doRevokePrivilegeImplicitly(ses.GetTxnHandler().GetTxnCtx(), ses, stmt)
  6537  		convey.So(err, convey.ShouldBeNil)
  6538  	})
  6539  
  6540  }
  6541  
  6542  func TestDoGetGlobalSystemVariable(t *testing.T) {
  6543  	convey.Convey("get global system variable succ", t, func() {
  6544  		ctrl := gomock.NewController(t)
  6545  		defer ctrl.Finish()
  6546  
  6547  		bh := &backgroundExecTest{}
  6548  		bh.init()
  6549  
  6550  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6551  		defer bhStub.Reset()
  6552  
  6553  		stmt := &tree.ShowVariables{
  6554  			Global: true,
  6555  		}
  6556  
  6557  		priv := determinePrivilegeSetOfStatement(stmt)
  6558  		ses := newSes(priv, ctrl)
  6559  
  6560  		//no result set
  6561  		bh.sql2result["begin;"] = nil
  6562  		bh.sql2result["commit;"] = nil
  6563  		bh.sql2result["rollback;"] = nil
  6564  
  6565  		sql := getSystemVariablesWithAccount(uint64(ses.GetTenantInfo().GetTenantID()))
  6566  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6567  		bh.sql2result[sql] = mrs
  6568  
  6569  		_, err := doGetGlobalSystemVariable(ses.GetTxnHandler().GetTxnCtx(), ses)
  6570  		convey.So(err, convey.ShouldBeNil)
  6571  	})
  6572  }
  6573  
  6574  func TestDoSetGlobalSystemVariable(t *testing.T) {
  6575  	convey.Convey("set global system variable succ", t, func() {
  6576  		ctrl := gomock.NewController(t)
  6577  		defer ctrl.Finish()
  6578  
  6579  		bh := &backgroundExecTest{}
  6580  		bh.init()
  6581  
  6582  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6583  		defer bhStub.Reset()
  6584  
  6585  		stmt := &tree.SetVar{
  6586  			Assignments: []*tree.VarAssignmentExpr{
  6587  				{
  6588  					System: true,
  6589  					Global: true,
  6590  					Name:   "sql_mode",
  6591  					Value:  tree.NewStrVal(""),
  6592  				},
  6593  			},
  6594  		}
  6595  
  6596  		priv := determinePrivilegeSetOfStatement(stmt)
  6597  		ses := newSes(priv, ctrl)
  6598  
  6599  		//no result set
  6600  		bh.sql2result["begin;"] = nil
  6601  		bh.sql2result["commit;"] = nil
  6602  		bh.sql2result["rollback;"] = nil
  6603  
  6604  		sql := getSqlForUpdateSystemVariableValue(getVariableValue(stmt.Assignments[0].Value), uint64(ses.GetTenantInfo().GetTenantID()), stmt.Assignments[0].Name)
  6605  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6606  		bh.sql2result[sql] = mrs
  6607  
  6608  		err := doSetGlobalSystemVariable(ses.GetTxnHandler().GetTxnCtx(), ses, stmt.Assignments[0].Name, stmt.Assignments[0].Value)
  6609  		convey.So(err, convey.ShouldBeNil)
  6610  	})
  6611  
  6612  	convey.Convey("set global system variable succ", t, func() {
  6613  		ctrl := gomock.NewController(t)
  6614  		defer ctrl.Finish()
  6615  
  6616  		bh := &backgroundExecTest{}
  6617  		bh.init()
  6618  
  6619  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6620  		defer bhStub.Reset()
  6621  
  6622  		stmt := &tree.SetVar{
  6623  			Assignments: []*tree.VarAssignmentExpr{
  6624  				{
  6625  					System: true,
  6626  					Global: true,
  6627  					Name:   "sql_mode",
  6628  					Value:  tree.NewStrVal("NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"),
  6629  				},
  6630  			},
  6631  		}
  6632  
  6633  		priv := determinePrivilegeSetOfStatement(stmt)
  6634  		ses := newSes(priv, ctrl)
  6635  
  6636  		//no result set
  6637  		bh.sql2result["begin;"] = nil
  6638  		bh.sql2result["commit;"] = nil
  6639  		bh.sql2result["rollback;"] = nil
  6640  
  6641  		sql := getSqlForUpdateSystemVariableValue(getVariableValue(stmt.Assignments[0].Value), uint64(ses.GetTenantInfo().GetTenantID()), stmt.Assignments[0].Name)
  6642  		mrs := newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6643  		bh.sql2result[sql] = mrs
  6644  
  6645  		err := doSetGlobalSystemVariable(ses.GetTxnHandler().GetTxnCtx(), ses, stmt.Assignments[0].Name, stmt.Assignments[0].Value)
  6646  		convey.So(err, convey.ShouldBeNil)
  6647  	})
  6648  }
  6649  
  6650  func boxExprStr(s string) tree.Expr {
  6651  	return tree.NewNumValWithType(constant.MakeString(s), s, false, tree.P_char)
  6652  }
  6653  
  6654  func mustUnboxExprStr(e tree.Expr) string {
  6655  	if e == nil {
  6656  		return ""
  6657  	}
  6658  	return e.(*tree.NumVal).OrigString()
  6659  }
  6660  
  6661  func Test_doAlterUser(t *testing.T) {
  6662  
  6663  	alterUserFrom := func(stmt *tree.AlterUser) *alterUser {
  6664  		au := &alterUser{}
  6665  		for _, su := range stmt.Users {
  6666  			u := &user{
  6667  				Username: su.Username,
  6668  				Hostname: su.Hostname,
  6669  			}
  6670  			if su.AuthOption != nil {
  6671  				u.AuthExist = true
  6672  				u.IdentTyp = su.AuthOption.Typ
  6673  				u.IdentStr = mustUnboxExprStr(su.AuthOption.Str)
  6674  			}
  6675  			au.Users = append(au.Users, u)
  6676  		}
  6677  		return au
  6678  	}
  6679  
  6680  	convey.Convey("alter user success", t, func() {
  6681  		ctrl := gomock.NewController(t)
  6682  		defer ctrl.Finish()
  6683  
  6684  		bh := &backgroundExecTest{}
  6685  		bh.init()
  6686  
  6687  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6688  		defer bhStub.Reset()
  6689  
  6690  		stmt := &tree.AlterUser{
  6691  			Users: []*tree.User{
  6692  				{Username: "u1", Hostname: "%", AuthOption: &tree.AccountIdentified{Typ: tree.AccountIdentifiedByPassword, Str: boxExprStr("123456")}},
  6693  			},
  6694  		}
  6695  		priv := determinePrivilegeSetOfStatement(stmt)
  6696  		ses := newSes(priv, ctrl)
  6697  
  6698  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  6699  		pu.SV.SetDefaultValues()
  6700  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  6701  
  6702  		rm, _ := NewRoutineManager(ctx)
  6703  		ses.rm = rm
  6704  
  6705  		//no result set
  6706  		bh.sql2result["begin;"] = nil
  6707  		bh.sql2result["commit;"] = nil
  6708  		bh.sql2result["rollback;"] = nil
  6709  
  6710  		for i, user := range stmt.Users {
  6711  			sql, _ := getSqlForPasswordOfUser(context.TODO(), user.Username)
  6712  			mrs := newMrsForPasswordOfUser([][]interface{}{
  6713  				{i, "111", 0},
  6714  			})
  6715  			bh.sql2result[sql] = mrs
  6716  
  6717  			sql, _ = getSqlForCheckUserHasRole(context.TODO(), "root", moAdminRoleID)
  6718  			mrs = newMrsForSqlForCheckUserHasRole([][]interface{}{
  6719  				{0, 0},
  6720  			})
  6721  			bh.sql2result[sql] = mrs
  6722  		}
  6723  
  6724  		for _, user := range stmt.Users {
  6725  			sql, _ := getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(user.AuthOption.Str), user.Username)
  6726  			bh.sql2result[sql] = nil
  6727  		}
  6728  
  6729  		err := doAlterUser(ctx, ses, alterUserFrom(stmt))
  6730  		convey.So(err, convey.ShouldBeNil)
  6731  	})
  6732  
  6733  	convey.Convey("alter user fail for alter multi user", t, func() {
  6734  		ctrl := gomock.NewController(t)
  6735  		defer ctrl.Finish()
  6736  
  6737  		bh := &backgroundExecTest{}
  6738  		bh.init()
  6739  
  6740  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6741  		defer bhStub.Reset()
  6742  
  6743  		stmt := &tree.AlterUser{
  6744  			Users: []*tree.User{
  6745  				{Username: "u1", Hostname: "%", AuthOption: &tree.AccountIdentified{Typ: tree.AccountIdentifiedByPassword, Str: boxExprStr("123456")}},
  6746  				{Username: "u2", Hostname: "%", AuthOption: &tree.AccountIdentified{Typ: tree.AccountIdentifiedByPassword, Str: boxExprStr("123456")}},
  6747  				{Username: "u3", Hostname: "%", AuthOption: &tree.AccountIdentified{Typ: tree.AccountIdentifiedByPassword, Str: boxExprStr("123456")}},
  6748  			},
  6749  		}
  6750  		priv := determinePrivilegeSetOfStatement(stmt)
  6751  		ses := newSes(priv, ctrl)
  6752  
  6753  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  6754  		pu.SV.SetDefaultValues()
  6755  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  6756  
  6757  		rm, _ := NewRoutineManager(ctx)
  6758  		ses.rm = rm
  6759  
  6760  		//no result set
  6761  		bh.sql2result["begin;"] = nil
  6762  		bh.sql2result["commit;"] = nil
  6763  		bh.sql2result["rollback;"] = nil
  6764  
  6765  		for i, user := range stmt.Users {
  6766  			sql, _ := getSqlForPasswordOfUser(context.TODO(), user.Username)
  6767  			mrs := newMrsForPasswordOfUser([][]interface{}{
  6768  				{i, "111", "public"},
  6769  			})
  6770  			bh.sql2result[sql] = mrs
  6771  
  6772  			sql, _ = getSqlForCheckUserHasRole(context.TODO(), user.Username, moAdminRoleID)
  6773  			mrs = newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6774  			bh.sql2result[sql] = mrs
  6775  		}
  6776  
  6777  		for _, user := range stmt.Users {
  6778  			sql, _ := getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(user.AuthOption.Str), user.Username)
  6779  			bh.sql2result[sql] = nil
  6780  		}
  6781  
  6782  		err := doAlterUser(ctx, ses, alterUserFrom(stmt))
  6783  		convey.So(err, convey.ShouldBeError)
  6784  	})
  6785  
  6786  	convey.Convey("alter user fail for privilege", t, func() {
  6787  		ctrl := gomock.NewController(t)
  6788  		defer ctrl.Finish()
  6789  
  6790  		bh := &backgroundExecTest{}
  6791  		bh.init()
  6792  
  6793  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6794  		defer bhStub.Reset()
  6795  
  6796  		stmt := &tree.AlterUser{
  6797  			Users: []*tree.User{
  6798  				{Username: "u1", Hostname: "%", AuthOption: &tree.AccountIdentified{Typ: tree.AccountIdentifiedByPassword, Str: boxExprStr("123456")}},
  6799  			},
  6800  		}
  6801  		priv := determinePrivilegeSetOfStatement(stmt)
  6802  		ses := newSes(priv, ctrl)
  6803  
  6804  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  6805  		pu.SV.SetDefaultValues()
  6806  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  6807  		rm, _ := NewRoutineManager(ctx)
  6808  		ses.rm = rm
  6809  
  6810  		//no result set
  6811  		bh.sql2result["begin;"] = nil
  6812  		bh.sql2result["commit;"] = nil
  6813  		bh.sql2result["rollback;"] = nil
  6814  
  6815  		for i, user := range stmt.Users {
  6816  			sql, _ := getSqlForPasswordOfUser(context.TODO(), user.Username)
  6817  			mrs := newMrsForPasswordOfUser([][]interface{}{
  6818  				{i, "111", "public"},
  6819  			})
  6820  			bh.sql2result[sql] = mrs
  6821  
  6822  			sql, _ = getSqlForCheckUserHasRole(context.TODO(), user.Username, moAdminRoleID)
  6823  			mrs = newMrsForSqlForCheckUserHasRole([][]interface{}{})
  6824  			bh.sql2result[sql] = mrs
  6825  		}
  6826  
  6827  		for _, user := range stmt.Users {
  6828  			sql, _ := getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(user.AuthOption.Str), user.Username)
  6829  			bh.sql2result[sql] = nil
  6830  		}
  6831  
  6832  		err := doAlterUser(ctx, ses, alterUserFrom(stmt))
  6833  		convey.So(err, convey.ShouldBeError)
  6834  	})
  6835  }
  6836  
  6837  func Test_doAlterAccount(t *testing.T) {
  6838  	alterAcountFromStmt := func(stmt *tree.AlterAccount) *alterAccount {
  6839  		aa := &alterAccount{
  6840  			IfExists:     stmt.IfExists,
  6841  			AuthExist:    stmt.AuthOption.Exist,
  6842  			StatusOption: stmt.StatusOption,
  6843  			Comment:      stmt.Comment,
  6844  		}
  6845  		aa.Name = mustUnboxExprStr(stmt.Name)
  6846  		if stmt.AuthOption.Exist {
  6847  			aa.AdminName = mustUnboxExprStr(stmt.AuthOption.AdminName)
  6848  			aa.IdentTyp = stmt.AuthOption.IdentifiedType.Typ
  6849  			aa.IdentStr = mustUnboxExprStr(stmt.AuthOption.IdentifiedType.Str)
  6850  		}
  6851  		return aa
  6852  	}
  6853  
  6854  	convey.Convey("alter account (auth_option) succ", t, func() {
  6855  		ctrl := gomock.NewController(t)
  6856  		defer ctrl.Finish()
  6857  
  6858  		bh := &backgroundExecTest{}
  6859  		bh.init()
  6860  
  6861  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6862  		defer bhStub.Reset()
  6863  
  6864  		stmt := &tree.AlterAccount{
  6865  			Name: boxExprStr("acc"),
  6866  			AuthOption: tree.AlterAccountAuthOption{
  6867  				Exist:     true,
  6868  				AdminName: boxExprStr("rootx"),
  6869  				IdentifiedType: tree.AccountIdentified{
  6870  					Typ: tree.AccountIdentifiedByPassword,
  6871  					Str: boxExprStr("111"),
  6872  				},
  6873  			},
  6874  		}
  6875  		priv := determinePrivilegeSetOfStatement(stmt)
  6876  		ses := newSes(priv, ctrl)
  6877  
  6878  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  6879  		pu.SV.SetDefaultValues()
  6880  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  6881  
  6882  		rm, _ := NewRoutineManager(ctx)
  6883  		ses.rm = rm
  6884  
  6885  		//no result set
  6886  		bh.sql2result["begin;"] = nil
  6887  		bh.sql2result["commit;"] = nil
  6888  		bh.sql2result["rollback;"] = nil
  6889  
  6890  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  6891  		mrs := newMrsForCheckTenant([][]interface{}{
  6892  			{0, 0, 0, 0},
  6893  		})
  6894  		bh.sql2result[sql] = mrs
  6895  
  6896  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  6897  		bh.sql2result[sql] = newMrsForPasswordOfUser([][]interface{}{
  6898  			{10, "111", 0},
  6899  		})
  6900  
  6901  		sql, _ = getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.IdentifiedType.Str), mustUnboxExprStr(stmt.AuthOption.AdminName))
  6902  		bh.sql2result[sql] = nil
  6903  
  6904  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  6905  		convey.So(err, convey.ShouldBeNil)
  6906  	})
  6907  
  6908  	convey.Convey("alter account (auth_option) failed (wrong identifiedBy)", t, func() {
  6909  		ctrl := gomock.NewController(t)
  6910  		defer ctrl.Finish()
  6911  
  6912  		bh := &backgroundExecTest{}
  6913  		bh.init()
  6914  
  6915  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6916  		defer bhStub.Reset()
  6917  
  6918  		stmt := &tree.AlterAccount{
  6919  			Name: boxExprStr("acc"),
  6920  			AuthOption: tree.AlterAccountAuthOption{
  6921  				Exist:     true,
  6922  				AdminName: boxExprStr("rootx"),
  6923  				IdentifiedType: tree.AccountIdentified{
  6924  					Typ: tree.AccountIdentifiedByRandomPassword,
  6925  					Str: boxExprStr("111"),
  6926  				},
  6927  			},
  6928  		}
  6929  		priv := determinePrivilegeSetOfStatement(stmt)
  6930  		ses := newSes(priv, ctrl)
  6931  
  6932  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  6933  		pu.SV.SetDefaultValues()
  6934  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  6935  
  6936  		rm, _ := NewRoutineManager(ctx)
  6937  		ses.rm = rm
  6938  
  6939  		//no result set
  6940  		bh.sql2result["begin;"] = nil
  6941  		bh.sql2result["commit;"] = nil
  6942  		bh.sql2result["rollback;"] = nil
  6943  
  6944  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  6945  		mrs := newMrsForCheckTenant([][]interface{}{
  6946  			{0, 0, 0, 0},
  6947  		})
  6948  		bh.sql2result[sql] = mrs
  6949  
  6950  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  6951  		bh.sql2result[sql] = newMrsForPasswordOfUser([][]interface{}{
  6952  			{10, "111", 0},
  6953  		})
  6954  
  6955  		sql, _ = getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.IdentifiedType.Str), mustUnboxExprStr(stmt.AuthOption.AdminName))
  6956  		bh.sql2result[sql] = nil
  6957  
  6958  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  6959  		convey.So(err, convey.ShouldNotBeNil)
  6960  	})
  6961  
  6962  	convey.Convey("alter account (auth_option) failed (no account)", t, func() {
  6963  		ctrl := gomock.NewController(t)
  6964  		defer ctrl.Finish()
  6965  
  6966  		bh := &backgroundExecTest{}
  6967  		bh.init()
  6968  
  6969  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  6970  		defer bhStub.Reset()
  6971  
  6972  		stmt := &tree.AlterAccount{
  6973  			Name: boxExprStr("acc"),
  6974  			AuthOption: tree.AlterAccountAuthOption{
  6975  				Exist:     true,
  6976  				AdminName: boxExprStr("rootx"),
  6977  				IdentifiedType: tree.AccountIdentified{
  6978  					Typ: tree.AccountIdentifiedByRandomPassword,
  6979  					Str: boxExprStr("111"),
  6980  				},
  6981  			},
  6982  		}
  6983  		priv := determinePrivilegeSetOfStatement(stmt)
  6984  		ses := newSes(priv, ctrl)
  6985  
  6986  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  6987  		pu.SV.SetDefaultValues()
  6988  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  6989  
  6990  		rm, _ := NewRoutineManager(ctx)
  6991  		ses.rm = rm
  6992  
  6993  		//no result set
  6994  		bh.sql2result["begin;"] = nil
  6995  		bh.sql2result["commit;"] = nil
  6996  		bh.sql2result["rollback;"] = nil
  6997  
  6998  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  6999  		bh.sql2result[sql] = nil
  7000  
  7001  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7002  		bh.sql2result[sql] = nil
  7003  
  7004  		sql, _ = getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.IdentifiedType.Str), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7005  		bh.sql2result[sql] = nil
  7006  
  7007  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  7008  		convey.So(err, convey.ShouldNotBeNil)
  7009  	})
  7010  
  7011  	convey.Convey("alter account (auth_option) succ (no account, if exists)", t, func() {
  7012  		ctrl := gomock.NewController(t)
  7013  		defer ctrl.Finish()
  7014  
  7015  		bh := &backgroundExecTest{}
  7016  		bh.init()
  7017  
  7018  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7019  		defer bhStub.Reset()
  7020  
  7021  		stmt := &tree.AlterAccount{
  7022  			IfExists: true,
  7023  			Name:     boxExprStr("acc"),
  7024  			AuthOption: tree.AlterAccountAuthOption{
  7025  				Exist:     true,
  7026  				AdminName: boxExprStr("rootx"),
  7027  				IdentifiedType: tree.AccountIdentified{
  7028  					Typ: tree.AccountIdentifiedByPassword,
  7029  					Str: boxExprStr("111"),
  7030  				},
  7031  			},
  7032  		}
  7033  		priv := determinePrivilegeSetOfStatement(stmt)
  7034  		ses := newSes(priv, ctrl)
  7035  
  7036  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7037  		pu.SV.SetDefaultValues()
  7038  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7039  
  7040  		rm, _ := NewRoutineManager(ctx)
  7041  		ses.rm = rm
  7042  
  7043  		//no result set
  7044  		bh.sql2result["begin;"] = nil
  7045  		bh.sql2result["commit;"] = nil
  7046  		bh.sql2result["rollback;"] = nil
  7047  
  7048  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7049  		mrs := newMrsForCheckTenant([][]interface{}{})
  7050  		bh.sql2result[sql] = mrs
  7051  
  7052  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7053  		bh.sql2result[sql] = nil
  7054  
  7055  		sql, _ = getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.IdentifiedType.Str), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7056  		bh.sql2result[sql] = nil
  7057  
  7058  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  7059  		convey.So(err, convey.ShouldBeNil)
  7060  	})
  7061  
  7062  	convey.Convey("alter account (auth_option) failed (has account,if exists, no user)", t, func() {
  7063  		ctrl := gomock.NewController(t)
  7064  		defer ctrl.Finish()
  7065  
  7066  		bh := &backgroundExecTest{}
  7067  		bh.init()
  7068  
  7069  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7070  		defer bhStub.Reset()
  7071  
  7072  		stmt := &tree.AlterAccount{
  7073  			IfExists: true,
  7074  			Name:     boxExprStr("acc"),
  7075  			AuthOption: tree.AlterAccountAuthOption{
  7076  				Exist:     true,
  7077  				AdminName: boxExprStr("rootx"),
  7078  				IdentifiedType: tree.AccountIdentified{
  7079  					Typ: tree.AccountIdentifiedByPassword,
  7080  					Str: boxExprStr("111"),
  7081  				},
  7082  			},
  7083  		}
  7084  		priv := determinePrivilegeSetOfStatement(stmt)
  7085  		ses := newSes(priv, ctrl)
  7086  
  7087  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7088  		pu.SV.SetDefaultValues()
  7089  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7090  
  7091  		rm, _ := NewRoutineManager(ctx)
  7092  		ses.rm = rm
  7093  
  7094  		//no result set
  7095  		bh.sql2result["begin;"] = nil
  7096  		bh.sql2result["commit;"] = nil
  7097  		bh.sql2result["rollback;"] = nil
  7098  
  7099  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7100  		mrs := newMrsForCheckTenant([][]interface{}{
  7101  			{0, "0", "open", 0},
  7102  		})
  7103  		bh.sql2result[sql] = mrs
  7104  
  7105  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7106  		bh.sql2result[sql] = newMrsForPasswordOfUser([][]interface{}{})
  7107  
  7108  		sql, _ = getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.IdentifiedType.Str), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7109  		bh.sql2result[sql] = newMrsForCheckTenant([][]interface{}{
  7110  			{0, 0, 0, 0},
  7111  		})
  7112  
  7113  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  7114  		convey.So(err, convey.ShouldNotBeNil)
  7115  	})
  7116  
  7117  	convey.Convey("alter account (auth_option) failed (no option)", t, func() {
  7118  		ctrl := gomock.NewController(t)
  7119  		defer ctrl.Finish()
  7120  
  7121  		bh := &backgroundExecTest{}
  7122  		bh.init()
  7123  
  7124  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7125  		defer bhStub.Reset()
  7126  
  7127  		stmt := &tree.AlterAccount{
  7128  			IfExists: true,
  7129  			Name:     boxExprStr("acc"),
  7130  		}
  7131  		priv := determinePrivilegeSetOfStatement(stmt)
  7132  		ses := newSes(priv, ctrl)
  7133  
  7134  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7135  		pu.SV.SetDefaultValues()
  7136  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7137  
  7138  		rm, _ := NewRoutineManager(ctx)
  7139  		ses.rm = rm
  7140  
  7141  		//no result set
  7142  		bh.sql2result["begin;"] = nil
  7143  		bh.sql2result["commit;"] = nil
  7144  		bh.sql2result["rollback;"] = nil
  7145  
  7146  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7147  		bh.sql2result[sql] = nil
  7148  
  7149  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7150  		bh.sql2result[sql] = nil
  7151  
  7152  		sql, _ = getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.IdentifiedType.Str), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7153  		bh.sql2result[sql] = nil
  7154  
  7155  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  7156  		convey.So(err, convey.ShouldNotBeNil)
  7157  	})
  7158  
  7159  	convey.Convey("alter account (auth_option) failed (two options)", t, func() {
  7160  		ctrl := gomock.NewController(t)
  7161  		defer ctrl.Finish()
  7162  
  7163  		bh := &backgroundExecTest{}
  7164  		bh.init()
  7165  
  7166  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7167  		defer bhStub.Reset()
  7168  
  7169  		stmt := &tree.AlterAccount{
  7170  			IfExists: true,
  7171  			Name:     boxExprStr("acc"),
  7172  			AuthOption: tree.AlterAccountAuthOption{
  7173  				Exist:     true,
  7174  				AdminName: boxExprStr("rootx"),
  7175  				IdentifiedType: tree.AccountIdentified{
  7176  					Typ: tree.AccountIdentifiedByPassword,
  7177  					Str: boxExprStr("111"),
  7178  				},
  7179  			},
  7180  			StatusOption: tree.AccountStatus{
  7181  				Exist:  true,
  7182  				Option: tree.AccountStatusOpen,
  7183  			},
  7184  		}
  7185  		priv := determinePrivilegeSetOfStatement(stmt)
  7186  		ses := newSes(priv, ctrl)
  7187  
  7188  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7189  		pu.SV.SetDefaultValues()
  7190  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7191  
  7192  		rm, _ := NewRoutineManager(ctx)
  7193  		ses.rm = rm
  7194  
  7195  		//no result set
  7196  		bh.sql2result["begin;"] = nil
  7197  		bh.sql2result["commit;"] = nil
  7198  		bh.sql2result["rollback;"] = nil
  7199  
  7200  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7201  		bh.sql2result[sql] = nil
  7202  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7203  		bh.sql2result[sql] = nil
  7204  
  7205  		sql, _ = getSqlForUpdatePasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.IdentifiedType.Str), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7206  		bh.sql2result[sql] = nil
  7207  
  7208  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  7209  		convey.So(err, convey.ShouldNotBeNil)
  7210  	})
  7211  
  7212  	convey.Convey("alter account (auth_option) succ Comments", t, func() {
  7213  		ctrl := gomock.NewController(t)
  7214  		defer ctrl.Finish()
  7215  
  7216  		bh := &backgroundExecTest{}
  7217  		bh.init()
  7218  
  7219  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7220  		defer bhStub.Reset()
  7221  
  7222  		stmt := &tree.AlterAccount{
  7223  			Name: boxExprStr("acc"),
  7224  			Comment: tree.AccountComment{
  7225  				Exist:   true,
  7226  				Comment: "new account",
  7227  			},
  7228  		}
  7229  		priv := determinePrivilegeSetOfStatement(stmt)
  7230  		ses := newSes(priv, ctrl)
  7231  
  7232  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7233  		pu.SV.SetDefaultValues()
  7234  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7235  
  7236  		rm, _ := NewRoutineManager(ctx)
  7237  		ses.rm = rm
  7238  
  7239  		//no result set
  7240  		bh.sql2result["begin;"] = nil
  7241  		bh.sql2result["commit;"] = nil
  7242  		bh.sql2result["rollback;"] = nil
  7243  
  7244  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7245  		mrs := newMrsForCheckTenant([][]interface{}{
  7246  			{0, 0, 0, 0},
  7247  		})
  7248  		bh.sql2result[sql] = mrs
  7249  
  7250  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7251  		bh.sql2result[sql] = nil
  7252  
  7253  		sql, _ = getSqlForUpdateCommentsOfAccount(context.TODO(), stmt.Comment.Comment, mustUnboxExprStr(stmt.Name))
  7254  		bh.sql2result[sql] = nil
  7255  
  7256  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  7257  		convey.So(err, convey.ShouldBeNil)
  7258  	})
  7259  
  7260  	convey.Convey("alter account (auth_option) succ Status", t, func() {
  7261  		ctrl := gomock.NewController(t)
  7262  		defer ctrl.Finish()
  7263  
  7264  		bh := &backgroundExecTest{}
  7265  		bh.init()
  7266  
  7267  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7268  		defer bhStub.Reset()
  7269  
  7270  		stmt := &tree.AlterAccount{
  7271  			Name: boxExprStr("acc"),
  7272  			StatusOption: tree.AccountStatus{
  7273  				Exist:  true,
  7274  				Option: tree.AccountStatusSuspend,
  7275  			},
  7276  		}
  7277  		priv := determinePrivilegeSetOfStatement(stmt)
  7278  		ses := newSes(priv, ctrl)
  7279  
  7280  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7281  		pu.SV.SetDefaultValues()
  7282  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7283  
  7284  		rm, _ := NewRoutineManager(ctx)
  7285  		ses.rm = rm
  7286  
  7287  		//no result set
  7288  		bh.sql2result["begin;"] = nil
  7289  		bh.sql2result["commit;"] = nil
  7290  		bh.sql2result["rollback;"] = nil
  7291  
  7292  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7293  		mrs := newMrsForCheckTenant([][]interface{}{
  7294  			{0, 0, 0, 0},
  7295  		})
  7296  		bh.sql2result[sql] = mrs
  7297  
  7298  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7299  		bh.sql2result[sql] = nil
  7300  
  7301  		sql, _ = getSqlForUpdateStatusOfAccount(context.TODO(), stmt.StatusOption.Option.String(), types.CurrentTimestamp().String2(time.UTC, 0), mustUnboxExprStr(stmt.Name))
  7302  		bh.sql2result[sql] = nil
  7303  
  7304  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  7305  		convey.So(err, convey.ShouldBeNil)
  7306  	})
  7307  
  7308  	convey.Convey("alter account (status_option) fail", t, func() {
  7309  		ctrl := gomock.NewController(t)
  7310  		defer ctrl.Finish()
  7311  
  7312  		bh := &backgroundExecTest{}
  7313  		bh.init()
  7314  
  7315  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7316  		defer bhStub.Reset()
  7317  
  7318  		stmt := &tree.AlterAccount{
  7319  			Name: boxExprStr("sys"),
  7320  			StatusOption: tree.AccountStatus{
  7321  				Exist:  true,
  7322  				Option: tree.AccountStatusSuspend,
  7323  			},
  7324  		}
  7325  		priv := determinePrivilegeSetOfStatement(stmt)
  7326  		ses := newSes(priv, ctrl)
  7327  
  7328  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7329  		pu.SV.SetDefaultValues()
  7330  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7331  
  7332  		rm, _ := NewRoutineManager(ctx)
  7333  		ses.rm = rm
  7334  
  7335  		//no result set
  7336  		bh.sql2result["begin;"] = nil
  7337  		bh.sql2result["commit;"] = nil
  7338  		bh.sql2result["rollback;"] = nil
  7339  
  7340  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7341  		bh.sql2result[sql] = nil
  7342  
  7343  		sql, _ = getSqlForPasswordOfUser(context.TODO(), mustUnboxExprStr(stmt.AuthOption.AdminName))
  7344  		bh.sql2result[sql] = nil
  7345  
  7346  		sql, _ = getSqlForUpdateStatusOfAccount(context.TODO(), stmt.StatusOption.Option.String(), types.CurrentTimestamp().String2(time.UTC, 0), mustUnboxExprStr(stmt.Name))
  7347  		bh.sql2result[sql] = nil
  7348  
  7349  		err := doAlterAccount(ses.GetTxnHandler().GetTxnCtx(), ses, alterAcountFromStmt(stmt))
  7350  		convey.So(err, convey.ShouldNotBeNil)
  7351  	})
  7352  }
  7353  
  7354  func newMrsForShowTables(rows [][]interface{}) *MysqlResultSet {
  7355  	mrs := &MysqlResultSet{}
  7356  
  7357  	col2 := &MysqlColumn{}
  7358  	col2.SetName("table")
  7359  	col2.SetColumnType(defines.MYSQL_TYPE_VARCHAR)
  7360  	mrs.AddColumn(col2)
  7361  
  7362  	for _, row := range rows {
  7363  		mrs.AddRow(row)
  7364  	}
  7365  
  7366  	return mrs
  7367  }
  7368  
  7369  func Test_doDropAccount(t *testing.T) {
  7370  	convey.Convey("drop account", t, func() {
  7371  		ctrl := gomock.NewController(t)
  7372  		defer ctrl.Finish()
  7373  
  7374  		bh := &backgroundExecTest{}
  7375  		bh.init()
  7376  
  7377  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7378  		defer bhStub.Reset()
  7379  
  7380  		stmt := &tree.DropAccount{
  7381  			Name: boxExprStr("acc"),
  7382  		}
  7383  		priv := determinePrivilegeSetOfStatement(stmt)
  7384  		ses := newSes(priv, ctrl)
  7385  
  7386  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7387  		pu.SV.SetDefaultValues()
  7388  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7389  
  7390  		rm, _ := NewRoutineManager(ctx)
  7391  		ses.rm = rm
  7392  
  7393  		//no result set
  7394  		bh.sql2result["begin;"] = nil
  7395  		bh.sql2result["commit;"] = nil
  7396  		bh.sql2result["rollback;"] = nil
  7397  
  7398  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7399  		mrs := newMrsForCheckTenant([][]interface{}{
  7400  			{0, "0", "open", 0},
  7401  		})
  7402  		bh.sql2result[sql] = mrs
  7403  
  7404  		sql, _ = getSqlForDeleteAccountFromMoAccount(context.TODO(), mustUnboxExprStr(stmt.Name))
  7405  		bh.sql2result[sql] = nil
  7406  
  7407  		for _, sql = range getSqlForDropAccount() {
  7408  			bh.sql2result[sql] = nil
  7409  		}
  7410  
  7411  		sql = "show databases;"
  7412  		bh.sql2result[sql] = newMrsForSqlForShowDatabases([][]interface{}{})
  7413  
  7414  		bh.sql2result["show tables from mo_catalog;"] = newMrsForShowTables([][]interface{}{})
  7415  
  7416  		err := doDropAccount(ses.GetTxnHandler().GetTxnCtx(), ses, &dropAccount{
  7417  			IfExists: stmt.IfExists,
  7418  			Name:     mustUnboxExprStr(stmt.Name),
  7419  		})
  7420  		convey.So(err, convey.ShouldBeNil)
  7421  	})
  7422  	convey.Convey("drop account (if exists)", t, func() {
  7423  		ctrl := gomock.NewController(t)
  7424  		defer ctrl.Finish()
  7425  
  7426  		bh := &backgroundExecTest{}
  7427  		bh.init()
  7428  
  7429  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7430  		defer bhStub.Reset()
  7431  
  7432  		stmt := &tree.DropAccount{
  7433  			IfExists: true,
  7434  			Name:     boxExprStr("acc"),
  7435  		}
  7436  		priv := determinePrivilegeSetOfStatement(stmt)
  7437  		ses := newSes(priv, ctrl)
  7438  
  7439  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7440  		pu.SV.SetDefaultValues()
  7441  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7442  
  7443  		rm, _ := NewRoutineManager(ctx)
  7444  		ses.rm = rm
  7445  
  7446  		//no result set
  7447  		bh.sql2result["begin;"] = nil
  7448  		bh.sql2result["commit;"] = nil
  7449  		bh.sql2result["rollback;"] = nil
  7450  
  7451  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7452  		mrs := newMrsForCheckTenant([][]interface{}{})
  7453  		bh.sql2result[sql] = mrs
  7454  
  7455  		sql, _ = getSqlForDeleteAccountFromMoAccount(context.TODO(), mustUnboxExprStr(stmt.Name))
  7456  		bh.sql2result[sql] = nil
  7457  
  7458  		for _, sql = range getSqlForDropAccount() {
  7459  			bh.sql2result[sql] = nil
  7460  		}
  7461  
  7462  		bh.sql2result["show tables from mo_catalog;"] = newMrsForShowTables([][]interface{}{})
  7463  
  7464  		err := doDropAccount(ses.GetTxnHandler().GetTxnCtx(), ses, &dropAccount{
  7465  			IfExists: stmt.IfExists,
  7466  			Name:     mustUnboxExprStr(stmt.Name),
  7467  		})
  7468  		convey.So(err, convey.ShouldBeNil)
  7469  	})
  7470  	convey.Convey("drop account fail", t, func() {
  7471  		ctrl := gomock.NewController(t)
  7472  		defer ctrl.Finish()
  7473  
  7474  		bh := &backgroundExecTest{}
  7475  		bh.init()
  7476  
  7477  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  7478  		defer bhStub.Reset()
  7479  
  7480  		stmt := &tree.DropAccount{
  7481  			Name: boxExprStr("acc"),
  7482  		}
  7483  		priv := determinePrivilegeSetOfStatement(stmt)
  7484  		ses := newSes(priv, ctrl)
  7485  
  7486  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7487  		pu.SV.SetDefaultValues()
  7488  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7489  
  7490  		rm, _ := NewRoutineManager(ctx)
  7491  		ses.rm = rm
  7492  
  7493  		//no result set
  7494  		bh.sql2result["begin;"] = nil
  7495  		bh.sql2result["commit;"] = nil
  7496  		bh.sql2result["rollback;"] = nil
  7497  
  7498  		sql, _ := getSqlForCheckTenant(context.TODO(), mustUnboxExprStr(stmt.Name))
  7499  		mrs := newMrsForCheckTenant([][]interface{}{})
  7500  		bh.sql2result[sql] = mrs
  7501  
  7502  		sql, _ = getSqlForDeleteAccountFromMoAccount(context.TODO(), mustUnboxExprStr(stmt.Name))
  7503  		bh.sql2result[sql] = nil
  7504  
  7505  		for _, sql = range getSqlForDropAccount() {
  7506  			bh.sql2result[sql] = nil
  7507  		}
  7508  
  7509  		err := doDropAccount(ses.GetTxnHandler().GetTxnCtx(), ses, &dropAccount{
  7510  			IfExists: stmt.IfExists,
  7511  			Name:     mustUnboxExprStr(stmt.Name),
  7512  		})
  7513  		convey.So(err, convey.ShouldBeError)
  7514  	})
  7515  }
  7516  
  7517  func generateGrantPrivilege(grant, to string, exists bool, roleNames []string, withGrantOption bool) {
  7518  	names := ""
  7519  	for i, name := range roleNames {
  7520  		if i > 0 {
  7521  			names += ","
  7522  		}
  7523  		names += name
  7524  	}
  7525  	levels := make(map[objectType][]privilegeLevelType)
  7526  	levels[objectTypeTable] = []privilegeLevelType{
  7527  		privilegeLevelStar,
  7528  		privilegeLevelStarStar,
  7529  		privilegeLevelDatabaseStar,
  7530  		privilegeLevelDatabaseTable,
  7531  		privilegeLevelTable,
  7532  	}
  7533  	levels[objectTypeDatabase] = []privilegeLevelType{
  7534  		privilegeLevelStar,
  7535  		privilegeLevelStarStar,
  7536  		privilegeLevelDatabase,
  7537  	}
  7538  	levels[objectTypeAccount] = []privilegeLevelType{
  7539  		privilegeLevelStar,
  7540  	}
  7541  	for i := PrivilegeTypeCreateAccount; i <= PrivilegeTypeExecute; i++ {
  7542  		switch i {
  7543  		case PrivilegeTypeCreateObject, PrivilegeTypeDropObject, PrivilegeTypeAlterObject:
  7544  			continue
  7545  		}
  7546  		for j := objectTypeDatabase; j <= objectTypeAccount; j++ {
  7547  			switch i.Scope() {
  7548  			case PrivilegeScopeSys, PrivilegeScopeAccount, PrivilegeScopeUser, PrivilegeScopeRole:
  7549  				if j != objectTypeAccount {
  7550  					continue
  7551  				}
  7552  			case PrivilegeScopeDatabase:
  7553  				if j != objectTypeDatabase {
  7554  					continue
  7555  				}
  7556  			case PrivilegeScopeTable:
  7557  				if j != objectTypeTable {
  7558  					continue
  7559  				}
  7560  			case PrivilegeScopeRoutine:
  7561  				if j != objectTypeFunction {
  7562  					continue
  7563  				}
  7564  			}
  7565  			if j == objectTypeFunction {
  7566  				continue
  7567  			}
  7568  
  7569  			for _, k := range levels[j] {
  7570  				bb := bytes.Buffer{}
  7571  				bb.WriteString(grant)
  7572  				if exists {
  7573  					bb.WriteString(" ")
  7574  					bb.WriteString("if exists")
  7575  				}
  7576  
  7577  				bb.WriteString(" ")
  7578  				s := fmt.Sprintf("%v on %v %v", i, j, k)
  7579  				bb.WriteString(s)
  7580  				bb.WriteString(" ")
  7581  				bb.WriteString(to)
  7582  				bb.WriteString(" ")
  7583  				bb.WriteString(names)
  7584  				if withGrantOption {
  7585  					bb.WriteString(" with grant option")
  7586  				}
  7587  				bb.WriteString(";")
  7588  				convey.So(len(s) != 0, convey.ShouldBeTrue)
  7589  				//fmt.Println(bb.String())
  7590  			}
  7591  		}
  7592  	}
  7593  }
  7594  
  7595  func Test_generateGrantPrivilege(t *testing.T) {
  7596  	convey.Convey("grant privilege combination", t, func() {
  7597  		generateGrantPrivilege("grant", "to", false, []string{"role_r1"}, false)
  7598  	})
  7599  }
  7600  
  7601  func Test_generateRevokePrivilege(t *testing.T) {
  7602  	convey.Convey("grant privilege combination", t, func() {
  7603  		generateGrantPrivilege("revoke", "from", true, []string{"role_r1", "rx"}, false)
  7604  		generateGrantPrivilege("revoke", "from", false, []string{"role_r1", "rx"}, false)
  7605  	})
  7606  }
  7607  
  7608  func Test_Name(t *testing.T) {
  7609  	convey.Convey("test", t, func() {
  7610  		type arg struct {
  7611  			input string
  7612  			want  string
  7613  		}
  7614  
  7615  		args := []arg{
  7616  			{" abc ", "abc"},
  7617  		}
  7618  
  7619  		for _, a := range args {
  7620  			ret, _ := normalizeName(context.TODO(), a.input)
  7621  			convey.So(ret == a.want, convey.ShouldBeTrue)
  7622  		}
  7623  	})
  7624  
  7625  	convey.Convey("test2", t, func() {
  7626  		type arg struct {
  7627  			input string
  7628  			want  bool
  7629  		}
  7630  
  7631  		args := []arg{
  7632  			{"abc", false},
  7633  			{"a:bc", true},
  7634  			{"  a:bc  ", true},
  7635  		}
  7636  
  7637  		for _, a := range args {
  7638  			ret := nameIsInvalid(a.input)
  7639  			convey.So(ret == a.want, convey.ShouldBeTrue)
  7640  		}
  7641  	})
  7642  }
  7643  
  7644  func genRevokeCases1(A [][]string, path []string, cur int, exists bool, out *[]string) {
  7645  	if cur == len(A) {
  7646  		bb := bytes.Buffer{}
  7647  		bb.WriteString("revoke ")
  7648  		if exists {
  7649  			bb.WriteString("if exists ")
  7650  		}
  7651  		bb.WriteString(path[0])
  7652  		bb.WriteString(",")
  7653  		bb.WriteString(path[1])
  7654  		bb.WriteString(" ")
  7655  		bb.WriteString("from ")
  7656  		bb.WriteString(path[2])
  7657  		bb.WriteString(",")
  7658  		bb.WriteString(path[3])
  7659  		bb.WriteString(";")
  7660  		*out = append(*out, bb.String())
  7661  	} else {
  7662  		for i := 0; i < len(A[cur]); i++ {
  7663  			path[cur] = A[cur][i]
  7664  			genRevokeCases1(A, path, cur+1, exists, out)
  7665  		}
  7666  	}
  7667  }
  7668  
  7669  func Test_genRevokeCases(t *testing.T) {
  7670  	A := [][]string{
  7671  		{"r1", "role_r1"},
  7672  		{"r2", "role_r2"},
  7673  		{"u1", "role_u1"},
  7674  		{"u2", "role_u2"},
  7675  	}
  7676  	Path := []string{"", "", "", ""}
  7677  	Out := []string{}
  7678  	genRevokeCases1(A, Path, 0, true, &Out)
  7679  	genRevokeCases1(A, Path, 0, false, &Out)
  7680  	for _, s := range Out {
  7681  		fmt.Println(s)
  7682  	}
  7683  }
  7684  
  7685  func newSes(priv *privilege, ctrl *gomock.Controller) *Session {
  7686  	pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  7687  	pu.SV.SetDefaultValues()
  7688  	setGlobalPu(pu)
  7689  
  7690  	ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  7691  	ctx = defines.AttachAccountId(ctx, 0)
  7692  	ioses := mock_frontend.NewMockIOSession(ctrl)
  7693  	ioses.EXPECT().OutBuf().Return(buf.NewByteBuf(1024)).AnyTimes()
  7694  	ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  7695  	ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  7696  	ioses.EXPECT().Ref().AnyTimes()
  7697  	proto := NewMysqlClientProtocol(0, ioses, 1024, pu.SV)
  7698  
  7699  	ses := NewSession(ctx, proto, nil, GSysVariables, true, nil)
  7700  	tenant := &TenantInfo{
  7701  		Tenant:        sysAccountName,
  7702  		User:          rootName,
  7703  		DefaultRole:   moAdminRoleName,
  7704  		TenantID:      sysAccountID,
  7705  		UserID:        rootID,
  7706  		DefaultRoleID: moAdminRoleID,
  7707  	}
  7708  	ses.SetTenantInfo(tenant)
  7709  	ses.priv = priv
  7710  
  7711  	rm, _ := NewRoutineManager(ctx)
  7712  	rm.baseService = new(MockBaseService)
  7713  	ses.rm = rm
  7714  
  7715  	return ses
  7716  }
  7717  
  7718  var _ BaseService = &MockBaseService{}
  7719  
  7720  type MockBaseService struct {
  7721  }
  7722  
  7723  func (m *MockBaseService) ID() string {
  7724  	//TODO implement me
  7725  	panic("implement me")
  7726  }
  7727  
  7728  func (m *MockBaseService) SQLAddress() string {
  7729  	//TODO implement me
  7730  	panic("implement me")
  7731  }
  7732  
  7733  func (m *MockBaseService) SessionMgr() *queryservice.SessionManager {
  7734  	//TODO implement me
  7735  	panic("implement me")
  7736  }
  7737  
  7738  func (m *MockBaseService) CheckTenantUpgrade(ctx context.Context, tenantID int64) error {
  7739  	//TODO implement me
  7740  	panic("implement me")
  7741  }
  7742  
  7743  func (m *MockBaseService) GetFinalVersion() string {
  7744  	return "1.2.0"
  7745  }
  7746  
  7747  func (s *MockBaseService) UpgradeTenant(ctx context.Context, tenantName string, retryCount uint32, isALLAccount bool) error {
  7748  	//TODO implement me
  7749  	panic("implement me")
  7750  }
  7751  
  7752  func newBh(ctrl *gomock.Controller, sql2result map[string]ExecResult) BackgroundExec {
  7753  	var currentSql string
  7754  	bh := mock_frontend.NewMockBackgroundExec(ctrl)
  7755  	bh.EXPECT().ClearExecResultSet().AnyTimes()
  7756  	bh.EXPECT().Close().Return().AnyTimes()
  7757  	bh.EXPECT().Exec(gomock.Any(), gomock.Any()).DoAndReturn(func(_ context.Context, sql string) error {
  7758  		currentSql = sql
  7759  		return nil
  7760  	}).AnyTimes()
  7761  	bh.EXPECT().GetExecResultSet().DoAndReturn(func() []interface{} {
  7762  		return []interface{}{sql2result[currentSql]}
  7763  	}).AnyTimes()
  7764  	return bh
  7765  }
  7766  
  7767  type backgroundExecTest struct {
  7768  	currentSql string
  7769  	sql2result map[string]ExecResult
  7770  }
  7771  
  7772  func (bt *backgroundExecTest) ExecStmt(ctx context.Context, statement tree.Statement) error {
  7773  	//TODO implement me
  7774  	panic("implement me")
  7775  }
  7776  
  7777  func (bt *backgroundExecTest) GetExecResultBatches() []*batch.Batch {
  7778  	//TODO implement me
  7779  	panic("implement me")
  7780  }
  7781  
  7782  func (bt *backgroundExecTest) ClearExecResultBatches() {
  7783  	//TODO implement me
  7784  	panic("implement me")
  7785  }
  7786  
  7787  func (bt *backgroundExecTest) init() {
  7788  	bt.sql2result = make(map[string]ExecResult)
  7789  }
  7790  
  7791  func (bt *backgroundExecTest) Close() {
  7792  }
  7793  
  7794  func (bt *backgroundExecTest) Clear() {}
  7795  
  7796  func (bt *backgroundExecTest) Exec(ctx context.Context, s string) error {
  7797  	bt.currentSql = s
  7798  	return nil
  7799  }
  7800  
  7801  func (bt *backgroundExecTest) ExecRestore(context.Context, string, uint32, uint32) error {
  7802  	panic("unimplement")
  7803  }
  7804  
  7805  func (bt *backgroundExecTest) GetExecResultSet() []interface{} {
  7806  	return []interface{}{bt.sql2result[bt.currentSql]}
  7807  }
  7808  
  7809  func (bt *backgroundExecTest) ClearExecResultSet() {
  7810  	//bt.init()
  7811  }
  7812  
  7813  var _ BackgroundExec = &backgroundExecTest{}
  7814  
  7815  func newMrsForSqlForShowDatabases(rows [][]interface{}) *MysqlResultSet {
  7816  	mrs := &MysqlResultSet{}
  7817  
  7818  	col1 := &MysqlColumn{}
  7819  	col1.SetName("Database")
  7820  	col1.SetColumnType(defines.MYSQL_TYPE_VARCHAR)
  7821  	mrs.AddColumn(col1)
  7822  
  7823  	for _, row := range rows {
  7824  		mrs.AddRow(row)
  7825  	}
  7826  
  7827  	return mrs
  7828  }
  7829  
  7830  func newMrsForSqlForCheckUserHasRole(rows [][]interface{}) *MysqlResultSet {
  7831  	mrs := &MysqlResultSet{}
  7832  
  7833  	col1 := &MysqlColumn{}
  7834  	col1.SetName("user_id")
  7835  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7836  
  7837  	col2 := &MysqlColumn{}
  7838  	col2.SetName("role_id")
  7839  	col2.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7840  
  7841  	mrs.AddColumn(col1)
  7842  	mrs.AddColumn(col2)
  7843  
  7844  	for _, row := range rows {
  7845  		mrs.AddRow(row)
  7846  	}
  7847  
  7848  	return mrs
  7849  }
  7850  
  7851  func newMrsForRoleIdOfRole(rows [][]interface{}) *MysqlResultSet {
  7852  	mrs := &MysqlResultSet{}
  7853  
  7854  	col1 := &MysqlColumn{}
  7855  	col1.SetName("role_id")
  7856  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7857  
  7858  	mrs.AddColumn(col1)
  7859  
  7860  	for _, row := range rows {
  7861  		mrs.AddRow(row)
  7862  	}
  7863  
  7864  	return mrs
  7865  }
  7866  
  7867  func newMrsForRoleIdOfUserId(rows [][]interface{}) *MysqlResultSet {
  7868  	mrs := &MysqlResultSet{}
  7869  
  7870  	col1 := &MysqlColumn{}
  7871  	col1.SetName("role_id")
  7872  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7873  
  7874  	col2 := &MysqlColumn{}
  7875  	col2.SetName("with_grant_option")
  7876  	col2.SetColumnType(defines.MYSQL_TYPE_BOOL)
  7877  
  7878  	mrs.AddColumn(col1)
  7879  	mrs.AddColumn(col2)
  7880  
  7881  	for _, row := range rows {
  7882  		mrs.AddRow(row)
  7883  	}
  7884  
  7885  	return mrs
  7886  }
  7887  
  7888  func newMrsForCheckRoleHasPrivilege(rows [][]interface{}) *MysqlResultSet {
  7889  	mrs := &MysqlResultSet{}
  7890  
  7891  	col1 := &MysqlColumn{}
  7892  	col1.SetName("role_id")
  7893  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7894  
  7895  	col2 := &MysqlColumn{}
  7896  	col2.SetName("with_grant_option")
  7897  	col2.SetColumnType(defines.MYSQL_TYPE_BOOL)
  7898  
  7899  	mrs.AddColumn(col1)
  7900  	mrs.AddColumn(col2)
  7901  
  7902  	for _, row := range rows {
  7903  		mrs.AddRow(row)
  7904  	}
  7905  
  7906  	return mrs
  7907  }
  7908  
  7909  func newMrsForInheritedRoleIdOfRoleId(rows [][]interface{}) *MysqlResultSet {
  7910  	mrs := &MysqlResultSet{}
  7911  
  7912  	col1 := &MysqlColumn{}
  7913  	col1.SetName("granted_id")
  7914  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7915  
  7916  	col2 := &MysqlColumn{}
  7917  	col2.SetName("with_grant_option")
  7918  	col2.SetColumnType(defines.MYSQL_TYPE_BOOL)
  7919  
  7920  	mrs.AddColumn(col1)
  7921  	mrs.AddColumn(col2)
  7922  
  7923  	for _, row := range rows {
  7924  		mrs.AddRow(row)
  7925  	}
  7926  
  7927  	return mrs
  7928  }
  7929  
  7930  func newMrsForGetAllStuffRoleGrant(rows [][]interface{}) *MysqlResultSet {
  7931  	mrs := &MysqlResultSet{}
  7932  
  7933  	col1 := &MysqlColumn{}
  7934  	col1.SetName("granted_id")
  7935  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7936  
  7937  	col2 := &MysqlColumn{}
  7938  	col2.SetName("grantee_id")
  7939  	col2.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7940  
  7941  	col3 := &MysqlColumn{}
  7942  	col3.SetName("with_grant_option")
  7943  	col3.SetColumnType(defines.MYSQL_TYPE_BOOL)
  7944  
  7945  	mrs.AddColumn(col1)
  7946  	mrs.AddColumn(col2)
  7947  	mrs.AddColumn(col3)
  7948  
  7949  	for _, row := range rows {
  7950  		mrs.AddRow(row)
  7951  	}
  7952  
  7953  	return mrs
  7954  }
  7955  
  7956  func newMrsForCheckRoleGrant(rows [][]interface{}) *MysqlResultSet {
  7957  	mrs := &MysqlResultSet{}
  7958  
  7959  	col1 := &MysqlColumn{}
  7960  	col1.SetName("granted_id")
  7961  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7962  
  7963  	col2 := &MysqlColumn{}
  7964  	col2.SetName("grantee_id")
  7965  	col2.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7966  
  7967  	col3 := &MysqlColumn{}
  7968  	col3.SetName("with_grant_option")
  7969  	col3.SetColumnType(defines.MYSQL_TYPE_BOOL)
  7970  
  7971  	mrs.AddColumn(col1)
  7972  	mrs.AddColumn(col2)
  7973  	mrs.AddColumn(col3)
  7974  
  7975  	for _, row := range rows {
  7976  		mrs.AddRow(row)
  7977  	}
  7978  
  7979  	return mrs
  7980  }
  7981  
  7982  func newMrsForPasswordOfUser(rows [][]interface{}) *MysqlResultSet {
  7983  	mrs := &MysqlResultSet{}
  7984  
  7985  	col1 := &MysqlColumn{}
  7986  	col1.SetName("user_id")
  7987  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7988  
  7989  	col2 := &MysqlColumn{}
  7990  	col2.SetName("authentication_string")
  7991  	col2.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  7992  
  7993  	col3 := &MysqlColumn{}
  7994  	col3.SetName("default_role")
  7995  	col3.SetColumnType(defines.MYSQL_TYPE_BOOL)
  7996  
  7997  	mrs.AddColumn(col1)
  7998  	mrs.AddColumn(col2)
  7999  	mrs.AddColumn(col3)
  8000  
  8001  	for _, row := range rows {
  8002  		mrs.AddRow(row)
  8003  	}
  8004  
  8005  	return mrs
  8006  }
  8007  
  8008  func newMrsForCheckUserGrant(rows [][]interface{}) *MysqlResultSet {
  8009  	mrs := &MysqlResultSet{}
  8010  
  8011  	col1 := &MysqlColumn{}
  8012  	col1.SetName("role_id")
  8013  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  8014  
  8015  	col2 := &MysqlColumn{}
  8016  	col2.SetName("user_id")
  8017  	col2.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  8018  
  8019  	col3 := &MysqlColumn{}
  8020  	col3.SetName("with_grant_option")
  8021  	col3.SetColumnType(defines.MYSQL_TYPE_BOOL)
  8022  
  8023  	mrs.AddColumn(col1)
  8024  	mrs.AddColumn(col2)
  8025  	mrs.AddColumn(col3)
  8026  
  8027  	for _, row := range rows {
  8028  		mrs.AddRow(row)
  8029  	}
  8030  
  8031  	return mrs
  8032  }
  8033  
  8034  func newMrsForRoleOfUser(rows [][]interface{}) *MysqlResultSet {
  8035  	mrs := &MysqlResultSet{}
  8036  
  8037  	col1 := &MysqlColumn{}
  8038  	col1.SetName("role_id")
  8039  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  8040  
  8041  	mrs.AddColumn(col1)
  8042  
  8043  	for _, row := range rows {
  8044  		mrs.AddRow(row)
  8045  	}
  8046  
  8047  	return mrs
  8048  }
  8049  
  8050  func newMrsForCheckDatabase(rows [][]interface{}) *MysqlResultSet {
  8051  	mrs := &MysqlResultSet{}
  8052  
  8053  	col1 := &MysqlColumn{}
  8054  	col1.SetName("dat_id")
  8055  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  8056  
  8057  	mrs.AddColumn(col1)
  8058  
  8059  	for _, row := range rows {
  8060  		mrs.AddRow(row)
  8061  	}
  8062  
  8063  	return mrs
  8064  }
  8065  
  8066  func newMrsForCheckDatabaseTable(rows [][]interface{}) *MysqlResultSet {
  8067  	mrs := &MysqlResultSet{}
  8068  
  8069  	col1 := &MysqlColumn{}
  8070  	col1.SetName("rel_id")
  8071  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  8072  
  8073  	mrs.AddColumn(col1)
  8074  
  8075  	for _, row := range rows {
  8076  		mrs.AddRow(row)
  8077  	}
  8078  
  8079  	return mrs
  8080  }
  8081  
  8082  func newMrsForCheckTenant(rows [][]interface{}) *MysqlResultSet {
  8083  	mrs := &MysqlResultSet{}
  8084  
  8085  	col1 := &MysqlColumn{}
  8086  	col1.SetName("account_id")
  8087  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  8088  
  8089  	col2 := &MysqlColumn{}
  8090  	col2.SetName("account_name")
  8091  	col2.SetColumnType(defines.MYSQL_TYPE_VARCHAR)
  8092  
  8093  	col3 := &MysqlColumn{}
  8094  	col3.SetName("status")
  8095  	col3.SetColumnType(defines.MYSQL_TYPE_VARCHAR)
  8096  
  8097  	col4 := &MysqlColumn{}
  8098  	col4.SetName("version")
  8099  	col4.SetColumnType(defines.MYSQL_TYPE_LONG)
  8100  
  8101  	mrs.AddColumn(col1)
  8102  	mrs.AddColumn(col2)
  8103  	mrs.AddColumn(col3)
  8104  	mrs.AddColumn(col4)
  8105  
  8106  	for _, row := range rows {
  8107  		mrs.AddRow(row)
  8108  	}
  8109  
  8110  	return mrs
  8111  }
  8112  
  8113  func makeRowsOfMoRole(sql2result map[string]ExecResult, roleNames []string, rows [][][]interface{}) {
  8114  	for i, name := range roleNames {
  8115  		sql, _ := getSqlForRoleIdOfRole(context.TODO(), name)
  8116  		sql2result[sql] = newMrsForRoleIdOfRole(rows[i])
  8117  	}
  8118  }
  8119  
  8120  func makeRowsOfMoUserGrant(sql2result map[string]ExecResult, userId int, rows [][]interface{}) {
  8121  	sql2result[getSqlForRoleIdOfUserId(userId)] = newMrsForRoleIdOfUserId(rows)
  8122  }
  8123  
  8124  func makeRowsOfMoRolePrivs(sql2result map[string]ExecResult, roleIds []int, entries []privilegeEntry, rowsOfMoRolePrivs [][]interface{}) {
  8125  	for _, roleId := range roleIds {
  8126  		for _, entry := range entries {
  8127  			sql, _ := getSqlFromPrivilegeEntry(context.TODO(), int64(roleId), entry)
  8128  			sql2result[sql] = newMrsForCheckRoleHasPrivilege(rowsOfMoRolePrivs)
  8129  		}
  8130  	}
  8131  }
  8132  
  8133  func makeRowsOfMoRoleGrant(sql2result map[string]ExecResult, roleIds []int, rowsOfMoRoleGrant [][]interface{}) {
  8134  	for _, roleId := range roleIds {
  8135  		sql := getSqlForInheritedRoleIdOfRoleId(int64(roleId))
  8136  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId(rowsOfMoRoleGrant)
  8137  	}
  8138  }
  8139  
  8140  func newMrsForWithGrantOptionPrivilege(rows [][]interface{}) *MysqlResultSet {
  8141  	mrs := &MysqlResultSet{}
  8142  
  8143  	col1 := &MysqlColumn{}
  8144  	col1.SetName("privilege_id")
  8145  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  8146  
  8147  	col2 := &MysqlColumn{}
  8148  	col2.SetName("with_grant_option")
  8149  	col2.SetColumnType(defines.MYSQL_TYPE_BOOL)
  8150  
  8151  	mrs.AddColumn(col1)
  8152  	mrs.AddColumn(col2)
  8153  
  8154  	for _, row := range rows {
  8155  		mrs.AddRow(row)
  8156  	}
  8157  
  8158  	return mrs
  8159  }
  8160  
  8161  func newMrsForRoleWGO(rows [][]interface{}) *MysqlResultSet {
  8162  	mrs := &MysqlResultSet{}
  8163  
  8164  	col1 := &MysqlColumn{}
  8165  	col1.SetName("grantee_id")
  8166  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  8167  
  8168  	mrs.AddColumn(col1)
  8169  
  8170  	for _, row := range rows {
  8171  		mrs.AddRow(row)
  8172  	}
  8173  
  8174  	return mrs
  8175  }
  8176  
  8177  func newMrsForPrivilegeWGO(rows [][]interface{}) *MysqlResultSet {
  8178  	mrs := &MysqlResultSet{}
  8179  
  8180  	col1 := &MysqlColumn{}
  8181  	col1.SetName("role_id")
  8182  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
  8183  
  8184  	mrs.AddColumn(col1)
  8185  
  8186  	for _, row := range rows {
  8187  		mrs.AddRow(row)
  8188  	}
  8189  
  8190  	return mrs
  8191  }
  8192  
  8193  func newMrsForSystemVariablesOfAccount(rows [][]interface{}) *MysqlResultSet {
  8194  	mrs := &MysqlResultSet{}
  8195  
  8196  	col1 := &MysqlColumn{}
  8197  	col1.SetName("variable_name")
  8198  	col1.SetColumnType(defines.MYSQL_TYPE_VARCHAR)
  8199  
  8200  	col2 := &MysqlColumn{}
  8201  	col2.SetName("variable_value")
  8202  	col2.SetColumnType(defines.MYSQL_TYPE_VARCHAR)
  8203  
  8204  	mrs.AddColumn(col1)
  8205  	mrs.AddColumn(col2)
  8206  
  8207  	for _, row := range rows {
  8208  		mrs.AddRow(row)
  8209  	}
  8210  
  8211  	return mrs
  8212  }
  8213  
  8214  func makeRowsOfWithGrantOptionPrivilege(sql2result map[string]ExecResult, sql string, rows [][]interface{}) {
  8215  	sql2result[sql] = newMrsForWithGrantOptionPrivilege(rows)
  8216  }
  8217  
  8218  func makeSql2ExecResult(userId int,
  8219  	rowsOfMoUserGrant [][]interface{},
  8220  	roleIdsInMoRolePrivs []int, entries []privilegeEntry, rowsOfMoRolePrivs [][]interface{},
  8221  	roleIdsInMoRoleGrant []int, rowsOfMoRoleGrant [][]interface{}) map[string]ExecResult {
  8222  	sql2result := make(map[string]ExecResult)
  8223  	makeRowsOfMoUserGrant(sql2result, userId, rowsOfMoUserGrant)
  8224  	makeRowsOfMoRolePrivs(sql2result, roleIdsInMoRolePrivs, entries, rowsOfMoRolePrivs)
  8225  	makeRowsOfMoRoleGrant(sql2result, roleIdsInMoRoleGrant, rowsOfMoRoleGrant)
  8226  	return sql2result
  8227  }
  8228  
  8229  func makeSql2ExecResult2(userId int, rowsOfMoUserGrant [][]interface{}, roleIdsInMoRolePrivs []int, entries []privilegeEntry, rowsOfMoRolePrivs [][][][]interface{}, roleIdsInMoRoleGrant []int, rowsOfMoRoleGrant [][][]interface{}, grantedIds []int, granteeRows [][][]interface{}) map[string]ExecResult {
  8230  	sql2result := make(map[string]ExecResult)
  8231  	makeRowsOfMoUserGrant(sql2result, userId, rowsOfMoUserGrant)
  8232  	for i, roleId := range roleIdsInMoRolePrivs {
  8233  		for j, entry := range entries {
  8234  			sql, _ := getSqlFromPrivilegeEntry(context.TODO(), int64(roleId), entry)
  8235  			sql2result[sql] = newMrsForCheckRoleHasPrivilege(rowsOfMoRolePrivs[i][j])
  8236  		}
  8237  	}
  8238  
  8239  	for i, roleId := range roleIdsInMoRoleGrant {
  8240  		sql := getSqlForInheritedRoleIdOfRoleId(int64(roleId))
  8241  		sql2result[sql] = newMrsForInheritedRoleIdOfRoleId(rowsOfMoRoleGrant[i])
  8242  	}
  8243  
  8244  	for i, id := range grantedIds {
  8245  		sql := getSqlForCheckRoleGrantWGO(int64(id))
  8246  		sql2result[sql] = newMrsForRoleWGO(granteeRows[i])
  8247  	}
  8248  
  8249  	return sql2result
  8250  }
  8251  
  8252  func Test_graph(t *testing.T) {
  8253  	convey.Convey("create graph", t, func() {
  8254  		g := NewGraph()
  8255  
  8256  		g.addEdge(1, 2)
  8257  		g.addEdge(2, 3)
  8258  		g.addEdge(3, 4)
  8259  
  8260  		convey.So(g.hasLoop(1), convey.ShouldBeFalse)
  8261  
  8262  		g2 := NewGraph()
  8263  		g2.addEdge(1, 2)
  8264  		g2.addEdge(2, 3)
  8265  		g2.addEdge(3, 4)
  8266  		e1 := g2.addEdge(4, 1)
  8267  
  8268  		convey.So(g2.hasLoop(1), convey.ShouldBeTrue)
  8269  
  8270  		g2.removeEdge(e1)
  8271  		convey.So(g2.hasLoop(1), convey.ShouldBeFalse)
  8272  
  8273  		g2.addEdge(4, 1)
  8274  		convey.So(g2.hasLoop(1), convey.ShouldBeTrue)
  8275  	})
  8276  }
  8277  
  8278  func Test_cache(t *testing.T) {
  8279  	type arg struct {
  8280  		db    string
  8281  		table string
  8282  	}
  8283  	cnt := 10
  8284  	args := make([]arg, 10)
  8285  	for i := 0; i < cnt; i++ {
  8286  		args[i].db = fmt.Sprintf("db%d", i)
  8287  		args[i].table = fmt.Sprintf("table%d", i)
  8288  	}
  8289  
  8290  	cache1 := &privilegeCache{}
  8291  	convey.Convey("has", t, func() {
  8292  		for _, a := range args {
  8293  			ret := cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateAccount)
  8294  			convey.So(ret, convey.ShouldBeFalse)
  8295  		}
  8296  	})
  8297  
  8298  	//add some privilege
  8299  	for _, a := range args {
  8300  		for i := PrivilegeTypeCreateAccount; i < PrivilegeTypeCreateObject; i++ {
  8301  			cache1.add(objectTypeTable, privilegeLevelStar, a.db, a.table, i)
  8302  		}
  8303  	}
  8304  
  8305  	convey.Convey("has2", t, func() {
  8306  		for _, a := range args {
  8307  			ret := cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateAccount)
  8308  			convey.So(ret, convey.ShouldBeTrue)
  8309  			ret = cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateObject)
  8310  			convey.So(ret, convey.ShouldBeFalse)
  8311  		}
  8312  	})
  8313  
  8314  	for _, a := range args {
  8315  		for i := PrivilegeTypeCreateObject; i < PrivilegeTypeExecute; i++ {
  8316  			cache1.add(objectTypeTable, privilegeLevelStar, a.db, a.table, i)
  8317  		}
  8318  	}
  8319  
  8320  	convey.Convey("has3", t, func() {
  8321  		for _, a := range args {
  8322  			ret := cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateAccount)
  8323  			convey.So(ret, convey.ShouldBeTrue)
  8324  			ret = cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateObject)
  8325  			convey.So(ret, convey.ShouldBeTrue)
  8326  		}
  8327  	})
  8328  
  8329  	//set
  8330  	for _, a := range args {
  8331  		for i := PrivilegeTypeCreateObject; i < PrivilegeTypeExecute; i++ {
  8332  			cache1.set(objectTypeTable, privilegeLevelStar, a.db, a.table)
  8333  		}
  8334  	}
  8335  
  8336  	convey.Convey("has4", t, func() {
  8337  		for _, a := range args {
  8338  			ret := cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateAccount)
  8339  			convey.So(ret, convey.ShouldBeFalse)
  8340  			ret = cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateObject)
  8341  			convey.So(ret, convey.ShouldBeFalse)
  8342  		}
  8343  	})
  8344  
  8345  	for _, a := range args {
  8346  		for i := PrivilegeTypeCreateAccount; i < PrivilegeTypeExecute; i++ {
  8347  			cache1.add(objectTypeTable, privilegeLevelStarStar, a.db, a.table, i)
  8348  		}
  8349  	}
  8350  
  8351  	convey.Convey("has4", t, func() {
  8352  		for _, a := range args {
  8353  			ret := cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateAccount)
  8354  			convey.So(ret, convey.ShouldBeFalse)
  8355  			ret = cache1.has(objectTypeTable, privilegeLevelStarStar, a.db, a.table, PrivilegeTypeCreateObject)
  8356  			convey.So(ret, convey.ShouldBeTrue)
  8357  		}
  8358  	})
  8359  
  8360  	cache1.invalidate()
  8361  	convey.Convey("has4", t, func() {
  8362  		for _, a := range args {
  8363  			ret := cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateAccount)
  8364  			convey.So(ret, convey.ShouldBeFalse)
  8365  			ret = cache1.has(objectTypeTable, privilegeLevelStar, a.db, a.table, PrivilegeTypeCreateObject)
  8366  			convey.So(ret, convey.ShouldBeFalse)
  8367  		}
  8368  	})
  8369  }
  8370  
  8371  func Test_DropDatabaseOfAccount(t *testing.T) {
  8372  	convey.Convey("drop account", t, func() {
  8373  		var db string
  8374  		databases := map[string]int8{
  8375  			"abc":        0,
  8376  			"mo_catalog": 0,
  8377  			"system":     0,
  8378  			"ABC":        0,
  8379  		}
  8380  		var sqlsForDropDatabases []string
  8381  		prefix := "drop database if exists "
  8382  		for db = range databases {
  8383  			if db == "mo_catalog" {
  8384  				continue
  8385  			}
  8386  			bb := &bytes.Buffer{}
  8387  			bb.WriteString(prefix)
  8388  			//handle the database annotated by '`'
  8389  			if db != strings.ToLower(db) {
  8390  				bb.WriteString("`")
  8391  				bb.WriteString(db)
  8392  				bb.WriteString("`")
  8393  			} else {
  8394  				bb.WriteString(db)
  8395  			}
  8396  			bb.WriteString(";")
  8397  			sqlsForDropDatabases = append(sqlsForDropDatabases, bb.String())
  8398  		}
  8399  
  8400  		has := func(s string) bool {
  8401  			for _, sql := range sqlsForDropDatabases {
  8402  				if strings.Contains(sql, s) {
  8403  					return true
  8404  				}
  8405  			}
  8406  			return false
  8407  		}
  8408  
  8409  		convey.So(has("ABC"), convey.ShouldBeTrue)
  8410  		convey.So(has("system"), convey.ShouldBeTrue)
  8411  		convey.So(has("mo_catalog"), convey.ShouldBeFalse)
  8412  	})
  8413  }
  8414  
  8415  func TestGetSqlForGetDbIdAndType(t *testing.T) {
  8416  	ctx := context.TODO()
  8417  	kases := []struct {
  8418  		pubName string
  8419  		want    string
  8420  		err     bool
  8421  	}{
  8422  		{
  8423  			pubName: "abc",
  8424  			want:    "select dat_id,dat_type from mo_catalog.mo_database where datname = 'abc' and account_id = 0;",
  8425  			err:     false,
  8426  		},
  8427  		{
  8428  			pubName: "abc\t",
  8429  			want:    "",
  8430  			err:     true,
  8431  		},
  8432  	}
  8433  	for _, k := range kases {
  8434  		sql, err := getSqlForGetDbIdAndType(ctx, k.pubName, true, 0)
  8435  		require.Equal(t, k.err, err != nil)
  8436  		require.Equal(t, k.want, sql)
  8437  	}
  8438  }
  8439  
  8440  func TestGetSqlForInsertIntoMoPubs(t *testing.T) {
  8441  	ctx := context.TODO()
  8442  	kases := []struct {
  8443  		pubName      string
  8444  		databaseName string
  8445  		err          bool
  8446  	}{
  8447  		{
  8448  			pubName:      "abc",
  8449  			databaseName: "abc",
  8450  			err:          false,
  8451  		},
  8452  		{
  8453  			pubName:      "abc\t",
  8454  			databaseName: "abc",
  8455  			err:          true,
  8456  		},
  8457  		{
  8458  			pubName:      "abc",
  8459  			databaseName: "abc\t",
  8460  			err:          true,
  8461  		},
  8462  	}
  8463  	for _, k := range kases {
  8464  		_, err := getSqlForInsertIntoMoPubs(ctx, k.pubName, k.databaseName, 0, false, "", "", 1, 1, "", true)
  8465  		require.Equal(t, k.err, err != nil)
  8466  	}
  8467  }
  8468  
  8469  func TestDoCreatePublication(t *testing.T) {
  8470  	ctrl := gomock.NewController(t)
  8471  	defer ctrl.Finish()
  8472  	ctx := context.Background()
  8473  	ses := newTestSession(t, ctrl)
  8474  	defer ses.Close()
  8475  
  8476  	tenant := &TenantInfo{
  8477  		Tenant:        sysAccountName,
  8478  		User:          rootName,
  8479  		DefaultRole:   moAdminRoleName,
  8480  		TenantID:      sysAccountID,
  8481  		UserID:        rootID,
  8482  		DefaultRoleID: moAdminRoleID,
  8483  	}
  8484  	ses.SetTenantInfo(tenant)
  8485  
  8486  	sa := &tree.CreatePublication{
  8487  		Name:     "pub1",
  8488  		Database: "db1",
  8489  		Comment:  "124",
  8490  		AccountsSet: &tree.AccountsSetOption{
  8491  			SetAccounts: tree.IdentifierList{"a1", "a2"},
  8492  		},
  8493  	}
  8494  	sql1, err := getSqlForGetDbIdAndType(ctx, string(sa.Database), true, 0)
  8495  	require.NoError(t, err)
  8496  	bh := &backgroundExecTest{}
  8497  	bh.init()
  8498  	sql2, err := getSqlForInsertIntoMoPubs(ctx, string(sa.Name), string(sa.Database), 0, true, "", "a1, a2", tenant.GetDefaultRoleID(), tenant.GetUserID(), sa.Comment, true)
  8499  	require.NoError(t, err)
  8500  	bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  8501  	defer bhStub.Reset()
  8502  
  8503  	bh.sql2result["begin;"] = nil
  8504  	bh.sql2result[sql1] = &MysqlResultSet{
  8505  		Columns: []Column{
  8506  			&MysqlColumn{
  8507  				ColumnImpl: ColumnImpl{
  8508  					name:       "dat_id",
  8509  					columnType: defines.MYSQL_TYPE_VARCHAR,
  8510  				},
  8511  			},
  8512  			&MysqlColumn{
  8513  				ColumnImpl: ColumnImpl{
  8514  					name:       "dat_type",
  8515  					columnType: defines.MYSQL_TYPE_VARCHAR,
  8516  				},
  8517  			},
  8518  		},
  8519  		Data: [][]interface{}{{0, ""}},
  8520  	}
  8521  	bh.sql2result[sql2] = nil
  8522  	bh.sql2result["commit;"] = nil
  8523  	bh.sql2result["rollback;"] = nil
  8524  
  8525  	err = doCreatePublication(ctx, ses, sa)
  8526  	require.NoError(t, err)
  8527  }
  8528  
  8529  func TestDoDropPublication(t *testing.T) {
  8530  	ctrl := gomock.NewController(t)
  8531  	defer ctrl.Finish()
  8532  	ctx := context.Background()
  8533  	ses := newTestSession(t, ctrl)
  8534  	defer ses.Close()
  8535  
  8536  	tenant := &TenantInfo{
  8537  		Tenant:        sysAccountName,
  8538  		User:          rootName,
  8539  		DefaultRole:   moAdminRoleName,
  8540  		TenantID:      sysAccountID,
  8541  		UserID:        rootID,
  8542  		DefaultRoleID: moAdminRoleID,
  8543  	}
  8544  	ses.SetTenantInfo(tenant)
  8545  
  8546  	sa := &tree.DropPublication{
  8547  		Name: "pub1",
  8548  	}
  8549  	sql1, err := getSqlForGetPubInfo(ctx, string(sa.Name), true)
  8550  	require.NoError(t, err)
  8551  	sql2, err := getSqlForDropPubInfo(ctx, string(sa.Name), true)
  8552  	require.NoError(t, err)
  8553  	bh := &backgroundExecTest{}
  8554  	bh.init()
  8555  	bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  8556  	defer bhStub.Reset()
  8557  
  8558  	bh.sql2result["begin;"] = nil
  8559  	bh.sql2result[sql1] = &MysqlResultSet{
  8560  		Data: [][]any{{"db1", 0, "a1, a2", "124"}},
  8561  	}
  8562  	bh.sql2result[sql2] = nil
  8563  	bh.sql2result["commit;"] = nil
  8564  	bh.sql2result["rollback;"] = nil
  8565  
  8566  	err = doDropPublication(ctx, ses, sa)
  8567  	require.NoError(t, err)
  8568  
  8569  }
  8570  
  8571  func TestDoAlterPublication(t *testing.T) {
  8572  	ctrl := gomock.NewController(t)
  8573  	defer ctrl.Finish()
  8574  	ctx := context.Background()
  8575  	ses := newTestSession(t, ctrl)
  8576  	defer ses.Close()
  8577  
  8578  	tenant := &TenantInfo{
  8579  		Tenant:        sysAccountName,
  8580  		User:          rootName,
  8581  		DefaultRole:   moAdminRoleName,
  8582  		TenantID:      sysAccountID,
  8583  		UserID:        rootID,
  8584  		DefaultRoleID: moAdminRoleID,
  8585  	}
  8586  	ses.SetTenantInfo(tenant)
  8587  	columns := []Column{
  8588  		&MysqlColumn{
  8589  			ColumnImpl: ColumnImpl{
  8590  				name:       "account_list",
  8591  				columnType: defines.MYSQL_TYPE_VARCHAR,
  8592  			},
  8593  		},
  8594  		&MysqlColumn{
  8595  			ColumnImpl: ColumnImpl{
  8596  				name:       "comment",
  8597  				columnType: defines.MYSQL_TYPE_VARCHAR,
  8598  			},
  8599  		},
  8600  		&MysqlColumn{
  8601  			ColumnImpl: ColumnImpl{
  8602  				name:       "database_name",
  8603  				columnType: defines.MYSQL_TYPE_VARCHAR,
  8604  			},
  8605  		},
  8606  		&MysqlColumn{
  8607  			ColumnImpl: ColumnImpl{
  8608  				name:       "database_id",
  8609  				columnType: defines.MYSQL_TYPE_LONGLONG,
  8610  			},
  8611  		},
  8612  	}
  8613  	dbColumns := []Column{
  8614  		&MysqlColumn{
  8615  			ColumnImpl: ColumnImpl{
  8616  				name:       "dat_id",
  8617  				columnType: defines.MYSQL_TYPE_LONGLONG,
  8618  			},
  8619  		},
  8620  		&MysqlColumn{
  8621  			ColumnImpl: ColumnImpl{
  8622  				name:       "dat_type",
  8623  				columnType: defines.MYSQL_TYPE_VARCHAR,
  8624  			},
  8625  		},
  8626  	}
  8627  	kases := []struct {
  8628  		pubName     string
  8629  		dbName      string
  8630  		dbId        uint64
  8631  		dbType      string
  8632  		comment     string
  8633  		accountsSet *tree.AccountsSetOption
  8634  		accountList string
  8635  		data        [][]any
  8636  		err         bool
  8637  	}{
  8638  		{
  8639  			pubName: "pub1",
  8640  			comment: "124",
  8641  			accountsSet: &tree.AccountsSetOption{
  8642  				All: true,
  8643  			},
  8644  			accountList: "121",
  8645  			data:        [][]any{{"all", "121", "db1", 1}},
  8646  			err:         false,
  8647  		},
  8648  		{
  8649  			pubName: "pub1",
  8650  			comment: "124",
  8651  			accountsSet: &tree.AccountsSetOption{
  8652  				AddAccounts: tree.IdentifierList{
  8653  					tree.Identifier("a1"),
  8654  				},
  8655  			},
  8656  			accountList: "a0",
  8657  			data:        [][]any{{"a0", "121", "db1", 1}},
  8658  			err:         false,
  8659  		},
  8660  		{
  8661  			pubName: "pub1",
  8662  			comment: "124",
  8663  			accountsSet: &tree.AccountsSetOption{
  8664  				SetAccounts: tree.IdentifierList{
  8665  					tree.Identifier("a1"),
  8666  				},
  8667  			},
  8668  			accountList: "a0",
  8669  			data:        [][]any{{"a0", "121", "db1", 1}},
  8670  			err:         false,
  8671  		},
  8672  		{
  8673  			pubName: "pub1",
  8674  			comment: "124",
  8675  			accountsSet: &tree.AccountsSetOption{
  8676  				DropAccounts: tree.IdentifierList{
  8677  					tree.Identifier("a1"),
  8678  				},
  8679  			},
  8680  			accountList: "all",
  8681  			data:        [][]any{{"all", "121", "db1", 1}},
  8682  			err:         true,
  8683  		},
  8684  		{
  8685  			pubName: "pub1",
  8686  			comment: "124",
  8687  			dbName:  "db2",
  8688  			dbId:    2,
  8689  			dbType:  "",
  8690  			data:    [][]any{{"all", "121", "db1", 1}},
  8691  			err:     false,
  8692  		},
  8693  		{
  8694  			pubName: "pub1",
  8695  			comment: "124",
  8696  			dbName:  "db2",
  8697  			dbId:    2,
  8698  			dbType:  "",
  8699  			accountsSet: &tree.AccountsSetOption{
  8700  				AddAccounts: tree.IdentifierList{
  8701  					tree.Identifier("a1"),
  8702  				},
  8703  			},
  8704  			accountList: "a0,a1",
  8705  			data:        [][]any{{"a0", "121", "db1", 1}},
  8706  			err:         false,
  8707  		},
  8708  	}
  8709  
  8710  	for _, kase := range kases {
  8711  		sa := &tree.AlterPublication{
  8712  			Name:        tree.Identifier(kase.pubName),
  8713  			Comment:     kase.comment,
  8714  			AccountsSet: kase.accountsSet,
  8715  			DbName:      kase.dbName,
  8716  		}
  8717  		sql1, err := getSqlForGetPubInfo(ctx, string(sa.Name), true)
  8718  		require.NoError(t, err)
  8719  
  8720  		sql3, err := getSqlForGetDbIdAndType(ctx, kase.dbName, true, 0)
  8721  		require.NoError(t, err)
  8722  
  8723  		sql2, err := getSqlForUpdatePubInfo(ctx, string(sa.Name), kase.accountList, sa.Comment, kase.dbName, kase.dbId, true)
  8724  		require.NoError(t, err)
  8725  
  8726  		bh := &backgroundExecTest{}
  8727  		bh.init()
  8728  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  8729  		defer bhStub.Reset()
  8730  
  8731  		bh.sql2result["begin;"] = nil
  8732  		bh.sql2result[sql1] = &MysqlResultSet{
  8733  			Data:    kase.data,
  8734  			Columns: columns,
  8735  		}
  8736  		bh.sql2result[sql2] = nil
  8737  		bh.sql2result[sql3] = &MysqlResultSet{
  8738  			Data:    [][]any{{kase.dbId, kase.dbType}},
  8739  			Columns: dbColumns,
  8740  		}
  8741  		bh.sql2result["commit;"] = nil
  8742  		bh.sql2result["rollback;"] = nil
  8743  
  8744  		err = doAlterPublication(ctx, ses, sa)
  8745  		if kase.err {
  8746  			require.Error(t, err)
  8747  		} else {
  8748  			require.NoError(t, err)
  8749  		}
  8750  	}
  8751  
  8752  }
  8753  
  8754  func TestCheckSubscriptionValid(t *testing.T) {
  8755  
  8756  	ctrl := gomock.NewController(t)
  8757  	defer ctrl.Finish()
  8758  	ses := newTestSession(t, ctrl)
  8759  	_ = ses.SetGlobalVar(context.TODO(), "lower_case_table_names", int64(1))
  8760  	defer ses.Close()
  8761  
  8762  	bh := &backgroundExecTest{}
  8763  	bh.init()
  8764  
  8765  	bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  8766  	defer bhStub.Reset()
  8767  
  8768  	pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  8769  	pu.SV.SetDefaultValues()
  8770  	ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  8771  
  8772  	rm, _ := NewRoutineManager(ctx)
  8773  	ses.rm = rm
  8774  
  8775  	proc := testutil.NewProcess()
  8776  	proc.FileService = getGlobalPu().FileService
  8777  	ses.GetTxnCompileCtx().execCtx = &ExecCtx{
  8778  		proc: proc,
  8779  	}
  8780  	ses.GetTxnCompileCtx().GetProcess().SessionInfo = process.SessionInfo{Account: sysAccountName}
  8781  
  8782  	columns := [][]Column{
  8783  		{
  8784  			&MysqlColumn{
  8785  				ColumnImpl: ColumnImpl{
  8786  					name:       "account_id",
  8787  					columnType: defines.MYSQL_TYPE_LONGLONG,
  8788  				},
  8789  			},
  8790  			&MysqlColumn{
  8791  				ColumnImpl: ColumnImpl{
  8792  					name:       "status",
  8793  					columnType: defines.MYSQL_TYPE_VARCHAR,
  8794  				},
  8795  			},
  8796  		},
  8797  		{
  8798  			&MysqlColumn{
  8799  				ColumnImpl: ColumnImpl{
  8800  					name:       "database_name",
  8801  					columnType: defines.MYSQL_TYPE_VARCHAR,
  8802  				},
  8803  			},
  8804  			&MysqlColumn{
  8805  				ColumnImpl: ColumnImpl{
  8806  					name:       "all_account",
  8807  					columnType: defines.MYSQL_TYPE_BOOL,
  8808  				},
  8809  			},
  8810  			&MysqlColumn{
  8811  				ColumnImpl: ColumnImpl{
  8812  					name:       "account_list",
  8813  					columnType: defines.MYSQL_TYPE_VARCHAR,
  8814  				},
  8815  			},
  8816  		},
  8817  	}
  8818  
  8819  	kases := []struct {
  8820  		createSql string
  8821  
  8822  		accName   string
  8823  		pubName   string
  8824  		pubExists bool
  8825  		accExists bool
  8826  
  8827  		subName string
  8828  
  8829  		accId     uint32
  8830  		accStatus string
  8831  
  8832  		databaseName string
  8833  		accountList  string
  8834  
  8835  		sqls  []string
  8836  		datas [][][]interface{}
  8837  
  8838  		err bool
  8839  	}{
  8840  		{
  8841  			createSql: "create database sub1 from acc0 publication",
  8842  			accName:   "acc0",
  8843  			pubName:   "",
  8844  			subName:   "sub1",
  8845  			accId:     1,
  8846  			err:       true,
  8847  		},
  8848  		{
  8849  			createSql: "create database sub1 from sys publication pub1",
  8850  			accName:   "sys",
  8851  			pubName:   "pub1",
  8852  			subName:   "sub1",
  8853  			accId:     0,
  8854  			accStatus: "",
  8855  			err:       true,
  8856  		},
  8857  		{
  8858  			createSql: "create database sub1 from acc0 publication pub1",
  8859  			accName:   "acc0",
  8860  			pubName:   "pub1",
  8861  			subName:   "sub1",
  8862  			pubExists: true,
  8863  			accExists: true,
  8864  			accId:     1,
  8865  			accStatus: "",
  8866  
  8867  			databaseName: "t1",
  8868  			accountList:  "all",
  8869  
  8870  			sqls: []string{},
  8871  			err:  false,
  8872  		},
  8873  		{
  8874  			createSql: "create database sub1 from acc0 publication pub1",
  8875  			accName:   "acc0",
  8876  			pubName:   "pub1",
  8877  			subName:   "sub1",
  8878  			pubExists: true,
  8879  			accExists: true,
  8880  			accId:     1,
  8881  			accStatus: "",
  8882  
  8883  			databaseName: "t1",
  8884  			accountList:  "sys",
  8885  
  8886  			sqls: []string{},
  8887  			err:  false,
  8888  		},
  8889  		{
  8890  			createSql: "create database sub1 from acc0 publication pub1",
  8891  			accName:   "acc0",
  8892  			pubName:   "pub1",
  8893  			subName:   "sub1",
  8894  			pubExists: true,
  8895  			accExists: false,
  8896  			accId:     1,
  8897  			accStatus: "",
  8898  
  8899  			databaseName: "t1",
  8900  			accountList:  "sys",
  8901  
  8902  			sqls: []string{},
  8903  			err:  true,
  8904  		},
  8905  		{
  8906  			createSql: "create database sub1 from acc0 publication pub1",
  8907  			accName:   "acc0",
  8908  			pubName:   "pub1",
  8909  			subName:   "sub1",
  8910  			pubExists: true,
  8911  			accExists: true,
  8912  			accId:     1,
  8913  			accStatus: tree.AccountStatusSuspend.String(),
  8914  
  8915  			databaseName: "t1",
  8916  			accountList:  "sys",
  8917  
  8918  			sqls: []string{},
  8919  			err:  true,
  8920  		},
  8921  		{
  8922  			createSql: "create database sub1 from acc0 publication pub1",
  8923  			accName:   "acc0",
  8924  			pubName:   "pub1",
  8925  			subName:   "sub1",
  8926  			pubExists: false,
  8927  			accExists: true,
  8928  			accId:     1,
  8929  			accStatus: tree.AccountStatusSuspend.String(),
  8930  
  8931  			databaseName: "t1",
  8932  			accountList:  "sys",
  8933  
  8934  			sqls: []string{},
  8935  			err:  true,
  8936  		},
  8937  	}
  8938  
  8939  	initData := func(idx int) {
  8940  		sql1, _ := getSqlForAccountIdAndStatus(ctx, kases[idx].accName, true)
  8941  		sql2, _ := getSqlForPubInfoForSub(ctx, kases[idx].pubName, true)
  8942  		kases[idx].sqls = []string{
  8943  			sql1, sql2,
  8944  		}
  8945  		kases[idx].datas = [][][]interface{}{
  8946  			{{kases[idx].accId, kases[idx].accStatus}},
  8947  			{{kases[idx].databaseName, kases[idx].accountList}},
  8948  		}
  8949  
  8950  		if !kases[idx].accExists {
  8951  			kases[idx].datas[0] = nil
  8952  		}
  8953  		if !kases[idx].pubExists {
  8954  			kases[idx].datas[1] = nil
  8955  		}
  8956  	}
  8957  
  8958  	for idx := range kases {
  8959  		initData(idx)
  8960  
  8961  		bh := &backgroundExecTest{}
  8962  		bh.init()
  8963  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  8964  		defer bhStub.Reset()
  8965  
  8966  		bh.sql2result["begin;"] = nil
  8967  		bh.sql2result["commit;"] = nil
  8968  		bh.sql2result["rollback;"] = nil
  8969  		for i := range kases[idx].sqls {
  8970  			bh.sql2result[kases[idx].sqls[i]] = &MysqlResultSet{
  8971  				Data:    kases[idx].datas[i],
  8972  				Columns: columns[i],
  8973  			}
  8974  		}
  8975  
  8976  		_, err := checkSubscriptionValid(ctx, ses, kases[idx].createSql)
  8977  		if kases[idx].err {
  8978  			require.Error(t, err)
  8979  		} else {
  8980  			require.NoError(t, err)
  8981  		}
  8982  	}
  8983  
  8984  }
  8985  
  8986  func TestDoCheckRole(t *testing.T) {
  8987  	ctrl := gomock.NewController(t)
  8988  	defer ctrl.Finish()
  8989  	ctx := context.Background()
  8990  	ses := newTestSession(t, ctrl)
  8991  	defer ses.Close()
  8992  
  8993  	tenant := &TenantInfo{
  8994  		Tenant:        sysAccountName,
  8995  		User:          rootName,
  8996  		DefaultRole:   moAdminRoleName,
  8997  		TenantID:      sysAccountID,
  8998  		UserID:        rootID,
  8999  		DefaultRoleID: moAdminRoleID,
  9000  	}
  9001  
  9002  	ses.SetTenantInfo(tenant)
  9003  	err := doCheckRole(ctx, ses)
  9004  	require.NoError(t, err)
  9005  
  9006  	tenant = &TenantInfo{
  9007  		Tenant:        "default_1",
  9008  		User:          "admin",
  9009  		DefaultRole:   accountAdminRoleName,
  9010  		TenantID:      3001,
  9011  		UserID:        2,
  9012  		DefaultRoleID: accountAdminRoleID,
  9013  	}
  9014  	ses.SetTenantInfo(tenant)
  9015  	err = doCheckRole(ctx, ses)
  9016  	require.NoError(t, err)
  9017  
  9018  	tenant = &TenantInfo{
  9019  		Tenant:        "default_1",
  9020  		User:          "admin",
  9021  		DefaultRole:   "role1",
  9022  		TenantID:      3001,
  9023  		UserID:        2,
  9024  		DefaultRoleID: 10,
  9025  	}
  9026  	ses.SetTenantInfo(tenant)
  9027  	err = doCheckRole(ctx, ses)
  9028  	require.Error(t, err)
  9029  }
  9030  
  9031  func TestGetUserPart(t *testing.T) {
  9032  	user1 := "user1"
  9033  	require.Equal(t, "user1", getUserPart(user1))
  9034  	user1 = "user1?"
  9035  	require.Equal(t, "user1", getUserPart(user1))
  9036  	user1 = "user1?a:b"
  9037  	require.Equal(t, "user1", getUserPart(user1))
  9038  }
  9039  
  9040  func TestCheckRoleWhetherTableOwner(t *testing.T) {
  9041  	convey.Convey("checkRoleWhetherTableOwner success", t, func() {
  9042  		ctrl := gomock.NewController(t)
  9043  		defer ctrl.Finish()
  9044  
  9045  		ses := newTestSession(t, ctrl)
  9046  		defer ses.Close()
  9047  
  9048  		bh := &backgroundExecTest{}
  9049  		bh.init()
  9050  
  9051  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9052  		defer bhStub.Reset()
  9053  
  9054  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9055  		pu.SV.SetDefaultValues()
  9056  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9057  
  9058  		rm, _ := NewRoutineManager(ctx)
  9059  		ses.rm = rm
  9060  
  9061  		tenant := &TenantInfo{
  9062  			Tenant:        sysAccountName,
  9063  			User:          rootName,
  9064  			DefaultRole:   moAdminRoleName,
  9065  			TenantID:      sysAccountID,
  9066  			UserID:        rootID,
  9067  			DefaultRoleID: moAdminRoleID,
  9068  		}
  9069  		ses.SetTenantInfo(tenant)
  9070  
  9071  		sql := getSqlForGetOwnerOfTable("db1", "t1")
  9072  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9073  			{0},
  9074  		})
  9075  		bh.sql2result[sql] = mrs
  9076  
  9077  		_, err := checkRoleWhetherTableOwner(ses.GetTxnHandler().GetTxnCtx(), ses, "db1", "t1", true)
  9078  		convey.So(err, convey.ShouldBeNil)
  9079  	})
  9080  
  9081  	convey.Convey("checkRoleWhetherTableOwner success", t, func() {
  9082  		ctrl := gomock.NewController(t)
  9083  		defer ctrl.Finish()
  9084  
  9085  		ses := newTestSession(t, ctrl)
  9086  		defer ses.Close()
  9087  
  9088  		bh := &backgroundExecTest{}
  9089  		bh.init()
  9090  
  9091  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9092  		defer bhStub.Reset()
  9093  
  9094  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9095  		pu.SV.SetDefaultValues()
  9096  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9097  
  9098  		rm, _ := NewRoutineManager(ctx)
  9099  		ses.rm = rm
  9100  
  9101  		tenant := &TenantInfo{
  9102  			Tenant:              sysAccountName,
  9103  			User:                rootName,
  9104  			DefaultRole:         moAdminRoleName,
  9105  			TenantID:            sysAccountID,
  9106  			UserID:              rootID,
  9107  			DefaultRoleID:       moAdminRoleID,
  9108  			useAllSecondaryRole: true,
  9109  		}
  9110  		ses.SetTenantInfo(tenant)
  9111  
  9112  		sql := getSqlForGetOwnerOfTable("db1", "t1")
  9113  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9114  			{0},
  9115  		})
  9116  		bh.sql2result[sql] = mrs
  9117  
  9118  		sql = getSqlForGetRolesOfCurrentUser(int64(ses.GetTenantInfo().GetUserID()))
  9119  		mrs = newMrsForPasswordOfUser([][]interface{}{
  9120  			{0},
  9121  		})
  9122  		bh.sql2result[sql] = mrs
  9123  
  9124  		ok, err := checkRoleWhetherTableOwner(ses.GetTxnHandler().GetTxnCtx(), ses, "db1", "t1", true)
  9125  		convey.So(err, convey.ShouldBeNil)
  9126  		convey.So(ok, convey.ShouldBeTrue)
  9127  	})
  9128  
  9129  	convey.Convey("checkRoleWhetherTableOwner fail", t, func() {
  9130  		ctrl := gomock.NewController(t)
  9131  		defer ctrl.Finish()
  9132  
  9133  		ses := newTestSession(t, ctrl)
  9134  		defer ses.Close()
  9135  
  9136  		bh := &backgroundExecTest{}
  9137  		bh.init()
  9138  
  9139  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9140  		defer bhStub.Reset()
  9141  
  9142  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9143  		pu.SV.SetDefaultValues()
  9144  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9145  
  9146  		rm, _ := NewRoutineManager(ctx)
  9147  		ses.rm = rm
  9148  
  9149  		tenant := &TenantInfo{
  9150  			Tenant:        sysAccountName,
  9151  			User:          rootName,
  9152  			DefaultRole:   moAdminRoleName,
  9153  			TenantID:      sysAccountID,
  9154  			UserID:        rootID,
  9155  			DefaultRoleID: moAdminRoleID,
  9156  		}
  9157  		ses.SetTenantInfo(tenant)
  9158  
  9159  		sql := getSqlForGetOwnerOfTable("db1", "t1")
  9160  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9161  			{1},
  9162  		})
  9163  		bh.sql2result[sql] = mrs
  9164  
  9165  		ok, err := checkRoleWhetherTableOwner(ses.GetTxnHandler().GetTxnCtx(), ses, "db1", "t1", false)
  9166  		convey.So(err, convey.ShouldBeNil)
  9167  		convey.So(ok, convey.ShouldBeFalse)
  9168  	})
  9169  }
  9170  
  9171  func TestCheckRoleWhetherDatabaseOwner(t *testing.T) {
  9172  	convey.Convey("checkRoleWhetherDatabaseOwner success", t, func() {
  9173  		ctrl := gomock.NewController(t)
  9174  		defer ctrl.Finish()
  9175  
  9176  		ses := newTestSession(t, ctrl)
  9177  		defer ses.Close()
  9178  
  9179  		bh := &backgroundExecTest{}
  9180  		bh.init()
  9181  
  9182  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9183  		defer bhStub.Reset()
  9184  
  9185  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9186  		pu.SV.SetDefaultValues()
  9187  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9188  
  9189  		rm, _ := NewRoutineManager(ctx)
  9190  		ses.rm = rm
  9191  
  9192  		tenant := &TenantInfo{
  9193  			Tenant:        sysAccountName,
  9194  			User:          rootName,
  9195  			DefaultRole:   moAdminRoleName,
  9196  			TenantID:      sysAccountID,
  9197  			UserID:        rootID,
  9198  			DefaultRoleID: moAdminRoleID,
  9199  		}
  9200  		ses.SetTenantInfo(tenant)
  9201  
  9202  		sql := getSqlForGetOwnerOfDatabase("db1")
  9203  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9204  			{0},
  9205  		})
  9206  		bh.sql2result[sql] = mrs
  9207  
  9208  		ok, err := checkRoleWhetherDatabaseOwner(ses.GetTxnHandler().GetTxnCtx(), ses, "db1", true)
  9209  		convey.So(err, convey.ShouldBeNil)
  9210  		convey.So(ok, convey.ShouldBeTrue)
  9211  	})
  9212  
  9213  	convey.Convey("checkRoleWhetherDatabaseOwner success", t, func() {
  9214  		ctrl := gomock.NewController(t)
  9215  		defer ctrl.Finish()
  9216  
  9217  		ses := newTestSession(t, ctrl)
  9218  		defer ses.Close()
  9219  
  9220  		bh := &backgroundExecTest{}
  9221  		bh.init()
  9222  
  9223  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9224  		defer bhStub.Reset()
  9225  
  9226  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9227  		pu.SV.SetDefaultValues()
  9228  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9229  
  9230  		rm, _ := NewRoutineManager(ctx)
  9231  		ses.rm = rm
  9232  
  9233  		tenant := &TenantInfo{
  9234  			Tenant:              sysAccountName,
  9235  			User:                rootName,
  9236  			DefaultRole:         moAdminRoleName,
  9237  			TenantID:            sysAccountID,
  9238  			UserID:              rootID,
  9239  			DefaultRoleID:       moAdminRoleID,
  9240  			useAllSecondaryRole: true,
  9241  		}
  9242  		ses.SetTenantInfo(tenant)
  9243  
  9244  		sql := getSqlForGetOwnerOfDatabase("db1")
  9245  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9246  			{0},
  9247  		})
  9248  		bh.sql2result[sql] = mrs
  9249  
  9250  		sql = getSqlForGetRolesOfCurrentUser(int64(ses.GetTenantInfo().GetUserID()))
  9251  		mrs = newMrsForPasswordOfUser([][]interface{}{
  9252  			{0},
  9253  		})
  9254  		bh.sql2result[sql] = mrs
  9255  
  9256  		ok, err := checkRoleWhetherDatabaseOwner(ses.GetTxnHandler().GetTxnCtx(), ses, "db1", true)
  9257  		convey.So(err, convey.ShouldBeNil)
  9258  		convey.So(ok, convey.ShouldBeTrue)
  9259  	})
  9260  
  9261  	convey.Convey("checkRoleWhetherDatabaseOwner fail", t, func() {
  9262  		ctrl := gomock.NewController(t)
  9263  		defer ctrl.Finish()
  9264  
  9265  		ses := newTestSession(t, ctrl)
  9266  		defer ses.Close()
  9267  
  9268  		bh := &backgroundExecTest{}
  9269  		bh.init()
  9270  
  9271  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9272  		defer bhStub.Reset()
  9273  
  9274  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9275  		pu.SV.SetDefaultValues()
  9276  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9277  
  9278  		rm, _ := NewRoutineManager(ctx)
  9279  		ses.rm = rm
  9280  
  9281  		tenant := &TenantInfo{
  9282  			Tenant:        sysAccountName,
  9283  			User:          rootName,
  9284  			DefaultRole:   moAdminRoleName,
  9285  			TenantID:      sysAccountID,
  9286  			UserID:        rootID,
  9287  			DefaultRoleID: moAdminRoleID,
  9288  		}
  9289  		ses.SetTenantInfo(tenant)
  9290  
  9291  		sql := getSqlForGetOwnerOfDatabase("db1")
  9292  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9293  			{1},
  9294  		})
  9295  		bh.sql2result[sql] = mrs
  9296  
  9297  		ok, err := checkRoleWhetherDatabaseOwner(ses.GetTxnHandler().GetTxnCtx(), ses, "db1", false)
  9298  		convey.So(err, convey.ShouldBeNil)
  9299  		convey.So(ok, convey.ShouldBeFalse)
  9300  	})
  9301  
  9302  }
  9303  
  9304  func TestGetSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(t *testing.T) {
  9305  	convey.Convey("getetSqlForCheckRoleHasPrivilegeWGODependsOnPrivType", t, func() {
  9306  		out1 := "select distinct role_id from mo_catalog.mo_role_privs where (with_grant_option = true and (privilege_id = 0 or privilege_id = 14)) or privilege_id = 15;"
  9307  		sql := getSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(PrivilegeTypeCreateAccount)
  9308  		convey.So(out1, convey.ShouldEqual, sql)
  9309  	})
  9310  
  9311  	convey.Convey("getetSqlForCheckRoleHasPrivilegeWGODependsOnPrivType", t, func() {
  9312  		out2 := "select distinct role_id from mo_catalog.mo_role_privs where (with_grant_option = true and (privilege_id = 18 or privilege_id = 28)) or privilege_id = 29;"
  9313  		sql := getSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(PrivilegeTypeShowTables)
  9314  		convey.So(out2, convey.ShouldEqual, sql)
  9315  	})
  9316  
  9317  	convey.Convey("getetSqlForCheckRoleHasPrivilegeWGODependsOnPrivType", t, func() {
  9318  		out3 := "select distinct role_id from mo_catalog.mo_role_privs where (with_grant_option = true and (privilege_id = 30 or privilege_id = 37)) or privilege_id = 38;"
  9319  		sql := getSqlForCheckRoleHasPrivilegeWGODependsOnPrivType(PrivilegeTypeSelect)
  9320  		convey.So(out3, convey.ShouldEqual, sql)
  9321  	})
  9322  }
  9323  
  9324  func TestDoAlterDatabaseConfig(t *testing.T) {
  9325  	convey.Convey("doAlterDatabaseConfig success", t, func() {
  9326  		ctrl := gomock.NewController(t)
  9327  		defer ctrl.Finish()
  9328  
  9329  		ses := newTestSession(t, ctrl)
  9330  		defer ses.Close()
  9331  
  9332  		bh := &backgroundExecTest{}
  9333  		bh.init()
  9334  
  9335  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9336  		defer bhStub.Reset()
  9337  
  9338  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9339  		pu.SV.SetDefaultValues()
  9340  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9341  
  9342  		rm, _ := NewRoutineManager(ctx)
  9343  		ses.rm = rm
  9344  
  9345  		tenant := &TenantInfo{
  9346  			Tenant:        sysAccountName,
  9347  			User:          rootName,
  9348  			DefaultRole:   moAdminRoleName,
  9349  			TenantID:      sysAccountID,
  9350  			UserID:        rootID,
  9351  			DefaultRoleID: moAdminRoleID,
  9352  		}
  9353  		ses.SetTenantInfo(tenant)
  9354  
  9355  		ad := &tree.AlterDataBaseConfig{
  9356  			AccountName:    sysAccountName,
  9357  			DbName:         "db1",
  9358  			IsAccountLevel: false,
  9359  			UpdateConfig:   "0.7",
  9360  		}
  9361  
  9362  		//no result set
  9363  		bh.sql2result["begin;"] = nil
  9364  		bh.sql2result["commit;"] = nil
  9365  		bh.sql2result["rollback;"] = nil
  9366  
  9367  		sql, _ := getSqlForCheckDatabaseWithOwner(ctx, ad.DbName, int64(ses.GetTenantInfo().GetTenantID()))
  9368  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9369  			{0, 0},
  9370  		})
  9371  		bh.sql2result[sql] = mrs
  9372  
  9373  		sql, _ = getSqlForupdateConfigurationByDbNameAndAccountName(ctx, ad.UpdateConfig, ses.GetTenantInfo().GetTenant(), ad.DbName, "version_compatibility")
  9374  		mrs = newMrsForPasswordOfUser([][]interface{}{{}})
  9375  		bh.sql2result[sql] = mrs
  9376  
  9377  		err := doAlterDatabaseConfig(ses.GetTxnHandler().GetTxnCtx(), ses, ad)
  9378  		convey.So(err, convey.ShouldBeNil)
  9379  	})
  9380  
  9381  	convey.Convey("doAlterDatabaseConfig fail", t, func() {
  9382  		ctrl := gomock.NewController(t)
  9383  		defer ctrl.Finish()
  9384  
  9385  		ses := newTestSession(t, ctrl)
  9386  		defer ses.Close()
  9387  
  9388  		bh := &backgroundExecTest{}
  9389  		bh.init()
  9390  
  9391  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9392  		defer bhStub.Reset()
  9393  
  9394  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9395  		pu.SV.SetDefaultValues()
  9396  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9397  
  9398  		rm, _ := NewRoutineManager(ctx)
  9399  		ses.rm = rm
  9400  
  9401  		tenant := &TenantInfo{
  9402  			Tenant:        sysAccountName,
  9403  			User:          rootName,
  9404  			DefaultRole:   moAdminRoleName,
  9405  			TenantID:      sysAccountID,
  9406  			UserID:        rootID,
  9407  			DefaultRoleID: moAdminRoleID,
  9408  		}
  9409  		ses.SetTenantInfo(tenant)
  9410  
  9411  		ad := &tree.AlterDataBaseConfig{
  9412  			AccountName:    sysAccountName,
  9413  			DbName:         "db1",
  9414  			IsAccountLevel: false,
  9415  			UpdateConfig:   "0.7",
  9416  		}
  9417  
  9418  		//no result set
  9419  		bh.sql2result["begin;"] = nil
  9420  		bh.sql2result["commit;"] = nil
  9421  		bh.sql2result["rollback;"] = nil
  9422  
  9423  		sql, _ := getSqlForCheckDatabaseWithOwner(ctx, ad.DbName, int64(ses.GetTenantInfo().GetTenantID()))
  9424  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9425  			{0, 1},
  9426  		})
  9427  		bh.sql2result[sql] = mrs
  9428  
  9429  		sql, _ = getSqlForupdateConfigurationByDbNameAndAccountName(ctx, ad.UpdateConfig, ses.GetTenantInfo().GetTenant(), ad.DbName, "version_compatibility")
  9430  		mrs = newMrsForPasswordOfUser([][]interface{}{{}})
  9431  		bh.sql2result[sql] = mrs
  9432  
  9433  		err := doAlterDatabaseConfig(ses.GetTxnHandler().GetTxnCtx(), ses, ad)
  9434  		convey.So(err, convey.ShouldNotBeNil)
  9435  	})
  9436  }
  9437  
  9438  func TestDoAlterAccountConfig(t *testing.T) {
  9439  	convey.Convey("doAlterAccountConfig success", t, func() {
  9440  		ctrl := gomock.NewController(t)
  9441  		defer ctrl.Finish()
  9442  
  9443  		ses := newTestSession(t, ctrl)
  9444  		defer ses.Close()
  9445  
  9446  		bh := &backgroundExecTest{}
  9447  		bh.init()
  9448  
  9449  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9450  		defer bhStub.Reset()
  9451  
  9452  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9453  		pu.SV.SetDefaultValues()
  9454  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9455  
  9456  		rm, _ := NewRoutineManager(ctx)
  9457  		ses.rm = rm
  9458  
  9459  		tenant := &TenantInfo{
  9460  			Tenant:        sysAccountName,
  9461  			User:          rootName,
  9462  			DefaultRole:   moAdminRoleName,
  9463  			TenantID:      sysAccountID,
  9464  			UserID:        rootID,
  9465  			DefaultRoleID: moAdminRoleID,
  9466  		}
  9467  		ses.SetTenantInfo(tenant)
  9468  
  9469  		ad := &tree.AlterDataBaseConfig{
  9470  			AccountName:    sysAccountName,
  9471  			IsAccountLevel: true,
  9472  			UpdateConfig:   "0.7",
  9473  		}
  9474  
  9475  		//no result set
  9476  		bh.sql2result["begin;"] = nil
  9477  		bh.sql2result["commit;"] = nil
  9478  		bh.sql2result["rollback;"] = nil
  9479  
  9480  		sql, _ := getSqlForCheckTenant(ctx, ad.AccountName)
  9481  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9482  			{0, 0},
  9483  		})
  9484  		bh.sql2result[sql] = mrs
  9485  
  9486  		sql, _ = getSqlForupdateConfigurationByAccount(ctx, ad.UpdateConfig, ses.GetTenantInfo().GetTenant(), "version_compatibility")
  9487  		mrs = newMrsForPasswordOfUser([][]interface{}{{}})
  9488  		bh.sql2result[sql] = mrs
  9489  
  9490  		err := doAlterAccountConfig(ctx, ses, ad)
  9491  		convey.So(err, convey.ShouldBeNil)
  9492  	})
  9493  }
  9494  
  9495  func TestInsertRecordToMoMysqlCompatibilityMode(t *testing.T) {
  9496  	convey.Convey("insertRecordToMoMysqlCompatibilityMode success", t, func() {
  9497  		ctrl := gomock.NewController(t)
  9498  		defer ctrl.Finish()
  9499  
  9500  		ses := newTestSession(t, ctrl)
  9501  		defer ses.Close()
  9502  
  9503  		bh := &backgroundExecTest{}
  9504  		bh.init()
  9505  
  9506  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9507  		defer bhStub.Reset()
  9508  
  9509  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9510  		pu.SV.SetDefaultValues()
  9511  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9512  
  9513  		rm, _ := NewRoutineManager(ctx)
  9514  		ses.rm = rm
  9515  
  9516  		tenant := &TenantInfo{
  9517  			Tenant:        sysAccountName,
  9518  			User:          rootName,
  9519  			DefaultRole:   moAdminRoleName,
  9520  			TenantID:      sysAccountID,
  9521  			UserID:        rootID,
  9522  			DefaultRoleID: moAdminRoleID,
  9523  		}
  9524  		ses.SetTenantInfo(tenant)
  9525  
  9526  		stmt := &tree.CreateDatabase{
  9527  			Name: tree.Identifier("abc"),
  9528  		}
  9529  
  9530  		//no result set
  9531  		bh.sql2result["begin;"] = nil
  9532  		bh.sql2result["commit;"] = nil
  9533  		bh.sql2result["rollback;"] = nil
  9534  
  9535  		sql := fmt.Sprintf(initMoMysqlCompatbilityModeFormat, tenant.TenantID, tenant.GetTenant(), "abc", "", "", false)
  9536  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9537  			{0, 0},
  9538  		})
  9539  		bh.sql2result[sql] = mrs
  9540  
  9541  		err := insertRecordToMoMysqlCompatibilityMode(ctx, ses, stmt)
  9542  		convey.So(err, convey.ShouldBeNil)
  9543  	})
  9544  }
  9545  
  9546  func TestDeleteRecordToMoMysqlCompatbilityMode(t *testing.T) {
  9547  	convey.Convey("insertRecordToMoMysqlCompatibilityMode success", t, func() {
  9548  		ctrl := gomock.NewController(t)
  9549  		defer ctrl.Finish()
  9550  
  9551  		ses := newTestSession(t, ctrl)
  9552  		defer ses.Close()
  9553  
  9554  		bh := &backgroundExecTest{}
  9555  		bh.init()
  9556  
  9557  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9558  		defer bhStub.Reset()
  9559  
  9560  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9561  		pu.SV.SetDefaultValues()
  9562  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9563  
  9564  		rm, _ := NewRoutineManager(ctx)
  9565  		ses.rm = rm
  9566  
  9567  		tenant := &TenantInfo{
  9568  			Tenant:        sysAccountName,
  9569  			User:          rootName,
  9570  			DefaultRole:   moAdminRoleName,
  9571  			TenantID:      sysAccountID,
  9572  			UserID:        rootID,
  9573  			DefaultRoleID: moAdminRoleID,
  9574  		}
  9575  		ses.SetTenantInfo(tenant)
  9576  
  9577  		stmt := &tree.DropDatabase{
  9578  			Name: tree.Identifier("abc"),
  9579  		}
  9580  
  9581  		//no result set
  9582  		bh.sql2result["begin;"] = nil
  9583  		bh.sql2result["commit;"] = nil
  9584  		bh.sql2result["rollback;"] = nil
  9585  
  9586  		sql := getSqlForDeleteMysqlCompatbilityMode("abc")
  9587  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9588  			{0, 0},
  9589  		})
  9590  		bh.sql2result[sql] = mrs
  9591  
  9592  		err := deleteRecordToMoMysqlCompatbilityMode(ctx, ses, stmt)
  9593  		convey.So(err, convey.ShouldBeNil)
  9594  	})
  9595  }
  9596  
  9597  func TestGetVersionCompatibility(t *testing.T) {
  9598  	convey.Convey("getVersionCompatibility success", t, func() {
  9599  		ctrl := gomock.NewController(t)
  9600  		defer ctrl.Finish()
  9601  
  9602  		ses := newTestSession(t, ctrl)
  9603  		defer ses.Close()
  9604  
  9605  		bh := &backgroundExecTest{}
  9606  		bh.init()
  9607  
  9608  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9609  		defer bhStub.Reset()
  9610  
  9611  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9612  		pu.SV.SetDefaultValues()
  9613  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9614  
  9615  		rm, _ := NewRoutineManager(ctx)
  9616  		ses.rm = rm
  9617  
  9618  		tenant := &TenantInfo{
  9619  			Tenant:        sysAccountName,
  9620  			User:          rootName,
  9621  			DefaultRole:   moAdminRoleName,
  9622  			TenantID:      sysAccountID,
  9623  			UserID:        rootID,
  9624  			DefaultRoleID: moAdminRoleID,
  9625  		}
  9626  		ses.SetTenantInfo(tenant)
  9627  
  9628  		//no result set
  9629  		bh.sql2result["begin;"] = nil
  9630  		bh.sql2result["commit;"] = nil
  9631  		bh.sql2result["rollback;"] = nil
  9632  
  9633  		sql := getSqlForGetSystemVariableValueWithDatabase("db1", "version_compatibility")
  9634  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9635  			{0, 0},
  9636  		})
  9637  		bh.sql2result[sql] = mrs
  9638  
  9639  		_, err := GetVersionCompatibility(ctx, ses, "db1")
  9640  		convey.So(err, convey.ShouldBeNil)
  9641  	})
  9642  }
  9643  
  9644  func TestCheckStageExistOrNot(t *testing.T) {
  9645  	convey.Convey("checkStageExistOrNot success", t, func() {
  9646  		ctrl := gomock.NewController(t)
  9647  		defer ctrl.Finish()
  9648  
  9649  		ses := newTestSession(t, ctrl)
  9650  		defer ses.Close()
  9651  
  9652  		bh := &backgroundExecTest{}
  9653  		bh.init()
  9654  
  9655  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9656  		defer bhStub.Reset()
  9657  
  9658  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9659  		pu.SV.SetDefaultValues()
  9660  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9661  
  9662  		rm, _ := NewRoutineManager(ctx)
  9663  		ses.rm = rm
  9664  
  9665  		tenant := &TenantInfo{
  9666  			Tenant:        sysAccountName,
  9667  			User:          rootName,
  9668  			DefaultRole:   moAdminRoleName,
  9669  			TenantID:      sysAccountID,
  9670  			UserID:        rootID,
  9671  			DefaultRoleID: moAdminRoleID,
  9672  		}
  9673  		ses.SetTenantInfo(tenant)
  9674  
  9675  		//no result set
  9676  		bh.sql2result["begin;"] = nil
  9677  		bh.sql2result["commit;"] = nil
  9678  		bh.sql2result["rollback;"] = nil
  9679  
  9680  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
  9681  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9682  			{0, 0},
  9683  		})
  9684  		bh.sql2result[sql] = mrs
  9685  
  9686  		rst, err := checkStageExistOrNot(ctx, bh, "my_stage_test")
  9687  		convey.So(err, convey.ShouldBeNil)
  9688  		convey.So(rst, convey.ShouldBeTrue)
  9689  	})
  9690  
  9691  	convey.Convey("checkStageExistOrNot success", t, func() {
  9692  		ctrl := gomock.NewController(t)
  9693  		defer ctrl.Finish()
  9694  
  9695  		ses := newTestSession(t, ctrl)
  9696  		defer ses.Close()
  9697  
  9698  		bh := &backgroundExecTest{}
  9699  		bh.init()
  9700  
  9701  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9702  		defer bhStub.Reset()
  9703  
  9704  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9705  		pu.SV.SetDefaultValues()
  9706  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9707  
  9708  		rm, _ := NewRoutineManager(ctx)
  9709  		ses.rm = rm
  9710  
  9711  		tenant := &TenantInfo{
  9712  			Tenant:        sysAccountName,
  9713  			User:          rootName,
  9714  			DefaultRole:   moAdminRoleName,
  9715  			TenantID:      sysAccountID,
  9716  			UserID:        rootID,
  9717  			DefaultRoleID: moAdminRoleID,
  9718  		}
  9719  		ses.SetTenantInfo(tenant)
  9720  
  9721  		//no result set
  9722  		bh.sql2result["begin;"] = nil
  9723  		bh.sql2result["commit;"] = nil
  9724  		bh.sql2result["rollback;"] = nil
  9725  
  9726  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
  9727  		mrs := newMrsForPasswordOfUser([][]interface{}{})
  9728  		bh.sql2result[sql] = mrs
  9729  
  9730  		rst, err := checkStageExistOrNot(ctx, bh, "my_stage_test")
  9731  		convey.So(err, convey.ShouldBeNil)
  9732  		convey.So(rst, convey.ShouldBeFalse)
  9733  	})
  9734  }
  9735  
  9736  func TestFormatCredentials(t *testing.T) {
  9737  	convey.Convey("formatCredentials success", t, func() {
  9738  		ta := tree.StageCredentials{
  9739  			Exist: false,
  9740  		}
  9741  		rstr := formatCredentials(ta)
  9742  		testRstr := ""
  9743  		convey.So(rstr, convey.ShouldEqual, testRstr)
  9744  	})
  9745  
  9746  	convey.Convey("formatCredentials success", t, func() {
  9747  		ta := tree.StageCredentials{
  9748  			Exist:       true,
  9749  			Credentials: []string{"AWS_KEY_ID", "1a2b3c"},
  9750  		}
  9751  		rstr := formatCredentials(ta)
  9752  		testRstr := "AWS_KEY_ID=1a2b3c"
  9753  		convey.So(rstr, convey.ShouldEqual, testRstr)
  9754  	})
  9755  
  9756  	convey.Convey("formatCredentials success", t, func() {
  9757  		ta := tree.StageCredentials{
  9758  			Exist:       true,
  9759  			Credentials: []string{"AWS_KEY_ID", "1a2b3c", "AWS_SECRET_KEY", "4x5y6z"},
  9760  		}
  9761  		rstr := formatCredentials(ta)
  9762  		testRstr := "AWS_KEY_ID=1a2b3c,AWS_SECRET_KEY=4x5y6z"
  9763  		convey.So(rstr, convey.ShouldEqual, testRstr)
  9764  	})
  9765  }
  9766  
  9767  func TestDoDropStage(t *testing.T) {
  9768  	convey.Convey("doDropStage success", t, func() {
  9769  		ctrl := gomock.NewController(t)
  9770  		defer ctrl.Finish()
  9771  
  9772  		ses := newTestSession(t, ctrl)
  9773  		defer ses.Close()
  9774  
  9775  		bh := &backgroundExecTest{}
  9776  		bh.init()
  9777  
  9778  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9779  		defer bhStub.Reset()
  9780  
  9781  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9782  		pu.SV.SetDefaultValues()
  9783  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9784  
  9785  		rm, _ := NewRoutineManager(ctx)
  9786  		ses.rm = rm
  9787  
  9788  		tenant := &TenantInfo{
  9789  			Tenant:        sysAccountName,
  9790  			User:          rootName,
  9791  			DefaultRole:   moAdminRoleName,
  9792  			TenantID:      sysAccountID,
  9793  			UserID:        rootID,
  9794  			DefaultRoleID: moAdminRoleID,
  9795  		}
  9796  		ses.SetTenantInfo(tenant)
  9797  
  9798  		ds := &tree.DropStage{
  9799  			IfNotExists: false,
  9800  			Name:        tree.Identifier("my_stage_test"),
  9801  		}
  9802  
  9803  		//no result set
  9804  		bh.sql2result["begin;"] = nil
  9805  		bh.sql2result["commit;"] = nil
  9806  		bh.sql2result["rollback;"] = nil
  9807  
  9808  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
  9809  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9810  			{0, 0},
  9811  		})
  9812  		bh.sql2result[sql] = mrs
  9813  
  9814  		sql = getSqlForDropStage(string(ds.Name))
  9815  		mrs = newMrsForPasswordOfUser([][]interface{}{})
  9816  		bh.sql2result[sql] = mrs
  9817  
  9818  		err := doDropStage(ctx, ses, ds)
  9819  		convey.So(err, convey.ShouldBeNil)
  9820  	})
  9821  
  9822  	convey.Convey("doDropStage success", t, func() {
  9823  		ctrl := gomock.NewController(t)
  9824  		defer ctrl.Finish()
  9825  
  9826  		ses := newTestSession(t, ctrl)
  9827  		defer ses.Close()
  9828  
  9829  		bh := &backgroundExecTest{}
  9830  		bh.init()
  9831  
  9832  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9833  		defer bhStub.Reset()
  9834  
  9835  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9836  		pu.SV.SetDefaultValues()
  9837  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9838  
  9839  		rm, _ := NewRoutineManager(ctx)
  9840  		ses.rm = rm
  9841  
  9842  		tenant := &TenantInfo{
  9843  			Tenant:        sysAccountName,
  9844  			User:          rootName,
  9845  			DefaultRole:   moAdminRoleName,
  9846  			TenantID:      sysAccountID,
  9847  			UserID:        rootID,
  9848  			DefaultRoleID: moAdminRoleID,
  9849  		}
  9850  		ses.SetTenantInfo(tenant)
  9851  
  9852  		ds := &tree.DropStage{
  9853  			IfNotExists: true,
  9854  			Name:        tree.Identifier("my_stage_test"),
  9855  		}
  9856  
  9857  		//no result set
  9858  		bh.sql2result["begin;"] = nil
  9859  		bh.sql2result["commit;"] = nil
  9860  		bh.sql2result["rollback;"] = nil
  9861  
  9862  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
  9863  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9864  			{0, 0},
  9865  		})
  9866  		bh.sql2result[sql] = mrs
  9867  
  9868  		sql = getSqlForDropStage(string(ds.Name))
  9869  		mrs = newMrsForPasswordOfUser([][]interface{}{})
  9870  		bh.sql2result[sql] = mrs
  9871  
  9872  		err := doDropStage(ctx, ses, ds)
  9873  		convey.So(err, convey.ShouldBeNil)
  9874  	})
  9875  
  9876  	convey.Convey("doDropStage fail", t, func() {
  9877  		ctrl := gomock.NewController(t)
  9878  		defer ctrl.Finish()
  9879  
  9880  		ses := newTestSession(t, ctrl)
  9881  		defer ses.Close()
  9882  
  9883  		bh := &backgroundExecTest{}
  9884  		bh.init()
  9885  
  9886  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9887  		defer bhStub.Reset()
  9888  
  9889  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9890  		pu.SV.SetDefaultValues()
  9891  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9892  
  9893  		rm, _ := NewRoutineManager(ctx)
  9894  		ses.rm = rm
  9895  
  9896  		tenant := &TenantInfo{
  9897  			Tenant:        sysAccountName,
  9898  			User:          rootName,
  9899  			DefaultRole:   moAdminRoleName,
  9900  			TenantID:      sysAccountID,
  9901  			UserID:        rootID,
  9902  			DefaultRoleID: moAdminRoleID,
  9903  		}
  9904  		ses.SetTenantInfo(tenant)
  9905  
  9906  		ds := &tree.DropStage{
  9907  			IfNotExists: false,
  9908  			Name:        tree.Identifier("my_stage_test"),
  9909  		}
  9910  
  9911  		//no result set
  9912  		bh.sql2result["begin;"] = nil
  9913  		bh.sql2result["commit;"] = nil
  9914  		bh.sql2result["rollback;"] = nil
  9915  
  9916  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
  9917  		mrs := newMrsForPasswordOfUser([][]interface{}{})
  9918  		bh.sql2result[sql] = mrs
  9919  
  9920  		sql = getSqlForDropStage(string(ds.Name))
  9921  		mrs = newMrsForPasswordOfUser([][]interface{}{})
  9922  		bh.sql2result[sql] = mrs
  9923  
  9924  		err := doDropStage(ctx, ses, ds)
  9925  		convey.So(err, convey.ShouldNotBeNil)
  9926  	})
  9927  
  9928  	convey.Convey("doDropStage fail", t, func() {
  9929  		ctrl := gomock.NewController(t)
  9930  		defer ctrl.Finish()
  9931  
  9932  		ses := newTestSession(t, ctrl)
  9933  		defer ses.Close()
  9934  
  9935  		bh := &backgroundExecTest{}
  9936  		bh.init()
  9937  
  9938  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9939  		defer bhStub.Reset()
  9940  
  9941  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9942  		pu.SV.SetDefaultValues()
  9943  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
  9944  
  9945  		rm, _ := NewRoutineManager(ctx)
  9946  		ses.rm = rm
  9947  
  9948  		tenant := &TenantInfo{
  9949  			Tenant:        "test_account",
  9950  			User:          rootName,
  9951  			DefaultRole:   "test_role",
  9952  			TenantID:      sysAccountID,
  9953  			UserID:        rootID,
  9954  			DefaultRoleID: moAdminRoleID,
  9955  		}
  9956  		ses.SetTenantInfo(tenant)
  9957  
  9958  		ds := &tree.DropStage{
  9959  			IfNotExists: true,
  9960  			Name:        tree.Identifier("my_stage_test"),
  9961  		}
  9962  
  9963  		//no result set
  9964  		bh.sql2result["begin;"] = nil
  9965  		bh.sql2result["commit;"] = nil
  9966  		bh.sql2result["rollback;"] = nil
  9967  
  9968  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
  9969  		mrs := newMrsForPasswordOfUser([][]interface{}{
  9970  			{0, 0},
  9971  		})
  9972  		bh.sql2result[sql] = mrs
  9973  
  9974  		sql = getSqlForDropStage(string(ds.Name))
  9975  		mrs = newMrsForPasswordOfUser([][]interface{}{})
  9976  		bh.sql2result[sql] = mrs
  9977  
  9978  		err := doDropStage(ctx, ses, ds)
  9979  		convey.So(err, convey.ShouldNotBeNil)
  9980  	})
  9981  }
  9982  
  9983  func TestDoCreateStage(t *testing.T) {
  9984  	convey.Convey("doCreateStage success", t, func() {
  9985  		ctrl := gomock.NewController(t)
  9986  		defer ctrl.Finish()
  9987  
  9988  		ses := newTestSession(t, ctrl)
  9989  		defer ses.Close()
  9990  
  9991  		bh := &backgroundExecTest{}
  9992  		bh.init()
  9993  
  9994  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
  9995  		defer bhStub.Reset()
  9996  
  9997  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  9998  		pu.SV.SetDefaultValues()
  9999  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10000  
 10001  		rm, _ := NewRoutineManager(ctx)
 10002  		ses.rm = rm
 10003  
 10004  		tenant := &TenantInfo{
 10005  			Tenant:        sysAccountName,
 10006  			User:          rootName,
 10007  			DefaultRole:   moAdminRoleName,
 10008  			TenantID:      sysAccountID,
 10009  			UserID:        rootID,
 10010  			DefaultRoleID: moAdminRoleID,
 10011  		}
 10012  		ses.SetTenantInfo(tenant)
 10013  
 10014  		cs := &tree.CreateStage{
 10015  			IfNotExists: false,
 10016  			Name:        tree.Identifier("my_stage_test"),
 10017  			Url:         "'s3://load/files/'",
 10018  			Credentials: tree.StageCredentials{
 10019  				Exist: false,
 10020  			},
 10021  			Status: tree.StageStatus{
 10022  				Exist: false,
 10023  			},
 10024  			Comment: tree.StageComment{
 10025  				Exist: false,
 10026  			},
 10027  		}
 10028  
 10029  		//no result set
 10030  		bh.sql2result["begin;"] = nil
 10031  		bh.sql2result["commit;"] = nil
 10032  		bh.sql2result["rollback;"] = nil
 10033  
 10034  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10035  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 10036  		bh.sql2result[sql] = mrs
 10037  
 10038  		err := doCreateStage(ctx, ses, cs)
 10039  		convey.So(err, convey.ShouldBeNil)
 10040  	})
 10041  
 10042  	convey.Convey("doCreateStage fail", t, func() {
 10043  		ctrl := gomock.NewController(t)
 10044  		defer ctrl.Finish()
 10045  
 10046  		ses := newTestSession(t, ctrl)
 10047  		defer ses.Close()
 10048  
 10049  		bh := &backgroundExecTest{}
 10050  		bh.init()
 10051  
 10052  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10053  		defer bhStub.Reset()
 10054  
 10055  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10056  		pu.SV.SetDefaultValues()
 10057  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10058  
 10059  		rm, _ := NewRoutineManager(ctx)
 10060  		ses.rm = rm
 10061  
 10062  		tenant := &TenantInfo{
 10063  			Tenant:        sysAccountName,
 10064  			User:          rootName,
 10065  			DefaultRole:   moAdminRoleName,
 10066  			TenantID:      sysAccountID,
 10067  			UserID:        rootID,
 10068  			DefaultRoleID: moAdminRoleID,
 10069  		}
 10070  		ses.SetTenantInfo(tenant)
 10071  
 10072  		cs := &tree.CreateStage{
 10073  			IfNotExists: false,
 10074  			Name:        tree.Identifier("my_stage_test"),
 10075  			Url:         "'s3://load/files/'",
 10076  			Credentials: tree.StageCredentials{
 10077  				Exist: false,
 10078  			},
 10079  			Status: tree.StageStatus{
 10080  				Exist: false,
 10081  			},
 10082  			Comment: tree.StageComment{
 10083  				Exist: false,
 10084  			},
 10085  		}
 10086  
 10087  		//no result set
 10088  		bh.sql2result["begin;"] = nil
 10089  		bh.sql2result["commit;"] = nil
 10090  		bh.sql2result["rollback;"] = nil
 10091  
 10092  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10093  		mrs := newMrsForPasswordOfUser([][]interface{}{
 10094  			{0, 0},
 10095  		})
 10096  		bh.sql2result[sql] = mrs
 10097  
 10098  		err := doCreateStage(ctx, ses, cs)
 10099  		convey.So(err, convey.ShouldNotBeNil)
 10100  	})
 10101  
 10102  	convey.Convey("doCreateStage success", t, func() {
 10103  		ctrl := gomock.NewController(t)
 10104  		defer ctrl.Finish()
 10105  
 10106  		ses := newTestSession(t, ctrl)
 10107  		defer ses.Close()
 10108  
 10109  		bh := &backgroundExecTest{}
 10110  		bh.init()
 10111  
 10112  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10113  		defer bhStub.Reset()
 10114  
 10115  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10116  		pu.SV.SetDefaultValues()
 10117  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10118  
 10119  		rm, _ := NewRoutineManager(ctx)
 10120  		ses.rm = rm
 10121  
 10122  		tenant := &TenantInfo{
 10123  			Tenant:        sysAccountName,
 10124  			User:          rootName,
 10125  			DefaultRole:   moAdminRoleName,
 10126  			TenantID:      sysAccountID,
 10127  			UserID:        rootID,
 10128  			DefaultRoleID: moAdminRoleID,
 10129  		}
 10130  		ses.SetTenantInfo(tenant)
 10131  
 10132  		cs := &tree.CreateStage{
 10133  			IfNotExists: true,
 10134  			Name:        tree.Identifier("my_stage_test"),
 10135  			Url:         "'s3://load/files/'",
 10136  			Credentials: tree.StageCredentials{
 10137  				Exist: false,
 10138  			},
 10139  			Status: tree.StageStatus{
 10140  				Exist: false,
 10141  			},
 10142  			Comment: tree.StageComment{
 10143  				Exist: false,
 10144  			},
 10145  		}
 10146  
 10147  		//no result set
 10148  		bh.sql2result["begin;"] = nil
 10149  		bh.sql2result["commit;"] = nil
 10150  		bh.sql2result["rollback;"] = nil
 10151  
 10152  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10153  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 10154  		bh.sql2result[sql] = mrs
 10155  
 10156  		err := doCreateStage(ctx, ses, cs)
 10157  		convey.So(err, convey.ShouldBeNil)
 10158  	})
 10159  
 10160  	convey.Convey("doCreateStage success", t, func() {
 10161  		ctrl := gomock.NewController(t)
 10162  		defer ctrl.Finish()
 10163  
 10164  		ses := newTestSession(t, ctrl)
 10165  		defer ses.Close()
 10166  
 10167  		bh := &backgroundExecTest{}
 10168  		bh.init()
 10169  
 10170  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10171  		defer bhStub.Reset()
 10172  
 10173  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10174  		pu.SV.SetDefaultValues()
 10175  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10176  
 10177  		rm, _ := NewRoutineManager(ctx)
 10178  		ses.rm = rm
 10179  
 10180  		tenant := &TenantInfo{
 10181  			Tenant:        sysAccountName,
 10182  			User:          rootName,
 10183  			DefaultRole:   moAdminRoleName,
 10184  			TenantID:      sysAccountID,
 10185  			UserID:        rootID,
 10186  			DefaultRoleID: moAdminRoleID,
 10187  		}
 10188  		ses.SetTenantInfo(tenant)
 10189  
 10190  		cs := &tree.CreateStage{
 10191  			IfNotExists: false,
 10192  			Name:        tree.Identifier("my_stage_test"),
 10193  			Url:         "'s3://load/files/'",
 10194  			Credentials: tree.StageCredentials{
 10195  				Exist:       true,
 10196  				Credentials: []string{"'AWS_KEY_ID'", "'1a2b3c'", "'AWS_SECRET_KEY'", "'4x5y6z'"},
 10197  			},
 10198  			Status: tree.StageStatus{
 10199  				Exist:  true,
 10200  				Option: tree.StageStatusEnabled,
 10201  			},
 10202  			Comment: tree.StageComment{
 10203  				Exist: false,
 10204  			},
 10205  		}
 10206  
 10207  		//no result set
 10208  		bh.sql2result["begin;"] = nil
 10209  		bh.sql2result["commit;"] = nil
 10210  		bh.sql2result["rollback;"] = nil
 10211  
 10212  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10213  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 10214  		bh.sql2result[sql] = mrs
 10215  
 10216  		err := doCreateStage(ctx, ses, cs)
 10217  		convey.So(err, convey.ShouldBeNil)
 10218  	})
 10219  
 10220  	convey.Convey("doCreateStage fail", t, func() {
 10221  		ctrl := gomock.NewController(t)
 10222  		defer ctrl.Finish()
 10223  
 10224  		ses := newTestSession(t, ctrl)
 10225  		defer ses.Close()
 10226  
 10227  		bh := &backgroundExecTest{}
 10228  		bh.init()
 10229  
 10230  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10231  		defer bhStub.Reset()
 10232  
 10233  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10234  		pu.SV.SetDefaultValues()
 10235  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10236  
 10237  		rm, _ := NewRoutineManager(ctx)
 10238  		ses.rm = rm
 10239  
 10240  		tenant := &TenantInfo{
 10241  			Tenant:        "test_account",
 10242  			User:          rootName,
 10243  			DefaultRole:   "test_role",
 10244  			TenantID:      sysAccountID,
 10245  			UserID:        rootID,
 10246  			DefaultRoleID: moAdminRoleID,
 10247  		}
 10248  		ses.SetTenantInfo(tenant)
 10249  
 10250  		cs := &tree.CreateStage{
 10251  			IfNotExists: false,
 10252  			Name:        tree.Identifier("my_stage_test"),
 10253  			Url:         "'s3://load/files/'",
 10254  			Credentials: tree.StageCredentials{
 10255  				Exist: false,
 10256  			},
 10257  			Status: tree.StageStatus{
 10258  				Exist: false,
 10259  			},
 10260  			Comment: tree.StageComment{
 10261  				Exist: false,
 10262  			},
 10263  		}
 10264  
 10265  		//no result set
 10266  		bh.sql2result["begin;"] = nil
 10267  		bh.sql2result["commit;"] = nil
 10268  		bh.sql2result["rollback;"] = nil
 10269  
 10270  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10271  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 10272  		bh.sql2result[sql] = mrs
 10273  
 10274  		err := doCreateStage(ctx, ses, cs)
 10275  		convey.So(err, convey.ShouldNotBeNil)
 10276  	})
 10277  }
 10278  
 10279  func TestDoAlterStage(t *testing.T) {
 10280  	convey.Convey("doAlterStage success", t, func() {
 10281  		ctrl := gomock.NewController(t)
 10282  		defer ctrl.Finish()
 10283  
 10284  		ses := newTestSession(t, ctrl)
 10285  		defer ses.Close()
 10286  
 10287  		bh := &backgroundExecTest{}
 10288  		bh.init()
 10289  
 10290  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10291  		defer bhStub.Reset()
 10292  
 10293  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10294  		pu.SV.SetDefaultValues()
 10295  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10296  
 10297  		rm, _ := NewRoutineManager(ctx)
 10298  		ses.rm = rm
 10299  
 10300  		tenant := &TenantInfo{
 10301  			Tenant:        sysAccountName,
 10302  			User:          rootName,
 10303  			DefaultRole:   moAdminRoleName,
 10304  			TenantID:      sysAccountID,
 10305  			UserID:        rootID,
 10306  			DefaultRoleID: moAdminRoleID,
 10307  		}
 10308  		ses.SetTenantInfo(tenant)
 10309  
 10310  		as := &tree.AlterStage{
 10311  			IfNotExists: false,
 10312  			Name:        tree.Identifier("my_stage_test"),
 10313  			UrlOption: tree.StageUrl{
 10314  				Exist: true,
 10315  				Url:   "'s3://load/files/'",
 10316  			},
 10317  			CredentialsOption: tree.StageCredentials{
 10318  				Exist: false,
 10319  			},
 10320  			StatusOption: tree.StageStatus{
 10321  				Exist: false,
 10322  			},
 10323  			Comment: tree.StageComment{
 10324  				Exist: false,
 10325  			},
 10326  		}
 10327  
 10328  		//no result set
 10329  		bh.sql2result["begin;"] = nil
 10330  		bh.sql2result["commit;"] = nil
 10331  		bh.sql2result["rollback;"] = nil
 10332  
 10333  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10334  		mrs := newMrsForPasswordOfUser([][]interface{}{
 10335  			{0, 0},
 10336  		})
 10337  		bh.sql2result[sql] = mrs
 10338  
 10339  		err := doAlterStage(ctx, ses, as)
 10340  		convey.So(err, convey.ShouldBeNil)
 10341  	})
 10342  
 10343  	convey.Convey("doAlterStage success", t, func() {
 10344  		ctrl := gomock.NewController(t)
 10345  		defer ctrl.Finish()
 10346  
 10347  		ses := newTestSession(t, ctrl)
 10348  		defer ses.Close()
 10349  
 10350  		bh := &backgroundExecTest{}
 10351  		bh.init()
 10352  
 10353  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10354  		defer bhStub.Reset()
 10355  
 10356  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10357  		pu.SV.SetDefaultValues()
 10358  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10359  
 10360  		rm, _ := NewRoutineManager(ctx)
 10361  		ses.rm = rm
 10362  
 10363  		tenant := &TenantInfo{
 10364  			Tenant:        sysAccountName,
 10365  			User:          rootName,
 10366  			DefaultRole:   moAdminRoleName,
 10367  			TenantID:      sysAccountID,
 10368  			UserID:        rootID,
 10369  			DefaultRoleID: moAdminRoleID,
 10370  		}
 10371  		ses.SetTenantInfo(tenant)
 10372  
 10373  		as := &tree.AlterStage{
 10374  			IfNotExists: false,
 10375  			Name:        tree.Identifier("my_stage_test"),
 10376  			UrlOption: tree.StageUrl{
 10377  				Exist: false,
 10378  			},
 10379  			CredentialsOption: tree.StageCredentials{
 10380  				Exist:       true,
 10381  				Credentials: []string{"'AWS_KEY_ID'", "'1a2b3c'", "'AWS_SECRET_KEY'", "'4x5y6z'"},
 10382  			},
 10383  			StatusOption: tree.StageStatus{
 10384  				Exist: false,
 10385  			},
 10386  			Comment: tree.StageComment{
 10387  				Exist: false,
 10388  			},
 10389  		}
 10390  
 10391  		//no result set
 10392  		bh.sql2result["begin;"] = nil
 10393  		bh.sql2result["commit;"] = nil
 10394  		bh.sql2result["rollback;"] = nil
 10395  
 10396  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10397  		mrs := newMrsForPasswordOfUser([][]interface{}{
 10398  			{0, 0},
 10399  		})
 10400  		bh.sql2result[sql] = mrs
 10401  
 10402  		err := doAlterStage(ctx, ses, as)
 10403  		convey.So(err, convey.ShouldBeNil)
 10404  	})
 10405  
 10406  	convey.Convey("doAlterStage success", t, func() {
 10407  		ctrl := gomock.NewController(t)
 10408  		defer ctrl.Finish()
 10409  
 10410  		ses := newTestSession(t, ctrl)
 10411  		defer ses.Close()
 10412  
 10413  		bh := &backgroundExecTest{}
 10414  		bh.init()
 10415  
 10416  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10417  		defer bhStub.Reset()
 10418  
 10419  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10420  		pu.SV.SetDefaultValues()
 10421  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10422  
 10423  		rm, _ := NewRoutineManager(ctx)
 10424  		ses.rm = rm
 10425  
 10426  		tenant := &TenantInfo{
 10427  			Tenant:        sysAccountName,
 10428  			User:          rootName,
 10429  			DefaultRole:   moAdminRoleName,
 10430  			TenantID:      sysAccountID,
 10431  			UserID:        rootID,
 10432  			DefaultRoleID: moAdminRoleID,
 10433  		}
 10434  		ses.SetTenantInfo(tenant)
 10435  
 10436  		as := &tree.AlterStage{
 10437  			IfNotExists: true,
 10438  			Name:        tree.Identifier("my_stage_test"),
 10439  			UrlOption: tree.StageUrl{
 10440  				Exist: true,
 10441  				Url:   "'s3://load/files/'",
 10442  			},
 10443  			CredentialsOption: tree.StageCredentials{
 10444  				Exist: false,
 10445  			},
 10446  			StatusOption: tree.StageStatus{
 10447  				Exist: false,
 10448  			},
 10449  			Comment: tree.StageComment{
 10450  				Exist: false,
 10451  			},
 10452  		}
 10453  
 10454  		//no result set
 10455  		bh.sql2result["begin;"] = nil
 10456  		bh.sql2result["commit;"] = nil
 10457  		bh.sql2result["rollback;"] = nil
 10458  
 10459  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10460  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 10461  		bh.sql2result[sql] = mrs
 10462  
 10463  		err := doAlterStage(ctx, ses, as)
 10464  		convey.So(err, convey.ShouldBeNil)
 10465  	})
 10466  
 10467  	convey.Convey("doAlterStage fail", t, func() {
 10468  		ctrl := gomock.NewController(t)
 10469  		defer ctrl.Finish()
 10470  
 10471  		ses := newTestSession(t, ctrl)
 10472  		defer ses.Close()
 10473  
 10474  		bh := &backgroundExecTest{}
 10475  		bh.init()
 10476  
 10477  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10478  		defer bhStub.Reset()
 10479  
 10480  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10481  		pu.SV.SetDefaultValues()
 10482  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10483  
 10484  		rm, _ := NewRoutineManager(ctx)
 10485  		ses.rm = rm
 10486  
 10487  		tenant := &TenantInfo{
 10488  			Tenant:        sysAccountName,
 10489  			User:          rootName,
 10490  			DefaultRole:   moAdminRoleName,
 10491  			TenantID:      sysAccountID,
 10492  			UserID:        rootID,
 10493  			DefaultRoleID: moAdminRoleID,
 10494  		}
 10495  		ses.SetTenantInfo(tenant)
 10496  
 10497  		as := &tree.AlterStage{
 10498  			IfNotExists: false,
 10499  			Name:        tree.Identifier("my_stage_test"),
 10500  			UrlOption: tree.StageUrl{
 10501  				Exist: true,
 10502  				Url:   "'s3://load/files/'",
 10503  			},
 10504  			CredentialsOption: tree.StageCredentials{
 10505  				Exist: false,
 10506  			},
 10507  			StatusOption: tree.StageStatus{
 10508  				Exist: false,
 10509  			},
 10510  			Comment: tree.StageComment{
 10511  				Exist: false,
 10512  			},
 10513  		}
 10514  
 10515  		//no result set
 10516  		bh.sql2result["begin;"] = nil
 10517  		bh.sql2result["commit;"] = nil
 10518  		bh.sql2result["rollback;"] = nil
 10519  
 10520  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10521  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 10522  		bh.sql2result[sql] = mrs
 10523  
 10524  		err := doAlterStage(ctx, ses, as)
 10525  		convey.So(err, convey.ShouldNotBeNil)
 10526  	})
 10527  
 10528  	convey.Convey("doAlterStage fail", t, func() {
 10529  		ctrl := gomock.NewController(t)
 10530  		defer ctrl.Finish()
 10531  
 10532  		ses := newTestSession(t, ctrl)
 10533  		defer ses.Close()
 10534  
 10535  		bh := &backgroundExecTest{}
 10536  		bh.init()
 10537  
 10538  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10539  		defer bhStub.Reset()
 10540  
 10541  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10542  		pu.SV.SetDefaultValues()
 10543  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10544  
 10545  		rm, _ := NewRoutineManager(ctx)
 10546  		ses.rm = rm
 10547  
 10548  		tenant := &TenantInfo{
 10549  			Tenant:        sysAccountName,
 10550  			User:          rootName,
 10551  			DefaultRole:   moAdminRoleName,
 10552  			TenantID:      sysAccountID,
 10553  			UserID:        rootID,
 10554  			DefaultRoleID: moAdminRoleID,
 10555  		}
 10556  		ses.SetTenantInfo(tenant)
 10557  
 10558  		as := &tree.AlterStage{
 10559  			IfNotExists: true,
 10560  			Name:        tree.Identifier("my_stage_test"),
 10561  			UrlOption: tree.StageUrl{
 10562  				Exist: true,
 10563  				Url:   "'s3://load/files/'",
 10564  			},
 10565  			CredentialsOption: tree.StageCredentials{
 10566  				Exist:       true,
 10567  				Credentials: []string{"'AWS_KEY_ID'", "'1a2b3c'", "'AWS_SECRET_KEY'", "'4x5y6z'"},
 10568  			},
 10569  			StatusOption: tree.StageStatus{
 10570  				Exist: false,
 10571  			},
 10572  			Comment: tree.StageComment{
 10573  				Exist: false,
 10574  			},
 10575  		}
 10576  
 10577  		//no result set
 10578  		bh.sql2result["begin;"] = nil
 10579  		bh.sql2result["commit;"] = nil
 10580  		bh.sql2result["rollback;"] = nil
 10581  
 10582  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10583  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 10584  		bh.sql2result[sql] = mrs
 10585  
 10586  		err := doAlterStage(ctx, ses, as)
 10587  		convey.So(err, convey.ShouldNotBeNil)
 10588  	})
 10589  
 10590  	convey.Convey("doAlterStage fail", t, func() {
 10591  		ctrl := gomock.NewController(t)
 10592  		defer ctrl.Finish()
 10593  
 10594  		ses := newTestSession(t, ctrl)
 10595  		defer ses.Close()
 10596  
 10597  		bh := &backgroundExecTest{}
 10598  		bh.init()
 10599  
 10600  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10601  		defer bhStub.Reset()
 10602  
 10603  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10604  		pu.SV.SetDefaultValues()
 10605  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10606  
 10607  		rm, _ := NewRoutineManager(ctx)
 10608  		ses.rm = rm
 10609  
 10610  		tenant := &TenantInfo{
 10611  			Tenant:        "test_account",
 10612  			User:          rootName,
 10613  			DefaultRole:   "test_role",
 10614  			TenantID:      sysAccountID,
 10615  			UserID:        rootID,
 10616  			DefaultRoleID: moAdminRoleID,
 10617  		}
 10618  		ses.SetTenantInfo(tenant)
 10619  
 10620  		as := &tree.AlterStage{
 10621  			IfNotExists: false,
 10622  			Name:        tree.Identifier("my_stage_test"),
 10623  			UrlOption: tree.StageUrl{
 10624  				Exist: false,
 10625  			},
 10626  			CredentialsOption: tree.StageCredentials{
 10627  				Exist:       true,
 10628  				Credentials: []string{"'AWS_KEY_ID'", "'1a2b3c'", "'AWS_SECRET_KEY'", "'4x5y6z'"},
 10629  			},
 10630  			StatusOption: tree.StageStatus{
 10631  				Exist: false,
 10632  			},
 10633  			Comment: tree.StageComment{
 10634  				Exist: false,
 10635  			},
 10636  		}
 10637  
 10638  		//no result set
 10639  		bh.sql2result["begin;"] = nil
 10640  		bh.sql2result["commit;"] = nil
 10641  		bh.sql2result["rollback;"] = nil
 10642  
 10643  		sql, _ := getSqlForCheckStage(ctx, "my_stage_test")
 10644  		mrs := newMrsForPasswordOfUser([][]interface{}{
 10645  			{0, 0},
 10646  		})
 10647  		bh.sql2result[sql] = mrs
 10648  
 10649  		err := doAlterStage(ctx, ses, as)
 10650  		convey.So(err, convey.ShouldNotBeNil)
 10651  	})
 10652  
 10653  }
 10654  
 10655  func TestDoCheckFilePath(t *testing.T) {
 10656  	convey.Convey("doCheckFilePath success", t, func() {
 10657  		ctrl := gomock.NewController(t)
 10658  		defer ctrl.Finish()
 10659  
 10660  		ses := newTestSession(t, ctrl)
 10661  		defer ses.Close()
 10662  
 10663  		bh := &backgroundExecTest{}
 10664  		bh.init()
 10665  
 10666  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10667  		defer bhStub.Reset()
 10668  
 10669  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10670  		pu.SV.SetDefaultValues()
 10671  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10672  
 10673  		rm, _ := NewRoutineManager(ctx)
 10674  		ses.rm = rm
 10675  
 10676  		tenant := &TenantInfo{
 10677  			Tenant:        sysAccountName,
 10678  			User:          rootName,
 10679  			DefaultRole:   moAdminRoleName,
 10680  			TenantID:      sysAccountID,
 10681  			UserID:        rootID,
 10682  			DefaultRoleID: moAdminRoleID,
 10683  		}
 10684  		ses.SetTenantInfo(tenant)
 10685  
 10686  		cs := &tree.Select{}
 10687  		ses.InitExportConfig(cs.Ep)
 10688  
 10689  		//no result set
 10690  		bh.sql2result["begin;"] = nil
 10691  		bh.sql2result["commit;"] = nil
 10692  		bh.sql2result["rollback;"] = nil
 10693  
 10694  		err := doCheckFilePath(ctx, ses, cs.Ep)
 10695  		convey.So(err, convey.ShouldBeNil)
 10696  	})
 10697  
 10698  	convey.Convey("doCheckFilePath success", t, func() {
 10699  		ctrl := gomock.NewController(t)
 10700  		defer ctrl.Finish()
 10701  
 10702  		ses := newTestSession(t, ctrl)
 10703  		defer ses.Close()
 10704  
 10705  		bh := &backgroundExecTest{}
 10706  		bh.init()
 10707  
 10708  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10709  		defer bhStub.Reset()
 10710  
 10711  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10712  		pu.SV.SetDefaultValues()
 10713  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10714  
 10715  		rm, _ := NewRoutineManager(ctx)
 10716  		ses.rm = rm
 10717  
 10718  		tenant := &TenantInfo{
 10719  			Tenant:        sysAccountName,
 10720  			User:          rootName,
 10721  			DefaultRole:   moAdminRoleName,
 10722  			TenantID:      sysAccountID,
 10723  			UserID:        rootID,
 10724  			DefaultRoleID: moAdminRoleID,
 10725  		}
 10726  		ses.SetTenantInfo(tenant)
 10727  
 10728  		cs := &tree.Select{
 10729  			Ep: &tree.ExportParam{
 10730  				FilePath: "/mnt/disk1/t1.csv",
 10731  			},
 10732  		}
 10733  		ses.InitExportConfig(cs.Ep)
 10734  
 10735  		//no result set
 10736  		bh.sql2result["begin;"] = nil
 10737  		bh.sql2result["commit;"] = nil
 10738  		bh.sql2result["rollback;"] = nil
 10739  
 10740  		sql := getSqlForCheckStageStatus(ctx, "enabled")
 10741  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 10742  		bh.sql2result[sql] = mrs
 10743  
 10744  		err := doCheckFilePath(ctx, ses, cs.Ep)
 10745  		convey.So(err, convey.ShouldBeNil)
 10746  	})
 10747  
 10748  	convey.Convey("doCheckFilePath success", t, func() {
 10749  		ctrl := gomock.NewController(t)
 10750  		defer ctrl.Finish()
 10751  
 10752  		ses := newTestSession(t, ctrl)
 10753  		defer ses.Close()
 10754  
 10755  		bh := &backgroundExecTest{}
 10756  		bh.init()
 10757  
 10758  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10759  		defer bhStub.Reset()
 10760  
 10761  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10762  		pu.SV.SetDefaultValues()
 10763  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10764  
 10765  		rm, _ := NewRoutineManager(ctx)
 10766  		ses.rm = rm
 10767  
 10768  		tenant := &TenantInfo{
 10769  			Tenant:        sysAccountName,
 10770  			User:          rootName,
 10771  			DefaultRole:   moAdminRoleName,
 10772  			TenantID:      sysAccountID,
 10773  			UserID:        rootID,
 10774  			DefaultRoleID: moAdminRoleID,
 10775  		}
 10776  		ses.SetTenantInfo(tenant)
 10777  
 10778  		cs := &tree.Select{
 10779  			Ep: &tree.ExportParam{
 10780  				FilePath: "/mnt/disk1/t1.csv",
 10781  			},
 10782  		}
 10783  		ses.InitExportConfig(cs.Ep)
 10784  
 10785  		//no result set
 10786  		bh.sql2result["begin;"] = nil
 10787  		bh.sql2result["commit;"] = nil
 10788  		bh.sql2result["rollback;"] = nil
 10789  
 10790  		sql := getSqlForCheckStageStatus(ctx, "enabled")
 10791  		mrs := newMrsForPasswordOfUser([][]interface{}{
 10792  			{0, 0},
 10793  		})
 10794  		bh.sql2result[sql] = mrs
 10795  
 10796  		err := doCheckFilePath(ctx, ses, cs.Ep)
 10797  		convey.So(err, convey.ShouldNotBeNil)
 10798  	})
 10799  
 10800  	convey.Convey("doCheckFilePath fail", t, func() {
 10801  		ctrl := gomock.NewController(t)
 10802  		defer ctrl.Finish()
 10803  
 10804  		ses := newTestSession(t, ctrl)
 10805  		defer ses.Close()
 10806  
 10807  		bh := &backgroundExecTest{}
 10808  		bh.init()
 10809  
 10810  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10811  		defer bhStub.Reset()
 10812  
 10813  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10814  		pu.SV.SetDefaultValues()
 10815  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10816  
 10817  		rm, _ := NewRoutineManager(ctx)
 10818  		ses.rm = rm
 10819  
 10820  		tenant := &TenantInfo{
 10821  			Tenant:        sysAccountName,
 10822  			User:          rootName,
 10823  			DefaultRole:   moAdminRoleName,
 10824  			TenantID:      sysAccountID,
 10825  			UserID:        rootID,
 10826  			DefaultRoleID: moAdminRoleID,
 10827  		}
 10828  		ses.SetTenantInfo(tenant)
 10829  
 10830  		cs := &tree.Select{
 10831  			Ep: &tree.ExportParam{
 10832  				FilePath: "stage1:/t1.csv",
 10833  			},
 10834  		}
 10835  		ses.InitExportConfig(cs.Ep)
 10836  
 10837  		//no result set
 10838  		bh.sql2result["begin;"] = nil
 10839  		bh.sql2result["commit;"] = nil
 10840  		bh.sql2result["rollback;"] = nil
 10841  
 10842  		sql, _ := getSqlForCheckStageStatusWithStageName(ctx, "stage1")
 10843  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 10844  		bh.sql2result[sql] = mrs
 10845  
 10846  		err := doCheckFilePath(ctx, ses, cs.Ep)
 10847  		convey.So(err, convey.ShouldNotBeNil)
 10848  	})
 10849  
 10850  	convey.Convey("doCheckFilePath fail", t, func() {
 10851  		ctrl := gomock.NewController(t)
 10852  		defer ctrl.Finish()
 10853  
 10854  		ses := newTestSession(t, ctrl)
 10855  		defer ses.Close()
 10856  
 10857  		bh := &backgroundExecTest{}
 10858  		bh.init()
 10859  
 10860  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10861  		defer bhStub.Reset()
 10862  
 10863  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10864  		pu.SV.SetDefaultValues()
 10865  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10866  
 10867  		rm, _ := NewRoutineManager(ctx)
 10868  		ses.rm = rm
 10869  
 10870  		tenant := &TenantInfo{
 10871  			Tenant:        sysAccountName,
 10872  			User:          rootName,
 10873  			DefaultRole:   moAdminRoleName,
 10874  			TenantID:      sysAccountID,
 10875  			UserID:        rootID,
 10876  			DefaultRoleID: moAdminRoleID,
 10877  		}
 10878  		ses.SetTenantInfo(tenant)
 10879  
 10880  		cs := &tree.Select{
 10881  			Ep: &tree.ExportParam{
 10882  				FilePath: "stage1:/t1.csv",
 10883  			},
 10884  		}
 10885  		ses.InitExportConfig(cs.Ep)
 10886  
 10887  		//no result set
 10888  		bh.sql2result["begin;"] = nil
 10889  		bh.sql2result["commit;"] = nil
 10890  		bh.sql2result["rollback;"] = nil
 10891  
 10892  		sql, _ := getSqlForCheckStageStatusWithStageName(ctx, "stage1")
 10893  		mrs := newMrsForPasswordOfUser([][]interface{}{
 10894  			{"/tmp", "disabled"},
 10895  		})
 10896  		bh.sql2result[sql] = mrs
 10897  
 10898  		err := doCheckFilePath(ctx, ses, cs.Ep)
 10899  		convey.So(err, convey.ShouldNotBeNil)
 10900  	})
 10901  
 10902  	convey.Convey("doCheckFilePath success", t, func() {
 10903  		ctrl := gomock.NewController(t)
 10904  		defer ctrl.Finish()
 10905  
 10906  		ses := newTestSession(t, ctrl)
 10907  		defer ses.Close()
 10908  
 10909  		bh := &backgroundExecTest{}
 10910  		bh.init()
 10911  
 10912  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 10913  		defer bhStub.Reset()
 10914  
 10915  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 10916  		pu.SV.SetDefaultValues()
 10917  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 10918  
 10919  		rm, _ := NewRoutineManager(ctx)
 10920  		ses.rm = rm
 10921  
 10922  		tenant := &TenantInfo{
 10923  			Tenant:        sysAccountName,
 10924  			User:          rootName,
 10925  			DefaultRole:   moAdminRoleName,
 10926  			TenantID:      sysAccountID,
 10927  			UserID:        rootID,
 10928  			DefaultRoleID: moAdminRoleID,
 10929  		}
 10930  		ses.SetTenantInfo(tenant)
 10931  
 10932  		cs := &tree.Select{
 10933  			Ep: &tree.ExportParam{
 10934  				FilePath: "stage1:/t1.csv",
 10935  			},
 10936  		}
 10937  		ses.InitExportConfig(cs.Ep)
 10938  
 10939  		//no result set
 10940  		bh.sql2result["begin;"] = nil
 10941  		bh.sql2result["commit;"] = nil
 10942  		bh.sql2result["rollback;"] = nil
 10943  
 10944  		sql, _ := getSqlForCheckStageStatusWithStageName(ctx, "stage1")
 10945  		mrs := newMrsForPasswordOfUser([][]interface{}{
 10946  			{"/tmp", "enabled"},
 10947  		})
 10948  		bh.sql2result[sql] = mrs
 10949  
 10950  		err := doCheckFilePath(ctx, ses, cs.Ep)
 10951  		convey.So(err, convey.ShouldBeNil)
 10952  		convey.So(cs.Ep.FilePath, convey.ShouldEqual, "stage1:/t1.csv")
 10953  	})
 10954  }
 10955  
 10956  func TestGetLabelPart(t *testing.T) {
 10957  	user1 := "user1"
 10958  	require.Equal(t, "", getLabelPart(user1))
 10959  	user1 = "user1?"
 10960  	require.Equal(t, "", getLabelPart(user1))
 10961  	user1 = "user1?a:b"
 10962  	require.Equal(t, "a:b", getLabelPart(user1))
 10963  }
 10964  
 10965  func TestParseLabel(t *testing.T) {
 10966  	cases := []struct {
 10967  		str string
 10968  		ret map[string]string
 10969  		err bool
 10970  	}{
 10971  		{
 10972  			str: "",
 10973  			ret: map[string]string{},
 10974  			err: false,
 10975  		},
 10976  		{
 10977  			str: "a=1",
 10978  			ret: map[string]string{"a": "1"},
 10979  			err: false,
 10980  		},
 10981  		{
 10982  			str: "a=1,",
 10983  			err: true,
 10984  		},
 10985  		{
 10986  			str: "a=1,b=2",
 10987  			ret: map[string]string{"b": "2", "a": "1"},
 10988  			err: false,
 10989  		},
 10990  		{
 10991  			str: "a=1,b",
 10992  			err: true,
 10993  		},
 10994  		{
 10995  			str: "a=1,b=",
 10996  			err: true,
 10997  		},
 10998  		{
 10999  			str: "a=1,=2",
 11000  			err: true,
 11001  		},
 11002  		{
 11003  			str: "a=1,=",
 11004  			err: true,
 11005  		},
 11006  		{
 11007  			str: "a",
 11008  			err: true,
 11009  		},
 11010  		{
 11011  			str: "a=1,b:2",
 11012  			err: true,
 11013  		},
 11014  	}
 11015  
 11016  	for _, item := range cases {
 11017  		lb, err := ParseLabel(item.str)
 11018  		if item.err {
 11019  			require.Error(t, err)
 11020  		} else {
 11021  			require.True(t, reflect.DeepEqual(item.ret, lb))
 11022  			require.NoError(t, err)
 11023  		}
 11024  	}
 11025  }
 11026  
 11027  func TestUpload(t *testing.T) {
 11028  	convey.Convey("call upload func", t, func() {
 11029  		ctrl := gomock.NewController(t)
 11030  		defer ctrl.Finish()
 11031  		ioses := mock_frontend.NewMockIOSession(ctrl)
 11032  		proc := testutil.NewProc()
 11033  		cnt := 0
 11034  		ioses.EXPECT().Read(gomock.Any()).DoAndReturn(func(options goetty.ReadOptions) (pkt any, err error) {
 11035  			if cnt == 0 {
 11036  				pkt = &Packet{Length: 5, Payload: []byte("def add(a, b):\n"), SequenceID: 1}
 11037  			} else if cnt == 1 {
 11038  				pkt = &Packet{Length: 5, Payload: []byte("  return a + b"), SequenceID: 2}
 11039  			} else {
 11040  				err = moerr.NewInvalidInput(context.TODO(), "length 0")
 11041  			}
 11042  			cnt++
 11043  			return
 11044  		}).AnyTimes()
 11045  		proto := &FakeProtocol{
 11046  			ioses: ioses,
 11047  		}
 11048  		fs, err := fileservice.NewLocalFS(context.TODO(), defines.SharedFileServiceName, t.TempDir(), fileservice.DisabledCacheConfig, nil)
 11049  		convey.So(err, convey.ShouldBeNil)
 11050  		proc.FileService = fs
 11051  
 11052  		//parameter
 11053  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11054  		_, err = toml.DecodeFile("test/system_vars_config.toml", pu.SV)
 11055  		assert.Nil(t, err)
 11056  		pu.SV.SetDefaultValues()
 11057  		pu.SV.SaveQueryResult = "on"
 11058  		if err != nil {
 11059  			assert.Nil(t, err)
 11060  		}
 11061  		//file service
 11062  		pu.FileService = fs
 11063  		setGlobalPu(pu)
 11064  		ses := &Session{
 11065  			feSessionImpl: feSessionImpl{
 11066  				proto: proto,
 11067  			},
 11068  			proc: proc,
 11069  		}
 11070  		ec := newTestExecCtx(context.TODO(), ctrl)
 11071  		fp, err := Upload(ses, ec, "test.py", "test")
 11072  		convey.So(err, convey.ShouldBeNil)
 11073  		iovec := &fileservice.IOVector{
 11074  			FilePath: fp,
 11075  			Entries: []fileservice.IOEntry{
 11076  				{
 11077  					Offset: 0,
 11078  					Size:   -1,
 11079  				},
 11080  			},
 11081  		}
 11082  		err = fs.Read(context.TODO(), iovec)
 11083  		convey.So(err, convey.ShouldBeNil)
 11084  		convey.So(iovec.Entries[0].Data, convey.ShouldResemble, []byte("def add(a, b):\n  return a + b"))
 11085  	})
 11086  }
 11087  
 11088  func TestCheckSnapshotExistOrNot(t *testing.T) {
 11089  	convey.Convey("checkSnapshotExistOrNot success", t, func() {
 11090  		ctrl := gomock.NewController(t)
 11091  		defer ctrl.Finish()
 11092  
 11093  		ses := newTestSession(t, ctrl)
 11094  		defer ses.Close()
 11095  
 11096  		bh := &backgroundExecTest{}
 11097  		bh.init()
 11098  
 11099  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11100  		defer bhStub.Reset()
 11101  
 11102  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11103  		pu.SV.SetDefaultValues()
 11104  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11105  		setGlobalPu(pu)
 11106  
 11107  		rm, _ := NewRoutineManager(ctx)
 11108  		ses.rm = rm
 11109  
 11110  		tenant := &TenantInfo{
 11111  			Tenant:        sysAccountName,
 11112  			User:          rootName,
 11113  			DefaultRole:   moAdminRoleName,
 11114  			TenantID:      sysAccountID,
 11115  			UserID:        rootID,
 11116  			DefaultRoleID: moAdminRoleID,
 11117  		}
 11118  		ses.SetTenantInfo(tenant)
 11119  
 11120  		//no result set
 11121  		bh.sql2result["begin;"] = nil
 11122  		bh.sql2result["commit;"] = nil
 11123  		bh.sql2result["rollback;"] = nil
 11124  
 11125  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11126  		mrs := newMrsForPasswordOfUser([][]interface{}{
 11127  			{0, 0},
 11128  		})
 11129  		bh.sql2result[sql] = mrs
 11130  
 11131  		rst, err := checkSnapShotExistOrNot(ctx, bh, "snapshot_test")
 11132  		convey.So(err, convey.ShouldBeNil)
 11133  		convey.So(rst, convey.ShouldBeTrue)
 11134  	})
 11135  
 11136  	convey.Convey("checkSnapshotExistOrNot success", t, func() {
 11137  		ctrl := gomock.NewController(t)
 11138  		defer ctrl.Finish()
 11139  
 11140  		ses := newTestSession(t, ctrl)
 11141  		defer ses.Close()
 11142  
 11143  		bh := &backgroundExecTest{}
 11144  		bh.init()
 11145  
 11146  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11147  		defer bhStub.Reset()
 11148  
 11149  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11150  		pu.SV.SetDefaultValues()
 11151  		setGlobalPu(pu)
 11152  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11153  		rm, _ := NewRoutineManager(ctx)
 11154  		ses.rm = rm
 11155  
 11156  		tenant := &TenantInfo{
 11157  			Tenant:        sysAccountName,
 11158  			User:          rootName,
 11159  			DefaultRole:   moAdminRoleName,
 11160  			TenantID:      sysAccountID,
 11161  			UserID:        rootID,
 11162  			DefaultRoleID: moAdminRoleID,
 11163  		}
 11164  		ses.SetTenantInfo(tenant)
 11165  
 11166  		//no result set
 11167  		bh.sql2result["begin;"] = nil
 11168  		bh.sql2result["commit;"] = nil
 11169  		bh.sql2result["rollback;"] = nil
 11170  
 11171  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11172  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 11173  		bh.sql2result[sql] = mrs
 11174  
 11175  		rst, err := checkSnapShotExistOrNot(ctx, bh, "snapshot_test")
 11176  		convey.So(err, convey.ShouldBeNil)
 11177  		convey.So(rst, convey.ShouldBeFalse)
 11178  	})
 11179  }
 11180  
 11181  func TestDoDropSnapshot(t *testing.T) {
 11182  	convey.Convey("doDropSnapshot success", t, func() {
 11183  		ctrl := gomock.NewController(t)
 11184  		defer ctrl.Finish()
 11185  
 11186  		ses := newTestSession(t, ctrl)
 11187  		defer ses.Close()
 11188  
 11189  		bh := &backgroundExecTest{}
 11190  		bh.init()
 11191  
 11192  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11193  		defer bhStub.Reset()
 11194  
 11195  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11196  		pu.SV.SetDefaultValues()
 11197  		setGlobalPu(pu)
 11198  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11199  		rm, _ := NewRoutineManager(ctx)
 11200  		ses.rm = rm
 11201  
 11202  		tenant := &TenantInfo{
 11203  			Tenant:        sysAccountName,
 11204  			User:          rootName,
 11205  			DefaultRole:   moAdminRoleName,
 11206  			TenantID:      sysAccountID,
 11207  			UserID:        rootID,
 11208  			DefaultRoleID: moAdminRoleID,
 11209  		}
 11210  		ses.SetTenantInfo(tenant)
 11211  
 11212  		ds := &tree.DropSnapShot{
 11213  			IfExists: false,
 11214  			Name:     tree.Identifier("snapshot_test"),
 11215  		}
 11216  
 11217  		//no result set
 11218  		bh.sql2result["begin;"] = nil
 11219  		bh.sql2result["commit;"] = nil
 11220  		bh.sql2result["rollback;"] = nil
 11221  
 11222  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11223  		mrs := newMrsForPasswordOfUser([][]interface{}{
 11224  			{0, 0},
 11225  		})
 11226  		bh.sql2result[sql] = mrs
 11227  
 11228  		sql = getSqlForDropSnapshot(string(ds.Name))
 11229  		mrs = newMrsForPasswordOfUser([][]interface{}{})
 11230  		bh.sql2result[sql] = mrs
 11231  
 11232  		err := doDropSnapshot(ctx, ses, ds)
 11233  		convey.So(err, convey.ShouldBeNil)
 11234  	})
 11235  
 11236  	convey.Convey("doDropSnapshot success", t, func() {
 11237  		ctrl := gomock.NewController(t)
 11238  		defer ctrl.Finish()
 11239  
 11240  		ses := newTestSession(t, ctrl)
 11241  		defer ses.Close()
 11242  
 11243  		bh := &backgroundExecTest{}
 11244  		bh.init()
 11245  
 11246  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11247  		defer bhStub.Reset()
 11248  
 11249  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11250  		pu.SV.SetDefaultValues()
 11251  		setGlobalPu(pu)
 11252  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11253  		rm, _ := NewRoutineManager(ctx)
 11254  		ses.rm = rm
 11255  
 11256  		tenant := &TenantInfo{
 11257  			Tenant:        sysAccountName,
 11258  			User:          rootName,
 11259  			DefaultRole:   moAdminRoleName,
 11260  			TenantID:      sysAccountID,
 11261  			UserID:        rootID,
 11262  			DefaultRoleID: moAdminRoleID,
 11263  		}
 11264  		ses.SetTenantInfo(tenant)
 11265  
 11266  		ds := &tree.DropSnapShot{
 11267  			IfExists: true,
 11268  			Name:     tree.Identifier("snapshot_test"),
 11269  		}
 11270  
 11271  		//no result set
 11272  		bh.sql2result["begin;"] = nil
 11273  		bh.sql2result["commit;"] = nil
 11274  		bh.sql2result["rollback;"] = nil
 11275  
 11276  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11277  		mrs := newMrsForPasswordOfUser([][]interface{}{
 11278  			{0, 0},
 11279  		})
 11280  		bh.sql2result[sql] = mrs
 11281  
 11282  		sql = getSqlForDropSnapshot(string(ds.Name))
 11283  		mrs = newMrsForPasswordOfUser([][]interface{}{})
 11284  		bh.sql2result[sql] = mrs
 11285  
 11286  		err := doDropSnapshot(ctx, ses, ds)
 11287  		convey.So(err, convey.ShouldBeNil)
 11288  	})
 11289  
 11290  	convey.Convey("doDropSnapshot fail", t, func() {
 11291  		ctrl := gomock.NewController(t)
 11292  		defer ctrl.Finish()
 11293  
 11294  		ses := newTestSession(t, ctrl)
 11295  		defer ses.Close()
 11296  
 11297  		bh := &backgroundExecTest{}
 11298  		bh.init()
 11299  
 11300  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11301  		defer bhStub.Reset()
 11302  
 11303  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11304  		pu.SV.SetDefaultValues()
 11305  		setGlobalPu(pu)
 11306  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11307  		rm, _ := NewRoutineManager(ctx)
 11308  		ses.rm = rm
 11309  
 11310  		tenant := &TenantInfo{
 11311  			Tenant:        sysAccountName,
 11312  			User:          rootName,
 11313  			DefaultRole:   moAdminRoleName,
 11314  			TenantID:      sysAccountID,
 11315  			UserID:        rootID,
 11316  			DefaultRoleID: moAdminRoleID,
 11317  		}
 11318  		ses.SetTenantInfo(tenant)
 11319  
 11320  		ds := &tree.DropSnapShot{
 11321  			IfExists: false,
 11322  			Name:     tree.Identifier("snapshot_test"),
 11323  		}
 11324  
 11325  		//no result set
 11326  		bh.sql2result["begin;"] = nil
 11327  		bh.sql2result["commit;"] = nil
 11328  		bh.sql2result["rollback;"] = nil
 11329  
 11330  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11331  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 11332  		bh.sql2result[sql] = mrs
 11333  
 11334  		sql = getSqlForDropSnapshot(string(ds.Name))
 11335  		mrs = newMrsForPasswordOfUser([][]interface{}{})
 11336  		bh.sql2result[sql] = mrs
 11337  
 11338  		err := doDropSnapshot(ctx, ses, ds)
 11339  		convey.So(err, convey.ShouldNotBeNil)
 11340  	})
 11341  
 11342  	convey.Convey("doDropSnapshot fail", t, func() {
 11343  		ctrl := gomock.NewController(t)
 11344  		defer ctrl.Finish()
 11345  
 11346  		ses := newTestSession(t, ctrl)
 11347  		defer ses.Close()
 11348  
 11349  		bh := &backgroundExecTest{}
 11350  		bh.init()
 11351  
 11352  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11353  		defer bhStub.Reset()
 11354  
 11355  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11356  		pu.SV.SetDefaultValues()
 11357  		setGlobalPu(pu)
 11358  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11359  		rm, _ := NewRoutineManager(ctx)
 11360  		ses.rm = rm
 11361  
 11362  		tenant := &TenantInfo{
 11363  			Tenant:        "test_account",
 11364  			User:          rootName,
 11365  			DefaultRole:   "test_role",
 11366  			TenantID:      sysAccountID,
 11367  			UserID:        rootID,
 11368  			DefaultRoleID: moAdminRoleID,
 11369  		}
 11370  		ses.SetTenantInfo(tenant)
 11371  
 11372  		ds := &tree.DropSnapShot{
 11373  			IfExists: true,
 11374  			Name:     tree.Identifier("snapshot_test"),
 11375  		}
 11376  
 11377  		//no result set
 11378  		bh.sql2result["begin;"] = nil
 11379  		bh.sql2result["commit;"] = nil
 11380  		bh.sql2result["rollback;"] = nil
 11381  
 11382  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11383  		mrs := newMrsForPasswordOfUser([][]interface{}{
 11384  			{0, 0},
 11385  		})
 11386  		bh.sql2result[sql] = mrs
 11387  
 11388  		sql = getSqlForDropSnapshot(string(ds.Name))
 11389  		mrs = newMrsForPasswordOfUser([][]interface{}{})
 11390  		bh.sql2result[sql] = mrs
 11391  
 11392  		err := doDropSnapshot(ctx, ses, ds)
 11393  		convey.So(err, convey.ShouldNotBeNil)
 11394  	})
 11395  }
 11396  
 11397  func TestDoCreateSnapshot(t *testing.T) {
 11398  	convey.Convey("doCreateSnapshot success", t, func() {
 11399  		ctrl := gomock.NewController(t)
 11400  		defer ctrl.Finish()
 11401  
 11402  		ses := newTestSession(t, ctrl)
 11403  		defer ses.Close()
 11404  
 11405  		bh := &backgroundExecTest{}
 11406  		bh.init()
 11407  
 11408  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11409  		defer bhStub.Reset()
 11410  
 11411  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11412  		pu.SV.SetDefaultValues()
 11413  		setGlobalPu(pu)
 11414  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11415  		rm, _ := NewRoutineManager(ctx)
 11416  		ses.rm = rm
 11417  
 11418  		tenant := &TenantInfo{
 11419  			Tenant:        sysAccountName,
 11420  			User:          rootName,
 11421  			DefaultRole:   moAdminRoleName,
 11422  			TenantID:      sysAccountID,
 11423  			UserID:        rootID,
 11424  			DefaultRoleID: moAdminRoleID,
 11425  		}
 11426  		ses.SetTenantInfo(tenant)
 11427  		txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
 11428  		txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
 11429  		timeStamp, _ := timestamp.ParseTimestamp("2021-01-01 00:00:00")
 11430  		txnOperator.EXPECT().SnapshotTS().Return(timeStamp).AnyTimes()
 11431  		// process.
 11432  		ses.proc = testutil.NewProc()
 11433  		ses.proc.TxnOperator = txnOperator
 11434  		cs := &tree.CreateSnapShot{
 11435  			IfNotExists: false,
 11436  			Name:        tree.Identifier("snapshot_test"),
 11437  			Object: tree.ObjectInfo{
 11438  				SLevel: tree.SnapshotLevelType{
 11439  					Level: tree.SNAPSHOTLEVELCLUSTER,
 11440  				},
 11441  				ObjName: "",
 11442  			},
 11443  		}
 11444  
 11445  		//no result set
 11446  		bh.sql2result["begin;"] = nil
 11447  		bh.sql2result["commit;"] = nil
 11448  		bh.sql2result["rollback;"] = nil
 11449  
 11450  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11451  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 11452  		bh.sql2result[sql] = mrs
 11453  
 11454  		err := doCreateSnapshot(ctx, ses, cs)
 11455  		convey.So(err, convey.ShouldBeNil)
 11456  	})
 11457  
 11458  	// non-system tenant can't create cluster level snapshot
 11459  	convey.Convey("doCreateSnapshot fail", t, func() {
 11460  		ctrl := gomock.NewController(t)
 11461  		defer ctrl.Finish()
 11462  
 11463  		ses := newTestSession(t, ctrl)
 11464  		defer ses.Close()
 11465  
 11466  		bh := &backgroundExecTest{}
 11467  		bh.init()
 11468  
 11469  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11470  		defer bhStub.Reset()
 11471  
 11472  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11473  		pu.SV.SetDefaultValues()
 11474  		setGlobalPu(pu)
 11475  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11476  		rm, _ := NewRoutineManager(ctx)
 11477  		ses.rm = rm
 11478  
 11479  		tenant := &TenantInfo{
 11480  			Tenant:        "test_account",
 11481  			User:          rootName,
 11482  			DefaultRole:   moAdminRoleName,
 11483  			TenantID:      sysAccountID,
 11484  			UserID:        rootID,
 11485  			DefaultRoleID: moAdminRoleID,
 11486  		}
 11487  		ses.SetTenantInfo(tenant)
 11488  		txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
 11489  		txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
 11490  		timeStamp, _ := timestamp.ParseTimestamp("2021-01-01 00:00:00")
 11491  		txnOperator.EXPECT().SnapshotTS().Return(timeStamp).AnyTimes()
 11492  		// process.
 11493  		ses.proc = testutil.NewProc()
 11494  		ses.proc.TxnOperator = txnOperator
 11495  		cs := &tree.CreateSnapShot{
 11496  			IfNotExists: false,
 11497  			Name:        tree.Identifier("snapshot_test"),
 11498  			Object: tree.ObjectInfo{
 11499  				SLevel: tree.SnapshotLevelType{
 11500  					Level: tree.SNAPSHOTLEVELCLUSTER,
 11501  				},
 11502  				ObjName: "",
 11503  			},
 11504  		}
 11505  
 11506  		//no result set
 11507  		bh.sql2result["begin;"] = nil
 11508  		bh.sql2result["commit;"] = nil
 11509  		bh.sql2result["rollback;"] = nil
 11510  
 11511  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11512  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 11513  		bh.sql2result[sql] = mrs
 11514  
 11515  		err := doCreateSnapshot(ctx, ses, cs)
 11516  		convey.So(err, convey.ShouldNotBeNil)
 11517  	})
 11518  
 11519  	// system tenant create account level snapshot for other tenant
 11520  	convey.Convey("doCreateSnapshot success", t, func() {
 11521  		ctrl := gomock.NewController(t)
 11522  		defer ctrl.Finish()
 11523  
 11524  		ses := newTestSession(t, ctrl)
 11525  		defer ses.Close()
 11526  
 11527  		bh := &backgroundExecTest{}
 11528  		bh.init()
 11529  
 11530  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11531  		defer bhStub.Reset()
 11532  
 11533  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11534  		pu.SV.SetDefaultValues()
 11535  		setGlobalPu(pu)
 11536  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11537  		rm, _ := NewRoutineManager(ctx)
 11538  		ses.rm = rm
 11539  
 11540  		tenant := &TenantInfo{
 11541  			Tenant:        sysAccountName,
 11542  			User:          rootName,
 11543  			DefaultRole:   moAdminRoleName,
 11544  			TenantID:      sysAccountID,
 11545  			UserID:        rootID,
 11546  			DefaultRoleID: moAdminRoleID,
 11547  		}
 11548  		ses.SetTenantInfo(tenant)
 11549  		txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
 11550  		txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
 11551  		timeStamp, _ := timestamp.ParseTimestamp("2021-01-01 00:00:00")
 11552  		txnOperator.EXPECT().SnapshotTS().Return(timeStamp).AnyTimes()
 11553  		// process.
 11554  		ses.proc = testutil.NewProc()
 11555  		ses.proc.TxnOperator = txnOperator
 11556  		cs := &tree.CreateSnapShot{
 11557  			IfNotExists: false,
 11558  			Name:        tree.Identifier("snapshot_test"),
 11559  			Object: tree.ObjectInfo{
 11560  				SLevel: tree.SnapshotLevelType{
 11561  					Level: tree.SNAPSHOTLEVELACCOUNT,
 11562  				},
 11563  				ObjName: "acc1",
 11564  			},
 11565  		}
 11566  
 11567  		//no result set
 11568  		bh.sql2result["begin;"] = nil
 11569  		bh.sql2result["commit;"] = nil
 11570  		bh.sql2result["rollback;"] = nil
 11571  
 11572  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11573  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 11574  		bh.sql2result[sql] = mrs
 11575  
 11576  		sql2, _ := getSqlForCheckTenant(ctx, "acc1")
 11577  		mrs2 := newMrsForPasswordOfUser([][]interface{}{{1}})
 11578  		bh.sql2result[sql2] = mrs2
 11579  
 11580  		err := doCreateSnapshot(ctx, ses, cs)
 11581  		convey.So(err, convey.ShouldBeNil)
 11582  	})
 11583  
 11584  	// non-system tenant can't create acccount level snapshot for other tenant
 11585  	convey.Convey("doCreateSnapshot fail", t, func() {
 11586  		ctrl := gomock.NewController(t)
 11587  		defer ctrl.Finish()
 11588  
 11589  		ses := newTestSession(t, ctrl)
 11590  		defer ses.Close()
 11591  
 11592  		bh := &backgroundExecTest{}
 11593  		bh.init()
 11594  
 11595  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11596  		defer bhStub.Reset()
 11597  
 11598  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11599  		pu.SV.SetDefaultValues()
 11600  		setGlobalPu(pu)
 11601  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11602  		rm, _ := NewRoutineManager(ctx)
 11603  		ses.rm = rm
 11604  
 11605  		tenant := &TenantInfo{
 11606  			Tenant:        "test_account",
 11607  			User:          rootName,
 11608  			DefaultRole:   moAdminRoleName,
 11609  			TenantID:      sysAccountID,
 11610  			UserID:        rootID,
 11611  			DefaultRoleID: moAdminRoleID,
 11612  		}
 11613  		ses.SetTenantInfo(tenant)
 11614  		txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
 11615  		txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
 11616  		timeStamp, _ := timestamp.ParseTimestamp("2021-01-01 00:00:00")
 11617  		txnOperator.EXPECT().SnapshotTS().Return(timeStamp).AnyTimes()
 11618  		// process.
 11619  		ses.proc = testutil.NewProc()
 11620  		ses.proc.TxnOperator = txnOperator
 11621  		cs := &tree.CreateSnapShot{
 11622  			IfNotExists: false,
 11623  			Name:        tree.Identifier("snapshot_test"),
 11624  			Object: tree.ObjectInfo{
 11625  				SLevel: tree.SnapshotLevelType{
 11626  					Level: tree.SNAPSHOTLEVELACCOUNT,
 11627  				},
 11628  				ObjName: "acc1",
 11629  			},
 11630  		}
 11631  
 11632  		//no result set
 11633  		bh.sql2result["begin;"] = nil
 11634  		bh.sql2result["commit;"] = nil
 11635  		bh.sql2result["rollback;"] = nil
 11636  
 11637  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11638  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 11639  		bh.sql2result[sql] = mrs
 11640  
 11641  		sql2, _ := getSqlForCheckTenant(ctx, "acc1")
 11642  		mrs2 := newMrsForPasswordOfUser([][]interface{}{{1}})
 11643  		bh.sql2result[sql2] = mrs2
 11644  
 11645  		err := doCreateSnapshot(ctx, ses, cs)
 11646  		convey.So(err, convey.ShouldNotBeNil)
 11647  	})
 11648  
 11649  	// no-admin user can't create acccount level snapshot for himself tenant
 11650  	convey.Convey("doCreateSnapshot fail", t, func() {
 11651  		ctrl := gomock.NewController(t)
 11652  		defer ctrl.Finish()
 11653  
 11654  		ses := newTestSession(t, ctrl)
 11655  		defer ses.Close()
 11656  
 11657  		bh := &backgroundExecTest{}
 11658  		bh.init()
 11659  
 11660  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11661  		defer bhStub.Reset()
 11662  
 11663  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11664  		pu.SV.SetDefaultValues()
 11665  		setGlobalPu(pu)
 11666  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11667  		rm, _ := NewRoutineManager(ctx)
 11668  		ses.rm = rm
 11669  
 11670  		tenant := &TenantInfo{
 11671  			Tenant:        "test_account",
 11672  			User:          rootName,
 11673  			DefaultRole:   "test_role",
 11674  			TenantID:      sysAccountID,
 11675  			UserID:        rootID,
 11676  			DefaultRoleID: moAdminRoleID,
 11677  		}
 11678  		ses.SetTenantInfo(tenant)
 11679  		txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
 11680  		txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
 11681  		timeStamp, _ := timestamp.ParseTimestamp("2021-01-01 00:00:00")
 11682  		txnOperator.EXPECT().SnapshotTS().Return(timeStamp).AnyTimes()
 11683  		// process.
 11684  		ses.proc = testutil.NewProc()
 11685  		ses.proc.TxnOperator = txnOperator
 11686  		cs := &tree.CreateSnapShot{
 11687  			IfNotExists: false,
 11688  			Name:        tree.Identifier("snapshot_test"),
 11689  			Object: tree.ObjectInfo{
 11690  				SLevel: tree.SnapshotLevelType{
 11691  					Level: tree.SNAPSHOTLEVELACCOUNT,
 11692  				},
 11693  				ObjName: "test_account",
 11694  			},
 11695  		}
 11696  
 11697  		//no result set
 11698  		bh.sql2result["begin;"] = nil
 11699  		bh.sql2result["commit;"] = nil
 11700  		bh.sql2result["rollback;"] = nil
 11701  
 11702  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11703  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 11704  		bh.sql2result[sql] = mrs
 11705  
 11706  		sql2, _ := getSqlForCheckTenant(ctx, "acc1")
 11707  		mrs2 := newMrsForPasswordOfUser([][]interface{}{{1}})
 11708  		bh.sql2result[sql2] = mrs2
 11709  
 11710  		err := doCreateSnapshot(ctx, ses, cs)
 11711  		convey.So(err, convey.ShouldNotBeNil)
 11712  	})
 11713  
 11714  	// system tenant  create account level snapshot for other tenant
 11715  	// but the snapshot name already exists
 11716  	convey.Convey("doCreateSnapshot fail", t, func() {
 11717  		ctrl := gomock.NewController(t)
 11718  		defer ctrl.Finish()
 11719  
 11720  		ses := newTestSession(t, ctrl)
 11721  		defer ses.Close()
 11722  
 11723  		bh := &backgroundExecTest{}
 11724  		bh.init()
 11725  
 11726  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11727  		defer bhStub.Reset()
 11728  
 11729  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11730  		pu.SV.SetDefaultValues()
 11731  		setGlobalPu(pu)
 11732  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11733  		rm, _ := NewRoutineManager(ctx)
 11734  		ses.rm = rm
 11735  
 11736  		tenant := &TenantInfo{
 11737  			Tenant:        sysAccountName,
 11738  			User:          rootName,
 11739  			DefaultRole:   moAdminRoleName,
 11740  			TenantID:      sysAccountID,
 11741  			UserID:        rootID,
 11742  			DefaultRoleID: moAdminRoleID,
 11743  		}
 11744  		ses.SetTenantInfo(tenant)
 11745  		txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
 11746  		txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
 11747  		timeStamp, _ := timestamp.ParseTimestamp("2021-01-01 00:00:00")
 11748  		txnOperator.EXPECT().SnapshotTS().Return(timeStamp).AnyTimes()
 11749  		// process.
 11750  		ses.proc = testutil.NewProc()
 11751  		ses.proc.TxnOperator = txnOperator
 11752  		cs := &tree.CreateSnapShot{
 11753  			IfNotExists: false,
 11754  			Name:        tree.Identifier("snapshot_test"),
 11755  			Object: tree.ObjectInfo{
 11756  				SLevel: tree.SnapshotLevelType{
 11757  					Level: tree.SNAPSHOTLEVELACCOUNT,
 11758  				},
 11759  				ObjName: "acc1",
 11760  			},
 11761  		}
 11762  
 11763  		//no result set
 11764  		bh.sql2result["begin;"] = nil
 11765  		bh.sql2result["commit;"] = nil
 11766  		bh.sql2result["rollback;"] = nil
 11767  
 11768  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11769  		mrs := newMrsForPasswordOfUser([][]interface{}{{1}})
 11770  		bh.sql2result[sql] = mrs
 11771  
 11772  		sql2, _ := getSqlForCheckTenant(ctx, "acc1")
 11773  		mrs2 := newMrsForPasswordOfUser([][]interface{}{{1}})
 11774  		bh.sql2result[sql2] = mrs2
 11775  
 11776  		err := doCreateSnapshot(ctx, ses, cs)
 11777  		convey.So(err, convey.ShouldNotBeNil)
 11778  	})
 11779  
 11780  	// system tenant  create account level snapshot for other tenant
 11781  	// but the account not exists
 11782  	convey.Convey("doCreateSnapshot fail", t, func() {
 11783  		ctrl := gomock.NewController(t)
 11784  		defer ctrl.Finish()
 11785  
 11786  		ses := newTestSession(t, ctrl)
 11787  		defer ses.Close()
 11788  
 11789  		bh := &backgroundExecTest{}
 11790  		bh.init()
 11791  
 11792  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11793  		defer bhStub.Reset()
 11794  
 11795  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11796  		pu.SV.SetDefaultValues()
 11797  		setGlobalPu(pu)
 11798  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11799  		rm, _ := NewRoutineManager(ctx)
 11800  		ses.rm = rm
 11801  
 11802  		tenant := &TenantInfo{
 11803  			Tenant:        sysAccountName,
 11804  			User:          rootName,
 11805  			DefaultRole:   moAdminRoleName,
 11806  			TenantID:      sysAccountID,
 11807  			UserID:        rootID,
 11808  			DefaultRoleID: moAdminRoleID,
 11809  		}
 11810  		ses.SetTenantInfo(tenant)
 11811  		txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
 11812  		txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
 11813  		timeStamp, _ := timestamp.ParseTimestamp("2021-01-01 00:00:00")
 11814  		txnOperator.EXPECT().SnapshotTS().Return(timeStamp).AnyTimes()
 11815  		// process.
 11816  		ses.proc = testutil.NewProc()
 11817  		ses.proc.TxnOperator = txnOperator
 11818  		cs := &tree.CreateSnapShot{
 11819  			IfNotExists: false,
 11820  			Name:        tree.Identifier("snapshot_test"),
 11821  			Object: tree.ObjectInfo{
 11822  				SLevel: tree.SnapshotLevelType{
 11823  					Level: tree.SNAPSHOTLEVELACCOUNT,
 11824  				},
 11825  				ObjName: "acc1",
 11826  			},
 11827  		}
 11828  
 11829  		//no result set
 11830  		bh.sql2result["begin;"] = nil
 11831  		bh.sql2result["commit;"] = nil
 11832  		bh.sql2result["rollback;"] = nil
 11833  
 11834  		sql, _ := getSqlForCheckSnapshot(ctx, "snapshot_test")
 11835  		mrs := newMrsForPasswordOfUser([][]interface{}{{}})
 11836  		bh.sql2result[sql] = mrs
 11837  
 11838  		sql2, _ := getSqlForCheckTenant(ctx, "acc1")
 11839  		mrs2 := newMrsForPasswordOfUser([][]interface{}{{1}})
 11840  		bh.sql2result[sql2] = mrs2
 11841  
 11842  		err := doCreateSnapshot(ctx, ses, cs)
 11843  		convey.So(err, convey.ShouldNotBeNil)
 11844  	})
 11845  }
 11846  
 11847  func TestDoResolveSnapshotTsWithSnapShotName(t *testing.T) {
 11848  	convey.Convey("doResolveSnapshotWithSnapshotName success", t, func() {
 11849  		ctrl := gomock.NewController(t)
 11850  		defer ctrl.Finish()
 11851  
 11852  		ses := newTestSession(t, ctrl)
 11853  		defer ses.Close()
 11854  
 11855  		bh := &backgroundExecTest{}
 11856  		bh.init()
 11857  
 11858  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11859  		defer bhStub.Reset()
 11860  
 11861  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11862  		pu.SV.SetDefaultValues()
 11863  		setGlobalPu(pu)
 11864  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11865  		rm, _ := NewRoutineManager(ctx)
 11866  		ses.rm = rm
 11867  
 11868  		tenant := &TenantInfo{
 11869  			Tenant:        sysAccountName,
 11870  			User:          rootName,
 11871  			DefaultRole:   moAdminRoleName,
 11872  			TenantID:      sysAccountID,
 11873  			UserID:        rootID,
 11874  			DefaultRoleID: moAdminRoleID,
 11875  		}
 11876  		ses.SetTenantInfo(tenant)
 11877  
 11878  		//no result set
 11879  		bh.sql2result["begin;"] = nil
 11880  		bh.sql2result["commit;"] = nil
 11881  		bh.sql2result["rollback;"] = nil
 11882  
 11883  		sql, _ := getSqlForGetSnapshotTsWithSnapshotName(ctx, "test_sp")
 11884  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 11885  		bh.sql2result[sql] = mrs
 11886  
 11887  		_, err := doResolveSnapshotWithSnapshotName(ctx, ses, "test_sp")
 11888  		convey.So(err, convey.ShouldNotBeNil)
 11889  	})
 11890  }
 11891  
 11892  func TestCheckTimeStampValid(t *testing.T) {
 11893  	convey.Convey("checkTimeStampValid success", t, func() {
 11894  		ctrl := gomock.NewController(t)
 11895  		defer ctrl.Finish()
 11896  
 11897  		ses := newTestSession(t, ctrl)
 11898  		defer ses.Close()
 11899  
 11900  		bh := &backgroundExecTest{}
 11901  		bh.init()
 11902  
 11903  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11904  		defer bhStub.Reset()
 11905  
 11906  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11907  		pu.SV.SetDefaultValues()
 11908  		setGlobalPu(pu)
 11909  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11910  		rm, _ := NewRoutineManager(ctx)
 11911  		ses.rm = rm
 11912  
 11913  		tenant := &TenantInfo{
 11914  			Tenant:        sysAccountName,
 11915  			User:          rootName,
 11916  			DefaultRole:   moAdminRoleName,
 11917  			TenantID:      sysAccountID,
 11918  			UserID:        rootID,
 11919  			DefaultRoleID: moAdminRoleID,
 11920  		}
 11921  		ses.SetTenantInfo(tenant)
 11922  
 11923  		//no result set
 11924  		bh.sql2result["begin;"] = nil
 11925  		bh.sql2result["commit;"] = nil
 11926  		bh.sql2result["rollback;"] = nil
 11927  
 11928  		sql := getSqlForCheckSnapshotTs(1713235646865937000)
 11929  		mrs := newMrsForPasswordOfUser([][]interface{}{})
 11930  		bh.sql2result[sql] = mrs
 11931  
 11932  		valid, err := checkTimeStampValid(ctx, ses, 1713235646865937000)
 11933  		convey.So(err, convey.ShouldBeNil)
 11934  		convey.So(valid, convey.ShouldBeFalse)
 11935  	})
 11936  
 11937  	convey.Convey("checkTimeStampValid success", t, func() {
 11938  		ctrl := gomock.NewController(t)
 11939  		defer ctrl.Finish()
 11940  
 11941  		ses := newTestSession(t, ctrl)
 11942  		defer ses.Close()
 11943  
 11944  		bh := &backgroundExecTest{}
 11945  		bh.init()
 11946  
 11947  		bhStub := gostub.StubFunc(&NewBackgroundExec, bh)
 11948  		defer bhStub.Reset()
 11949  
 11950  		pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
 11951  		pu.SV.SetDefaultValues()
 11952  		setGlobalPu(pu)
 11953  		ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
 11954  		rm, _ := NewRoutineManager(ctx)
 11955  		ses.rm = rm
 11956  
 11957  		tenant := &TenantInfo{
 11958  			Tenant:        sysAccountName,
 11959  			User:          rootName,
 11960  			DefaultRole:   moAdminRoleName,
 11961  			TenantID:      sysAccountID,
 11962  			UserID:        rootID,
 11963  			DefaultRoleID: moAdminRoleID,
 11964  		}
 11965  		ses.SetTenantInfo(tenant)
 11966  
 11967  		//no result set
 11968  		bh.sql2result["begin;"] = nil
 11969  		bh.sql2result["commit;"] = nil
 11970  		bh.sql2result["rollback;"] = nil
 11971  
 11972  		sql := getSqlForCheckSnapshotTs(1713235646865937000)
 11973  		mrs := newMrsForPasswordOfUser([][]interface{}{{"018ee4cd-5991-7caa-b75d-f9290144bd9f"}})
 11974  		bh.sql2result[sql] = mrs
 11975  
 11976  		valid, err := checkTimeStampValid(ctx, ses, 1713235646865937000)
 11977  		convey.So(err, convey.ShouldBeNil)
 11978  		convey.So(valid, convey.ShouldBeTrue)
 11979  	})
 11980  }