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..19d08556da 100644 --- a/src/backend/commands/copyfrom.c +++ b/src/backend/commands/copyfrom.c @@ -116,6 +116,7 @@ CopyFromErrorCallback(void *arg) { CopyFromState cstate = (CopyFromState) arg; + pgstat_progress_update_param(PROGRESS_COPY_STATUS, CP_ERROR); 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..ebe0fa7b81 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -329,6 +329,7 @@ EndCopy(CopyToState cstate) } pgstat_progress_end_command(); + pgstat_progress_update_param(PROGRESS_COPY_STATUS, CP_SUCCESS); MemoryContextDelete(cstate->copycontext); pfree(cstate); @@ -655,6 +656,7 @@ BeginCopyTo(ParseState *pstate, cstate->encoding_embeds_ascii = PG_ENCODING_IS_CLIENT_ONLY(cstate->file_encoding); cstate->copy_dest = COPY_FILE; /* default */ + pgstat_progress_update_param(PROGRESS_COPY_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..e615021e87 100644 --- a/src/backend/utils/activity/backend_progress.c +++ b/src/backend/utils/activity/backend_progress.c @@ -106,7 +106,13 @@ pgstat_progress_end_command(void) return; PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - beentry->st_progress_command = PROGRESS_COMMAND_INVALID; - beentry->st_progress_command_target = InvalidOid; + if (beentry->st_progress_command == PROGRESS_COMMAND_COPY) + // We want to show the relation for the most recent COPY command + beentry->st_progress_command = PROGRESS_COMMAND_COPY_DONE; + else + { + beentry->st_progress_command = PROGRESS_COMMAND_INVALID; + beentry->st_progress_command_target = InvalidOid; + } PGSTAT_END_WRITE_ACTIVITY(beentry); } diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 893690dad5..89909725f2 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -506,7 +506,9 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) * Report values for only those backends which are running the given * command. */ - if (!beentry || beentry->st_progress_command != cmdtype) + if (!beentry || beentry->st_progress_command != cmdtype && + cmdtype == PROGRESS_COMMAND_COPY && + beentry->st_progress_command != PROGRESS_COMMAND_COPY_DONE) continue; /* Value available to all callers */ 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 diff --git a/src/include/utils/backend_progress.h b/src/include/utils/backend_progress.h index 47bf8029b0..b4eab8e9cb 100644 --- a/src/include/utils/backend_progress.h +++ b/src/include/utils/backend_progress.h @@ -27,7 +27,8 @@ typedef enum ProgressCommandType PROGRESS_COMMAND_CLUSTER, PROGRESS_COMMAND_CREATE_INDEX, PROGRESS_COMMAND_BASEBACKUP, - PROGRESS_COMMAND_COPY + PROGRESS_COMMAND_COPY, + PROGRESS_COMMAND_COPY_DONE } ProgressCommandType; #define PGSTAT_NUM_PROGRESS_PARAM 20