github.com/matrixorigin/matrixone@v1.2.0/pkg/frontend/internal_executor_test.go (about) 1 // Copyright 2022 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 "testing" 21 22 "github.com/stretchr/testify/assert" 23 "github.com/stretchr/testify/require" 24 25 "github.com/matrixorigin/matrixone/pkg/common/moerr" 26 "github.com/matrixorigin/matrixone/pkg/common/runtime" 27 "github.com/matrixorigin/matrixone/pkg/config" 28 "github.com/matrixorigin/matrixone/pkg/defines" 29 ie "github.com/matrixorigin/matrixone/pkg/util/internalExecutor" 30 ) 31 32 func mockResultSet() *MysqlResultSet { 33 set := &MysqlResultSet{} 34 col := &MysqlColumn{} 35 col.SetName("test") 36 col.SetColumnType(defines.MYSQL_TYPE_LONG) 37 col.SetSigned(true) 38 set.AddColumn(col) 39 set.AddRow([]any{42}) 40 return set 41 } 42 43 func TestIe(t *testing.T) { 44 runtime.SetupProcessLevelRuntime(runtime.DefaultRuntime()) 45 46 ctx := context.TODO() 47 pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) 48 setGlobalPu(pu) 49 executor := newIe() 50 executor.ApplySessionOverride(ie.NewOptsBuilder().Username("dump").Finish()) 51 sess := executor.newCmdSession(ctx, ie.NewOptsBuilder().Database("mo_catalog").Internal(true).Finish()) 52 assert.Equal(t, "dump", sess.GetMysqlProtocol().GetUserName()) 53 54 err := executor.Exec(ctx, "whatever", ie.NewOptsBuilder().Finish()) 55 assert.Error(t, err) 56 res := executor.Query(ctx, "whatever", ie.NewOptsBuilder().Finish()) 57 assert.Error(t, err) 58 assert.Equal(t, uint64(0), res.RowCount()) 59 } 60 61 func TestIeProto(t *testing.T) { 62 setGlobalPu(config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)) 63 // Mock autoIncrCaches 64 setGlobalAicm(&defines.AutoIncrCacheManager{}) 65 66 executor := NewInternalExecutor() 67 p := executor.proto 68 assert.True(t, p.IsEstablished()) 69 p.SetEstablished() 70 p.Quit() 71 p.ResetStatistics() 72 _ = p.GetStats() 73 _ = p.ConnectionID() 74 ctx := context.TODO() 75 assert.Panics(t, func() { p.GetRequest([]byte{1}) }) 76 assert.Nil(t, p.SendColumnDefinitionPacket(ctx, nil, 1)) 77 assert.Nil(t, p.SendColumnCountPacket(1)) 78 assert.Nil(t, p.SendEOFPacketIf(0, 1)) 79 assert.Nil(t, p.sendOKPacket(1, 1, 0, 0, "")) 80 assert.Nil(t, p.sendEOFOrOkPacket(0, 1)) 81 82 p.stashResult = true 83 p.SendResponse(ctx, &Response{ 84 category: OkResponse, 85 status: 0, 86 affectedRows: 1, 87 data: nil, 88 }) 89 assert.Nil(t, nil, p.result.resultSet) 90 assert.Equal(t, uint64(1), p.result.affectedRows) 91 p.SendResponse(ctx, &Response{ 92 category: ResultResponse, 93 status: 0, 94 data: &MysqlExecutionResult{ 95 affectedRows: 1, 96 mrs: mockResultSet(), 97 }, 98 }) 99 v, _ := p.result.Value(ctx, 0, 0) 100 assert.Equal(t, 42, v.(int)) 101 102 p.ResetStatistics() 103 assert.NoError(t, p.SendResultSetTextBatchRowSpeedup(mockResultSet(), 1)) 104 r := p.swapOutResult() 105 v, e := r.Value(ctx, 0, 0) 106 assert.NoError(t, e) 107 assert.Equal(t, 42, v.(int)) 108 p.ResetStatistics() 109 assert.NoError(t, p.SendResultSetTextBatchRow(mockResultSet(), 1)) 110 r = p.swapOutResult() 111 v, e = r.Value(ctx, 0, 0) 112 assert.NoError(t, e) 113 assert.Equal(t, 42, v.(int)) 114 assert.Equal(t, uint64(1), r.affectedRows) 115 p.ResetStatistics() 116 117 r = p.swapOutResult() 118 assert.Equal(t, uint64(0), r.resultSet.GetRowCount()) 119 } 120 121 func TestIeResult(t *testing.T) { 122 set := mockResultSet() 123 result := &internalExecResult{affectedRows: 1, resultSet: set, err: moerr.NewInternalError(context.TODO(), "random")} 124 require.Equal(t, "internal error: random", result.Error().Error()) 125 require.Equal(t, uint64(1), result.ColumnCount()) 126 require.Equal(t, uint64(1), result.RowCount()) 127 n, ty, s, e := result.Column(context.TODO(), 0) 128 require.NoError(t, e) 129 require.Equal(t, "test", n) 130 require.Equal(t, defines.MYSQL_TYPE_LONG, defines.MysqlType(ty)) 131 require.True(t, s) 132 _, _, _, e = result.Column(context.TODO(), 1) 133 require.Error(t, e) 134 r, e := result.Row(context.TODO(), 0) 135 require.Equal(t, 42, r[0].(int)) 136 require.NoError(t, e) 137 _, e = result.Row(context.TODO(), 1) 138 require.Error(t, e) 139 v, e := result.Value(context.TODO(), 0, 0) 140 require.NoError(t, e) 141 require.Equal(t, 42, v.(int)) 142 v, e = result.ValueByName(context.TODO(), 0, "test") 143 require.NoError(t, e) 144 require.Equal(t, 42, v.(int)) 145 str, e := result.StringValueByName(context.TODO(), 0, "test") 146 require.NoError(t, e) 147 require.Equal(t, "42", str) 148 str, e = result.StringValueByName(context.TODO(), 0, "tet") 149 require.Error(t, e) 150 require.Equal(t, "", str) 151 } 152 153 func DebugPrintInternalResult(ctx context.Context, res ie.InternalExecResult) string { 154 buf := &bytes.Buffer{} 155 for i := uint64(0); i < res.ColumnCount(); i++ { 156 col, _, _, _ := res.Column(context.TODO(), i) 157 buf.WriteString(col + ": ") 158 for j := uint64(0); j < res.RowCount(); j++ { 159 s, _ := res.StringValueByName(ctx, j, col) 160 buf.WriteString(" | ") 161 buf.WriteString(s) 162 } 163 buf.WriteString("\n") 164 } 165 return buf.String() 166 }