From d8fefb3d6f67bda9035843841befe1249ed100b4 Mon Sep 17 00:00:00 2001 From: Shlomi Noach Date: Tue, 5 Apr 2016 19:50:49 +0200 Subject: [PATCH] exploded args on range query building; iteration works --- go/logic/applier.go | 52 ++++++++++++++++--------------- go/logic/migrator.go | 3 +- go/sql/builder.go | 70 +++++++++++++++++++++++++----------------- go/sql/builder_test.go | 49 +++++++++++++++++++++-------- go/sql/types.go | 16 ++++------ 5 files changed, 112 insertions(+), 78 deletions(-) diff --git a/go/logic/applier.go b/go/logic/applier.go index ed90a9a..d82bf0c 100644 --- a/go/logic/applier.go +++ b/go/logic/applier.go @@ -11,7 +11,6 @@ import ( "github.com/github/gh-osc/go/base" "github.com/github/gh-osc/go/mysql" "github.com/github/gh-osc/go/sql" - "reflect" "github.com/outbrain/golib/log" "github.com/outbrain/golib/sqlutils" @@ -156,17 +155,17 @@ func (this *Applier) IterationIsComplete() (bool, error) { if this.migrationContext.MigrationIterationRangeMinValues == nil { return false, nil } - compareWithIterationRangeStart, err := sql.BuildRangePreparedComparison(this.migrationContext.UniqueKey.Columns, sql.GreaterThanOrEqualsComparisonSign) - if err != nil { - return false, err - } - compareWithRangeEnd, err := sql.BuildRangePreparedComparison(this.migrationContext.UniqueKey.Columns, sql.LessThanComparisonSign) - if err != nil { - return false, err - } args := sqlutils.Args() - args = append(args, this.migrationContext.MigrationIterationRangeMinValues.AbstractValues()...) - args = append(args, this.migrationContext.MigrationRangeMaxValues.AbstractValues()...) + compareWithIterationRangeStart, explodedArgs, err := sql.BuildRangePreparedComparison(this.migrationContext.UniqueKey.Columns, this.migrationContext.MigrationIterationRangeMinValues.AbstractValues(), sql.GreaterThanOrEqualsComparisonSign) + if err != nil { + return false, err + } + args = append(args, explodedArgs...) + compareWithRangeEnd, explodedArgs, err := sql.BuildRangePreparedComparison(this.migrationContext.UniqueKey.Columns, this.migrationContext.MigrationRangeMaxValues.AbstractValues(), sql.LessThanComparisonSign) + if err != nil { + return false, err + } + args = append(args, explodedArgs...) query := fmt.Sprintf(` select /* gh-osc IterationIsComplete */ 1 from %s.%s @@ -178,13 +177,12 @@ func (this *Applier) IterationIsComplete() (bool, error) { compareWithIterationRangeStart, compareWithRangeEnd, ) - log.Debugf(query) moreRowsFound := false err = sqlutils.QueryRowsMap(this.db, query, func(rowMap sqlutils.RowMap) error { moreRowsFound = true return nil - }, args) + }, args...) if err != nil { return false, err } @@ -192,16 +190,24 @@ func (this *Applier) IterationIsComplete() (bool, error) { } func (this *Applier) CalculateNextIterationRangeEndValues() error { - query, err := sql.BuildUniqueKeyRangeEndPreparedQuery(this.migrationContext.DatabaseName, this.migrationContext.OriginalTableName, this.migrationContext.UniqueKey.Columns, this.migrationContext.ChunkSize) - if err != nil { - return err - } startingFromValues := this.migrationContext.MigrationRangeMinValues this.migrationContext.MigrationIterationRangeMinValues = this.migrationContext.MigrationIterationRangeMaxValues if this.migrationContext.MigrationIterationRangeMinValues != nil { startingFromValues = this.migrationContext.MigrationIterationRangeMinValues } - rows, err := this.db.Query(query, startingFromValues.AbstractValues()...) + query, explodedArgs, err := sql.BuildUniqueKeyRangeEndPreparedQuery( + this.migrationContext.DatabaseName, + this.migrationContext.OriginalTableName, + this.migrationContext.UniqueKey.Columns, + startingFromValues.AbstractValues(), + this.migrationContext.MigrationRangeMaxValues.AbstractValues(), + this.migrationContext.ChunkSize, + fmt.Sprintf("iteration:%d", this.migrationContext.Iteration), + ) + if err != nil { + return err + } + rows, err := this.db.Query(query, explodedArgs...) if err != nil { return err } @@ -213,12 +219,12 @@ func (this *Applier) CalculateNextIterationRangeEndValues() error { } iterationRangeEndFound = true } - log.Debugf("5") if !iterationRangeEndFound { - return fmt.Errorf("Cannot find iteration range end") + log.Debugf("Iteration complete: cannot find iteration end") + return nil } this.migrationContext.MigrationIterationRangeMaxValues = iterationRangeMaxValues - log.Debugf("column values: %s", this.migrationContext.MigrationIterationRangeMaxValues) + log.Debugf("column values: %s; iteration: %d; chunk-size: %d", this.migrationContext.MigrationIterationRangeMaxValues, this.migrationContext.Iteration, this.migrationContext.ChunkSize) return nil } @@ -238,10 +244,6 @@ func (this *Applier) IterateTable(uniqueKey *sql.UniqueKey) error { if err = rows.Scan(columnValues.ValuesPointers...); err != nil { return err } - for _, val := range columnValues.BinaryValues() { - log.Debugf("%s", reflect.TypeOf(val)) - log.Debugf("%s", string(val)) - } } log.Debugf("column values: %s", columnValues) query = `insert into test.sample_data_dump (category, ts) values (?, ?)` diff --git a/go/logic/migrator.go b/go/logic/migrator.go index d3b7bc6..63a73b4 100644 --- a/go/logic/migrator.go +++ b/go/logic/migrator.go @@ -56,12 +56,10 @@ func (this *Migrator) Migrate() (err error) { // return err // } this.migrationContext.UniqueKey = uniqueKeys[0] - this.migrationContext.ChunkSize = 100 if err := this.applier.ReadMigrationRangeValues(); err != nil { return err } for { - log.Debugf("checking if complete") isComplete, err := this.applier.IterationIsComplete() if err != nil { return err @@ -73,6 +71,7 @@ func (this *Migrator) Migrate() (err error) { if err != nil { return err } + this.migrationContext.Iteration++ } if err := this.applier.IterateTable(uniqueKeys[0]); err != nil { return err diff --git a/go/sql/builder.go b/go/sql/builder.go index 1f55b9e..27a5e20 100644 --- a/go/sql/builder.go +++ b/go/sql/builder.go @@ -64,12 +64,15 @@ func BuildEqualsComparison(columns []string, values []string) (result string, er return result, nil } -func BuildRangeComparison(columns []string, values []string, comparisonSign ValueComparisonSign) (result string, err error) { +func BuildRangeComparison(columns []string, values []string, args []interface{}, comparisonSign ValueComparisonSign) (result string, explodedArgs []interface{}, err error) { if len(columns) == 0 { - return "", fmt.Errorf("Got 0 columns in GetRangeComparison") + return "", explodedArgs, fmt.Errorf("Got 0 columns in GetRangeComparison") } if len(columns) != len(values) { - return "", fmt.Errorf("Got %d columns but %d values in GetEqualsComparison", len(columns), len(values)) + return "", explodedArgs, fmt.Errorf("Got %d columns but %d values in GetEqualsComparison", len(columns), len(values)) + } + if len(columns) != len(args) { + return "", explodedArgs, fmt.Errorf("Got %d columns but %d args in GetEqualsComparison", len(columns), len(args)) } includeEquals := false if comparisonSign == LessThanOrEqualsComparisonSign { @@ -87,43 +90,47 @@ func BuildRangeComparison(columns []string, values []string, comparisonSign Valu value := values[i] rangeComparison, err := BuildValueComparison(column, value, comparisonSign) if err != nil { - return "", err + return "", explodedArgs, err } if len(columns[0:i]) > 0 { equalitiesComparison, err := BuildEqualsComparison(columns[0:i], values[0:i]) if err != nil { - return "", err + return "", explodedArgs, err } comparison := fmt.Sprintf("(%s AND %s)", equalitiesComparison, rangeComparison) comparisons = append(comparisons, comparison) + explodedArgs = append(explodedArgs, args[0:i]...) + explodedArgs = append(explodedArgs, args[i]) } else { comparisons = append(comparisons, rangeComparison) + explodedArgs = append(explodedArgs, args[i]) } } if includeEquals { comparison, err := BuildEqualsComparison(columns, values) if err != nil { - return "", nil + return "", explodedArgs, nil } comparisons = append(comparisons, comparison) + explodedArgs = append(explodedArgs, args...) } result = strings.Join(comparisons, " or ") result = fmt.Sprintf("(%s)", result) - return result, nil + return result, explodedArgs, nil } -func BuildRangePreparedComparison(columns []string, comparisonSign ValueComparisonSign) (result string, err error) { +func BuildRangePreparedComparison(columns []string, args []interface{}, comparisonSign ValueComparisonSign) (result string, explodedArgs []interface{}, err error) { values := make([]string, len(columns), len(columns)) for i := range columns { values[i] = "?" } - return BuildRangeComparison(columns, values, comparisonSign) + return BuildRangeComparison(columns, values, args, comparisonSign) } -func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, uniqueKey string, uniqueKeyColumns, rangeStartValues, rangeEndValues []string, includeRangeStartValues bool) (string, error) { +func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, uniqueKey string, uniqueKeyColumns, rangeStartValues, rangeEndValues []string, rangeStartArgs, rangeEndArgs []interface{}, includeRangeStartValues bool) (result string, explodedArgs []interface{}, err error) { if len(sharedColumns) == 0 { - return "", fmt.Errorf("Got 0 shared columns in BuildRangeInsertQuery") + return "", explodedArgs, fmt.Errorf("Got 0 shared columns in BuildRangeInsertQuery") } databaseName = EscapeName(databaseName) originalTableName = EscapeName(originalTableName) @@ -138,15 +145,17 @@ func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName strin if includeRangeStartValues { minRangeComparisonSign = GreaterThanOrEqualsComparisonSign } - rangeStartComparison, err := BuildRangeComparison(uniqueKeyColumns, rangeStartValues, minRangeComparisonSign) + rangeStartComparison, rangeExplodedArgs, err := BuildRangeComparison(uniqueKeyColumns, rangeStartValues, rangeStartArgs, minRangeComparisonSign) if err != nil { - return "", err + return "", explodedArgs, err } - rangeEndComparison, err := BuildRangeComparison(uniqueKeyColumns, rangeEndValues, LessThanOrEqualsComparisonSign) + explodedArgs = append(explodedArgs, rangeExplodedArgs...) + rangeEndComparison, rangeExplodedArgs, err := BuildRangeComparison(uniqueKeyColumns, rangeEndValues, rangeEndArgs, LessThanOrEqualsComparisonSign) if err != nil { - return "", err + return "", explodedArgs, err } - query := fmt.Sprintf(` + explodedArgs = append(explodedArgs, rangeExplodedArgs...) + result = fmt.Sprintf(` insert /* gh-osc %s.%s */ ignore into %s.%s (%s) (select %s from %s.%s force index (%s) where (%s and %s) @@ -154,34 +163,37 @@ func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName strin `, databaseName, originalTableName, databaseName, ghostTableName, sharedColumnsListing, sharedColumnsListing, databaseName, originalTableName, uniqueKey, rangeStartComparison, rangeEndComparison) - return query, nil + return result, explodedArgs, nil } -func BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, uniqueKey string, uniqueKeyColumns []string, includeRangeStartValues bool) (string, error) { +func BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, uniqueKey string, uniqueKeyColumns []string, rangeStartArgs, rangeEndArgs []interface{}, includeRangeStartValues bool) (result string, explodedArgs []interface{}, err error) { rangeStartValues := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns)) rangeEndValues := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns)) for i := range uniqueKeyColumns { rangeStartValues[i] = "?" rangeEndValues[i] = "?" } - return BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, includeRangeStartValues) + return BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, includeRangeStartValues) } -func BuildUniqueKeyRangeEndPreparedQuery(databaseName, tableName string, uniqueKeyColumns []string, chunkSize int) (string, error) { +func BuildUniqueKeyRangeEndPreparedQuery(databaseName, tableName string, uniqueKeyColumns []string, rangeStartArgs, rangeEndArgs []interface{}, chunkSize int, hint string) (result string, explodedArgs []interface{}, err error) { if len(uniqueKeyColumns) == 0 { - return "", fmt.Errorf("Got 0 columns in BuildUniqueKeyRangeEndPreparedQuery") + return "", explodedArgs, fmt.Errorf("Got 0 columns in BuildUniqueKeyRangeEndPreparedQuery") } databaseName = EscapeName(databaseName) tableName = EscapeName(tableName) - rangeStartComparison, err := BuildRangePreparedComparison(uniqueKeyColumns, GreaterThanComparisonSign) + rangeStartComparison, rangeExplodedArgs, err := BuildRangePreparedComparison(uniqueKeyColumns, rangeStartArgs, GreaterThanComparisonSign) if err != nil { - return "", err + return "", explodedArgs, err } - rangeEndComparison, err := BuildRangePreparedComparison(uniqueKeyColumns, LessThanOrEqualsComparisonSign) + explodedArgs = append(explodedArgs, rangeExplodedArgs...) + rangeEndComparison, rangeExplodedArgs, err := BuildRangePreparedComparison(uniqueKeyColumns, rangeEndArgs, LessThanOrEqualsComparisonSign) if err != nil { - return "", err + return "", explodedArgs, err } + explodedArgs = append(explodedArgs, rangeExplodedArgs...) + uniqueKeyColumnAscending := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns)) uniqueKeyColumnDescending := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns)) for i := range uniqueKeyColumns { @@ -189,8 +201,8 @@ func BuildUniqueKeyRangeEndPreparedQuery(databaseName, tableName string, uniqueK uniqueKeyColumnAscending[i] = fmt.Sprintf("%s asc", uniqueKeyColumns[i]) uniqueKeyColumnDescending[i] = fmt.Sprintf("%s desc", uniqueKeyColumns[i]) } - query := fmt.Sprintf(` - select /* gh-osc %s.%s */ %s + result = fmt.Sprintf(` + select /* gh-osc %s.%s %s */ %s from ( select %s @@ -204,13 +216,13 @@ func BuildUniqueKeyRangeEndPreparedQuery(databaseName, tableName string, uniqueK order by %s limit 1 - `, databaseName, tableName, strings.Join(uniqueKeyColumns, ", "), + `, databaseName, tableName, hint, strings.Join(uniqueKeyColumns, ", "), strings.Join(uniqueKeyColumns, ", "), databaseName, tableName, rangeStartComparison, rangeEndComparison, strings.Join(uniqueKeyColumnAscending, ", "), chunkSize, strings.Join(uniqueKeyColumnDescending, ", "), ) - return query, nil + return result, explodedArgs, nil } func BuildUniqueKeyMinValuesPreparedQuery(databaseName, tableName string, uniqueKeyColumns []string) (string, error) { diff --git a/go/sql/builder_test.go b/go/sql/builder_test.go index ec114c4..b101bbf 100644 --- a/go/sql/builder_test.go +++ b/go/sql/builder_test.go @@ -8,6 +8,7 @@ package sql import ( "testing" + "reflect" "regexp" "strings" @@ -71,48 +72,60 @@ func TestBuildRangeComparison(t *testing.T) { { columns := []string{"c1"} values := []string{"@v1"} - comparison, err := BuildRangeComparison(columns, values, LessThanComparisonSign) + args := []interface{}{3} + comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanComparisonSign) test.S(t).ExpectNil(err) test.S(t).ExpectEquals(comparison, "((`c1` < @v1))") + test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3})) } { columns := []string{"c1"} values := []string{"@v1"} - comparison, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign) + args := []interface{}{3} + comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign) test.S(t).ExpectNil(err) test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or ((`c1` = @v1)))") + test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3})) } { columns := []string{"c1", "c2"} values := []string{"@v1", "@v2"} - comparison, err := BuildRangeComparison(columns, values, LessThanComparisonSign) + args := []interface{}{3, 17} + comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanComparisonSign) test.S(t).ExpectNil(err) test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or (((`c1` = @v1)) AND (`c2` < @v2)))") + test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17})) } { columns := []string{"c1", "c2"} values := []string{"@v1", "@v2"} - comparison, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign) + args := []interface{}{3, 17} + comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign) test.S(t).ExpectNil(err) test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or (((`c1` = @v1)) AND (`c2` < @v2)) or ((`c1` = @v1) and (`c2` = @v2)))") + test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17})) } { columns := []string{"c1", "c2", "c3"} values := []string{"@v1", "@v2", "@v3"} - comparison, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign) + args := []interface{}{3, 17, 22} + comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign) test.S(t).ExpectNil(err) test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or (((`c1` = @v1)) AND (`c2` < @v2)) or (((`c1` = @v1) and (`c2` = @v2)) AND (`c3` < @v3)) or ((`c1` = @v1) and (`c2` = @v2) and (`c3` = @v3)))") + test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 22, 3, 17, 22})) } { columns := []string{"c1"} values := []string{"@v1", "@v2"} - _, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign) + args := []interface{}{3, 17} + _, _, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign) test.S(t).ExpectNotNil(err) } { columns := []string{} values := []string{} - _, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign) + args := []interface{}{} + _, _, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign) test.S(t).ExpectNotNil(err) } } @@ -127,8 +140,10 @@ func TestBuildRangeInsertQuery(t *testing.T) { uniqueKeyColumns := []string{"id"} rangeStartValues := []string{"@v1s"} rangeEndValues := []string{"@v1e"} + rangeStartArgs := []interface{}{3} + rangeEndArgs := []interface{}{103} - query, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, true) + query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true) test.S(t).ExpectNil(err) expected := ` insert /* gh-osc mydb.tbl */ ignore into mydb.ghost (id, name, position) @@ -137,14 +152,17 @@ func TestBuildRangeInsertQuery(t *testing.T) { ) ` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 103, 103})) } { uniqueKey := "name_position_uidx" uniqueKeyColumns := []string{"name", "position"} rangeStartValues := []string{"@v1s", "@v2s"} rangeEndValues := []string{"@v1e", "@v2e"} + rangeStartArgs := []interface{}{3, 17} + rangeEndArgs := []interface{}{103, 117} - query, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, true) + query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true) test.S(t).ExpectNil(err) expected := ` insert /* gh-osc mydb.tbl */ ignore into mydb.ghost (id, name, position) @@ -153,6 +171,7 @@ func TestBuildRangeInsertQuery(t *testing.T) { ) ` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 103, 103, 117, 103, 117})) } } @@ -164,8 +183,10 @@ func TestBuildRangeInsertPreparedQuery(t *testing.T) { { uniqueKey := "name_position_uidx" uniqueKeyColumns := []string{"name", "position"} + rangeStartArgs := []interface{}{3, 17} + rangeEndArgs := []interface{}{103, 117} - query, err := BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, true) + query, explodedArgs, err := BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartArgs, rangeEndArgs, true) test.S(t).ExpectNil(err) expected := ` insert /* gh-osc mydb.tbl */ ignore into mydb.ghost (id, name, position) @@ -174,6 +195,7 @@ func TestBuildRangeInsertPreparedQuery(t *testing.T) { ) ` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 103, 103, 117, 103, 117})) } } @@ -183,11 +205,13 @@ func TestBuildUniqueKeyRangeEndPreparedQuery(t *testing.T) { chunkSize := 500 { uniqueKeyColumns := []string{"name", "position"} + rangeStartArgs := []interface{}{3, 17} + rangeEndArgs := []interface{}{103, 117} - query, err := BuildUniqueKeyRangeEndPreparedQuery(databaseName, originalTableName, uniqueKeyColumns, chunkSize) + query, explodedArgs, err := BuildUniqueKeyRangeEndPreparedQuery(databaseName, originalTableName, uniqueKeyColumns, rangeStartArgs, rangeEndArgs, chunkSize, "test") test.S(t).ExpectNil(err) expected := ` - select /* gh-osc mydb.tbl */ name, position + select /* gh-osc mydb.tbl test */ name, position from ( select name, position @@ -203,6 +227,7 @@ func TestBuildUniqueKeyRangeEndPreparedQuery(t *testing.T) { limit 1 ` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) + test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 103, 103, 117, 103, 117})) } } diff --git a/go/sql/types.go b/go/sql/types.go index 9ff719c..69a68ee 100644 --- a/go/sql/types.go +++ b/go/sql/types.go @@ -65,18 +65,14 @@ func (this *ColumnValues) AbstractValues() []interface{} { return this.abstractValues } -func (this *ColumnValues) BinaryValues() [][]uint8 { - result := make([][]uint8, len(this.abstractValues), len(this.abstractValues)) - for i, val := range this.abstractValues { - result[i] = val.([]uint8) - } - return result -} - func (this *ColumnValues) String() string { stringValues := []string{} - for _, val := range this.BinaryValues() { - stringValues = append(stringValues, string(val)) + for _, val := range this.AbstractValues() { + if ints, ok := val.([]uint8); ok { + stringValues = append(stringValues, string(ints)) + } else { + stringValues = append(stringValues, fmt.Sprintf("%+v", val)) + } } return strings.Join(stringValues, ",") }