Commit Graph

392 Commits (5f28621394af52c69a814fc9d00b6a96b6ba0266)

Author SHA1 Message Date
Klaus c542df4fb4 added MarshalJSON and UnmarshalJSON to timestamp and added their tests (based on timestamptz implementation) 2023-06-12 09:52:49 -05:00
Evan Jones 4d643b75f5 pgtype/hstore_test.go: Extend coverage of scan benchmark
I am working on an application that reads a lot of hstore values, and
have discovered that scanning it is fairly slow. I'm working on some
improvements, but first I wanted a better benchmark. This adds more
realistic data, and extends it to cover the three APIs: database/sql,
and pgconn.Rows.Scan with both text and binary protocols.
2023-06-12 09:17:24 -05:00
Evan Jones 1b68b5970e pgtype/hstore: Save 2 allocs in database/sql Scan implementation
Remove unneeded string to []byte to string conversion, which saves 2
allocs and should make Hstore text scanning slightly faster.

The Hstore.Scan() function takes a string as input, converts it to
[]byte, and calls scanPlanTextAnyToHstoreScanner.Scan(). That
function converts []byte back to string and calls parseHstore. This
refactors scanPlanTextAnyToHstoreScanner.Scan into
scanPlanTextAnyToHstoreScanner.scanString so the database/sql Scan
function can call it directly, bypassing this conversion.

The added Benchmark shows this saves 2 allocs for longer strings, and
saves about 5% CPU overall on my M1 Pro. benchstat output:

goos: darwin
goarch: arm64
pkg: github.com/jackc/pgx/v5/pgtype
              │  orig.txt   │              new.txt               │
              │   sec/op    │   sec/op     vs base               │
HstoreScan-10   1.334µ ± 2%   1.257µ ± 2%  -5.77% (p=0.000 n=10)

              │   orig.txt   │               new.txt               │
              │     B/op     │     B/op      vs base               │
HstoreScan-10   2.094Ki ± 0%   1.969Ki ± 0%  -5.97% (p=0.000 n=10)

              │  orig.txt  │              new.txt              │
              │ allocs/op  │ allocs/op   vs base               │
HstoreScan-10   36.00 ± 0%   34.00 ± 0%  -5.56% (p=0.000 n=10)
2023-06-07 15:35:22 -05:00
Evan Jones ee04d4a74d pgtype/hstore: Avoid Postgres Mac OS X parsing bug
Postgres on Mac OS X has a bug in how it parses hstore text values
that causes it to misinterpret some Unicode values as spaces. This
causes values sent by pgx to be misinterpreted. To avoid this, always
quote hstore values, which is how Postgres serializes them itself.
The test change fails on Mac OS X without this fix.

While I suspect this should not be performance critical for any
application, I added a quick benchmark to test the performance of the
encoding. This change actually makes encoding slightly faster on my
M1 Pro. The output from the benchstat program on this banchmark is:

goos: darwin
goarch: arm64
pkg: github.com/jackc/pgx/v5/pgtype
                          │   orig.txt   │           new-quotes.txt            │
                          │    sec/op    │   sec/op     vs base                │
HstoreSerialize/text-10      207.1n ± 0%   142.3n ± 1%  -31.31% (p=0.000 n=10)
HstoreSerialize/binary-10   100.10n ± 0%   99.64n ± 1%   -0.45% (p=0.013 n=10)
geomean                      144.0n        119.1n       -17.31%

I have also attempted to fix the Postgres bug, but it will take a
long time for this fix to get upstream:

https://www.postgresql.org/message-id/CA%2BHWA9awUW0%2BRV_gO9r1ABZwGoZxPztcJxPy8vMFSTbTfi4jig%40mail.gmail.com
2023-06-07 15:29:25 -05:00
Jack Christensen 9f00b6f750 Use context timeouts in more tests
Tests should timeout in a reasonable time if something is stuck. In
particular this is important when testing deadlock conditions such as
can occur with the copy protocol if both the client and the server are
blocked writing until the other side does a read.
2023-05-29 10:25:57 -05:00
Alek Anokhin 70a200cff4 Fix test failures
Add bool type alias conversion in `elemKindToPointerTypes` and `underlyingNumberType`
2023-05-20 08:53:23 -05:00
Wichert Akkerman c1c67e4e58 Fix: correctly handle bool type aliases
https://github.com/jackc/pgx/issue/1593
2023-05-20 08:53:23 -05:00
Evan Jones eab316e200 pgtype.Hstore: Fix quoting of whitespace; Add test
Before this change, the Hstore text protocol did not quote keys or
values containing non-space whitespace ("\r\n\v\t"). This causes
inserts with these values to fail with errors like:

    ERROR: Syntax error near "r" at position 17 (SQLSTATE XX000)

The previous version also quoted curly braces ("{}"), but they don't
seem to require quoting.

It is possible that it would be easier to just always quote the
values, which is what Postgres does when encoding its text protocol,
but this is a smaller change.
2023-05-16 07:02:55 -05:00
Evan Jones 8ceef73b84 pgtype.parseHstore: Reject invalid input; Fix error messages
The parseHstore function did not check the return value from
p.Consume() after a ', ' sequence. It expects a doublequote '"' that
starts the next key, but would accept any character. This means it
accepted invalid input such as:

    "key1"=>"b", ,key2"=>"value"

Add a unit test that covers this case
Fix a couple of the nearby error strings while looking at this.

Found by looking at staticcheck warnings:

    pgtype/hstore.go:434:6: this value of end is never used (SA4006)
    pgtype/hstore.go:434:6: this value of r is never used (SA4006)
2023-05-15 18:10:20 -05:00
Evan Jones bbcc4fc0b8 pgtype/hstore_test.go: Add coverage for text protocol
The existing test registers pgtype.Hstore in the text map, then uses
the query modes that use the binary protocol. The existing test did
not use the text parsing code. Add a version of the test that uses
pgtype.Hstore as the input and output argument in all query modes,
and tests it without registering the codec.
2023-05-15 18:09:31 -05:00
Evan Jones d8b38b28be pgtype/hstore.go: Remove unused quoteHstore{Element,Replacer}
These are unused. The code uses quoteArrayElement instead.
2023-05-13 10:03:22 -05:00
Evan Jones 2a86501e86 Fix hstore NULL versus empty
When running queries with the hstore type registered, and with simple
mode queries, the scan implementation does not correctly distinguish
between NULL and empty. Fix the implementation and add a test to
verify this.
2023-05-13 09:34:30 -05:00
Lev Zakharov c27b9b49ea support different bool string representations 2023-04-27 20:29:41 -05:00
Jack Christensen 67f2a41587 Fix scanning a table type into a struct
Table types have system / hidden columns like tableoid, cmax, xmax, etc.
These are not included when sending or receiving composite types.

https://github.com/jackc/pgx/issues/1576
2023-04-20 20:13:37 -05:00
Simon Paredes 2cf1541bb9 wrap error 2023-04-11 18:07:05 -05:00
Jack Christensen 847f888631 Fix scan array of record to pointer to slice of struct
https://github.com/jackc/pgx/issues/1570
2023-04-08 14:39:48 -05:00
cemre.mengu ca022267db add tests 2023-03-25 10:22:11 -05:00
Cemre Mengu 2a653b4a8d fix: handle null interface for json
When using `scany` I encountered the following case. This seems to fix it.

Looks like null `jsonb` columns cause the problem. If you create a table like below you can see that the following code fails. Is this expected?

```sql
CREATE TABLE test (
	a int4 NULL,
	b int4 NULL,
	c jsonb NULL
);

INSERT INTO test (a, b, c) VALUES (1, null, null);
```

```go
package main

import (
	"context"
	"log"

	"github.com/georgysavva/scany/v2/pgxscan"
	"github.com/jackc/pgx/v5"
)

func main() {
	var rows []map[string]interface{}
	conn, _ := pgx.Connect(context.Background(), , ts.PGURL().String())
	
	// this will fail with can't scan into dest[0]: cannot scan NULL into *interface {}
	err := pgxscan.Select(context.Background(), conn, &rows, `SELECT c from test`) 
	
	// this works
	// err = pgxscan.Select(context.Background(), conn, &rows, `SELECT a,b from test`)
	
	if err != nil {
		panic(err)
	}

	log.Printf("%+v", rows)
}
```
2023-03-25 10:22:11 -05:00
Sergej Brazdeikis 9ae852eb58 Fix typo in error message `uint32` -> `uint16` 2023-03-11 15:34:08 -06:00
Jack Christensen 38e09bda4c Fix *wrapSliceEncodePlan[T].Encode
It should pass a FlatArray[T] to the next step instead of a
anySliceArrayReflect. By using a anySliceArrayReflect, an encode of
[]github.com/google/uuid.UUID followed by []string into a PostgreSQL
uuid[] would crash. This was caused by a EncodePlan cache collision
where the second encoding used part of the cached plan of the first.

In proper usage a cache collision shouldn't be able to occur. If this
assertion proves incorrect it will be necessary to add an optional
interface to ScanPlan and EncodePlan that marks the plan as ineligable
for caching. But I have been unable to construct a failing case, and
given that ScanPlans have been cached for quite some time now without
incident I do not think it is possible. This issue only occurred due to
the bug in *wrapSliceEncodePlan[T].Encode.

https://github.com/jackc/pgx/issues/1502
2023-02-21 21:04:30 -06:00
Jack Christensen 42d327f660 Add text format jsonpath support 2023-02-14 19:52:47 -06:00
Jack Christensen a6ace8969b Fix: Prefer sql.Scanner before TryWrapScanPlanFuncs
This was already the case when the data type was unknown but should also
be the case when it is known.
2023-02-14 09:03:41 -06:00
Jack Christensen 2100a64dbe Fix broken benchmarks 2023-02-10 20:26:18 -06:00
Jack Christensen 4484831550 Prefer binary format for arrays
This improves performance decoding text[].
2023-02-10 20:21:25 -06:00
Jack Christensen 1f43e2e490 Fix text format array decoding with a string of "NULL"
It was incorrectly being treated as NULL instead of 'NULL'.

fixes https://github.com/jackc/pgx/issues/1494
2023-02-10 19:59:03 -06:00
Felix Röhrich a47e836471 make TestPointerPointerStructScan easier to read 2023-02-10 19:06:20 -06:00
Felix Röhrich 5cd8468b99 replace erroneous reflect.New with reflect.Zero in TryWrapStructScanPlan 2023-02-10 19:06:20 -06:00
Jack Christensen c875abea84 Fix encode []any to array
https://github.com/jackc/pgx/issues/1488
2023-02-04 07:28:52 -06:00
Yumin Xia 766d2bba4f add UnmarshalJSON for pgtype Numeric 2023-01-30 21:33:02 -06:00
Jack Christensen 42a47194a2 Memoize encode plans
This significantly reduces memory allocations in paths that repeatedly
encode the same type of values such as CopyFrom.

https://github.com/jackc/pgx/issues/1481
2023-01-27 20:19:06 -06:00
Alexey Palazhchenko f839d501a7 Apply `gofmt -s`
And add CI check for that.
2023-01-24 07:55:00 -06:00
Jack Christensen e48e7a7189 Fix scanning json column into **string
refs https://github.com/jackc/pgx/issues/1470
2023-01-20 18:38:11 -06:00
Mark Chambers c46d792c93 Numeric numberTextBytes() workaround...
This seems a bit of a hack. It fixes the problems demonstrated in my previous commit.

Maybe there's a cleaner way?

Associated: https://github.com/jackc/pgx/issues/1426
2023-01-14 08:42:42 -06:00
Mark Chambers 37c6f97b11 pgtype.Numeric numberTextBytes() encoding bug
Demonstrate the problem with the tests:

...for negative decimal values e.g. -0.01

This causes errors when encoding to JSON:

    "json: error calling MarshalJSON for type pgtype.Numeric"

It also causes scan failures of sql.NullFloat64:

    "converting driver.Value type string ("0.-1") to a float64"

As reported here: https://github.com/jackc/pgx/issues/1426
2023-01-14 08:42:42 -06:00
Jack Christensen d4fcd4a897 Support sql.Scanner on renamed base type
https://github.com/jackc/pgtype/issues/197
2022-12-23 14:22:59 -06:00
Jack Christensen e66ad1bcec Fix encode to json ignoring driver.Valuer
https://github.com/jackc/pgx/issues/1430
2022-12-23 13:44:09 -06:00
Jack Christensen 456a242f5c Unregistered OIDs are handled the same as unknown OIDs
This improves handling of unregistered types. In general, they should
"just work". But there are performance benefits gained and some edge
cases avoided by registering types. Updated documentation to mention
this.

https://github.com/jackc/pgx/issues/1445
2022-12-23 13:14:56 -06:00
Jack Christensen d737852654 Fix: driver.Value representation of bytea should be []byte not string
https://github.com/jackc/pgx/issues/1445
2022-12-21 17:54:42 -06:00
Jack Christensen f42af35884 Add support for single dimensional arrays
https://github.com/jackc/pgx/issues/1442
2022-12-20 20:12:12 -06:00
Mark Chambers 1ce3e0384a pgtype Int fix minimum error message.
Previously on the minimum condition the error would be:

  "is greater than maximum"

Also add encoding/json import into the .erb template as the import was
missing after running rake generate.
2022-12-17 09:10:02 -06:00
Jack Christensen 279c3c0a20 Fix: json values work with sql.Scanner
https://github.com/jackc/pgx/issues/1418
2022-12-06 19:44:55 -06:00
Jack Christensen f0a73424b1 Fix: Scan uint and uint64 ScanNumeric
fixes https://github.com/jackc/pgx/issues/1414
2022-12-05 20:34:46 -06:00
Jack Christensen b265fedd75 Correct error message 2022-11-12 07:06:54 -06:00
Jack Christensen 871f14e43b Fix text decoding of dates with 5 digit years 2022-11-12 07:01:11 -06:00
Jack Christensen 071d1c9467 DateCodec.DecodeValue can return pgtype.InfinityModifier
Previously, an infinite value was returned as a string. Other types
that can be infinite such as Timestamptz return a
pgtype.InfinityModifier. This change brings them into alignment.
2022-11-12 06:27:41 -06:00
Jack Christensen 29109487ec DateCodec.DecodeDatabaseSQLValue returns time.Time when possible
Previously it returned a string. However, this was an unintended
behavior change from pgx v4.

89f69aaea9 (commitcomment-89173737)
2022-11-12 06:21:48 -06:00
Jack Christensen daf570c752 Date text encoding pads year with 0 for at least 4 digits
e.g. 0007-01-02 instead of 7-01-02

89f69aaea9 (commitcomment-89173737)
2022-11-12 06:14:04 -06:00
Jack Christensen 6fabd8f5b1 Fix encoding uint64 larger than math.MaxInt64 into numeric
fixes https://github.com/jackc/pgx/issues/1357
2022-10-29 08:47:12 -05:00
Jack Christensen 48b4807b33 Fix some reflect Kind checks to first check for nil
fixes https://github.com/jackc/pgx/issues/1335
2022-10-22 08:57:49 -05:00
Jack Christensen f2e7c8144d reflect.TypeOf can return nil. Check before using
https://github.com/jackc/pgx/issues/1331
2022-10-12 20:03:51 -05:00