-
Notifications
You must be signed in to change notification settings - Fork 828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pgtype.ArrayCodec should support non-comma delimiter #2086
Comments
This seems like a good idea to me. Not sure on whether this configuration should go on Either way, the |
Good point about err := pool.AcquireFunc(ctx, func(conn *pgxpool.Conn) error {
formats := []struct{code int16; name string}{
{code: pgx.BinaryFormatCode, name: "binary"},
{code: pgx.TextFormatCode, name: "text"},
}
for _, format := range formats {
rows, err := conn.Query(ctx, "WITH g(g) AS (VALUES('((1,1),(2,2))'::box)) SELECT array[array[g,g],array[g,g]] FROM g", pgx.QueryResultFormats{format.code})
if err != nil {
return err
}
for rows.Next() {
var dst [][]pgtype.Box
if err := rows.Scan(&dst); err != nil {
return fmt.Errorf("format=%v: failed to scan: %w", format.name, err)
}
fmt.Printf("format=%v: row: %T %v\n", format.name, dst, dst)
}
}
return nil
})
fmt.Printf("AcquireFunc error: %v\n", err)
(On my system, it is just |
Is your feature request related to a problem? Please describe.
For many Postgres types, array elements are separated by commas:
However, some types use a different delimiter. In particular, PostGIS
geometry
andgeography
types use a colon as the delimiter:(Note that, in this multidimensional array, the delimiter separates both the base elements and the constituent 1D arrays.)
This is controlled by the
DELIMITER
option toCREATE TYPE
: see, e.g.,CREATE TYPE geometry (..., delimiter = ':')
.I am using twpayne/pgx-geom to encode and decode my PostGIS values with pgx. So far, this only supports scalars. I see that pgtype's
ArrayCodec
should make it nice and easy to support arrays, too, and indeed the obvious approach works out of the box for the binary format, but for the text format it fails with "can't scan into dest[0]: encoding/hex: invalid byte: U+003A ':'". This is becauseArrayCodec
gives the whole0107...:0107...
string to the element codec, even though that represents two values.Describe the solution you'd like
Perhaps
pgtype.Type
could have a new public field likeDelimiter string
, such that the empty string (default) means "use comma as delimiter" but any other string would be used as the delimiter instead. Then,ArrayCodec
could read this value from theElementType *pgtype.Type
to encode and decode. If I understand correctly, this should be a backward-compatible change.Describe alternatives you've considered
Alternately, the
Delimiter
field could exist on theArrayCodec
itself. In some ways, that seems more natural, since it affects only the array parsing, but it would deviate from Postgres's ontology, where (quoting the sameCREATE TYPE
docs) "the delimiter is associated with the array element type, not the array type itself".I have of course also considered hand-rolling the parsers and encoders. It's not too bad, but I'd probably end up with a weird half-and-half solution using the
ArrayCodec
implementation for the binary format but a custom implementation for the text format. Workable, but certainly a shame when all that's needed is a single character to be handled differently!Additional context
None comes to mind.
The text was updated successfully, but these errors were encountered: