Re: [HACKERS] UPDATE of partition key - Mailing list pgsql-hackers

From Robert Haas
Subject Re: [HACKERS] UPDATE of partition key
Date
Msg-id CA+TgmobYKoh7aPvGpCOs2bpDxGiuJrJ=-6Fn=ETF5H3X=D=SJA@mail.gmail.com
Whole thread Raw
In response to Re: [HACKERS] UPDATE of partition key  (Amit Khandekar <amitdkhan.pg@gmail.com>)
Responses Re: [HACKERS] UPDATE of partition key
List pgsql-hackers
On Fri, Jan 12, 2018 at 5:12 AM, Amit Khandekar <amitdkhan.pg@gmail.com> wrote:
> The reason why I am having map_required field inside a structure along
> with the map, as against a separate array, is so that we can do the
> on-demand allocation for both per-leaf array and per-subplan array.

Putting the map_required field inside the structure with the map makes
it completely silly to do the 0/1/2 thing, because the whole structure
is going to be on the same cache line anyway.  It won't save anything
to access the flag instead of a pointer in the same struct.   Also,
the uint8 will be followed by 7 bytes of padding, because the pointer
that follows will need to begin on an 8-byte boundary (at least, on
64-bit machines), so this will use more memory.

What I suggest is:

#define MT_CONVERSION_REQUIRED_UNKNOWN        0
#define MT_CONVERSION_REQUIRED_YES                    1
#define MT_CONVERSION_REQUIRED_NO                      2

In ModifyTableState:

uint8 *mt_per_leaf_tupconv_required;
TupleConversionMap **mt_per_leaf_tupconv_maps;

In PartitionTupleRouting:

int *subplan_partition_offsets;

When you initialize the ModifyTableState, do this:

mtstate->mt_per_leaf_tupconv_required = palloc0(sizeof(uint8) *
numResultRelInfos);
mtstate->mt_per_leaf_tupconv_maps = palloc0(sizeof(TupleConversionMap
*) * numResultRelInfos);

When somebody needs a map, then

(1) if they need it by subplan index, first use
subplan_partition_offsets to convert it to a per-leaf index

(2) then write a function that takes the per-leaf index and does this:

switch (mtstate->mt_per_leaf_tupconv_required[leaf_part_index])
{
    case MT_CONVERSION_REQUIRED_UNKNOWN:
        map = convert_tuples_by_name(...);
        if (map == NULL)
            mtstate->mt_per_leaf_tupconv_required[leaf_part_index] =
MT_CONVERSION_REQUIRED_NO;
        else
        {
            mtstate->mt_per_leaf_tupconv_required[leaf_part_index] =
MT_CONVERSION_REQUIRED_YES;
            mtstate->mt_per_leaf_tupconv_maps[leaf_part_index] = map;
        }
        return map;
    case MT_CONVERSION_REQUIRED_YES:
        return mtstate->mt_per_leaf_tupconv_maps[leaf_part_index];
    case MT_CONVERSION_REQUIRED_NO:
        return NULL;
}

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


pgsql-hackers by date:

Previous
From: Curt Tilmes
Date:
Subject: [PATCH] Find additional connection service files in pg_service.conf.d directory
Next
From: Fabien COELHO
Date:
Subject: Re: General purpose hashing func in pgbench