BUG #16909: On update (not insert) the attisdropped flag is set for tables which are recreated with the same col
The following bug has been logged on the website:
Bug reference: 16909
Logged by: Grumpylittleted
Email address: grumpylittleted@googlemail.com
PostgreSQL version: 13.2
Operating system: Linux 5.8.0-44-generic #50~20.04.1-Ubuntu S
Description:
/*
BUG:
Using 13.2
On update (not insert) the attisdropped flag is set for tables which are
recreated with the same column names as the original but where preceding
columns have been dropped
METHOD:
Create a table t with more than two columns: x, y, z
Drop that table
Create a table t with a subset of the columns with the same name as the
previous table: here we remove y
Insert a new row: there are two attributes (correct), neither of which
have the attisdropped flag set (correct) (so bug not apparent with
inserts)
Update the row: there are two attributes (correct), the first attribute
has the attisdropped flag unset (correct) BUT the second attribute has the
attisdropped flag set (incorrect)
make
sudo cp ./f.so `pg_config --pkglibdir`
SQL:
create or replace function f() returns trigger as './f.so','f' language c
strict;
drop table if exists t cascade;
create table t(x int, y int, z int);
drop table t cascade;
create table t(x int, z int);
create trigger tf before insert or update on t for each row execute
procedure f();
insert into t values(4,5); -- attr num=1 attisdropped=0
update t set x=2;
*/
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "postgres.h"
#include "fmgr.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "utils/rel.h"
#include "utils/fmgrprotos.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1( f );
Datum f( PG_FUNCTION_ARGS ) {
TriggerData *trigdata = ( TriggerData * ) fcinfo->context;
const TupleDesc tupdesc = trigdata->tg_relation->rd_att;
HeapTuple tuple = TRIGGER_FIRED_BY_UPDATE( trigdata->tg_event ) ?
trigdata->tg_newtuple : trigdata->tg_trigtuple;
for( int i = 1; i <= tupdesc->natts; i++ ) {
elog( INFO, "attr num=%d attisdropped=%d", i, TupleDescAttr( tupdesc, i
)->attisdropped );
}
return PointerGetDatum( tuple );
}
Can you please share the complete output?
Seems like a false alarm per my testing.
On Tue, Mar 2, 2021 at 3:58 PM PG Bug reporting form <noreply@postgresql.org>
wrote:
Show quoted text
The following bug has been logged on the website:
Bug reference: 16909
Logged by: Grumpylittleted
Email address: grumpylittleted@googlemail.com
PostgreSQL version: 13.2
Operating system: Linux 5.8.0-44-generic #50~20.04.1-Ubuntu S
Description:/*
BUG:
Using 13.2
On update (not insert) the attisdropped flag is set for tables which are
recreated with the same column names as the original but where preceding
columns have been droppedMETHOD:
Create a table t with more than two columns: x, y, z
Drop that table
Create a table t with a subset of the columns with the same name as the
previous table: here we remove y
Insert a new row: there are two attributes (correct), neither of which
have the attisdropped flag set (correct) (so bug not apparent with
inserts)
Update the row: there are two attributes (correct), the first attribute
has the attisdropped flag unset (correct) BUT the second attribute has the
attisdropped flag set (incorrect)make
sudo cp ./f.so `pg_config --pkglibdir`SQL:
create or replace function f() returns trigger as './f.so','f' language c
strict;drop table if exists t cascade;
create table t(x int, y int, z int);drop table t cascade;
create table t(x int, z int);
create trigger tf before insert or update on t for each row execute
procedure f();
insert into t values(4,5); -- attr num=1 attisdropped=0
update t set x=2;*/
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "postgres.h"
#include "fmgr.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "utils/rel.h"
#include "utils/fmgrprotos.h"PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1( f );
Datum f( PG_FUNCTION_ARGS ) {TriggerData *trigdata = ( TriggerData * ) fcinfo->context;
const TupleDesc tupdesc = trigdata->tg_relation->rd_att;
HeapTuple tuple = TRIGGER_FIRED_BY_UPDATE( trigdata->tg_event ) ?
trigdata->tg_newtuple : trigdata->tg_trigtuple;for( int i = 1; i <= tupdesc->natts; i++ ) {
elog( INFO, "attr num=%d attisdropped=%d", i, TupleDescAttr( tupdesc, i
)->attisdropped );
}return PointerGetDatum( tuple );
}
PG Bug reporting form <noreply@postgresql.org> writes:
On update (not insert) the attisdropped flag is set for tables which are
recreated with the same column names as the original but where preceding
columns have been dropped
I think this is just faulty C code.
for( int i = 1; i <= tupdesc->natts; i++ ) {
elog( INFO, "attr num=%d attisdropped=%d", i, TupleDescAttr( tupdesc, i
)->attisdropped );
}
The index argument of TupleDescAttr needs to run from 0 to natts-1.
As coded, this is fetching off the end of the array and getting garbage.
The mistake might've been more obvious if you'd tried to print any
non-boolean fields of the tupledesc.
regards, tom lane
Thanks Tom, that explains it.
I had seen the use of attisdropped elsewhere, thought I'd better check it
and assumed that the TupleDescAttr was 1 based, like the SPI functions,
rather than 0 based. I have now gone into the code and it does indeed have
a comment /* attrs[N] is the description of Attribute Number N+1 */
It also explains why Hamid got different results. Sorry to raise a false
alarm.
On Tue, 2 Mar 2021 at 15:40, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Show quoted text
PG Bug reporting form <noreply@postgresql.org> writes:
On update (not insert) the attisdropped flag is set for tables which
are
recreated with the same column names as the original but where preceding
columns have been droppedI think this is just faulty C code.
for( int i = 1; i <= tupdesc->natts; i++ ) {
elog( INFO, "attr num=%d attisdropped=%d", i, TupleDescAttr(tupdesc, i
)->attisdropped );
}The index argument of TupleDescAttr needs to run from 0 to natts-1.
As coded, this is fetching off the end of the array and getting garbage.The mistake might've been more obvious if you'd tried to print any
non-boolean fields of the tupledesc.regards, tom lane