Re: posgres 12 bug (partitioned table)

Поиск
Список
Период
Сортировка
От Amit Langote
Тема Re: posgres 12 bug (partitioned table)
Дата
Msg-id CA+HiwqHrsNa4e0MfpSzv7xOM94TvX=R0MskYxYWfy0kjL0DAdQ@mail.gmail.com
обсуждение исходный текст
Ответ на Re: posgres 12 bug (partitioned table)  (Soumyadeep Chakraborty <soumyadeep2007@gmail.com>)
Ответы Re: posgres 12 bug (partitioned table)  (Soumyadeep Chakraborty <soumyadeep2007@gmail.com>)
Re: posgres 12 bug (partitioned table)  (Soumyadeep Chakraborty <soumyadeep2007@gmail.com>)
Список pgsql-bugs
Hi Soumyadeep,

Thanks for picking this up.

On Tue, Jul 7, 2020 at 7:46 AM Soumyadeep Chakraborty
<soumyadeep2007@gmail.com> wrote:
> Upon investigation, it seems that the problem is caused by the
> following:
>
> The slot passed to the call to ExecProcessReturning() inside
> ExecInsert() is often a virtual tuple table slot.

Actually, not that often in practice.  The slot is not virtual, for
example, when inserting into a regular non-partitioned table.  Whether
or not it is virtual depends on the following piece of code in
ExecInitModifyTable():

        mtstate->mt_scans[i] =
            ExecInitExtraTupleSlot(mtstate->ps.state,
ExecGetResultType(mtstate->mt_plans[i]),

table_slot_callbacks(resultRelInfo->ri_RelationDesc));

Specifically, the call to table_slot_callbacks() above determines what
kind of slot is assigned for a given target relation.  For partitioned
tables, it happens to return a virtual slot currently, per this
implementation:

    if (relation->rd_tableam)
        tts_cb = relation->rd_tableam->slot_callbacks(relation);
    else if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
    {
        /*
         * Historically FDWs expect to store heap tuples in slots. Continue
         * handing them one, to make it less painful to adapt FDWs to new
         * versions. The cost of a heap slot over a virtual slot is pretty
         * small.
         */
        tts_cb = &TTSOpsHeapTuple;
    }
    else
    {
        /*
         * These need to be supported, as some parts of the code (like COPY)
         * need to create slots for such relations too. It seems better to
         * centralize the knowledge that a heap slot is the right thing in
         * that case here.
         */
        Assert(relation->rd_rel->relkind == RELKIND_VIEW ||
               relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
        tts_cb = &TTSOpsVirtual;
    }

If I change this to return a "heap" slot for partitioned tables, just
like for foreign tables, the problem goes away (see the attached).  In
fact, even make check-world passes, so I don't know why it isn't that
way to begin with.

> I have attached two alternate patches to solve the problem.

IMHO, they are solving the problem at the wrong place.  We should
really fix things so that the slot that gets passed down to
ExecProcessReturning() is of the correct type to begin with.  We could
do what I suggest above or maybe find some other way.

--
Amit Langote
EnterpriseDB: http://www.enterprisedb.com

Вложения

В списке pgsql-bugs по дате отправления:

Предыдущее
От: Markus Wanner
Дата:
Сообщение: invalid alloc size error possible in shm_mq
Следующее
От: Tobias Völk
Дата:
Сообщение: Bug: Very poor query optimization by Postgres