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  }