Hi Soumyadeep, Thanks for picking this up.
On Tue, Jul 7, 2020 at 7:46 AM Soumyadeep Chakraborty <soumyadeep2...@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
partitioned-table-heap-slot.patch
Description: Binary data