vitess.io/vitess@v0.16.2/go/vt/vttablet/endtoend/call_test.go (about) 1 /* 2 Copyright 2021 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package endtoend 18 19 import ( 20 "testing" 21 22 "github.com/stretchr/testify/assert" 23 24 "github.com/stretchr/testify/require" 25 26 "vitess.io/vitess/go/vt/vttablet/endtoend/framework" 27 ) 28 29 var procSQL = []string{ 30 `create procedure proc_select1() 31 BEGIN 32 select intval from vitess_test; 33 END;`, 34 `create procedure proc_select4() 35 BEGIN 36 select intval from vitess_test; 37 select intval from vitess_test; 38 select intval from vitess_test; 39 select intval from vitess_test; 40 END;`, 41 `create procedure proc_dml() 42 BEGIN 43 start transaction; 44 insert into vitess_test(intval) values(1432); 45 update vitess_test set intval = 2341 where intval = 1432; 46 delete from vitess_test where intval = 2341; 47 commit; 48 END;`, 49 `create procedure proc_tx_begin() 50 BEGIN 51 start transaction; 52 END;`, 53 `create procedure proc_tx_commit() 54 BEGIN 55 commit; 56 END;`, 57 `create procedure proc_tx_rollback() 58 BEGIN 59 rollback; 60 END;`, 61 `create procedure in_parameter(IN val int) 62 BEGIN 63 insert into vitess_test(intval) values(val); 64 END;`, 65 `create procedure out_parameter(OUT name varchar(255)) 66 BEGIN 67 select 42 into name from dual; 68 END;`, 69 } 70 71 func TestCallProcedure(t *testing.T) { 72 client := framework.NewClient() 73 type testcases struct { 74 query string 75 wantErr bool 76 } 77 tcases := []testcases{{ 78 query: "call proc_select1()", 79 wantErr: true, 80 }, { 81 query: "call proc_select4()", 82 wantErr: true, 83 }, { 84 query: "call proc_dml()", 85 }} 86 87 for _, tc := range tcases { 88 t.Run(tc.query, func(t *testing.T) { 89 _, err := client.Execute(tc.query, nil) 90 if tc.wantErr { 91 require.EqualError(t, err, "Multi-Resultset not supported in stored procedure (CallerID: dev)") 92 return 93 } 94 require.NoError(t, err) 95 96 }) 97 } 98 } 99 100 func TestCallProcedureInsideTx(t *testing.T) { 101 client := framework.NewClient() 102 defer client.Release() 103 104 _, err := client.BeginExecute(`call proc_dml()`, nil, nil) 105 require.EqualError(t, err, "Transaction state change inside the stored procedure is not allowed (CallerID: dev)") 106 107 _, err = client.Execute(`select 1`, nil) 108 require.Contains(t, err.Error(), "ended") 109 110 } 111 112 func TestCallProcedureInsideReservedConn(t *testing.T) { 113 client := framework.NewClient() 114 _, err := client.ReserveBeginExecute(`call proc_dml()`, nil, nil, nil) 115 require.EqualError(t, err, "Transaction state change inside the stored procedure is not allowed (CallerID: dev)") 116 client.Release() 117 118 _, err = client.ReserveExecute(`call proc_dml()`, nil, nil) 119 require.NoError(t, err) 120 121 _, err = client.Execute(`call proc_dml()`, nil) 122 require.NoError(t, err) 123 124 client.Release() 125 } 126 127 func TestCallProcedureLeakTx(t *testing.T) { 128 client := framework.NewClient() 129 130 _, err := client.Execute(`call proc_tx_begin()`, nil) 131 require.EqualError(t, err, "Transaction not concluded inside the stored procedure, leaking transaction from stored procedure is not allowed (CallerID: dev)") 132 } 133 134 func TestCallProcedureChangedTx(t *testing.T) { 135 client := framework.NewClient() 136 137 _, err := client.Execute(`call proc_tx_begin()`, nil) 138 require.EqualError(t, err, "Transaction not concluded inside the stored procedure, leaking transaction from stored procedure is not allowed (CallerID: dev)") 139 140 queries := []string{ 141 `call proc_tx_commit()`, 142 `call proc_tx_rollback()`, 143 } 144 for _, query := range queries { 145 t.Run(query, func(t *testing.T) { 146 _, err := client.BeginExecute(query, nil, nil) 147 assert.EqualError(t, err, "Transaction state change inside the stored procedure is not allowed (CallerID: dev)") 148 client.Release() 149 }) 150 } 151 152 // This passes as this starts a new transaction by commiting the old transaction implicitly. 153 _, err = client.BeginExecute(`call proc_tx_begin()`, nil, nil) 154 require.NoError(t, err) 155 }