diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index fedaed533b..1a22966211 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1258,6 +1258,10 @@ CREATE VIEW pg_stat_progress_copy AS WHEN 3 THEN 'PIPE' WHEN 4 THEN 'CALLBACK' END AS "type", + CASE S.param7 WHEN 0 THEN 'IN PROG' + WHEN 1 THEN 'ERR' + WHEN 2 THEN 'PASS' + END AS 'status', S.param1 AS bytes_processed, S.param2 AS bytes_total, S.param3 AS tuples_processed, diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c index 35a1d3a774..e0427e6e2f 100644 --- a/src/backend/commands/copyfrom.c +++ b/src/backend/commands/copyfrom.c @@ -116,6 +116,8 @@ CopyFromErrorCallback(void *arg) { CopyFromState cstate = (CopyFromState) arg; + cstate->status = CP_ERROR; + pgstat_progress_update_param(PROGRESS_COPY_STATUS, cstate->status); if (cstate->opts.binary) { /* can't usefully display the data */ diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index fca29a9a10..e64ff44273 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -97,6 +97,7 @@ typedef struct CopyToStateData FmgrInfo *out_functions; /* lookup info for output functions */ MemoryContext rowcontext; /* per-row evaluation context */ uint64 bytes_processed; /* number of bytes processed so far */ + int status; /* See PROGRESS_COPY_STATUS */ } CopyToStateData; /* DestReceiver for COPY (query) TO */ @@ -329,6 +330,9 @@ EndCopy(CopyToState cstate) } pgstat_progress_end_command(); + if (!cstate->status) + cstate->status = CP_SUCCESS; + pgstat_progress_update_param(PROGRESS_COPY_STATUS, cstate->status); MemoryContextDelete(cstate->copycontext); pfree(cstate); @@ -655,6 +659,7 @@ BeginCopyTo(ParseState *pstate, cstate->encoding_embeds_ascii = PG_ENCODING_IS_CLIENT_ONLY(cstate->file_encoding); cstate->copy_dest = COPY_FILE; /* default */ + cstate->status = CP_IN_PROG; if (pipe) { diff --git a/src/backend/utils/activity/backend_progress.c b/src/backend/utils/activity/backend_progress.c index f29199725b..eda27f2393 100644 --- a/src/backend/utils/activity/backend_progress.c +++ b/src/backend/utils/activity/backend_progress.c @@ -107,6 +107,7 @@ pgstat_progress_end_command(void) PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); beentry->st_progress_command = PROGRESS_COMMAND_INVALID; - beentry->st_progress_command_target = InvalidOid; + // We keep beentry->st_progress_command_target so that user can query copy progress + // after the COPY command finishes. PGSTAT_END_WRITE_ACTIVITY(beentry); } diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 893690dad5..1cfc86a6dc 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -503,10 +503,9 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) beentry = &local_beentry->backendStatus; /* - * Report values for only those backends which are running the given - * command. + * Report values for only those backends which are running or have run. */ - if (!beentry || beentry->st_progress_command != cmdtype) + if (!beentry || beentry->st_progress_command_target == InvalidOid) continue; /* Value available to all callers */ diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h index 3df1c5a97c..63f1281d84 100644 --- a/src/include/commands/copyfrom_internal.h +++ b/src/include/commands/copyfrom_internal.h @@ -164,6 +164,7 @@ typedef struct CopyFromStateData #define RAW_BUF_BYTES(cstate) ((cstate)->raw_buf_len - (cstate)->raw_buf_index) uint64 bytes_processed; /* number of bytes processed so far */ + int status; /* See PROGRESS_COPY_STATUS */ } CopyFromStateData; extern void ReceiveCopyBegin(CopyFromState cstate); diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h index a28938caf4..39ea358e42 100644 --- a/src/include/commands/progress.h +++ b/src/include/commands/progress.h @@ -140,6 +140,14 @@ #define PROGRESS_COPY_TUPLES_EXCLUDED 3 #define PROGRESS_COPY_COMMAND 4 #define PROGRESS_COPY_TYPE 5 +#define PROGRESS_COPY_STATUS 6 // See progress_type below + +enum progress_type +{ + CP_IN_PROG, + CP_ERROR, + CP_SUCCESS +}; /* Commands of COPY (as advertised via PROGRESS_COPY_COMMAND) */ #define PROGRESS_COPY_COMMAND_FROM 1