Hi Alvaro and Amit!

On 2019/11/29 9:54, Tatsuro Yamada wrote:
Hi Alvaro!

Hmmm... I understand your opinion but I'd like to get more opinions too. :)
Do you prefer these column names? See below:

Here's my take on it:

  <Columns of the view>
   pid
   datid
   datname
   relid
   phase
   sample_blks_total
   sample_blks_scanned
   ext_stats_total
   ext_stats_computed
   child_tables_total
   child_tables_done
   current_child_table_relid

It seems to make sense to keep using the "child table" terminology in
that last column; but since the column carries an OID then as Robert
said it should have "relid" in the name.  For the other two "child
tables" columns, not using "relid" is appropriate because what they have
is not relids.

I think there should be an obvious correspondence in columns that are
closely related, which there isn't if you use "sample" in one and "heap"
in the other, so I'd go for "sample" in both.


Thanks for the comment.
Oops, You are right, I overlooked they are not relids..
I agreed with you and Amit's opinion so I'll send a revised patch on the next 
mail. :-)

Next patch will be included:
  - New columns definition of the view (as above)
  - Renamed the phase name: s/acquiring inh sample rows/acquiring inherited 
sample rows/
  - Update document

Attached patch is the revised patch. :)

I wonder two things below. What do you think?

1)
For now, I'm not sure it should be set current_child_table_relid to zero
when the current phase is changed from "acquiring inherited sample rows" to
"computing stats". See <Test result> bellow.

2)
There are many "finalizing analyze" phases based on relids in the case
of partitioning tables. Would it better to fix the document? or it
would be better to reduce it to one?

<Document>
---------------------------------------------------------
     <entry><literal>finalizing analyze</literal></entry>
     <entry>
       The command is updating pg_class. When this phase is completed,
       <command>ANALYZE</command> will end.
---------------------------------------------------------


<New columns of the view>
---------------------------------------------------------
# \d pg_stat_progress_analyze
              View "pg_catalog.pg_stat_progress_analyze"
          Column           |  Type   | Collation | Nullable | Default
---------------------------+---------+-----------+----------+---------
 pid                       | integer |           |          |
 datid                     | oid     |           |          |
 datname                   | name    |           |          |
 relid                     | oid     |           |          |
 phase                     | text    |           |          |
 sample_blks_total         | bigint  |           |          |
 sample_blks_scanned       | bigint  |           |          |
 ext_stats_total           | bigint  |           |          |
 ext_stats_computed        | bigint  |           |          |
 child_tables_total        | bigint  |           |          |
 child_tables_done         | bigint  |           |          |
 current_child_table_relid | oid     |           |          |
---------------------------------------------------------



<Test result using partitioning tables>
---------------------------------------------------------
# select * from pg_stat_progress_analyze ; \watch 0.0001

19309|13583|postgres|36081|acquiring inherited sample rows|0|0|0|0|0|0|0
19309|13583|postgres|36081|acquiring inherited sample rows|45|17|0|0|4|0|36084
19309|13583|postgres|36081|acquiring inherited sample rows|45|35|0|0|4|0|36084
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|0|36084
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|0|36084
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|0|36084
19309|13583|postgres|36081|acquiring inherited sample rows|45|3|0|0|4|1|36087
19309|13583|postgres|36081|acquiring inherited sample rows|45|22|0|0|4|1|36087
19309|13583|postgres|36081|acquiring inherited sample rows|45|38|0|0|4|1|36087
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|1|36087
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|1|36087
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|1|36087
19309|13583|postgres|36081|acquiring inherited sample rows|45|16|0|0|4|2|36090
19309|13583|postgres|36081|acquiring inherited sample rows|45|34|0|0|4|2|36090
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|2|36090
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|2|36090
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|2|36090
19309|13583|postgres|36081|acquiring inherited sample rows|45|10|0|0|4|3|36093
19309|13583|postgres|36081|acquiring inherited sample rows|45|29|0|0|4|3|36093
19309|13583|postgres|36081|acquiring inherited sample rows|45|43|0|0|4|3|36093
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|3|36093
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|3|36093
19309|13583|postgres|36081|acquiring inherited sample rows|45|45|0|0|4|3|36093
19309|13583|postgres|36081|computing stats|45|45|0|0|4|4|36093    <== 
current_*_reid should be zero?
19309|13583|postgres|36081|computing stats|45|45|0|0|4|4|36093
19309|13583|postgres|36081|finalizing analyze|45|45|0|0|4|4|36093 <== there are 
many finalizing phases
19309|13583|postgres|36081|finalizing analyze|45|45|0|0|4|4|36093
19309|13583|postgres|36084|acquiring sample rows|45|3|0|0|0|0|0
19309|13583|postgres|36084|acquiring sample rows|45|33|0|0|0|0|0
19309|13583|postgres|36084|computing stats|45|45|0|0|0|0|0
19309|13583|postgres|36087|acquiring sample rows|45|15|0|0|0|0|0
19309|13583|postgres|36087|computing stats|45|45|0|0|0|0|0
19309|13583|postgres|36087|finalizing analyze|45|45|0|0|0|0|0     <== same as 
above
19309|13583|postgres|36090|acquiring sample rows|45|11|0|0|0|0|0
19309|13583|postgres|36090|acquiring sample rows|45|41|0|0|0|0|0
19309|13583|postgres|36090|finalizing analyze|45|45|0|0|0|0|0     <== same as 
above
19309|13583|postgres|36093|acquiring sample rows|45|7|0|0|0|0|0
19309|13583|postgres|36093|acquiring sample rows|45|37|0|0|0|0|0
19309|13583|postgres|36093|finalizing analyze|45|45|0|0|0|0|0     <== same as 
above
---------------------------------------------------------

Thanks,
Tatsuro Yamada

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index a3c5f86b7e..9564fad294 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -360,6 +360,14 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   
11:34   0:00 postgres: ser
       </entry>
      </row>
 
+     <row>
+      
<entry><structname>pg_stat_progress_analyze</structname><indexterm><primary>pg_stat_progress_analyze</primary></indexterm></entry>
+      <entry>One row for each backend (including autovacuum worker processes) 
running
+       <command>ANALYZE</command>, showing current progress.
+       See <xref linkend='analyze-progress-reporting'/>.
+      </entry>
+     </row>
+
      <row>
       
<entry><structname>pg_stat_progress_cluster</structname><indexterm><primary>pg_stat_progress_cluster</primary></indexterm></entry>
       <entry>One row for each backend running
@@ -3502,7 +3510,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
    <productname>PostgreSQL</productname> has the ability to report the 
progress of
    certain commands during command execution.  Currently, the only commands
    which support progress reporting are <command>CREATE INDEX</command>,
-   <command>VACUUM</command> and
+   <command>VACUUM</command>, <command>ANALYZE</command> and
    <command>CLUSTER</command>. This may be expanded in the future.
   </para>
 
@@ -3948,6 +3956,164 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
 
  </sect2>
 
+ <sect2 id="analyze-progress-reporting">
+  <title>ANALYZE Progress Reporting</title>
+
+  <para>
+   Whenever <command>ANALYZE</command> is running, the
+   <structname>pg_stat_progress_analyze</structname> view will contain a
+   row for each backend that is currently running that command.  The tables
+   below describe the information that will be reported and provide
+   information about how to interpret it.
+  </para>
+
+  <table id="pg-stat-progress-analyze-view" 
xreflabel="pg_stat_progress_analyze">
+   <title><structname>pg_stat_progress_analyze</structname> View</title>
+   <tgroup cols="3">
+    <thead>
+    <row>
+      <entry>Column</entry>
+      <entry>Type</entry>
+      <entry>Description</entry>
+     </row>
+    </thead>
+
+   <tbody>
+    <row>
+     <entry><structfield>pid</structfield></entry>
+     <entry><type>integer</type></entry>
+     <entry>Process ID of backend.</entry>
+    </row>
+    <row>
+     <entry><structfield>datid</structfield></entry>
+     <entry><type>oid</type></entry>
+     <entry>OID of the database to which this backend is connected.</entry>
+    </row>
+    <row>
+     <entry><structfield>datname</structfield></entry>
+     <entry><type>name</type></entry>
+     <entry>Name of the database to which this backend is connected.</entry>
+    </row>
+    <row>
+     <entry><structfield>relid</structfield></entry>
+     <entry><type>oid</type></entry>
+     <entry>OID of the table being analyzed.</entry>
+    </row>
+    <row>
+     <entry><structfield>phase</structfield></entry>
+     <entry><type>text</type></entry>
+     <entry>Current processing phase. See <xref linkend="analyze-phases" 
/></entry>
+    </row>
+    <row>
+     <entry><structfield>sample_blks_total</structfield></entry>
+     <entry><type>bigint</type></entry>
+     <entry>
+       Total number of heap blocks that will be sampled.
+     </entry>
+    </row>
+    <row>
+     <entry><structfield>sample_blks_scanned</structfield></entry>
+     <entry><type>bigint</type></entry>
+     <entry>
+       Number of heap blocks scanned.
+     </entry>
+    </row>
+    <row>
+     <entry><structfield>ext_stats_total</structfield></entry>
+     <entry><type>bigint</type></entry>
+     <entry>
+       Number of extended stats.
+     </entry>
+    </row>
+    <row>
+     <entry><structfield>ext_stats_computed</structfield></entry>
+     <entry><type>bigint</type></entry>
+     <entry>
+       Number of computed extended stats.  This counter only advances when the 
phase
+       is <literal>computing extended stats</literal>.
+     </entry>
+    </row>
+    <row>
+     <entry><structfield>child_tables_total</structfield></entry>
+     <entry><type>bigint</type></entry>
+     <entry>
+       Number of child tables.
+     </entry>
+    </row>
+    <row>
+     <entry><structfield>child_tables_done</structfield></entry>
+     <entry><type>bigint</type></entry>
+     <entry>
+       Number of analyzed child tables.  This counter only advances when the 
phase
+       is <literal>computing extended stats</literal>.
+     </entry>
+    </row>
+    <row>
+     <entry><structfield>current_child_table_relid</structfield></entry>
+     <entry><type>oid</type></entry>
+     <entry>OID of the child table currently being scanned.
+       It might be different from relid when analyzing tables that have child 
tables.
+     </entry>
+    </row>
+   </tbody>
+   </tgroup>
+  </table>
+
+  <table id="analyze-phases">
+   <title>ANALYZE phases</title>
+   <tgroup cols="2">
+    <thead>
+    <row>
+      <entry>Phase</entry>
+      <entry>Description</entry>
+     </row>
+    </thead>
+   <tbody>
+    <row>
+     <entry><literal>initializing</literal></entry>
+     <entry>
+       The command is preparing to begin scanning the heap.  This phase is
+       expected to be very brief.
+     </entry>
+    </row>
+    <row>
+     <entry><literal>acquiring sample rows</literal></entry>
+     <entry>
+       The command is currently scanning the 
<structfield>current_relid</structfield>
+       to obtain samples.
+     </entry>
+    </row>
+    <row>
+     <entry><literal>acquiring inherited sample rows</literal></entry>
+     <entry>
+       The command is currently scanning the 
<structfield>current_child_table_relid</structfield>
+       to obtain samples.
+     </entry>
+    </row>
+    <row>
+     <entry><literal>computing stats</literal></entry>
+     <entry>
+       The command is computing stats from the samples obtained during the 
table scan.
+     </entry>
+    </row>
+    <row>
+     <entry><literal>computing extended stats</literal></entry>
+     <entry>
+       The command is computing extended stats from the samples obtained in 
the previous phase.
+     </entry>
+    </row>
+    <row>
+     <entry><literal>finalizing analyze</literal></entry>
+     <entry>
+       The command is updating pg_class. When this phase is completed, 
+       <command>ANALYZE</command> will end.
+     </entry>
+    </row>
+   </tbody>
+   </tgroup>
+  </table>
+ </sect2>
+
  <sect2 id="cluster-progress-reporting">
   <title>CLUSTER Progress Reporting</title>
 
diff --git a/src/backend/catalog/system_views.sql 
b/src/backend/catalog/system_views.sql
index f7800f01a6..afe45e0737 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -969,6 +969,27 @@ CREATE VIEW pg_stat_progress_vacuum AS
     FROM pg_stat_get_progress_info('VACUUM') AS S
         LEFT JOIN pg_database D ON S.datid = D.oid;
 
+CREATE VIEW pg_stat_progress_analyze AS
+    SELECT
+        S.pid AS pid, S.datid AS datid, D.datname AS datname,
+        CAST(S.relid AS oid) AS relid,
+        CASE S.param1 WHEN 0 THEN 'initializing'
+                      WHEN 1 THEN 'acquiring sample rows'
+                      WHEN 2 THEN 'acquiring inherited sample rows'
+                      WHEN 3 THEN 'computing stats'
+                      WHEN 4 THEN 'computing extended stats'
+                      WHEN 5 THEN 'finalizing analyze'
+                      END AS phase,
+        S.param2 AS sample_blks_total,
+               S.param3 AS sample_blks_scanned,
+        S.param4 AS ext_stats_total,
+        S.param5 AS ext_stats_computed,
+        S.param6 AS child_tables_total,
+        S.param7 AS child_tables_done,
+        CAST(S.param8 AS oid) AS current_child_table_relid
+    FROM pg_stat_get_progress_info('ANALYZE') AS S
+        LEFT JOIN pg_database D ON S.datid = D.oid;
+
 CREATE VIEW pg_stat_progress_cluster AS
     SELECT
         S.pid AS pid,
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 71372ceb16..1be98e7cb3 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -35,6 +35,7 @@
 #include "catalog/pg_namespace.h"
 #include "catalog/pg_statistic_ext.h"
 #include "commands/dbcommands.h"
+#include "commands/progress.h"
 #include "commands/tablecmds.h"
 #include "commands/vacuum.h"
 #include "executor/executor.h"
@@ -251,6 +252,8 @@ analyze_rel(Oid relid, RangeVar *relation,
        LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
        MyPgXact->vacuumFlags |= PROC_IN_ANALYZE;
        LWLockRelease(ProcArrayLock);
+       pgstat_progress_start_command(PROGRESS_COMMAND_ANALYZE,
+                                                                 
RelationGetRelid(onerel));
 
        /*
         * Do the normal non-recursive ANALYZE.  We can skip this for 
partitioned
@@ -275,6 +278,8 @@ analyze_rel(Oid relid, RangeVar *relation,
         */
        relation_close(onerel, NoLock);
 
+       pgstat_progress_end_command();
+
        /*
         * Reset my PGXACT flag.  Note: we need this here, and not in 
vacuum_rel,
         * because the vacuum flag is cleared by the end-of-xact code.
@@ -507,13 +512,23 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
         */
        rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple));
        if (inh)
+       {
+               pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE,
+                                                                        
PROGRESS_ANALYZE_PHASE_ACQUIRE_INHERITED_SAMPLE_ROWS);
+
                numrows = acquire_inherited_sample_rows(onerel, elevel,
                                                                                
                rows, targrows,
                                                                                
                &totalrows, &totaldeadrows);
+       }
        else
+       {
+               pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE,
+                                                                        
PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS);
+
                numrows = (*acquirefunc) (onerel, elevel,
                                                                  rows, 
targrows,
                                                                  &totalrows, 
&totaldeadrows);
+       }
 
        /*
         * Compute the statistics.  Temporary results during the calculations 
for
@@ -524,7 +539,10 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
        if (numrows > 0)
        {
                MemoryContext col_context,
-                                       old_context;
+                                         old_context;
+
+               pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE,
+                                                                        
PROGRESS_ANALYZE_PHASE_COMPUTE_STATS);
 
                col_context = AllocSetContextCreate(anl_context,
                                                                                
        "Analyze Column",
@@ -592,10 +610,17 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
                 * not for relations representing inheritance trees.
                 */
                if (!inh)
+               {
+                       pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE,
+                                                                               
 PROGRESS_ANALYZE_PHASE_COMPUTE_EXT_STATS);
                        BuildRelationExtStatistics(onerel, totalrows, numrows, 
rows,
                                                                           
attr_cnt, vacattrstats);
+               }
        }
 
+       pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE,
+                                                                
PROGRESS_ANALYZE_PHASE_FINALIZE_ANALYZE);
+
        /*
         * Update pages/tuples stats in pg_class ... but not if we're doing
         * inherited stats.
@@ -1034,6 +1059,8 @@ acquire_sample_rows(Relation onerel, int elevel,
        ReservoirStateData rstate;
        TupleTableSlot *slot;
        TableScanDesc scan;
+       BlockNumber     nblocks;
+       BlockNumber     blksdone = 0;
 
        Assert(targrows > 0);
 
@@ -1043,7 +1070,12 @@ acquire_sample_rows(Relation onerel, int elevel,
        OldestXmin = GetOldestXmin(onerel, PROCARRAY_FLAGS_VACUUM);
 
        /* Prepare for sampling block numbers */
-       BlockSampler_Init(&bs, totalblocks, targrows, random());
+       nblocks = BlockSampler_Init(&bs, totalblocks, targrows, random());
+
+       /* Report sampling block numbers */
+       pgstat_progress_update_param(PROGRESS_ANALYZE_BLOCKS_TOTAL,
+                                                                nblocks);
+
        /* Prepare for sampling rows */
        reservoir_init_selection_state(&rstate, targrows);
 
@@ -1104,6 +1136,9 @@ acquire_sample_rows(Relation onerel, int elevel,
 
                        samplerows += 1;
                }
+
+               pgstat_progress_update_param(PROGRESS_ANALYZE_BLOCKS_DONE,
+                                                                        
++blksdone);
        }
 
        ExecDropSingleTupleTableSlot(slot);
@@ -1332,6 +1367,8 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
         * rels have radically different free-space percentages, but it's not
         * clear that it's worth working harder.)
         */
+       pgstat_progress_update_param(PROGRESS_ANALYZE_CHILD_TABLES_TOTAL,
+                                                                nrels);
        numrows = 0;
        *totalrows = 0;
        *totaldeadrows = 0;
@@ -1341,6 +1378,9 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
                AcquireSampleRowsFunc acquirefunc = acquirefuncs[i];
                double          childblocks = relblocks[i];
 
+               
pgstat_progress_update_param(PROGRESS_ANALYZE_CURRENT_CHILD_TABLE_RELID,
+                                                                        
RelationGetRelid(childrel));
+
                if (childblocks > 0)
                {
                        int                     childtargrows;
@@ -1396,6 +1436,8 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
                 * pointers to their TOAST tables in the sampled rows.
                 */
                table_close(childrel, NoLock);
+               pgstat_progress_update_param(PROGRESS_ANALYZE_CHILD_TABLES_DONE,
+                                                                        i + 1);
        }
 
        return numrows;
diff --git a/src/backend/statistics/extended_stats.c 
b/src/backend/statistics/extended_stats.c
index 9d339433f6..5bbdf6d820 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -24,10 +24,12 @@
 #include "catalog/pg_collation.h"
 #include "catalog/pg_statistic_ext.h"
 #include "catalog/pg_statistic_ext_data.h"
+#include "commands/progress.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/optimizer.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "statistics/extended_stats_internal.h"
 #include "statistics/statistics.h"
@@ -92,6 +94,7 @@ BuildRelationExtStatistics(Relation onerel, double totalrows,
        List       *stats;
        MemoryContext cxt;
        MemoryContext oldcxt;
+       int64           ext_cnt;
 
        cxt = AllocSetContextCreate(CurrentMemoryContext,
                                                                
"BuildRelationExtStatistics",
@@ -101,6 +104,11 @@ BuildRelationExtStatistics(Relation onerel, double 
totalrows,
        pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock);
        stats = fetch_statentries_for_relation(pg_stext, 
RelationGetRelid(onerel));
 
+       /* for reporting progress */
+       pgstat_progress_update_param(PROGRESS_ANALYZE_EXT_STATS_TOTAL,
+                                                                
list_length(stats));
+
+       ext_cnt = 0;
        foreach(lc, stats)
        {
                StatExtEntry *stat = (StatExtEntry *) lfirst(lc);
@@ -165,6 +173,10 @@ BuildRelationExtStatistics(Relation onerel, double 
totalrows,
 
                /* store the statistics in the catalog */
                statext_store(stat->statOid, ndistinct, dependencies, mcv, 
stats);
+
+               /* for reporting progress */
+               
pgstat_progress_update_param(PROGRESS_ANALYZE_EXT_STATS_COMPUTED,
+                                                                        
++ext_cnt);
        }
 
        table_close(pg_stext, RowExclusiveLock);
diff --git a/src/backend/utils/adt/pgstatfuncs.c 
b/src/backend/utils/adt/pgstatfuncs.c
index 05240bfd14..db2cc5c316 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -469,6 +469,8 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
        /* Translate command name into command type code. */
        if (pg_strcasecmp(cmd, "VACUUM") == 0)
                cmdtype = PROGRESS_COMMAND_VACUUM;
+       else if (pg_strcasecmp(cmd, "ANALYZE") == 0)
+               cmdtype = PROGRESS_COMMAND_ANALYZE;
        else if (pg_strcasecmp(cmd, "CLUSTER") == 0)
                cmdtype = PROGRESS_COMMAND_CLUSTER;
        else if (pg_strcasecmp(cmd, "CREATE INDEX") == 0)
diff --git a/src/backend/utils/misc/sampling.c 
b/src/backend/utils/misc/sampling.c
index d2a1537979..f7daece5ee 100644
--- a/src/backend/utils/misc/sampling.c
+++ b/src/backend/utils/misc/sampling.c
@@ -32,8 +32,10 @@
  * Since we know the total number of blocks in advance, we can use the
  * straightforward Algorithm S from Knuth 3.4.2, rather than Vitter's
  * algorithm.
+ *
+ * Returns the number of blocks that BlockSampler_Next will return.
  */
-void
+BlockNumber
 BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, int samplesize,
                                  long randseed)
 {
@@ -48,6 +50,8 @@ BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, int 
samplesize,
        bs->m = 0;                                      /* blocks selected so 
far */
 
        sampler_random_init_state(randseed, bs->randstate);
+
+       return Min(bs->n, bs->N);
 }
 
 bool
diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h
index acd1313cb3..c29c1e00fc 100644
--- a/src/include/commands/progress.h
+++ b/src/include/commands/progress.h
@@ -34,6 +34,23 @@
 #define PROGRESS_VACUUM_PHASE_TRUNCATE                 5
 #define PROGRESS_VACUUM_PHASE_FINAL_CLEANUP            6
 
+/* Progress parameters for analyze */
+#define PROGRESS_ANALYZE_PHASE                                         0
+#define PROGRESS_ANALYZE_BLOCKS_TOTAL                          1
+#define PROGRESS_ANALYZE_BLOCKS_DONE                           2
+#define PROGRESS_ANALYZE_EXT_STATS_TOTAL                       3
+#define PROGRESS_ANALYZE_EXT_STATS_COMPUTED                    4
+#define PROGRESS_ANALYZE_CHILD_TABLES_TOTAL                    5
+#define PROGRESS_ANALYZE_CHILD_TABLES_DONE                     6
+#define PROGRESS_ANALYZE_CURRENT_CHILD_TABLE_RELID     7
+
+/* Phases of analyze (as advertised via PROGRESS_ANALYZE_PHASE) */
+#define PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS                             
1
+#define PROGRESS_ANALYZE_PHASE_ACQUIRE_INHERITED_SAMPLE_ROWS   2
+#define PROGRESS_ANALYZE_PHASE_COMPUTE_STATS                                   
3
+#define PROGRESS_ANALYZE_PHASE_COMPUTE_EXT_STATS                               
4
+#define PROGRESS_ANALYZE_PHASE_FINALIZE_ANALYZE                                
        5
+
 /* Progress parameters for cluster */
 #define PROGRESS_CLUSTER_COMMAND                               0
 #define PROGRESS_CLUSTER_PHASE                                 1
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index fe076d823d..df418af4e7 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -955,6 +955,7 @@ typedef enum ProgressCommandType
 {
        PROGRESS_COMMAND_INVALID,
        PROGRESS_COMMAND_VACUUM,
+       PROGRESS_COMMAND_ANALYZE,
        PROGRESS_COMMAND_CLUSTER,
        PROGRESS_COMMAND_CREATE_INDEX
 } ProgressCommandType;
diff --git a/src/include/utils/sampling.h b/src/include/utils/sampling.h
index 541b507fb5..76d31dc126 100644
--- a/src/include/utils/sampling.h
+++ b/src/include/utils/sampling.h
@@ -37,7 +37,7 @@ typedef struct
 
 typedef BlockSamplerData *BlockSampler;
 
-extern void BlockSampler_Init(BlockSampler bs, BlockNumber nblocks,
+extern BlockNumber BlockSampler_Init(BlockSampler bs, BlockNumber nblocks,
                                                          int samplesize, long 
randseed);
 extern bool BlockSampler_HasMore(BlockSampler bs);
 extern BlockNumber BlockSampler_Next(BlockSampler bs);
diff --git a/src/test/regress/expected/rules.out 
b/src/test/regress/expected/rules.out
index c9cc569404..af5e27fe6c 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1847,6 +1847,28 @@ pg_stat_gssapi| SELECT s.pid,
     s.gss_enc AS encrypted
    FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, 
application_name, state, query, wait_event_type, wait_event, xact_start, 
query_start, backend_start, state_change, client_addr, client_hostname, 
client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, 
sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, 
ssl_issuer_dn, gss_auth, gss_princ, gss_enc)
   WHERE (s.client_port IS NOT NULL);
+pg_stat_progress_analyze| SELECT s.pid,
+    s.datid,
+    d.datname,
+    s.relid,
+        CASE s.param1
+            WHEN 0 THEN 'initializing'::text
+            WHEN 1 THEN 'acquiring sample rows'::text
+            WHEN 2 THEN 'acquiring inherited sample rows'::text
+            WHEN 3 THEN 'computing stats'::text
+            WHEN 4 THEN 'computing extended stats'::text
+            WHEN 5 THEN 'finalizing analyze'::text
+            ELSE NULL::text
+        END AS phase,
+    s.param2 AS sample_blks_total,
+    s.param3 AS sample_blks_scanned,
+    s.param4 AS ext_stats_total,
+    s.param5 AS ext_stats_computed,
+    s.param6 AS child_tables_total,
+    s.param7 AS child_tables_done,
+    (s.param8)::oid AS current_child_table_relid
+   FROM (pg_stat_get_progress_info('ANALYZE'::text) s(pid, datid, relid, 
param1, param2, param3, param4, param5, param6, param7, param8, param9, 
param10, param11, param12, param13, param14, param15, param16, param17, 
param18, param19, param20)
+     LEFT JOIN pg_database d ON ((s.datid = d.oid)));
 pg_stat_progress_cluster| SELECT s.pid,
     s.datid,
     d.datname,

Reply via email to