Re: minimal update - Mailing list pgsql-hackers

From Andrew Dunstan
Subject Re: minimal update
Date
Msg-id 47757F38.8060509@dunslane.net
Whole thread Raw
In response to Re: minimal update  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: minimal update  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers

Tom Lane wrote:
> Andrew Dunstan <andrew@dunslane.net> writes:
>   
>> Tom Lane wrote:
>>     
>>> Well, you could write the trigger in C and it'd work for any table.
>>> I think it could be as simple as a memcmp of the tuples' data areas,
>>> since we now require padding bytes to be 0 ...
>>>       
>
>   
>> Something like this fragment?
>>     
>
>   
>>   newtuple = trigdata->tg_newtuple;
>>   oldtuple = trigdata->tg_trigtuple;
>>   rettuple = newtuple;
>>     
>
>   
>>   if (newtuple->t_len == oldtuple->t_len &&
>>       newtuple->t_data->t_hoff == oldtuple->t_data->t_hoff &&
>>       memcmp(GETSTRUCT(newtuple),GETSTRUCT(oldtuple),
>>              newtuple->t_len - newtuple->t_data->t_hoff) == 0)
>>     rettuple = NULL;
>>     
>
>   
>>   return PointerGetDatum(rettuple);
>>     
>
> Close, but I think you also need to take care to compare natts and
> the null bitmaps (if any).  Might be worth comparing OIDs too, though
> AFAIR there is no mechanism for substituting a different OID during
> UPDATE.  Probably the easiest coding is to memcmp all the way from
> offsetof(t_bits) to t_len, after comparing natts and the HASNULL and
> HASOID flags.
>   


How does this look?
   if (newtuple->t_len == oldtuple->t_len &&       newtuple->t_data->t_hoff == oldtuple->t_data->t_hoff &&
HeapTupleHeaderGetNatts(newtuple)== HeapTupleHeaderGetNatts(oldtuple) &&       (newtuple->t_data->t_infomask &
(HEAP_HASOID|HEAP_HASNULL))== (oldtuple->t_data->t_infomask & (HEAP_HASOID|HEAP_HASNULL)) &&
memcmp(newtuple->t_data+ offsetof(HeapTupleHeaderData, t_bits),              oldtuple->t_data +
offsetof(HeapTupleHeaderData,t_bits)              newtuple->t_len - offsetof(HeapTupleHeaderData, t_bits)) == 0)
 
     rettuple = NULL;
   return PointerGetDatum(rettuple);



cheers

andrew
>   
>> Also, when did we first require padding bytes to be 0?
>>     
>
> The 8.3 varvarlena patch is what requires it, but in practice
> heap_formtuple has always started with a palloc0, so I think it would
> work a long ways back.
>
>             regards, tom lane
>
>   


pgsql-hackers by date:

Previous
From: Mark Mielke
Date:
Subject: Re: Spoofing as the postmaster
Next
From: Tom Lane
Date:
Subject: Re: minimal update