aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/gin/gindatapage.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index 8504f4c7afc..ebdacd40c55 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -753,6 +753,13 @@ ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer, GinVacuumState *gvs)
* *prdata is filled with WAL information about this operation. The caller
* is responsible for inserting to the WAL, along with any other information
* about the operation that triggered this recompression.
+ *
+ * NOTE: The segment pointers can point directly to the same buffer, with
+ * the limitation that any earlier segment must not overlap with an original,
+ * later segment. In other words, some segments may point the original buffer
+ * as long as you don't make any segments larger. Currently, leafRepackItems
+ * satisies this rule because it rewrites all segments after the first
+ * modified one, and vacuum can only make segments shorter.
*/
static void
dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf,
@@ -798,7 +805,13 @@ dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf,
if (!modified)
unmodifiedsize += segsize;
else
- memcpy(ptr, seginfo->seg, segsize);
+ {
+ /*
+ * Use memmove rather than memcpy, in case the segment points
+ * to the same buffer
+ */
+ memmove(ptr, seginfo->seg, segsize);
+ }
ptr += segsize;
newsize += segsize;
}