github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/compile/compile_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 compile
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"github.com/golang/mock/gomock"
    22  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    23  	mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test"
    24  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    25  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql"
    26  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    27  	plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan"
    28  	"github.com/matrixorigin/matrixone/pkg/testutil"
    29  	"github.com/matrixorigin/matrixone/pkg/testutil/testengine"
    30  	"github.com/matrixorigin/matrixone/pkg/util/fault"
    31  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    32  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    33  	"github.com/stretchr/testify/require"
    34  )
    35  
    36  type compileTestCase struct {
    37  	sql  string
    38  	pn   *plan.Plan
    39  	e    engine.Engine
    40  	stmt tree.Statement
    41  	proc *process.Process
    42  }
    43  
    44  var (
    45  	tcs []compileTestCase
    46  )
    47  
    48  func init() {
    49  	tcs = []compileTestCase{
    50  		newTestCase("select 1", new(testing.T)),
    51  		newTestCase("select * from R", new(testing.T)),
    52  		newTestCase("select * from R where uid > 1", new(testing.T)),
    53  		newTestCase("select * from R order by uid", new(testing.T)),
    54  		newTestCase("select * from R order by uid limit 1", new(testing.T)),
    55  		newTestCase("select * from R limit 1", new(testing.T)),
    56  		newTestCase("select * from R limit 2, 1", new(testing.T)),
    57  		newTestCase("select count(*) from R", new(testing.T)),
    58  		newTestCase("select * from R join S on R.uid = S.uid", new(testing.T)),
    59  		newTestCase("select * from R left join S on R.uid = S.uid", new(testing.T)),
    60  		newTestCase("select * from R right join S on R.uid = S.uid", new(testing.T)),
    61  		newTestCase("select * from R join S on R.uid > S.uid", new(testing.T)),
    62  		newTestCase("select * from R limit 10", new(testing.T)),
    63  		newTestCase("insert into R values('1', '2', '3')", new(testing.T)),
    64  		newTestCase("insert into R select * from R", new(testing.T)),
    65  		newTestCase("select count(*) from R group by uid", new(testing.T)),
    66  		newTestCase("select count(distinct uid) from R", new(testing.T)),
    67  	}
    68  }
    69  
    70  func testPrint(_ interface{}, _ *batch.Batch) error {
    71  	return nil
    72  }
    73  
    74  func TestCompile(t *testing.T) {
    75  	ctrl := gomock.NewController(t)
    76  	ctx := context.TODO()
    77  	txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
    78  	txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes()
    79  	txnOperator.EXPECT().Rollback(ctx).Return(nil).AnyTimes()
    80  
    81  	txnClient := mock_frontend.NewMockTxnClient(ctrl)
    82  	txnClient.EXPECT().New().Return(txnOperator, nil).AnyTimes()
    83  	for _, tc := range tcs {
    84  		tc.proc.TxnClient = txnClient
    85  		c := New("", "test", tc.sql, "", context.TODO(), tc.e, tc.proc, tc.stmt)
    86  		err := c.Compile(ctx, tc.pn, nil, testPrint)
    87  		require.NoError(t, err)
    88  		c.GetAffectedRows()
    89  		err = c.Run(0)
    90  		require.NoError(t, err)
    91  		// Enable memory check
    92  		require.Equal(t, int64(0), tc.proc.Mp().CurrNB())
    93  	}
    94  }
    95  
    96  func TestCompileWithFaults(t *testing.T) {
    97  	// Enable this line to trigger the Hung.
    98  	// fault.Enable()
    99  	var ctx = context.Background()
   100  	fault.AddFaultPoint(ctx, "panic_in_batch_append", ":::", "panic", 0, "")
   101  	tc := newTestCase("select * from R join S on R.uid = S.uid", t)
   102  	c := New("", "test", tc.sql, "", context.TODO(), tc.e, tc.proc, nil)
   103  	err := c.Compile(ctx, tc.pn, nil, testPrint)
   104  	require.NoError(t, err)
   105  	c.GetAffectedRows()
   106  	err = c.Run(0)
   107  	require.NoError(t, err)
   108  }
   109  
   110  func newTestCase(sql string, t *testing.T) compileTestCase {
   111  	proc := testutil.NewProcess()
   112  	e, _, compilerCtx := testengine.New(context.Background())
   113  	stmts, err := mysql.Parse(compilerCtx.GetContext(), sql)
   114  	require.NoError(t, err)
   115  	pn, err := plan2.BuildPlan(compilerCtx, stmts[0])
   116  	require.NoError(t, err)
   117  	return compileTestCase{
   118  		e:    e,
   119  		sql:  sql,
   120  		proc: proc,
   121  		pn:   pn,
   122  		stmt: stmts[0],
   123  	}
   124  }