DBD::Pg has async support for queries (pg_async/PG_ASYNC) and async COPY TO (pg_getcopydata_async), but COPY FROM is unconditionally blocking. pg_putcopydata blocks inside PQputCopyData when the TCP send buffer fills because PQsetnonblocking is never called.
This prevents async Perl libraries (Future::IO-based, EV::Pg-style, IO::Async) from performing non-blocking bulk data loading. COPY is the standard PostgreSQL mechanism for bulk import and is dramatically faster than multi-row INSERT.
Proposed API
Three new methods mirroring the existing pg_getcopydata_async pattern:
pg_putcopydata_async — non-blocking pg_putcopydata. Returns 1 (queued), 0 (buffer full, retry), -1 (error).
pg_putcopyend_async — non-blocking pg_putcopyend. Polls for server result without blocking. Returns 1 (done), 0 (not ready, poll), -1 (error).
pg_flush — exposes PQflush for output buffer management. Returns 0 (flushed), 1 (pending, poll), -1 (error).
Return values match libpq conventions exactly. After pg_putcopydata_async returns 1, the caller calls pg_flush to push data to the server — the standard PQputCopyData + PQflush pattern.
Implementation notes
PQsetnonblocking is scoped to COPY state only (safe since no other operations are permitted during COPY)
- Blocking mode restored automatically when
pg_putcopyend_async completes
- Zero impact on existing blocking
pg_putcopydata behavior
PR: #176
DBD::Pg has async support for queries (
pg_async/PG_ASYNC) and async COPY TO (pg_getcopydata_async), but COPY FROM is unconditionally blocking.pg_putcopydatablocks insidePQputCopyDatawhen the TCP send buffer fills becausePQsetnonblockingis never called.This prevents async Perl libraries (Future::IO-based, EV::Pg-style, IO::Async) from performing non-blocking bulk data loading. COPY is the standard PostgreSQL mechanism for bulk import and is dramatically faster than multi-row INSERT.
Proposed API
Three new methods mirroring the existing
pg_getcopydata_asyncpattern:pg_putcopydata_async— non-blockingpg_putcopydata. Returns1(queued),0(buffer full, retry),-1(error).pg_putcopyend_async— non-blockingpg_putcopyend. Polls for server result without blocking. Returns1(done),0(not ready, poll),-1(error).pg_flush— exposesPQflushfor output buffer management. Returns0(flushed),1(pending, poll),-1(error).Return values match libpq conventions exactly. After
pg_putcopydata_asyncreturns 1, the caller callspg_flushto push data to the server — the standardPQputCopyData+PQflushpattern.Implementation notes
PQsetnonblockingis scoped to COPY state only (safe since no other operations are permitted during COPY)pg_putcopyend_asynccompletespg_putcopydatabehaviorPR: #176