Re: inconsistent tableoid handling in COPY WHERE clause

From: jian he <jian(dot)universality(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Peter Eisentraut <peter(at)eisentraut(dot)org>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: inconsistent tableoid handling in COPY WHERE clause
Date: 2025-11-06 07:16:36
Message-ID: CACJufxE2R_Wr+jFjXmGX=VEs=dPc-Cv+zUd1rTVN5esZWn2gUA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Nov 6, 2025 at 3:44 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> >
> > I suggest that we should prohibit using tableoid in COPY WHERE clauses
> > for the time being. I don't know if there would be a way to make them
> > work correctly at all, but most likely not in a backpatchable way anyway.
> >
> > I also suggest that the above piece of code assigning tts_tableOid
> > should be changed somehow. Maybe just delete it, or set it to
> > InvalidOid, because as it is it's misleading and probably wrong.
>
> Probably should we filter rows by WHERE clause after determining the
> partition to insert the tuple into? Currently, after getting a row
> from NextCopyFrom(), we check the WHERE clause and then determine the
> partition to insert the tuple into if the partitioned table is
> specified in the COPY FROM. Then, we set the slot's tableoid to the
> right leaf partition's oid:

I think it is doable.

BEFORE ROW TRIGGER no need to correct slot->tts_tableOid information.
see ExecInsert:
at the beginning of ExecInsert, slot->tts_tableOid == 0
ExecMaterializeSlot won't touch the Tableoid field.
ExecBRInsertTriggers happen before explicitly setting slot->tts_tableOid.

ExecBRInsertTriggers->ExecFetchSlotHeapTuple->tts_virtual_copy_heap_tuple->heap_form_tuple
will set (TriggerData->tg_trigtuple) t_tableOid as InvalidOid
trigger execution function plpgsql_exec_trigger only use
TriggerData->tg_trigtuple, not using TriggerData->tg_trigslot.
That means during ExecBRInsertTriggers execution, the t_tableOid is InvalidOid.

exec_assign_value have "cannot assign to system column" ERROR check
forbidden us change system column.

CopyMultiInsertInfoFlush->CopyMultiInsertBufferFlush->table_multi_insert
will set the proper tableoid for the slot.
That mean don't need to worry about AFTER ROW TRIGGER,

We can place filtering rows by WHERE clause logic right below ExecFindPartition.
Please check the attached patch.

--
jian
https://www.enterprisedb.com

Attachment Content-Type Size
v1-0001-fix-COPY-WHERE-clause-with-tableoid-field.patch text/x-patch 4.5 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Quan Zongliang 2025-11-06 07:20:25 Re: [PATCH] Add pg_get_role_ddl() functions for role recreation
Previous Message Paul A Jungwirth 2025-11-06 06:36:01 Re: GiST README typos