Re: UPDATE of partition key
Amit Khandekar <amitdkhan.pg@gmail.com>
Attachments
- update-partition-key_v10.patch (application/octet-stream) patch v10
On 13 June 2017 at 15:40, Amit Khandekar <amitdkhan.pg@gmail.com> wrote: > While rebasing my patch for the below recent commit, I realized that a > similar issue exists for the uptate-tuple-routing patch as well : > > commit 78a030a441966d91bc7e932ef84da39c3ea7d970 > Author: Tom Lane <tgl@sss.pgh.pa.us> > Date: Mon Jun 12 23:29:44 2017 -0400 > > Fix confusion about number of subplans in partitioned INSERT setup. > > The above issue was about incorrectly using 'i' in > mtstate->mt_plans[i] during handling WITH CHECK OPTIONS in > ExecInitModifyTable(), where 'i' was actually meant to refer to the > positions in mtstate->mt_num_partitions. Actually for INSERT, there is > only a single plan element in mtstate->mt_plans[] array. > > Similarly, for update-tuple routing, we cannot use > mtstate->mt_plans[i], because 'i' refers to position in > mtstate->mt_partitions[] , whereas mtstate->mt_plans is not at all in > order of mtstate->mt_partitions; in fact mt_plans has only the plans > that are to be scanned on pruned partitions; so it can well be a small > subset of total partitions. > > I am working on an updated patch to fix the above. Attached patch v10 fixes the above. In the existing code, where it builds WCO constraints for each leaf partition; with the patch, that code now is applicable to row-movement-updates as well. So the assertions in the code are now updated to allow the same. Secondly, the mapping for each of the leaf partitions was constructed using the root partition attributes. Now in the patch, the mtstate->resultRelInfo[0] (i.e. the first resultRelInfo) is used as reference. So effectively, map_partition_varattnos() now represents not just parent-to-partition mapping, but rather, mapping between any two partitions/partitioned_tables. It's done this way, so that we can have a common WCO building code for inserts as well as updates. For e.g. for inserts, the first (and only) WCO belongs to node->nominalRelation so nominalRelation is used for map_partition_varattnos(), whereas for updates, first WCO belongs to the first resultRelInfo which is not same as nominalRelation. So in the patch, in both cases, we use the first resultRelInfo and the WCO of the first resultRelInfo for map_partition_varattnos(). Similar thing is done for Returning expressions. --------- Another change in the patch is : for ExecInitQual() for WCO quals, mtstate->ps is used as parent, rather than first plan. For updates, first plan does not belong to the parent partition. In fact, I think in all cases, we should use mtstate->ps as the parent. mtstate->mt_plans[0] don't look like they should be considered parent of these expressions. May be it does not matter to which parent we link these quals, because there is no ReScan for ExecModifyTable(). Note that for RETURNING projection expressions, we do use mtstate->ps. -------- There is another issue I discovered. The row-movement works fine if the destination leaf partition has different attribute ordering than the root : the existing insert-tuple-routing mapping handles that. But if the source partition has different ordering w.r.t. the root, it has a problem : there is no mapping in the opposite direction, i.e. from the leaf to root. And we require that because the tuple of source leaf partition needs to be converted to root partition tuple descriptor, since ExecFindPartition() starts with root. To fix this, I have introduced another mapping array mtstate->mt_resultrel_maps[]. This corresponds to the mtstate->resultRelInfo[]. We don't require per-leaf-partition mapping, because the update result relations are pruned subset of the total leaf partitions. So in ExecInsert, before calling ExecFindPartition(), we need to convert the leaf partition tuple to root using this reverse mapping. Since we need to convert the tuple here, and again after ExecFindPartition() for the found leaf partition, I have replaced the common code by new function ConvertPartitionTupleSlot(). ------- Used a new flag is_partitionkey_update in ExecInitModifyTable(), which can be re-used in subsequent sections , rather than again calling IsPartitionKeyUpdate() function again. ------- Some more test scenarios added that cover above changes. Basically partitions that have different tuple descriptors than parents.
Commits
-
Avoid referencing off the end of subplan_partition_offsets.
- 945f71db8452 11.0 landed
-
Allow UPDATE to move rows between partitions.
- 2f178441044b 11.0 landed
-
Remove useless lookup of root partitioned rel in ExecInitModifyTable().
- dca48d145e0e 11.0 cited
-
Factor error generation out of ExecPartitionCheck.
- 19c47e7c8202 11.0 landed
-
Minor preparatory refactoring for UPDATE row movement.
- ef6087ee5fa8 11.0 landed
-
Simplify and encapsulate tuple routing support code.
- cc6337d2fed5 11.0 landed
-
Avoid coercing a whole-row variable that is already coerced.
- 1c497fa72df7 11.0 landed
-
Use ResultRelInfo ** rather than ResultRelInfo * for tuple routing.
- 60f7c0abef03 11.0 landed
-
Make RelationGetPartitionDispatchInfo expand depth-first.
- 77b6b5e9ceca 11.0 cited
-
Expand partitioned tables in PartDesc order.
- 30833ba154e0 11.0 cited
-
Use a real RT index when setting up partition tuple routing.
- f81a91db4d1c 10.0 cited
-
Fix transition tables for partition/inheritance.
- 501ed02cf6f4 10.0 cited
-
Fix confusion about number of subplans in partitioned INSERT setup.
- 78a030a44196 10.0 cited
-
Prevent BEFORE triggers from violating partitioning constraints.
- 15ce775faa42 10.0 cited
-
Fire per-statement triggers on partitioned tables.
- e180c8aa8caf 10.0 cited
-
Fix reporting of violations in ExecConstraints, again.
- c0a8ae7be392 10.0 cited
-
Don't scan partitioned tables.
- d3cc37f1d801 10.0 cited
-
Allow FDWs to push down quals without breaking EvalPlanQual rechecks.
- 5fc4c26db512 9.6.0 cited