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  }