`pgx.Conn.Query()` behavior for JSON string value of "null" returns incorrect value
- Dominant language
- Go
- Stars
- 14.3k
- Forks
- 1.1k
- Avg merge
- 6d 9h
- Merged PRs (30d)
- 11
Description
This query incorrectly returns a nil value when using the `pgx.Conn.Query()` method:
```sql
select 'null'::json;
```
This response is the JSON string literal value "null", not the JSON null literal. The JSON codec is incorrectly parsing this response into a nil value.
Here's a simple repro:
```go
package main
import (
"context"
"fmt"
"log"
"github.com/jackc/pgx/v5"
)
func main() {
// Adjust connection string as needed
connStr := "postgres://postgres:postgres@localhost:5432/postgres"
conn, err := pgx.Connect(context.Background(), connStr)
if err != nil {
log.Fatal("connect error:", err)
}
defer conn.Close(context.Background())
rows, err := conn.Query(context.Background(), `select 'null'::json;`)
if err != nil {
log.Fatal("query error:", err)
}
var rowSlice []any
for rows.Next() {
row, err := rows.Values()
if err != nil {
log.Fatal("query error:", err)
}
rowSlice = append(rowSlice, row)
}
fmt.Println("Result:", rowSlice)
}
```
Prints:
```
Result: [[]]
```
This works correctly using the QueryRow() and Scan() interfaces directly with a string scan target, like this:
```go
var result string
err = conn.QueryRow(context.Background(), `select 'null'::json;`).Scan(&result)
```
Also works correctly with the vanilla postgres connector:
```go
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
func main() {
connStr := "host=localhost port=5432 user=postgres password=postgres dbname=postgres sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()
var result string
err = db.QueryRow(`select 'null'::json;`).Scan(&result)
if err != nil {
log.Fatal(err)
}
fmt.Println("Result:", result)
}
```
Prints:
```
Result: null
```
**Version**
- Go: go version go1.25.3 darwin/arm64
- PostgreSQL: PostgreSQL 18.0 (Homebrew) on aarch64-apple-darwin24.4.0, compiled by Apple clang version 17.0.0 (clang-1700.0.13.3), 64-bit
- pgx: v5.6.1-0.20240826124046-97d20ccfadaa
Contributor guide
Research direction
Start by tracing the JSON codec used by pgx.Conn.Query() and compare its behavior with QueryRow().Scan() for `select 'null'::json;`. Add or update coverage for JSON string `"null"` versus the JSON null literal, and verify that Query() returns the string value rather than nil while JSON null remains nil.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, postgresql
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100