aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorAndrew Gierth <rhodiumtoad@postgresql.org>2020-02-05 19:49:47 +0000
committerAndrew Gierth <rhodiumtoad@postgresql.org>2020-02-05 20:08:11 +0000
commit0e37489ed682d29e8e010abbb1b28fa91237539a (patch)
treeac83f6ebe286ad17cf6ffa748539135cdba6fe73 /src/backend
parent308724bcc3b9c1aeb33ce04e232e5199518fa06a (diff)
downloadpostgresql-0e37489ed682d29e8e010abbb1b28fa91237539a.tar.gz
postgresql-0e37489ed682d29e8e010abbb1b28fa91237539a.zip
Force tuple conversion when the source has missing attributes.
Tuple conversion incorrectly concluded that no conversion was needed as long as all the attributes lined up. But if the source tuple has a missing attribute (from addition of a column with default), then the destination tupdesc might not reflect the same default. The typical symptom was that the affected columns would be unexpectedly NULL. Repair by always forcing conversion if the source has missing attributes, which will be filled in by the deform operation. (In theory we could optimize for when the destination has the same default, but that seemed overkill.) Backpatch to 11 where missing attributes were added. Per bug #16242. Vik Fearing (discovery, code, testing) and me (analysis, testcase). Discussion: https://postgr.es/m/16242-d1c9fca28445966b@postgresql.org
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/common/tupconvert.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/backend/access/common/tupconvert.c b/src/backend/access/common/tupconvert.c
index 8cda16431c1..5ed136246af 100644
--- a/src/backend/access/common/tupconvert.c
+++ b/src/backend/access/common/tupconvert.c
@@ -144,8 +144,18 @@ convert_tuples_by_position(TupleDesc indesc,
{
for (i = 0; i < n; i++)
{
- Form_pg_attribute inatt;
- Form_pg_attribute outatt;
+ Form_pg_attribute inatt = TupleDescAttr(indesc, i);
+ Form_pg_attribute outatt = TupleDescAttr(outdesc, i);
+
+ /*
+ * If the input column has a missing attribute, we need a
+ * conversion.
+ */
+ if (inatt->atthasmissing)
+ {
+ same = false;
+ break;
+ }
if (attrMap[i] == (i + 1))
continue;
@@ -155,8 +165,6 @@ convert_tuples_by_position(TupleDesc indesc,
* also dropped, we needn't convert. However, attlen and attalign
* must agree.
*/
- inatt = TupleDescAttr(indesc, i);
- outatt = TupleDescAttr(outdesc, i);
if (attrMap[i] == 0 &&
inatt->attisdropped &&
inatt->attlen == outatt->attlen &&
@@ -347,8 +355,18 @@ convert_tuples_by_name_map_if_req(TupleDesc indesc,
same = true;
for (i = 0; i < n; i++)
{
- Form_pg_attribute inatt;
- Form_pg_attribute outatt;
+ Form_pg_attribute inatt = TupleDescAttr(indesc, i);
+ Form_pg_attribute outatt = TupleDescAttr(outdesc, i);
+
+ /*
+ * If the input column has a missing attribute, we need a
+ * conversion.
+ */
+ if (inatt->atthasmissing)
+ {
+ same = false;
+ break;
+ }
if (attrMap[i] == (i + 1))
continue;
@@ -358,8 +376,6 @@ convert_tuples_by_name_map_if_req(TupleDesc indesc,
* also dropped, we needn't convert. However, attlen and attalign
* must agree.
*/
- inatt = TupleDescAttr(indesc, i);
- outatt = TupleDescAttr(outdesc, i);
if (attrMap[i] == 0 &&
inatt->attisdropped &&
inatt->attlen == outatt->attlen &&