pgx
pgx copied to clipboard
CopyFrom with null schema gives zero-length delimited identifier error
Describe the bug Turns out it's a minor thing but tripped me up for a bit. If you send a null schema into pgx.Identifier like so:
copyCount, err := dstConn.CopyFrom(ctx, pgx.Identifier{"", "dstTable"}, columnNames, pgx.CopyFromRows(filteredRows[0:1]))
then Identifier.Sanitize()
will return "\"\".\"dst_table\""
and you'll end up with the error: "zero-length delimited identifier at or near \"\"\"\""
Identifier.Sanitize()
should probably check for parts[0] == ""
Maybe it should also ensure len(parts) <= 2
To Reproduce Runnable example:
package main
import (
"context"
"log"
"os"
"github.com/jackc/pgx/v5"
)
// Sample code to demonstrate the bug
//
// Returns:
// (base) ➜ copyfrombug gor .
// 2024/01/11 12:00:29 copyCount 1
// 2024/01/11 12:00:29 copyfrom errstatement description failed: ERROR: zero-length delimited identifier at or near """" (SQLSTATE 42601)
// exit status 1
func main() {
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer conn.Close(context.Background())
_, err = conn.Exec(context.Background(), "DROP TABLE IF EXISTS copyfrombug")
if err != nil {
log.Fatal("drop table", err)
}
_, err = conn.Exec(context.Background(), "CREATE TABLE copyfrombug(id serial primary key, name text)")
if err != nil {
log.Fatal(err)
}
// WORKS
inputRows := [][]any{
{int16(1), "abc"},
}
// IDENT IS JUST THE TABLE NAME
ident := pgx.Identifier{"copyfrombug"}
copyCount, err := conn.CopyFrom(context.Background(), ident, []string{"id", "name"}, pgx.CopyFromRows(inputRows))
if err != nil {
log.Fatal("copyfrom err", err)
}
log.Println("copyCount", copyCount)
// DOES NOT WORK
inputRows = [][]any{
{int16(2), "def"},
}
// IDENT IS THE SCHEMA(null) AND TABLE NAME
// statement description failed: ERROR: zero-length delimited identifier at or near """" (SQLSTATE 42601)
ident = pgx.Identifier{"", "copyfrombug"}
copyCount, err = conn.CopyFrom(context.Background(), ident, []string{"id", "name"}, pgx.CopyFromRows(inputRows))
if err != nil {
log.Fatal("copyfrom err", err)
}
log.Println("copyCount", copyCount)
}
Version go 1.21.6 pgx 5.4.3
Additional Thanks for the great library!
Identifier.Sanitize() should probably check for parts[0] == ""
Maybe it should also ensure len(parts) <= 2
Sanitize
doesn't return an error so there is really nothing that can be done about length. As far as checking for ""
, again there is no error return. I suppose ""
could be filtered out. Not sure if that would just be hiding an application bug though.
Maybe just a note in the docs could suffice.