diff options
author | Andrew Dunstan <andrew@dunslane.net> | 2018-09-24 16:11:24 -0400 |
---|---|---|
committer | Andrew Dunstan <andrew@dunslane.net> | 2018-09-24 16:20:08 -0400 |
commit | 9625ab79245b5b91162ede9d1b4d8b4be823c21c (patch) | |
tree | 2b1d8eaf8fdda395fc085f7654eaab67c78aaf6a /src/backend | |
parent | bfdd02f88b9678dea0e0ba5866ee772f3aa55cba (diff) | |
download | postgresql-9625ab79245b5b91162ede9d1b4d8b4be823c21c.tar.gz postgresql-9625ab79245b5b91162ede9d1b4d8b4be823c21c.zip |
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.c | 51 | ||||
-rw-r--r-- | src/backend/commands/trigger.c | 5 |
2 files changed, 25 insertions, 31 deletions
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index 2ec7e6a4392..efe4ac0e7dc 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; |