mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-09 08:10:09 +08:00
Be more aggressive in avoiding tuple conversion.
According to the comments in tupconvert.c, it's necessary to perform tuple conversion when either table has OIDs, and this was previously checked by ensuring that the tdtypeid value matched between the tables in question. However, that's overly stringent: we have access to tdhasoid and can test directly whether OIDs are present, which lets us avoid conversion in cases where the type OIDs are different but the tuple descriptors are entirely the same (and neither has OIDs). This is useful to the partitioning code, which can thereby avoid converting tuples when inserting into a partition whose columns appear in the same order as the parent columns, the normal case. It's possible for the tuple routing code to avoid some additional overhead in this case as well, so do that, too. It's not clear whether it would be OK to skip this when both tables have OIDs: do callers count on this to build a new tuple (losing the previous OID) in such instances? Until we figure it out, leave the behavior in that case alone. Amit Langote, reviewed by me.
This commit is contained in:
parent
7fa7bf18e4
commit
3838074f86
@ -138,12 +138,13 @@ convert_tuples_by_position(TupleDesc indesc,
|
||||
nincols, noutcols)));
|
||||
|
||||
/*
|
||||
* Check to see if the map is one-to-one and the tuple types are the same.
|
||||
* (We check the latter because if they're not, we want to do conversion
|
||||
* to inject the right OID into the tuple datum.)
|
||||
* Check to see if the map is one-to-one, in which case we need not do
|
||||
* the tuple conversion. That's not enough though if either source or
|
||||
* destination (tuples) contains OIDs; we'd need conversion in that case
|
||||
* to inject the right OID into the tuple datum.
|
||||
*/
|
||||
if (indesc->natts == outdesc->natts &&
|
||||
indesc->tdtypeid == outdesc->tdtypeid)
|
||||
!indesc->tdhasoid && !outdesc->tdhasoid)
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
@ -214,12 +215,13 @@ convert_tuples_by_name(TupleDesc indesc,
|
||||
attrMap = convert_tuples_by_name_map(indesc, outdesc, msg);
|
||||
|
||||
/*
|
||||
* Check to see if the map is one-to-one and the tuple types are the same.
|
||||
* (We check the latter because if they're not, we want to do conversion
|
||||
* to inject the right OID into the tuple datum.)
|
||||
* Check to see if the map is one-to-one, in which case we need not do
|
||||
* the tuple conversion. That's not enough though if either source or
|
||||
* destination (tuples) contains OIDs; we'd need conversion in that case
|
||||
* to inject the right OID into the tuple datum.
|
||||
*/
|
||||
if (indesc->natts == outdesc->natts &&
|
||||
indesc->tdtypeid == outdesc->tdtypeid)
|
||||
!indesc->tdhasoid && !outdesc->tdhasoid)
|
||||
{
|
||||
same = true;
|
||||
for (i = 0; i < n; i++)
|
||||
|
@ -1700,12 +1700,11 @@ get_partition_for_tuple(PartitionDispatch *pd,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (myslot != NULL)
|
||||
if (myslot != NULL && map != NULL)
|
||||
{
|
||||
HeapTuple tuple = ExecFetchSlotTuple(slot);
|
||||
|
||||
ExecClearTuple(myslot);
|
||||
Assert(map != NULL);
|
||||
tuple = do_convert_tuple(tuple, map);
|
||||
ExecStoreTuple(tuple, myslot, InvalidBuffer, true);
|
||||
slot = myslot;
|
||||
|
Loading…
Reference in New Issue
Block a user