vitess.io/vitess@v0.16.2/go/test/endtoend/vtgate/reservedconn/udv_test.go (about) 1 /* 2 Copyright 2020 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 reservedconn 18 19 import ( 20 "context" 21 "fmt" 22 "testing" 23 24 utils2 "vitess.io/vitess/go/test/endtoend/utils" 25 26 "github.com/stretchr/testify/assert" 27 28 "vitess.io/vitess/go/test/utils" 29 30 "github.com/google/go-cmp/cmp" 31 "github.com/stretchr/testify/require" 32 33 "vitess.io/vitess/go/mysql" 34 "vitess.io/vitess/go/test/endtoend/cluster" 35 ) 36 37 func TestSetUDV(t *testing.T) { 38 defer cluster.PanicHandler(t) 39 ctx := context.Background() 40 41 type queriesWithExpectations struct { 42 query string 43 expectedRows string 44 rowsAffected int 45 rowsReturned int 46 } 47 48 queries := []queriesWithExpectations{{ 49 query: "select @foo", 50 expectedRows: "[[NULL]]", rowsReturned: 1, 51 }, { 52 query: "set @foo = 'abc', @bar = 42, @baz = 30.5, @tablet = concat('foo','bar')", 53 }, { 54 query: "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE */", 55 }, { // This is handled at vtgate. 56 query: "select @foo, @bar, @baz, @tablet", 57 expectedRows: `[[VARCHAR("abc") INT64(42) DECIMAL(30.5) VARCHAR("foobar")]]`, rowsReturned: 1, 58 }, { // Cannot really check a specific value for sql_mode as it will differ based on database selected to run these tests. 59 query: "select @OLD_SQL_MODE = @@SQL_MODE", 60 expectedRows: `[[INT64(1)]]`, rowsReturned: 1, 61 }, { // This one is sent to tablet. 62 query: "select @foo, @bar, @baz, @tablet, @OLD_SQL_MODE = @@SQL_MODE", 63 expectedRows: `[[VARCHAR("abc") INT64(42) DECIMAL(30.5) VARCHAR("foobar") INT64(1)]]`, rowsReturned: 1, 64 }, { 65 query: "insert into test(id, val1, val2, val3) values(1, @foo, null, null), (2, null, @bar, null), (3, null, null, @baz)", 66 expectedRows: ``, rowsAffected: 3, 67 }, { 68 query: "select id, val1, val2, val3 from test order by id", 69 expectedRows: `[[INT64(1) VARCHAR("abc") NULL NULL] [INT64(2) NULL INT32(42) NULL] [INT64(3) NULL NULL FLOAT32(30.5)]]`, rowsReturned: 3, 70 }, { 71 query: "select id, val1 from test where val1=@foo", 72 expectedRows: `[[INT64(1) VARCHAR("abc")]]`, rowsReturned: 1, 73 }, { 74 query: "select id, val2 from test where val2=@bar", 75 expectedRows: `[[INT64(2) INT32(42)]]`, rowsReturned: 1, 76 }, { 77 query: "select id, val3 from test where val3=@baz", 78 expectedRows: `[[INT64(3) FLOAT32(30.5)]]`, rowsReturned: 1, 79 }, { 80 query: "delete from test where val2 = @bar", 81 expectedRows: ``, rowsAffected: 1, 82 }, { 83 query: "select id, val2 from test where val2=@bar", 84 expectedRows: ``, 85 }, { 86 query: "update test set val2 = @bar where val1 = @foo", 87 expectedRows: ``, rowsAffected: 1, 88 }, { 89 query: "select id, val1, val2 from test where val1=@foo", 90 expectedRows: `[[INT64(1) VARCHAR("abc") INT32(42)]]`, rowsReturned: 1, 91 }, { 92 query: "insert into test(id, val1, val2, val3) values (42, @tablet, null, null)", 93 expectedRows: ``, rowsAffected: 1, 94 }, { 95 query: "select id, val1 from test where val1 = @tablet", 96 expectedRows: `[[INT64(42) VARCHAR("foobar")]]`, rowsReturned: 1, 97 }, { 98 query: "set @foo = now(), @bar = now(), @dd = date('2020-10-20'), @tt = time('10:15')", 99 expectedRows: `[]`, 100 }, { 101 query: "select @foo = @bar, @dd, @tt", 102 expectedRows: `[[INT64(1) DATE("2020-10-20") TIME("10:15:00")]]`, rowsReturned: 1, 103 }} 104 105 conn, err := mysql.Connect(ctx, &vtParams) 106 require.NoError(t, err) 107 defer conn.Close() 108 utils2.Exec(t, conn, "delete from test") 109 110 for i, q := range queries { 111 t.Run(fmt.Sprintf("%d-%s", i, q.query), func(t *testing.T) { 112 qr := utils2.Exec(t, conn, q.query) 113 assert.EqualValues(t, q.rowsAffected, qr.RowsAffected, "rows affected wrong for query: %s", q.query) 114 assert.EqualValues(t, q.rowsReturned, len(qr.Rows), "rows returned wrong for query: %s", q.query) 115 if q.expectedRows != "" { 116 result := fmt.Sprintf("%v", qr.Rows) 117 if diff := cmp.Diff(q.expectedRows, result); diff != "" { 118 t.Errorf("%s\nfor query: %s", diff, q.query) 119 } 120 } 121 }) 122 } 123 } 124 125 func TestMysqlDumpInitialLog(t *testing.T) { 126 defer cluster.PanicHandler(t) 127 ctx := context.Background() 128 129 conn, err := mysql.Connect(ctx, &vtParams) 130 require.NoError(t, err) 131 defer conn.Close() 132 133 queries := []string{ 134 "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;", 135 "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;", 136 "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;", 137 "/*!50503 SET NAMES utf8mb4 */;", 138 "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;", 139 "/*!40103 SET TIME_ZONE='+00:00' */;", 140 "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;", 141 "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;", 142 "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;", 143 "/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;", 144 "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;", 145 "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;", 146 "/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;", 147 "/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;", 148 "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;", 149 "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;", 150 "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;", 151 "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;", 152 } 153 154 for _, query := range queries { 155 t.Run(query, func(t *testing.T) { 156 _, more, err := conn.ExecuteFetchMulti(query, 1000, true) 157 require.NoError(t, err) 158 require.False(t, more) 159 }) 160 } 161 } 162 163 func TestUserDefinedVariableResolvedAtTablet(t *testing.T) { 164 ctx := context.Background() 165 166 conn, err := mysql.Connect(ctx, &vtParams) 167 require.NoError(t, err) 168 defer conn.Close() 169 170 // this should set the UDV foo to a value that has to be evaluated by mysqld 171 utils2.Exec(t, conn, "set @foo = CONCAT('Any','Expression','Is','Valid')") 172 173 // now getting that value should return the value from the tablet 174 qr := utils2.Exec(t, conn, "select @foo") 175 got := fmt.Sprintf("%v", qr.Rows) 176 utils.MustMatch(t, `[[VARCHAR("AnyExpressionIsValid")]]`, got, "didnt match") 177 }