aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2013-02-01 10:43:09 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2013-02-01 10:43:09 -0300
commit9ee00ef4c7de991b9371f614ce9c03ff436ce383 (patch)
treec75c3f6a247f0d68c8936f20487858fc6cd58fe4 /src
parent583905269378bf41c24585773885b1e226a998ce (diff)
downloadpostgresql-9ee00ef4c7de991b9371f614ce9c03ff436ce383.tar.gz
postgresql-9ee00ef4c7de991b9371f614ce9c03ff436ce383.zip
Fill tuple before HeapSatisfiesHOTAndKeyUpdate
Failing to do this results in almost all updates to system catalogs being non-HOT updates, because the OID column would differ (not having been set for the new tuple), which is an indexed column. While at it, make sure to set the tableoid early in both old and new tuples as well. This isn't of much consequence, since that column is seldom (never?) indexed. Report and patch from Andres Freund.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/heap/heapam.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 94568433319..39c3ee27559 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2978,10 +2978,33 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
lp = PageGetItemId(page, ItemPointerGetOffsetNumber(otid));
Assert(ItemIdIsNormal(lp));
+ /*
+ * Fill in enough data in oldtup for HeapSatisfiesHOTandKeyUpdate to work
+ * properly.
+ */
+ oldtup.t_tableOid = RelationGetRelid(relation);
oldtup.t_data = (HeapTupleHeader) PageGetItem(page, lp);
oldtup.t_len = ItemIdGetLength(lp);
oldtup.t_self = *otid;
+ /* the new tuple is ready, except for this: */
+ newtup->t_tableOid = RelationGetRelid(relation);
+
+ /* Fill in OID for newtup */
+ if (relation->rd_rel->relhasoids)
+ {
+#ifdef NOT_USED
+ /* this is redundant with an Assert in HeapTupleSetOid */
+ Assert(newtup->t_data->t_infomask & HEAP_HASOID);
+#endif
+ HeapTupleSetOid(newtup, HeapTupleGetOid(&oldtup));
+ }
+ else
+ {
+ /* check there is not space for an OID */
+ Assert(!(newtup->t_data->t_infomask & HEAP_HASOID));
+ }
+
/*
* If we're not updating any "key" column, we can grab a weaker lock type.
* This allows for more concurrency when we are running simultaneously with
@@ -3243,20 +3266,7 @@ l2:
*/
CheckForSerializableConflictIn(relation, &oldtup, buffer);
- /* Fill in OID and transaction status data for newtup */
- if (relation->rd_rel->relhasoids)
- {
-#ifdef NOT_USED
- /* this is redundant with an Assert in HeapTupleSetOid */
- Assert(newtup->t_data->t_infomask & HEAP_HASOID);
-#endif
- HeapTupleSetOid(newtup, HeapTupleGetOid(&oldtup));
- }
- else
- {
- /* check there is not space for an OID */
- Assert(!(newtup->t_data->t_infomask & HEAP_HASOID));
- }
+ /* Fill in transaction status data */
/*
* If the tuple we're updating is locked, we need to preserve the locking
@@ -3318,7 +3328,6 @@ l2:
newtup->t_data->t_infomask |= HEAP_UPDATED | infomask_new_tuple;
newtup->t_data->t_infomask2 |= infomask2_new_tuple;
HeapTupleHeaderSetXmax(newtup->t_data, xmax_new_tuple);
- newtup->t_tableOid = RelationGetRelid(relation);
/*
* Replace cid with a combo cid if necessary. Note that we already put