From 16d76aa299ba02b0f2bdc8ef0b90ce134b624fec Mon Sep 17 00:00:00 2001 From: Shlomi Noach Date: Wed, 17 Aug 2016 06:52:23 +0200 Subject: [PATCH] builder fixes arg type from signed to unsigned based on UnsingedFlags --- go/sql/builder.go | 35 +++++++++-- go/sql/builder_test.go | 135 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 4 deletions(-) diff --git a/go/sql/builder.go b/go/sql/builder.go index 6ccdb62..6c2e4b2 100644 --- a/go/sql/builder.go +++ b/go/sql/builder.go @@ -32,6 +32,29 @@ func EscapeName(name string) string { return fmt.Sprintf("`%s`", name) } +func fixArgType(arg interface{}, isUnsigned bool) interface{} { + if !isUnsigned { + return arg + } + // unsigned + if i, ok := arg.(int8); ok { + return uint8(i) + } + if i, ok := arg.(int16); ok { + return uint16(i) + } + if i, ok := arg.(int32); ok { + return uint32(i) + } + if i, ok := arg.(int64); ok { + return uint64(i) + } + if i, ok := arg.(int); ok { + return uint(i) + } + return arg +} + func buildPreparedValues(length int) []string { values := make([]string, length, length) for i := 0; i < length; i++ { @@ -309,7 +332,8 @@ func BuildDMLDeleteQuery(databaseName, tableName string, tableColumns, uniqueKey } for _, column := range uniqueKeyColumns.Names { tableOrdinal := tableColumns.Ordinals[column] - uniqueKeyArgs = append(uniqueKeyArgs, args[tableOrdinal]) + arg := fixArgType(args[tableOrdinal], uniqueKeyColumns.IsUnsigned(column)) + uniqueKeyArgs = append(uniqueKeyArgs, arg) } databaseName = EscapeName(databaseName) tableName = EscapeName(tableName) @@ -345,7 +369,8 @@ func BuildDMLInsertQuery(databaseName, tableName string, tableColumns, sharedCol for _, column := range sharedColumns.Names { tableOrdinal := tableColumns.Ordinals[column] - sharedArgs = append(sharedArgs, args[tableOrdinal]) + arg := fixArgType(args[tableOrdinal], sharedColumns.IsUnsigned(column)) + sharedArgs = append(sharedArgs, arg) } sharedColumnNames := duplicateNames(sharedColumns.Names) @@ -392,12 +417,14 @@ func BuildDMLUpdateQuery(databaseName, tableName string, tableColumns, sharedCol for _, column := range sharedColumns.Names { tableOrdinal := tableColumns.Ordinals[column] - sharedArgs = append(sharedArgs, valueArgs[tableOrdinal]) + arg := fixArgType(valueArgs[tableOrdinal], sharedColumns.IsUnsigned(column)) + sharedArgs = append(sharedArgs, arg) } for _, column := range uniqueKeyColumns.Names { tableOrdinal := tableColumns.Ordinals[column] - uniqueKeyArgs = append(uniqueKeyArgs, whereArgs[tableOrdinal]) + arg := fixArgType(whereArgs[tableOrdinal], uniqueKeyColumns.IsUnsigned(column)) + uniqueKeyArgs = append(uniqueKeyArgs, arg) } sharedColumnNames := duplicateNames(sharedColumns.Names) diff --git a/go/sql/builder_test.go b/go/sql/builder_test.go index 0ca4d38..db2617e 100644 --- a/go/sql/builder_test.go +++ b/go/sql/builder_test.go @@ -397,6 +397,44 @@ func TestBuildDMLDeleteQuery(t *testing.T) { } } +func TestBuildDMLDeleteQuerySignedUnsigned(t *testing.T) { + databaseName := "mydb" + tableName := "tbl" + tableColumns := NewColumnList([]string{"id", "name", "rank", "position", "age"}) + uniqueKeyColumns := NewColumnList([]string{"position"}) + { + // test signed (expect no change) + args := []interface{}{3, "testname", "first", -1, 23} + query, uniqueKeyArgs, err := BuildDMLDeleteQuery(databaseName, tableName, tableColumns, uniqueKeyColumns, args) + test.S(t).ExpectNil(err) + expected := ` + delete /* gh-ost mydb.tbl */ + from + mydb.tbl + where + ((position = ?)) + ` + test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(uniqueKeyArgs, []interface{}{-1})) + } + { + // test unsigned + args := []interface{}{3, "testname", "first", int8(-1), 23} + uniqueKeyColumns.SetUnsigned("position") + query, uniqueKeyArgs, err := BuildDMLDeleteQuery(databaseName, tableName, tableColumns, uniqueKeyColumns, args) + test.S(t).ExpectNil(err) + expected := ` + delete /* gh-ost mydb.tbl */ + from + mydb.tbl + where + ((position = ?)) + ` + test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(uniqueKeyArgs, []interface{}{uint8(255)})) + } +} + func TestBuildDMLInsertQuery(t *testing.T) { databaseName := "mydb" tableName := "tbl" @@ -442,6 +480,61 @@ func TestBuildDMLInsertQuery(t *testing.T) { } } +func TestBuildDMLInsertQuerySignedUnsigned(t *testing.T) { + databaseName := "mydb" + tableName := "tbl" + tableColumns := NewColumnList([]string{"id", "name", "rank", "position", "age"}) + sharedColumns := NewColumnList([]string{"id", "name", "position", "age"}) + { + // testing signed + args := []interface{}{3, "testname", "first", int8(-1), 23} + sharedColumns := NewColumnList([]string{"id", "name", "position", "age"}) + query, sharedArgs, err := BuildDMLInsertQuery(databaseName, tableName, tableColumns, sharedColumns, args) + test.S(t).ExpectNil(err) + expected := ` + replace /* gh-ost mydb.tbl */ + into mydb.tbl + (id, name, position, age) + values + (?, ?, ?, ?) + ` + test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(sharedArgs, []interface{}{3, "testname", int8(-1), 23})) + } + { + // testing unsigned + args := []interface{}{3, "testname", "first", int8(-1), 23} + sharedColumns.SetUnsigned("position") + query, sharedArgs, err := BuildDMLInsertQuery(databaseName, tableName, tableColumns, sharedColumns, args) + test.S(t).ExpectNil(err) + expected := ` + replace /* gh-ost mydb.tbl */ + into mydb.tbl + (id, name, position, age) + values + (?, ?, ?, ?) + ` + test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(sharedArgs, []interface{}{3, "testname", uint8(255), 23})) + } + { + // testing unsigned + args := []interface{}{3, "testname", "first", int32(-1), 23} + sharedColumns.SetUnsigned("position") + query, sharedArgs, err := BuildDMLInsertQuery(databaseName, tableName, tableColumns, sharedColumns, args) + test.S(t).ExpectNil(err) + expected := ` + replace /* gh-ost mydb.tbl */ + into mydb.tbl + (id, name, position, age) + values + (?, ?, ?, ?) + ` + test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(sharedArgs, []interface{}{3, "testname", uint32(4294967295), 23})) + } +} + func TestBuildDMLUpdateQuery(t *testing.T) { databaseName := "mydb" tableName := "tbl" @@ -525,3 +618,45 @@ func TestBuildDMLUpdateQuery(t *testing.T) { test.S(t).ExpectNotNil(err) } } + +func TestBuildDMLUpdateQuerySignedUnsigned(t *testing.T) { + databaseName := "mydb" + tableName := "tbl" + tableColumns := NewColumnList([]string{"id", "name", "rank", "position", "age"}) + valueArgs := []interface{}{3, "testname", "newval", int8(-17), int8(-2)} + whereArgs := []interface{}{3, "testname", "findme", int8(-3), 56} + sharedColumns := NewColumnList([]string{"id", "name", "position", "age"}) + uniqueKeyColumns := NewColumnList([]string{"position"}) + { + // test signed + query, sharedArgs, uniqueKeyArgs, err := BuildDMLUpdateQuery(databaseName, tableName, tableColumns, sharedColumns, uniqueKeyColumns, valueArgs, whereArgs) + test.S(t).ExpectNil(err) + expected := ` + update /* gh-ost mydb.tbl */ + mydb.tbl + set id=?, name=?, position=?, age=? + where + ((position = ?)) + ` + test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(sharedArgs, []interface{}{3, "testname", int8(-17), int8(-2)})) + test.S(t).ExpectTrue(reflect.DeepEqual(uniqueKeyArgs, []interface{}{int8(-3)})) + } + { + // test unsigned + sharedColumns.SetUnsigned("age") + uniqueKeyColumns.SetUnsigned("position") + query, sharedArgs, uniqueKeyArgs, err := BuildDMLUpdateQuery(databaseName, tableName, tableColumns, sharedColumns, uniqueKeyColumns, valueArgs, whereArgs) + test.S(t).ExpectNil(err) + expected := ` + update /* gh-ost mydb.tbl */ + mydb.tbl + set id=?, name=?, position=?, age=? + where + ((position = ?)) + ` + test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(sharedArgs, []interface{}{3, "testname", int8(-17), uint8(254)})) + test.S(t).ExpectTrue(reflect.DeepEqual(uniqueKeyArgs, []interface{}{uint8(253)})) + } +}