]> granicus.if.org Git - postgresql/blobdiff - src/backend/access/gist/gistbuild.c
Report progress of CREATE INDEX operations
[postgresql] / src / backend / access / gist / gistbuild.c
index 98ea0cb2d1450e1ed3acde37f4e43f75c0389bc3..6024671989e93cf94bcf095f7d5a71a6bd499958 100644 (file)
@@ -4,7 +4,7 @@
  *       build algorithm for GiST indexes implementation.
  *
  *
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
 
 #include "access/genam.h"
 #include "access/gist_private.h"
+#include "access/gistxlog.h"
+#include "access/tableam.h"
 #include "access/xloginsert.h"
 #include "catalog/index.h"
 #include "miscadmin.h"
-#include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "storage/bufmgr.h"
 #include "storage/smgr.h"
 #include "utils/memutils.h"
@@ -55,6 +57,7 @@ typedef enum
 typedef struct
 {
        Relation        indexrel;
+       Relation        heaprel;
        GISTSTATE  *giststate;
 
        int64           indtuples;              /* number of tuples indexed */
@@ -109,12 +112,9 @@ static BlockNumber gistGetParent(GISTBuildState *buildstate, BlockNumber child);
  * but switches to more efficient buffering build algorithm after a certain
  * number of tuples (unless buffering mode is disabled).
  */
-Datum
-gistbuild(PG_FUNCTION_ARGS)
+IndexBuildResult *
+gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
 {
-       Relation        heap = (Relation) PG_GETARG_POINTER(0);
-       Relation        index = (Relation) PG_GETARG_POINTER(1);
-       IndexInfo  *indexInfo = (IndexInfo *) PG_GETARG_POINTER(2);
        IndexBuildResult *result;
        double          reltuples;
        GISTBuildState buildstate;
@@ -124,6 +124,7 @@ gistbuild(PG_FUNCTION_ARGS)
        int                     fillfactor;
 
        buildstate.indexrel = index;
+       buildstate.heaprel = heap;
        if (index->rd_options)
        {
                /* Get buffering mode from the options string */
@@ -204,8 +205,9 @@ gistbuild(PG_FUNCTION_ARGS)
        /*
         * Do the heap scan.
         */
-       reltuples = IndexBuildHeapScan(heap, index, indexInfo, true,
-                                                                  gistBuildCallback, (void *) &buildstate);
+       reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
+                                                                          gistBuildCallback,
+                                                                          (void *) &buildstate, NULL);
 
        /*
         * If buffering was used, flush out all the tuples that are still in the
@@ -232,7 +234,7 @@ gistbuild(PG_FUNCTION_ARGS)
        result->heap_tuples = reltuples;
        result->index_tuples = (double) buildstate.indtuples;
 
-       PG_RETURN_POINTER(result);
+       return result;
 }
 
 /*
@@ -240,7 +242,7 @@ gistbuild(PG_FUNCTION_ARGS)
  * and "auto" values.
  */
 void
-gistValidateBufferingOption(char *value)
+gistValidateBufferingOption(const char *value)
 {
        if (value == NULL ||
                (strcmp(value, "on") != 0 &&
@@ -250,7 +252,7 @@ gistValidateBufferingOption(char *value)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                 errmsg("invalid value for \"buffering\" option"),
-                         errdetail("Valid values are \"on\", \"off\", and \"auto\".")));
+                                errdetail("Valid values are \"on\", \"off\", and \"auto\".")));
        }
 }
 
@@ -297,10 +299,10 @@ gistInitBuffering(GISTBuildState *buildstate)
        itupMinSize = (Size) MAXALIGN(sizeof(IndexTupleData));
        for (i = 0; i < index->rd_att->natts; i++)
        {
-               if (index->rd_att->attrs[i]->attlen < 0)
+               if (TupleDescAttr(index->rd_att, i)->attlen < 0)
                        itupMinSize += VARHDRSZ;
                else
-                       itupMinSize += index->rd_att->attrs[i]->attlen;
+                       itupMinSize += TupleDescAttr(index->rd_att, i)->attlen;
        }
 
        /* Calculate average and maximal number of index tuples which fit to page */
@@ -454,7 +456,7 @@ calculatePagesPerBuffer(GISTBuildState *buildstate, int levelStep)
 }
 
 /*
- * Per-tuple callback from IndexBuildHeapScan.
+ * Per-tuple callback for table_index_build_scan.
  */
 static void
 gistBuildCallback(Relation index,
@@ -486,7 +488,7 @@ gistBuildCallback(Relation index,
                 * locked, we call gistdoinsert directly.
                 */
                gistdoinsert(index, itup, buildstate->freespace,
-                                        buildstate->giststate);
+                                        buildstate->giststate, buildstate->heaprel);
        }
 
        /* Update tuple count and total size. */
@@ -692,7 +694,8 @@ gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level,
                                                           itup, ntup, oldoffnum, &placed_to_blk,
                                                           InvalidBuffer,
                                                           &splitinfo,
-                                                          false);
+                                                          false,
+                                                          buildstate->heaprel);
 
        /*
         * If this is a root split, update the root path item kept in memory. This
@@ -816,7 +819,7 @@ gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level,
                                                                  downlinks, ndownlinks, downlinkoffnum,
                                                                  InvalidBlockNumber, InvalidOffsetNumber);
 
-               list_free_deep(splitinfo);              /* we don't need this anymore */
+               list_free_deep(splitinfo);      /* we don't need this anymore */
        }
        else
                UnlockReleaseBuffer(buffer);
@@ -1085,7 +1088,7 @@ gistGetMaxLevel(Relation index)
                 * everywhere, so we just pick the first one.
                 */
                itup = (IndexTuple) PageGetItem(page,
-                                                                        PageGetItemId(page, FirstOffsetNumber));
+                                                                               PageGetItemId(page, FirstOffsetNumber));
                blkno = ItemPointerGetBlockNumber(&(itup->t_tid));
                UnlockReleaseBuffer(buffer);
 
@@ -1145,7 +1148,7 @@ gistInitParentMap(GISTBuildState *buildstate)
        buildstate->parentMap = hash_create("gistbuild parent map",
                                                                                1024,
                                                                                &hashCtl,
-                                                                         HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
+                                                                               HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
 }
 
 static void