vitess.io/vitess@v0.16.2/go/vt/vtgate/vindexes/lookup_unique_test.go (about)

     1  /*
     2  Copyright 2019 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 vindexes
    18  
    19  import (
    20  	"context"
    21  	"reflect"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  
    27  	"vitess.io/vitess/go/sqltypes"
    28  	"vitess.io/vitess/go/vt/key"
    29  	querypb "vitess.io/vitess/go/vt/proto/query"
    30  	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
    31  )
    32  
    33  func TestLookupUniqueNew(t *testing.T) {
    34  	l := createLookup(t, "lookup_unique", false)
    35  	if want, got := l.(*LookupUnique).writeOnly, false; got != want {
    36  		t.Errorf("Create(lookup, false): %v, want %v", got, want)
    37  	}
    38  
    39  	vindex, _ := CreateVindex("lookup_unique", "lookup_unique", map[string]string{
    40  		"table":      "t",
    41  		"from":       "fromc",
    42  		"to":         "toc",
    43  		"write_only": "true",
    44  	})
    45  	l = vindex.(SingleColumn)
    46  	if want, got := l.(*LookupUnique).writeOnly, true; got != want {
    47  		t.Errorf("Create(lookup, false): %v, want %v", got, want)
    48  	}
    49  
    50  	_, err := CreateVindex("lookup_unique", "lookup_unique", map[string]string{
    51  		"table":      "t",
    52  		"from":       "fromc",
    53  		"to":         "toc",
    54  		"write_only": "invalid",
    55  	})
    56  	want := "write_only value must be 'true' or 'false': 'invalid'"
    57  	if err == nil || err.Error() != want {
    58  		t.Errorf("Create(bad_scatter): %v, want %s", err, want)
    59  	}
    60  }
    61  
    62  func TestLookupUniqueInfo(t *testing.T) {
    63  	lookupUnique := createLookup(t, "lookup_unique", false)
    64  	assert.Equal(t, 10, lookupUnique.Cost())
    65  	assert.Equal(t, "lookup_unique", lookupUnique.String())
    66  	assert.True(t, lookupUnique.IsUnique())
    67  }
    68  
    69  func TestLookupUniqueMap(t *testing.T) {
    70  	lookupUnique := createLookup(t, "lookup_unique", false)
    71  	vc := &vcursor{numRows: 1}
    72  
    73  	got, err := lookupUnique.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)})
    74  	require.NoError(t, err)
    75  	want := []key.Destination{
    76  		key.DestinationKeyspaceID([]byte("1")),
    77  		key.DestinationNone{},
    78  	}
    79  	if !reflect.DeepEqual(got, want) {
    80  		t.Errorf("Map(): %+v, want %+v", got, want)
    81  	}
    82  
    83  	vc.numRows = 0
    84  	got, err = lookupUnique.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)})
    85  	require.NoError(t, err)
    86  	want = []key.Destination{
    87  		key.DestinationNone{},
    88  		key.DestinationNone{},
    89  	}
    90  	if !reflect.DeepEqual(got, want) {
    91  		t.Errorf("Map(): %#v, want %+v", got, want)
    92  	}
    93  
    94  	vc.numRows = 2
    95  	_, err = lookupUnique.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)})
    96  	wantErr := "Lookup.Map: unexpected multiple results from vindex t: INT64(1)"
    97  	if err == nil || err.Error() != wantErr {
    98  		t.Errorf("lookupUnique(query fail) err: %v, want %s", err, wantErr)
    99  	}
   100  
   101  	// Test query fail.
   102  	vc.mustFail = true
   103  	_, err = lookupUnique.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)})
   104  	wantErr = "lookup.Map: execute failed"
   105  	if err == nil || err.Error() != wantErr {
   106  		t.Errorf("lookupUnique(query fail) err: %v, want %s", err, wantErr)
   107  	}
   108  	vc.mustFail = false
   109  }
   110  
   111  func TestLookupUniqueMapWriteOnly(t *testing.T) {
   112  	lookupUnique := createLookup(t, "lookup_unique", true)
   113  	vc := &vcursor{numRows: 0}
   114  
   115  	got, err := lookupUnique.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)})
   116  	require.NoError(t, err)
   117  	want := []key.Destination{
   118  		key.DestinationKeyRange{
   119  			KeyRange: &topodatapb.KeyRange{},
   120  		},
   121  		key.DestinationKeyRange{
   122  			KeyRange: &topodatapb.KeyRange{},
   123  		},
   124  	}
   125  	if !reflect.DeepEqual(got, want) {
   126  		t.Errorf("Map(): %#v, want %+v", got, want)
   127  	}
   128  }
   129  
   130  func TestLookupUniqueVerify(t *testing.T) {
   131  	lookupUnique := createLookup(t, "lookup_unique", false)
   132  	vc := &vcursor{numRows: 1}
   133  
   134  	_, err := lookupUnique.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}, [][]byte{[]byte("test")})
   135  	require.NoError(t, err)
   136  	if got, want := len(vc.queries), 1; got != want {
   137  		t.Errorf("vc.queries length: %v, want %v", got, want)
   138  	}
   139  }
   140  
   141  func TestLookupUniqueVerifyWriteOnly(t *testing.T) {
   142  	lookupUnique := createLookup(t, "lookup_unique", true)
   143  	vc := &vcursor{numRows: 0}
   144  
   145  	got, err := lookupUnique.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}, [][]byte{[]byte("test")})
   146  	require.NoError(t, err)
   147  	want := []bool{true}
   148  	if !reflect.DeepEqual(got, want) {
   149  		t.Errorf("lookupUnique.Verify: %v, want %v", got, want)
   150  	}
   151  	if got, want := len(vc.queries), 0; got != want {
   152  		t.Errorf("vc.queries length: %v, want %v", got, want)
   153  	}
   154  }
   155  
   156  func TestLookupUniqueCreate(t *testing.T) {
   157  	lookupUnique, err := CreateVindex("lookup_unique", "lookup_unique", map[string]string{
   158  		"table":      "t",
   159  		"from":       "from",
   160  		"to":         "toc",
   161  		"autocommit": "true",
   162  	})
   163  	if err != nil {
   164  		t.Fatal(err)
   165  	}
   166  	vc := &vcursor{}
   167  
   168  	err = lookupUnique.(Lookup).Create(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1)}}, [][]byte{[]byte("test")}, false /* ignoreMode */)
   169  	require.NoError(t, err)
   170  
   171  	wantqueries := []*querypb.BoundQuery{{
   172  		Sql: "insert into t(from, toc) values(:from_0, :toc_0)",
   173  		BindVariables: map[string]*querypb.BindVariable{
   174  			"from_0": sqltypes.Int64BindVariable(1),
   175  			"toc_0":  sqltypes.BytesBindVariable([]byte("test")),
   176  		},
   177  	}}
   178  	if !reflect.DeepEqual(vc.queries, wantqueries) {
   179  		t.Errorf("lookup.Create queries:\n%v, want\n%v", vc.queries, wantqueries)
   180  	}
   181  
   182  	if got, want := vc.autocommits, 1; got != want {
   183  		t.Errorf("Create(autocommit) count: %d, want %d", got, want)
   184  	}
   185  }
   186  
   187  func TestLookupUniqueCreateAutocommit(t *testing.T) {
   188  	lookupUnique := createLookup(t, "lookup_unique", false)
   189  	vc := &vcursor{}
   190  
   191  	err := lookupUnique.(Lookup).Create(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1)}}, [][]byte{[]byte("test")}, false /* ignoreMode */)
   192  	require.NoError(t, err)
   193  	if got, want := len(vc.queries), 1; got != want {
   194  		t.Errorf("vc.queries length: %v, want %v", got, want)
   195  	}
   196  }
   197  
   198  func TestLookupUniqueDelete(t *testing.T) {
   199  	lookupUnique := createLookup(t, "lookup_unique", false)
   200  	vc := &vcursor{}
   201  
   202  	err := lookupUnique.(Lookup).Delete(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1)}}, []byte("test"))
   203  	require.NoError(t, err)
   204  	if got, want := len(vc.queries), 1; got != want {
   205  		t.Errorf("vc.queries length: %v, want %v", got, want)
   206  	}
   207  }
   208  
   209  func TestLookupUniqueUpdate(t *testing.T) {
   210  	lookupUnique := createLookup(t, "lookup_unique", false)
   211  	vc := &vcursor{}
   212  
   213  	err := lookupUnique.(Lookup).Update(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}, []byte("test"), []sqltypes.Value{sqltypes.NewInt64(2)})
   214  	require.NoError(t, err)
   215  	if got, want := len(vc.queries), 2; got != want {
   216  		t.Errorf("vc.queries length: %v, want %v", got, want)
   217  	}
   218  }