Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbf6cc19

Browse files
committed
Force tuple conversion when the source has missing attributes.
Tuple conversion incorrectly concluded that no conversion was neededas long as all the attributes lined up. But if the source tuple has amissing attribute (from addition of a column with default), then thedestination tupdesc might not reflect the same default. The typicalsymptom was that the affected columns would be unexpectedly NULL.Repair by always forcing conversion if the source has missingattributes, which will be filled in by the deform operation. (Intheory we could optimize for when the destination has the samedefault, 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
1 parent15d13e8 commitbf6cc19

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

‎src/backend/access/common/attmap.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,14 @@ check_attrmap_match(TupleDesc indesc,
294294

295295
for (i=0;i<attrMap->maplen;i++)
296296
{
297-
Form_pg_attributeinatt;
298-
Form_pg_attributeoutatt;
297+
Form_pg_attributeinatt=TupleDescAttr(indesc,i);
298+
Form_pg_attributeoutatt=TupleDescAttr(outdesc,i);
299+
300+
/*
301+
* If the input column has a missing attribute, we need a conversion.
302+
*/
303+
if (inatt->atthasmissing)
304+
return false;
299305

300306
if (attrMap->attnums[i]== (i+1))
301307
continue;
@@ -305,8 +311,6 @@ check_attrmap_match(TupleDesc indesc,
305311
* dropped, we don't need a conversion. However, attlen and attalign
306312
* must agree.
307313
*/
308-
inatt=TupleDescAttr(indesc,i);
309-
outatt=TupleDescAttr(outdesc,i);
310314
if (attrMap->attnums[i]==0&&
311315
inatt->attisdropped&&
312316
inatt->attlen==outatt->attlen&&

‎src/test/regress/expected/alter_table.out

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4258,3 +4258,41 @@ alter table at_test_sql_partop attach partition at_test_sql_partop_1 for values
42584258
drop table at_test_sql_partop;
42594259
drop operator class at_test_sql_partop using btree;
42604260
drop function at_test_sql_partop;
4261+
/* Test case for bug #16242 */
4262+
-- We create a parent and child where the child has missing
4263+
-- non-null attribute values, and arrange to pass them through
4264+
-- tuple conversion from the child to the parent tupdesc
4265+
create table bar1 (a integer, b integer not null default 1)
4266+
partition by range (a);
4267+
create table bar2 (a integer);
4268+
insert into bar2 values (1);
4269+
alter table bar2 add column b integer not null default 1;
4270+
-- (at this point bar2 contains tuple with natts=1)
4271+
alter table bar1 attach partition bar2 default;
4272+
-- this works:
4273+
select * from bar1;
4274+
a | b
4275+
---+---
4276+
1 | 1
4277+
(1 row)
4278+
4279+
-- this exercises tuple conversion:
4280+
create function xtrig()
4281+
returns trigger language plpgsql
4282+
as $$
4283+
declare
4284+
r record;
4285+
begin
4286+
for r in select * from old loop
4287+
raise info 'a=%, b=%', r.a, r.b;
4288+
end loop;
4289+
return NULL;
4290+
end;
4291+
$$;
4292+
create trigger xtrig
4293+
after update on bar1
4294+
referencing old table as old
4295+
for each statement execute procedure xtrig();
4296+
update bar1 set a = a + 1;
4297+
INFO: a=1, b=1
4298+
/* End test case for bug #16242 */

‎src/test/regress/sql/alter_table.sql

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2801,3 +2801,42 @@ alter table at_test_sql_partop attach partition at_test_sql_partop_1 for values
28012801
droptable at_test_sql_partop;
28022802
dropoperator class at_test_sql_partop using btree;
28032803
dropfunction at_test_sql_partop;
2804+
2805+
2806+
/* Test case for bug #16242*/
2807+
2808+
-- We create a parent and child where the child has missing
2809+
-- non-null attribute values, and arrange to pass them through
2810+
-- tuple conversion from the child to the parent tupdesc
2811+
createtablebar1 (ainteger, bintegernot null default1)
2812+
partition by range (a);
2813+
createtablebar2 (ainteger);
2814+
insert into bar2values (1);
2815+
altertable bar2 add column bintegernot null default1;
2816+
-- (at this point bar2 contains tuple with natts=1)
2817+
altertable bar1 attach partition bar2 default;
2818+
2819+
-- this works:
2820+
select*from bar1;
2821+
2822+
-- this exercises tuple conversion:
2823+
createfunctionxtrig()
2824+
returns trigger language plpgsql
2825+
as $$
2826+
declare
2827+
r record;
2828+
begin
2829+
for rinselect*from old loop
2830+
raise info'a=%, b=%',r.a,r.b;
2831+
end loop;
2832+
returnNULL;
2833+
end;
2834+
$$;
2835+
createtriggerxtrig
2836+
afterupdateon bar1
2837+
referencing old tableas old
2838+
for each statement execute procedure xtrig();
2839+
2840+
update bar1set a= a+1;
2841+
2842+
/* End test case for bug #16242*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp