Skip to content

Commit

Permalink
fix & test driver.Valuer interface for sql
Browse files Browse the repository at this point in the history
  • Loading branch information
4el0ve4ek committed Dec 13, 2024
1 parent 9a4b4f8 commit b451a8b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
18 changes: 13 additions & 5 deletions internal/bind/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ func toType(v interface{}) (_ types.Type, err error) { //nolint:funlen

//nolint:gocyclo,funlen
func toValue(v interface{}) (_ value.Value, err error) {
if valuer, ok := v.(driver.Valuer); ok {
v, err = valuer.Value()
if err != nil {
return nil, fmt.Errorf("ydb: driver.Valuer error: %w", err)
}
}

if x, ok := asUUID(v); ok {
return x, nil
}
Expand Down Expand Up @@ -337,16 +344,17 @@ func supportNewTypeLink(x interface{}) string {
}

func toYdbParam(name string, value interface{}) (*params.Parameter, error) {
if na, ok := value.(driver.NamedValue); ok {
n, v := na.Name, na.Value
switch tv := value.(type) {
case driver.NamedValue:
n, v := tv.Name, tv.Value
if n != "" {
name = n
}
value = v
case *params.Parameter:
return tv, nil
}
if v, ok := value.(*params.Parameter); ok {
return v, nil
}

v, err := toValue(value)
if err != nil {
return nil, xerrors.WithStackTrace(err)
Expand Down
38 changes: 38 additions & 0 deletions tests/integration/database_sql_regression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package integration
import (
"context"
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"math/rand"
Expand Down Expand Up @@ -435,3 +436,40 @@ func TestUUIDSerializationDatabaseSQLIssue1501(t *testing.T) {
require.Equal(t, id.String(), res.String())
})
}

type testValuer struct {
value driver.Value
}

func (v *testValuer) Value() (driver.Value, error) {
return v.value, nil
}

func TestSQLX(t *testing.T) {
// test sqlx

t.Run("named-exec-context", func(t *testing.T) {
// test old behavior - for test way of safe work with data, written with bagged API version
var (
scope = newScope(t)
db = scope.SQLDriver()
)

id := "6E73B41C-4EDE-4D08-9CFB-B7462D9E498B"
v := testValuer{value: id}

row := db.QueryRow(`
DECLARE $val AS String;
SELECT $val as result_s`,
sql.Named("val", v),
)

require.NoError(t, row.Err())

var res string
err := row.Scan(&res)
require.NoError(t, err)

require.Equal(t, id, res)
})
}

0 comments on commit b451a8b

Please sign in to comment.