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 }