Re: [HACKERS] UPDATE of partition key - Mailing list pgsql-hackers
From | Amit Khandekar |
---|---|
Subject | Re: [HACKERS] UPDATE of partition key |
Date | |
Msg-id | CAJ3gD9fNtm7Xb7a5=NPUqGs1cvDSGWLZV88sq=k_Kn63L31OMA@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 1 January 2018 at 21:43, Amit Khandekar <amitdkhan.pg@gmail.com> wrote: > On 16 December 2017 at 03:09, Robert Haas <robertmhaas@gmail.com> wrote: >> + /* >> + * UPDATEs set the transition capture map only when a new subplan >> + * is chosen. But for INSERTs, it is set for each row. So after >> + * INSERT, we need to revert back to the map created for UPDATE; >> + * otherwise the next UPDATE will incorrectly use the one created >> + * for INESRT. So first save the one created for UPDATE. >> + */ >> + if (mtstate->mt_transition_capture) >> + saved_tcs_map = mtstate->mt_transition_capture->tcs_map; >> >> I wonder if there is some more elegant way to handle this problem. >> Basically, the issue is that ExecInsert() is stomping on >> mtstate->mt_transition_capture, and your solution is to save and >> restore the value you want to have there. But maybe we could instead >> find a way to get ExecInsert() not to stomp on that state in the first >> place. It seems like the ON CONFLICT stuff handled that by adding a >> second TransitionCaptureState pointer to ModifyTable, thus >> mt_transition_capture and mt_oc_transition_capture. By that >> precedent, we could add mt_utr_transition_capture or similar, and >> maybe that's the way to go. It seems a bit unsatisfying, but so does >> what you have now. > > In case of ON CONFLICT, if there are both INSERT and UPDATE statement > triggers referencing transition tables, both of the triggers need to > independently populate their own transition tables, and hence the need > for two separate transition states : mt_transition_capture and > mt_oc_transition_capture. But in case of update-tuple-routing, the > INSERT statement trigger won't come into picture. So the same > mt_transition_capture can serve the purpose of populating the > transition table with OLD and NEW rows. So I think it would be too > redundant, if not incorrect, to have a whole new transition state for > update tuple routing. > > I will see if it turns out better to have two tcs_maps in > TransitionCaptureState, one for update and one for insert. But this, > on first look, does not look good. Suppose TransitionCaptureState has separate maps, upd_del_tcs_maps and insert_tcs_maps for UPDATE/DELETE and INSERT events respectively. So upd_del_tcs_maps will be updated only after we start with the next UPDATE subplan, whereas insert_tcs_maps will keep on getting updated for each row. So in AfterTriggerSaveEvent(), upd_del_tcs_maps would be used when the event is TRIGGER_EVENT_[UPDATE/DELETE], and insert_tcs_maps will be used when event == TRIGGER_EVENT_INSERT. But the issue is : even if the event is TRIGGER_EVENT_UPDATE, we don't know whether this is caused by a normal update or as part of an insert into new partition during partition-key-update. So blindly using upd_del_tcs_maps is incorrect. If the event is caused by the later, we should use insert_tcs_maps rather than upd_del_tcs_maps. But we do not have the information in trigger.c as to what caused this event. So, overall, it would not work, and even if we make it work by passing or storing some more information somewhere, the AfterTriggerSaveEvent() logic will become too complicated. So I can't think of anything else, but to keep the way I did, i.e. reverting back the tcs_map once insert finishes. We so a similar thing for reverting back the estate->es_result_relation_info. -- Thanks, -Amit Khandekar EnterpriseDB Corporation The Postgres Database Company
pgsql-hackers by date: