Change in behavior v4->v5 on inserting nil slices
alexgo84 opened this issue · comments
Upon upgrading from pgx v4 to v5, I've noticed several breaking changes in behavior. Not sure which behavior is correct (new or old), but I wanted to understand if this is a conscious decision or a side effect and how is it best mitigated.
The change in behavior is that while previouslly we could insert nil slice values into non nullable columns (resulting in using the default value for that column), now Exec
returns an error:
ERROR: null value in column <column_name> of relation <table_name> violates not-null constraint (SQLSTATE 23502)
I'm adding a test that captures the change in behavior. The first test uses pgx v4 and passes, while the second uses pgx v5 and fails:
package main
import (
"context"
"os"
"testing"
pgxv4 "github.com/jackc/pgx/v4"
pgxv5 "github.com/jackc/pgx/v5"
)
const createTableQuery = `CREATE TABLE test_table (
id bigint not null generated always as identity primary key,
created timestamptz not null default current_timestamp,
value jsonb not null default '[]'::jsonb
);`
// this test uses pgx v4 and passes without error
func TestEmptySliceInExecV4(t *testing.T) {
connString := os.Getenv("DB_CONNECTION_STRING")
db, err := pgxv4.Connect(context.Background(), dsn)
if err != nil {
t.Fatal(err)
}
defer db.Close(context.Background())
txn, err := db.Begin(context.Background())
if err != nil {
t.Fatal(err)
}
defer txn.Rollback(context.Background())
_, err = txn.Exec(context.Background(), createTableQuery)
if err != nil {
t.Fatal(err)
}
var slc []string
_, err = txn.Exec(context.Background(), "INSERT INTO test_table (value) VALUES ($1)", slc)
if err != nil {
t.Fatal(err.Error())
}
}
// this test uses pgx v5 and produces the following error from Exec:
// ERROR: null value in column "value" of relation "test_table" violates not-null constraint (SQLSTATE 23502)
func TestEmptySliceInExecV5(t *testing.T) {
connString := os.Getenv("DB_CONNECTION_STRING")
db, err := pgxv5.Connect(context.Background(), dsn)
if err != nil {
t.Fatal(err)
}
defer db.Close(context.Background())
txn, err := db.Begin(context.Background())
if err != nil {
t.Fatal(err)
}
defer txn.Rollback(context.Background())
_, err = txn.Exec(context.Background(), createTableQuery)
if err != nil {
t.Fatal(err)
}
var slc []string
_, err = txn.Exec(context.Background(), "INSERT INTO test_table (value) VALUES ($1)", slc)
if err != nil {
t.Fatal(err.Error())
}
}
I suspect this also happens with nil maps.
This might be related to #1566. If so I guess we can close this issue.
Correct. I believe this is the same issue as #1566.