Skip to content

Commit 381d253

Browse files
authored
Add support for NamedValueChecker interface (#1125)
Added in 1.9: https://go.dev/doc/go1.9#minor_library_changes.
1 parent 3bc0bdf commit 381d253

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

conn_go19.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//go:build go1.9
2+
// +build go1.9
3+
4+
package pq
5+
6+
import (
7+
"database/sql/driver"
8+
"reflect"
9+
)
10+
11+
var _ driver.NamedValueChecker = (*conn)(nil)
12+
13+
func (c *conn) CheckNamedValue(nv *driver.NamedValue) error {
14+
if _, ok := nv.Value.(driver.Valuer); ok {
15+
// Ignore Valuer, for backward compatibility with pq.Array().
16+
return driver.ErrSkip
17+
}
18+
19+
// Ignoring []byte / []uint8.
20+
if _, ok := nv.Value.([]uint8); ok {
21+
return driver.ErrSkip
22+
}
23+
24+
v := reflect.ValueOf(nv.Value)
25+
if v.Kind() == reflect.Ptr {
26+
v = v.Elem()
27+
}
28+
if v.Kind() == reflect.Slice {
29+
var err error
30+
nv.Value, err = Array(v.Interface()).Value()
31+
return err
32+
}
33+
34+
return driver.ErrSkip
35+
}

conn_go19_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//go:build go1.9
2+
// +build go1.9
3+
4+
package pq
5+
6+
import (
7+
"fmt"
8+
"reflect"
9+
"testing"
10+
)
11+
12+
func TestArrayArg(t *testing.T) {
13+
db := openTestConn(t)
14+
defer db.Close()
15+
16+
for _, tc := range []struct {
17+
pgType string
18+
in, out interface{}
19+
}{
20+
{
21+
pgType: "int[]",
22+
in: []int{245, 231},
23+
out: []int64{245, 231},
24+
},
25+
{
26+
pgType: "int[]",
27+
in: &[]int{245, 231},
28+
out: []int64{245, 231},
29+
},
30+
{
31+
pgType: "int[]",
32+
in: []int64{245, 231},
33+
},
34+
{
35+
pgType: "int[]",
36+
in: &[]int64{245, 231},
37+
out: []int64{245, 231},
38+
},
39+
{
40+
pgType: "varchar[]",
41+
in: []string{"hello", "world"},
42+
},
43+
{
44+
pgType: "varchar[]",
45+
in: &[]string{"hello", "world"},
46+
out: []string{"hello", "world"},
47+
},
48+
} {
49+
if tc.out == nil {
50+
tc.out = tc.in
51+
}
52+
t.Run(fmt.Sprintf("%#v", tc.in), func(t *testing.T) {
53+
r, err := db.Query(fmt.Sprintf("SELECT $1::%s", tc.pgType), tc.in)
54+
if err != nil {
55+
t.Fatal(err)
56+
}
57+
defer r.Close()
58+
59+
if !r.Next() {
60+
if r.Err() != nil {
61+
t.Fatal(r.Err())
62+
}
63+
t.Fatal("expected row")
64+
}
65+
66+
defer func() {
67+
if r.Next() {
68+
t.Fatal("unexpected row")
69+
}
70+
}()
71+
72+
got := reflect.New(reflect.TypeOf(tc.out))
73+
if err := r.Scan(Array(got.Interface())); err != nil {
74+
t.Fatal(err)
75+
}
76+
77+
if !reflect.DeepEqual(tc.out, got.Elem().Interface()) {
78+
t.Errorf("got %v, want %v", got, tc.out)
79+
}
80+
})
81+
}
82+
83+
}

0 commit comments

Comments
 (0)