summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorAndrew Dunstan2018-09-24 20:11:24 +0000
committerAndrew Dunstan2018-09-24 20:11:24 +0000
commit7636e5c60fea83a9f3cd2ad278c0819b98941c74 (patch)
tree285eb988abdec36c3e3835eafdf08125d6aeac3f /src/backend
parent60e612b602999e670f2d57a01e52799eaa903ca9 (diff)
Fast default trigger and expand_tuple fixes
Ensure that triggers get properly filled in tuples for the OLD value. Also fix the logic of detecting missing null values. The previous logic failed to detect a missing null column before the first missing column with a default. Fixing this has simplified the logic a bit. Regression tests are added to test changes. This should ensure better coverage of expand_tuple(). Original bug reports, and some code and test scripts from Tomas Vondra Backpatch to release 11.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/common/heaptuple.c51
-rw-r--r--src/backend/commands/trigger.c5
2 files changed, 25 insertions, 31 deletions
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index d8b06bca7e7..7fc2fee74ab 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -823,44 +823,35 @@ expand_tuple(HeapTuple *targetHeapTuple,
{
if (attrmiss[firstmissingnum].am_present)
break;
+ else
+ hasNulls = true;
}
/*
- * If there are no more missing values everything else must be NULL
+ * Now walk the missing attributes. If there is a missing value
+ * make space for it. Otherwise, it's going to be NULL.
*/
- if (firstmissingnum >= natts)
- {
- hasNulls = true;
- }
- else
+ for (attnum = firstmissingnum;
+ attnum < natts;
+ attnum++)
{
-
- /*
- * Now walk the missing attributes. If there is a missing value
- * make space for it. Otherwise, it's going to be NULL.
- */
- for (attnum = firstmissingnum;
- attnum < natts;
- attnum++)
+ if (attrmiss[attnum].am_present)
{
- if (attrmiss[attnum].am_present)
- {
- Form_pg_attribute att = TupleDescAttr(tupleDesc, attnum);
+ Form_pg_attribute att = TupleDescAttr(tupleDesc, attnum);
- targetDataLen = att_align_datum(targetDataLen,
- att->attalign,
- att->attlen,
- attrmiss[attnum].am_value);
+ targetDataLen = att_align_datum(targetDataLen,
+ att->attalign,
+ att->attlen,
+ attrmiss[attnum].am_value);
- targetDataLen = att_addlength_pointer(targetDataLen,
- att->attlen,
- attrmiss[attnum].am_value);
- }
- else
- {
- /* no missing value, so it must be null */
- hasNulls = true;
- }
+ targetDataLen = att_addlength_pointer(targetDataLen,
+ att->attlen,
+ attrmiss[attnum].am_value);
+ }
+ else
+ {
+ /* no missing value, so it must be null */
+ hasNulls = true;
}
}
} /* end if have missing values */
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 2436692eb85..0665f110ba3 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -3396,7 +3396,10 @@ ltrmark:;
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
}
- result = heap_copytuple(&tuple);
+ if (HeapTupleHeaderGetNatts(tuple.t_data) < relation->rd_att->natts)
+ result = heap_expand_tuple(&tuple, relation->rd_att);
+ else
+ result = heap_copytuple(&tuple);
ReleaseBuffer(buffer);
return result;