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  }