jackc / pgx

PostgreSQL driver and toolkit for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.