github.com/matrixorigin/matrixone@v1.2.0/pkg/frontend/show_subscriptions_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 "context" 19 "go/constant" 20 "strings" 21 "testing" 22 "time" 23 24 "github.com/golang/mock/gomock" 25 "github.com/prashantv/gostub" 26 "github.com/stretchr/testify/require" 27 28 "github.com/matrixorigin/matrixone/pkg/common/mpool" 29 "github.com/matrixorigin/matrixone/pkg/container/batch" 30 "github.com/matrixorigin/matrixone/pkg/container/types" 31 "github.com/matrixorigin/matrixone/pkg/container/vector" 32 "github.com/matrixorigin/matrixone/pkg/defines" 33 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 34 ) 35 36 type mockedBackgroundHandler struct { 37 currentSql string 38 accountIdNamesBatches []*batch.Batch 39 pubBatches map[int32][]*batch.Batch 40 subBatches []*batch.Batch 41 accountId int32 42 } 43 44 func (m *mockedBackgroundHandler) Close() {} 45 46 func (m *mockedBackgroundHandler) Exec(ctx context.Context, s string) error { 47 m.currentSql = s 48 m.accountId = int32(ctx.Value(defines.TenantIDKey{}).(uint32)) 49 return nil 50 } 51 52 func (m *mockedBackgroundHandler) ExecStmt(ctx context.Context, statement tree.Statement) error { 53 return nil 54 } 55 56 func (m *mockedBackgroundHandler) ExecRestore(context.Context, string, uint32, uint32) error { 57 panic("unimplement") 58 } 59 60 func (m *mockedBackgroundHandler) GetExecResultSet() []interface{} { 61 return nil 62 } 63 64 func (m *mockedBackgroundHandler) ClearExecResultSet() {} 65 66 func (m *mockedBackgroundHandler) GetExecResultBatches() []*batch.Batch { 67 if m.currentSql == getAccountIdNamesSql { 68 return m.accountIdNamesBatches 69 } else if strings.HasPrefix(m.currentSql, getPubsSql) { 70 return m.pubBatches[m.accountId] 71 } else { 72 return m.subBatches 73 } 74 } 75 76 func (m *mockedBackgroundHandler) ClearExecResultBatches() {} 77 78 func (m *mockedBackgroundHandler) init(mp *mpool.MPool) { 79 m.pubBatches = make(map[int32][]*batch.Batch) 80 81 var b *batch.Batch 82 v1 := vector.NewVec(types.T_int32.ToType()) 83 _ = vector.AppendFixedList(v1, []int32{0, 1}, nil, mp) 84 v2 := vector.NewVec(types.T_varchar.ToType()) 85 _ = vector.AppendStringList(v2, []string{"sys", "account1"}, nil, mp) 86 b = &batch.Batch{Vecs: []*vector.Vector{v1, v2}} 87 b.SetRowCount(2) 88 m.accountIdNamesBatches = []*batch.Batch{b} 89 90 v3 := vector.NewVec(types.T_varchar.ToType()) 91 _ = vector.AppendStringList(v3, []string{"pub1", "pub2"}, nil, mp) 92 v4 := vector.NewVec(types.T_varchar.ToType()) 93 _ = vector.AppendStringList(v4, []string{"db1", "db2"}, nil, mp) 94 v12 := vector.NewVec(types.T_varchar.ToType()) 95 _ = vector.AppendStringList(v12, []string{"all", "all"}, nil, mp) 96 v5 := vector.NewVec(types.T_timestamp.ToType()) 97 _ = vector.AppendFixedList(v5, []types.Timestamp{1234567, 2234567}, nil, mp) 98 b = &batch.Batch{Vecs: []*vector.Vector{v3, v4, v12, v5}} 99 b.SetRowCount(2) 100 m.pubBatches[0] = []*batch.Batch{b} 101 102 v6 := vector.NewVec(types.T_varchar.ToType()) 103 _ = vector.AppendStringList(v6, []string{"pub3", "pub4"}, nil, mp) 104 v7 := vector.NewVec(types.T_varchar.ToType()) 105 _ = vector.AppendStringList(v7, []string{"db3", "db4"}, nil, mp) 106 v13 := vector.NewVec(types.T_varchar.ToType()) 107 _ = vector.AppendStringList(v13, []string{"account2", "all"}, nil, mp) 108 v8 := vector.NewVec(types.T_timestamp.ToType()) 109 _ = vector.AppendFixedList(v8, []types.Timestamp{3234567, 4234567}, nil, mp) 110 b = &batch.Batch{Vecs: []*vector.Vector{v6, v7, v13, v8}} 111 b.SetRowCount(2) 112 m.pubBatches[1] = []*batch.Batch{b} 113 114 v9 := vector.NewVec(types.T_varchar.ToType()) 115 _ = vector.AppendStringList(v9, []string{"sub1", "sub4"}, nil, mp) 116 v10 := vector.NewVec(types.T_varchar.ToType()) 117 _ = vector.AppendStringList(v10, []string{ 118 "create database sub1 from sys publication pub1", 119 "create database sub4 from account1 publication pub4", 120 }, nil, mp) 121 v11 := vector.NewVec(types.T_timestamp.ToType()) 122 _ = vector.AppendFixedList(v11, []types.Timestamp{1234568, 4234568}, nil, mp) 123 b = &batch.Batch{Vecs: []*vector.Vector{v9, v10, v11}} 124 b.SetRowCount(2) 125 m.subBatches = []*batch.Batch{b} 126 } 127 128 func (m *mockedBackgroundHandler) initLike(mp *mpool.MPool) { 129 m.pubBatches = make(map[int32][]*batch.Batch) 130 131 var b *batch.Batch 132 v1 := vector.NewVec(types.T_int32.ToType()) 133 _ = vector.AppendFixedList(v1, []int32{0, 1}, nil, mp) 134 v2 := vector.NewVec(types.T_varchar.ToType()) 135 _ = vector.AppendStringList(v2, []string{"sys", "account1"}, nil, mp) 136 b = &batch.Batch{Vecs: []*vector.Vector{v1, v2}} 137 b.SetRowCount(2) 138 m.accountIdNamesBatches = []*batch.Batch{b} 139 140 v3 := vector.NewVec(types.T_varchar.ToType()) 141 _ = vector.AppendStringList(v3, []string{"pub1"}, nil, mp) 142 v4 := vector.NewVec(types.T_varchar.ToType()) 143 _ = vector.AppendStringList(v4, []string{"db1"}, nil, mp) 144 v12 := vector.NewVec(types.T_varchar.ToType()) 145 _ = vector.AppendStringList(v12, []string{"all"}, nil, mp) 146 v5 := vector.NewVec(types.T_timestamp.ToType()) 147 _ = vector.AppendFixedList(v5, []types.Timestamp{1234567}, nil, mp) 148 b = &batch.Batch{Vecs: []*vector.Vector{v3, v4, v12, v5}} 149 b.SetRowCount(1) 150 m.pubBatches[0] = []*batch.Batch{b} 151 152 v6 := vector.NewVec(types.T_varchar.ToType()) 153 _ = vector.AppendStringList(v6, []string{}, nil, mp) 154 v7 := vector.NewVec(types.T_varchar.ToType()) 155 _ = vector.AppendStringList(v7, []string{}, nil, mp) 156 v13 := vector.NewVec(types.T_varchar.ToType()) 157 _ = vector.AppendStringList(v13, []string{}, nil, mp) 158 v8 := vector.NewVec(types.T_timestamp.ToType()) 159 _ = vector.AppendFixedList(v8, []types.Timestamp{}, nil, mp) 160 b = &batch.Batch{Vecs: []*vector.Vector{v6, v7, v13, v8}} 161 b.SetRowCount(0) 162 m.pubBatches[1] = []*batch.Batch{b} 163 164 v9 := vector.NewVec(types.T_varchar.ToType()) 165 _ = vector.AppendStringList(v9, []string{"sub1", "sub4"}, nil, mp) 166 v10 := vector.NewVec(types.T_varchar.ToType()) 167 _ = vector.AppendStringList(v10, []string{ 168 "create database sub1 from sys publication pub1", 169 "create database sub4 from account1 publication pub4", 170 }, nil, mp) 171 v11 := vector.NewVec(types.T_timestamp.ToType()) 172 _ = vector.AppendFixedList(v11, []types.Timestamp{1234568, 4234568}, nil, mp) 173 b = &batch.Batch{Vecs: []*vector.Vector{v9, v10, v11}} 174 b.SetRowCount(2) 175 m.subBatches = []*batch.Batch{b} 176 } 177 178 func (m *mockedBackgroundHandler) Clear() {} 179 180 var _ BackgroundExec = &mockedBackgroundHandler{} 181 182 var bh = &mockedBackgroundHandler{} 183 184 var tenant = &TenantInfo{ 185 Tenant: sysAccountName, 186 User: rootName, 187 DefaultRole: moAdminRoleName, 188 TenantID: sysAccountID, 189 UserID: rootID, 190 DefaultRoleID: moAdminRoleID, 191 } 192 193 func TestDoShowSubscriptions(t *testing.T) { 194 ctrl := gomock.NewController(t) 195 defer ctrl.Finish() 196 197 ctx := context.Background() 198 ctx = context.WithValue(ctx, defines.TenantIDKey{}, uint32(sysAccountID)) 199 200 ses := newTestSession(t, ctrl) 201 ses.SetTimeZone(time.UTC) 202 ses.SetTenantInfo(tenant) 203 ses.SetMysqlResultSet(&MysqlResultSet{}) 204 defer ses.Close() 205 206 mp := ses.GetMemPool() 207 bh.init(mp) 208 sa := &tree.ShowSubscriptions{} 209 210 bhStub := gostub.StubFunc(&GetRawBatchBackgroundExec, bh) 211 defer bhStub.Reset() 212 213 err := doShowSubscriptions(ctx, ses, sa) 214 require.NoError(t, err) 215 216 rs := ses.GetMysqlResultSet() 217 require.Equal(t, uint64(len(showSubscriptionOutputColumns)), rs.GetColumnCount()) 218 require.Equal(t, uint64(2), rs.GetRowCount()) 219 220 var actual, expected []interface{} 221 // sort by sub_time, pub_time desc 222 expected = []interface{}{"pub4", "account1", "db4", "0001-01-01 00:00:04", "sub4", "0001-01-01 00:00:04"} 223 actual, err = rs.GetRow(ctx, uint64(0)) 224 require.NoError(t, err) 225 require.Equal(t, expected, actual) 226 227 expected = []interface{}{"pub1", "sys", "db1", "0001-01-01 00:00:01", "sub1", "0001-01-01 00:00:01"} 228 actual, err = rs.GetRow(ctx, uint64(1)) 229 require.NoError(t, err) 230 require.Equal(t, expected, actual) 231 } 232 233 func TestDoShowSubscriptionsAll(t *testing.T) { 234 ctrl := gomock.NewController(t) 235 defer ctrl.Finish() 236 237 ctx := context.Background() 238 ctx = context.WithValue(ctx, defines.TenantIDKey{}, uint32(sysAccountID)) 239 240 ses := newTestSession(t, ctrl) 241 ses.SetTimeZone(time.UTC) 242 ses.SetTenantInfo(tenant) 243 ses.SetMysqlResultSet(&MysqlResultSet{}) 244 defer ses.Close() 245 246 mp := ses.GetMemPool() 247 bh.init(mp) 248 sa := &tree.ShowSubscriptions{All: true} 249 250 bhStub := gostub.StubFunc(&GetRawBatchBackgroundExec, bh) 251 defer bhStub.Reset() 252 253 err := doShowSubscriptions(ctx, ses, sa) 254 require.NoError(t, err) 255 256 rs := ses.GetMysqlResultSet() 257 require.Equal(t, uint64(len(showSubscriptionOutputColumns)), rs.GetColumnCount()) 258 require.Equal(t, uint64(3), rs.GetRowCount()) 259 260 var actual, expected []interface{} 261 // sort by sub_time, pub_time desc 262 expected = []interface{}{"pub4", "account1", "db4", "0001-01-01 00:00:04", "sub4", "0001-01-01 00:00:04"} 263 actual, err = rs.GetRow(ctx, uint64(0)) 264 require.NoError(t, err) 265 require.Equal(t, expected, actual) 266 267 expected = []interface{}{"pub1", "sys", "db1", "0001-01-01 00:00:01", "sub1", "0001-01-01 00:00:01"} 268 actual, err = rs.GetRow(ctx, uint64(1)) 269 require.NoError(t, err) 270 require.Equal(t, expected, actual) 271 272 expected = []interface{}{"pub2", "sys", "db2", "0001-01-01 00:00:02", nil, nil} 273 actual, err = rs.GetRow(ctx, uint64(2)) 274 require.NoError(t, err) 275 require.Equal(t, expected, actual) 276 } 277 278 func TestDoShowSubscriptionsAllLike(t *testing.T) { 279 ctrl := gomock.NewController(t) 280 defer ctrl.Finish() 281 282 ctx := context.Background() 283 ctx = context.WithValue(ctx, defines.TenantIDKey{}, uint32(sysAccountID)) 284 285 ses := newTestSession(t, ctrl) 286 ses.SetTimeZone(time.UTC) 287 ses.SetTenantInfo(tenant) 288 ses.SetMysqlResultSet(&MysqlResultSet{}) 289 defer ses.Close() 290 291 mp := ses.GetMemPool() 292 bh.initLike(mp) 293 sa := &tree.ShowSubscriptions{ 294 All: true, 295 Like: &tree.ComparisonExpr{ 296 Op: tree.LIKE, 297 Right: &tree.NumVal{Value: constant.MakeString("%1")}, 298 }, 299 } 300 301 bhStub := gostub.StubFunc(&GetRawBatchBackgroundExec, bh) 302 defer bhStub.Reset() 303 304 err := doShowSubscriptions(ctx, ses, sa) 305 require.NoError(t, err) 306 307 rs := ses.GetMysqlResultSet() 308 require.Equal(t, uint64(len(showSubscriptionOutputColumns)), rs.GetColumnCount()) 309 require.Equal(t, uint64(1), rs.GetRowCount()) 310 311 var actual, expected []interface{} 312 expected = []interface{}{"pub1", "sys", "db1", "0001-01-01 00:00:01", "sub1", "0001-01-01 00:00:01"} 313 actual, err = rs.GetRow(ctx, uint64(0)) 314 require.NoError(t, err) 315 require.Equal(t, expected, actual) 316 }