aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/common/tupconvert.c32
-rw-r--r--src/test/regress/expected/alter_table.out38
-rw-r--r--src/test/regress/sql/alter_table.sql39
3 files changed, 101 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 &&
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 3e1ab10f59c..258530835ed 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -4148,3 +4148,41 @@ alter table at_test_sql_partop attach partition at_test_sql_partop_1 for values
drop table at_test_sql_partop;
drop operator class at_test_sql_partop using btree;
drop function at_test_sql_partop;
+/* Test case for bug #16242 */
+-- We create a parent and child where the child has missing
+-- non-null attribute values, and arrange to pass them through
+-- tuple conversion from the child to the parent tupdesc
+create table bar1 (a integer, b integer not null default 1)
+ partition by range (a);
+create table bar2 (a integer);
+insert into bar2 values (1);
+alter table bar2 add column b integer not null default 1;
+-- (at this point bar2 contains tuple with natts=1)
+alter table bar1 attach partition bar2 default;
+-- this works:
+select * from bar1;
+ a | b
+---+---
+ 1 | 1
+(1 row)
+
+-- this exercises tuple conversion:
+create function xtrig()
+ returns trigger language plpgsql
+as $$
+ declare
+ r record;
+ begin
+ for r in select * from old loop
+ raise info 'a=%, b=%', r.a, r.b;
+ end loop;
+ return NULL;
+ end;
+$$;
+create trigger xtrig
+ after update on bar1
+ referencing old table as old
+ for each statement execute procedure xtrig();
+update bar1 set a = a + 1;
+INFO: a=1, b=1
+/* End test case for bug #16242 */
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index 0917e129905..0e8f7015c9d 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -2775,3 +2775,42 @@ alter table at_test_sql_partop attach partition at_test_sql_partop_1 for values
drop table at_test_sql_partop;
drop operator class at_test_sql_partop using btree;
drop function at_test_sql_partop;
+
+
+/* Test case for bug #16242 */
+
+-- We create a parent and child where the child has missing
+-- non-null attribute values, and arrange to pass them through
+-- tuple conversion from the child to the parent tupdesc
+create table bar1 (a integer, b integer not null default 1)
+ partition by range (a);
+create table bar2 (a integer);
+insert into bar2 values (1);
+alter table bar2 add column b integer not null default 1;
+-- (at this point bar2 contains tuple with natts=1)
+alter table bar1 attach partition bar2 default;
+
+-- this works:
+select * from bar1;
+
+-- this exercises tuple conversion:
+create function xtrig()
+ returns trigger language plpgsql
+as $$
+ declare
+ r record;
+ begin
+ for r in select * from old loop
+ raise info 'a=%, b=%', r.a, r.b;
+ end loop;
+ return NULL;
+ end;
+$$;
+create trigger xtrig
+ after update on bar1
+ referencing old table as old
+ for each statement execute procedure xtrig();
+
+update bar1 set a = a + 1;
+
+/* End test case for bug #16242 */