github.com/dolthub/go-mysql-server@v0.18.0/sql/rowexec/update_test.go (about) 1 // Copyright 2022 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package rowexec 16 17 import ( 18 "testing" 19 "time" 20 21 "github.com/dolthub/vitess/go/sqltypes" 22 "github.com/stretchr/testify/require" 23 24 "github.com/dolthub/go-mysql-server/memory" 25 "github.com/dolthub/go-mysql-server/sql" 26 "github.com/dolthub/go-mysql-server/sql/expression" 27 "github.com/dolthub/go-mysql-server/sql/plan" 28 "github.com/dolthub/go-mysql-server/sql/types" 29 ) 30 31 func TestUpdateIgnoreConversions(t *testing.T) { 32 testCases := []struct { 33 name string 34 colType sql.Type 35 value interface{} 36 valueType sql.Type 37 expected interface{} 38 }{ 39 { 40 name: "inserting a string into a integer defaults to a 0", 41 colType: types.Int64, 42 value: "dadasd", 43 valueType: types.Text, 44 expected: int64(0), 45 }, 46 { 47 name: "string too long gets truncated", 48 colType: types.MustCreateStringWithDefaults(sqltypes.VarChar, 2), 49 value: "dadsa", 50 valueType: types.Text, 51 expected: "da", 52 }, 53 { 54 name: "inserting a string into a datetime results in 0 time", 55 colType: types.Datetime, 56 value: "dadasd", 57 valueType: types.Text, 58 expected: time.Unix(-62167219200, 0).UTC(), 59 }, 60 { 61 name: "inserting a negative into an unsigned int results in 0", 62 colType: types.Uint64, 63 value: int64(-1), 64 expected: uint64(1<<64 - 1), 65 valueType: types.Uint64, 66 }, 67 } 68 69 for _, tc := range testCases { 70 t.Run(tc.name, func(t *testing.T) { 71 db := memory.NewDatabase("foo") 72 pro := memory.NewDBProvider(db) 73 ctx := newContext(pro) 74 75 sch := sql.NewPrimaryKeySchema(sql.Schema{ 76 {Name: "c1", Source: "foo", Type: tc.colType, Nullable: true}, 77 }) 78 table := memory.NewTable(db, "foo", sch, nil) 79 80 err := table.Insert(ctx, sql.Row{nil}) 81 require.NoError(t, err) 82 83 // Run the UPDATE IGNORE 84 sf := expression.NewSetField(expression.NewGetField(0, tc.colType, "c1", true), expression.NewLiteral(tc.value, tc.valueType)) 85 updatePlan := plan.NewUpdate(plan.NewResolvedTable(table, nil, nil), true, []sql.Expression{sf}) 86 87 ri, err := DefaultBuilder.Build(ctx, updatePlan, nil) 88 require.NoError(t, err) 89 90 _, err = sql.RowIterToRows(ctx, ri) 91 require.NoError(t, err) 92 93 // Run a SELECT to see the updated data 94 selectPlan := plan.NewProject([]sql.Expression{ 95 expression.NewGetField(0, tc.colType, "c1", true), 96 }, plan.NewResolvedTable(table, nil, nil)) 97 98 ri, err = DefaultBuilder.Build(ctx, selectPlan, nil) 99 require.NoError(t, err) 100 101 rows, err := sql.RowIterToRows(ctx, ri) 102 require.NoError(t, err) 103 104 require.Equal(t, 1, len(rows)) 105 require.Equal(t, tc.expected, rows[0][0]) 106 }) 107 } 108 }