Skip to content

Commit 4c1308c

Browse files
committed
Revert "stdlib matches native pgx scanning support"
This reverts commit f6980e4. The enabling change was reverted from Go. It was determined that a different interface could not only provide the new functionality, but also improve performance. refs: #2403
1 parent 14ce2b7 commit 4c1308c

File tree

5 files changed

+39
-263
lines changed

5 files changed

+39
-263
lines changed

pgtype/pgtype.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,8 +1980,6 @@ func (m *Map) Encode(oid uint32, formatCode int16, value any, buf []byte) (newBu
19801980
//
19811981
// This uses the type of v to look up the PostgreSQL OID that v presumably came from. This means v must be registered
19821982
// with m by calling RegisterDefaultPgType.
1983-
//
1984-
// As of Go 1.26, this should be unnecessary.
19851983
func (m *Map) SQLScanner(v any) sql.Scanner {
19861984
if s, ok := v.(sql.Scanner); ok {
19871985
return s

stdlib/bench_test.go

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"strings"
99
"testing"
1010
"time"
11-
12-
"github.com/jackc/pgx/v5/pgtype"
1311
)
1412

1513
func getSelectRowsCounts(b *testing.B) []int64 {
@@ -109,48 +107,3 @@ func BenchmarkSelectRowsScanNull(b *testing.B) {
109107
})
110108
}
111109
}
112-
113-
func BenchmarkFlatArrayEncodeArgument(b *testing.B) {
114-
db := openDB(b)
115-
defer closeDB(b, db)
116-
117-
input := make(pgtype.FlatArray[string], 10)
118-
for i := range input {
119-
input[i] = fmt.Sprintf("String %d", i)
120-
}
121-
122-
for b.Loop() {
123-
var n int64
124-
err := db.QueryRow("select cardinality($1::text[])", input).Scan(&n)
125-
if err != nil {
126-
b.Fatal(err)
127-
}
128-
if n != int64(len(input)) {
129-
b.Fatalf("Expected %d, got %d", len(input), n)
130-
}
131-
}
132-
}
133-
134-
func BenchmarkFlatArrayScanResult(b *testing.B) {
135-
db := openDB(b)
136-
defer closeDB(b, db)
137-
138-
var input string
139-
for i := range 10 {
140-
if i > 0 {
141-
input += ","
142-
}
143-
input += fmt.Sprintf(`'String %d'`, i)
144-
}
145-
146-
for b.Loop() {
147-
var result pgtype.FlatArray[string]
148-
err := db.QueryRow(fmt.Sprintf("select array[%s]::text[]", input)).Scan(&result)
149-
if err != nil {
150-
b.Fatal(err)
151-
}
152-
if len(result) != 10 {
153-
b.Fatalf("Expected %d, got %d", len(result), 10)
154-
}
155-
}
156-
}

stdlib/sql.go

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,12 @@
5757
//
5858
// # PostgreSQL Specific Data Types
5959
//
60-
// As of Go 1.26 the database/sql allows drivers to implement their own scanning logic by implementing the
61-
// driver.RowsColumnScanner interface. This allows PostgreSQL arrays to be scanned directly into Go slices.
62-
//
63-
// var a []int64
64-
// err := db.QueryRow("select '{1,2,3}'::bigint[]").Scan(&a)
65-
//
66-
// In older versions of Go, *pgtype.Map.SQLScanner can be used as an adapter that makes these types usable as a
67-
// sql.Scanner.
60+
// The pgtype package provides support for PostgreSQL specific types. *pgtype.Map.SQLScanner is an adapter that makes
61+
// these types usable as a sql.Scanner.
6862
//
6963
// m := pgtype.NewMap()
7064
// var a []int64
7165
// err := db.QueryRow("select '{1,2,3}'::bigint[]").Scan(m.SQLScanner(&a))
72-
//
73-
// The pgtype package provides support for PostgreSQL specific types. These types can be used directly in Go 1.26 and
74-
// with *pgtype.Map.SQLScanner in older Go versions.
75-
//
76-
// var r pgtype.Range[pgtype.Int4]
77-
// err := db.QueryRow("select int4range(1, 5)").Scan(&r)
7866
package stdlib
7967

8068
import (
@@ -903,12 +891,6 @@ func convertNamedArguments(args []any, argsV []driver.NamedValue) {
903891
}
904892
}
905893

906-
func (r *Rows) ScanColumn(dest any, index int) error {
907-
m := r.conn.conn.TypeMap()
908-
fd := r.rows.FieldDescriptions()[index]
909-
return m.Scan(fd.DataTypeOID, fd.Format, r.rows.RawValues()[index], dest)
910-
}
911-
912894
type wrapTx struct {
913895
ctx context.Context
914896
tx pgx.Tx

stdlib/sql_go1.26_test.go

Lines changed: 0 additions & 168 deletions
This file was deleted.

stdlib/sql_test.go

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -110,32 +110,6 @@ func testWithAllQueryExecModes(t *testing.T, f func(t *testing.T, db *sql.DB)) {
110110
}
111111
}
112112

113-
func testWithKnownOIDQueryExecModes(t *testing.T, f func(t *testing.T, db *sql.DB)) {
114-
for _, mode := range []pgx.QueryExecMode{
115-
pgx.QueryExecModeCacheStatement,
116-
pgx.QueryExecModeCacheDescribe,
117-
pgx.QueryExecModeDescribeExec,
118-
} {
119-
t.Run(mode.String(),
120-
func(t *testing.T) {
121-
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
122-
require.NoError(t, err)
123-
124-
config.DefaultQueryExecMode = mode
125-
db := stdlib.OpenDB(*config)
126-
defer func() {
127-
err := db.Close()
128-
require.NoError(t, err)
129-
}()
130-
131-
f(t, db)
132-
133-
ensureDBValid(t, db)
134-
},
135-
)
136-
}
137-
}
138-
139113
// Do a simple query to ensure the DB is still usable. This is of less use in stdlib as the connection pool should
140114
// cover broken connections.
141115
func ensureDBValid(t testing.TB, db *sql.DB) {
@@ -537,6 +511,43 @@ func TestConnQueryScanGoArray(t *testing.T) {
537511
})
538512
}
539513

514+
func TestConnQueryScanArray(t *testing.T) {
515+
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
516+
m := pgtype.NewMap()
517+
518+
var a pgtype.Array[int64]
519+
err := db.QueryRow("select '{1,2,3}'::bigint[]").Scan(m.SQLScanner(&a))
520+
require.NoError(t, err)
521+
assert.Equal(t, pgtype.Array[int64]{Elements: []int64{1, 2, 3}, Dims: []pgtype.ArrayDimension{{Length: 3, LowerBound: 1}}, Valid: true}, a)
522+
523+
err = db.QueryRow("select null::bigint[]").Scan(m.SQLScanner(&a))
524+
require.NoError(t, err)
525+
assert.Equal(t, pgtype.Array[int64]{Elements: nil, Dims: nil, Valid: false}, a)
526+
})
527+
}
528+
529+
func TestConnQueryScanRange(t *testing.T) {
530+
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
531+
skipCockroachDB(t, db, "Server does not support int4range")
532+
533+
m := pgtype.NewMap()
534+
535+
var r pgtype.Range[pgtype.Int4]
536+
err := db.QueryRow("select int4range(1, 5)").Scan(m.SQLScanner(&r))
537+
require.NoError(t, err)
538+
assert.Equal(
539+
t,
540+
pgtype.Range[pgtype.Int4]{
541+
Lower: pgtype.Int4{Int32: 1, Valid: true},
542+
Upper: pgtype.Int4{Int32: 5, Valid: true},
543+
LowerType: pgtype.Inclusive,
544+
UpperType: pgtype.Exclusive,
545+
Valid: true,
546+
},
547+
r)
548+
})
549+
}
550+
540551
// Test type that pgx would handle natively in binary, but since it is not a
541552
// database/sql native type should be passed through as a string
542553
func TestConnQueryRowPgxBinary(t *testing.T) {

0 commit comments

Comments
 (0)