CopyFrom with null schema gives zero-length delimited identifier error
- Dominant language
- Go
- Stars
- 14.3k
- Forks
- 1.1k
- Avg merge
- 6d 9h
- Merged PRs (30d)
- 11
Description
**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:
```go
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:
```go
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!
Contributor guide
Research direction
Start at pgx.Identifier.Sanitize and the CopyFrom path shown in the runnable example. Determine the expected handling of an empty schema component, then add regression coverage for the two-part identifier case and confirm CopyFrom no longer produces the zero-length delimited identifier error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, postgresql
- Domain
- database
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100