* In Postgres planner, we add a SplitUpdate node at top so that updating on * distribution columns could be handled. The SplitUpdate will split each * update into delete + insert. * * There are several important points should be highlighted: * * First, in order to split each update operation into two operations, * delete + insert, we need several junk columns in the subplan's targetlist, *
| 2743 | * 'rti' is the UPDATE target relation. |
| 2744 | */ |
| 2745 | Path * |
| 2746 | create_split_update_path(PlannerInfo *root, Index rti, GpPolicy *policy, Path *subpath) |
| 2747 | { |
| 2748 | GpPolicyType policyType = policy->ptype; |
| 2749 | CdbPathLocus targetLocus; |
| 2750 | |
| 2751 | if (policyType == POLICYTYPE_PARTITIONED) |
| 2752 | { |
| 2753 | /* |
| 2754 | * If any of the distribution key columns are being changed, |
| 2755 | * the UPDATE might move tuples from one segment to another. |
| 2756 | * Create a Split Update node to deal with that. |
| 2757 | * |
| 2758 | * If the input is a dummy plan that cannot return any rows, |
| 2759 | * e.g. because the input was eliminated by constraint |
| 2760 | * exclusion, we can skip it. |
| 2761 | */ |
| 2762 | targetLocus = cdbpathlocus_for_insert(root, policy, subpath->pathtarget); |
| 2763 | |
| 2764 | subpath = (Path *) make_splitupdate_path(root, subpath, rti); |
| 2765 | subpath = cdbpath_create_explicit_motion_path(root, |
| 2766 | subpath, |
| 2767 | targetLocus); |
| 2768 | } |
| 2769 | else if (policyType == POLICYTYPE_ENTRY) |
| 2770 | { |
| 2771 | /* Master-only table */ |
| 2772 | CdbPathLocus_MakeEntry(&targetLocus); |
| 2773 | subpath = cdbpath_create_motion_path(root, subpath, NIL, false, targetLocus); |
| 2774 | } |
| 2775 | else if (policyType == POLICYTYPE_REPLICATED) |
| 2776 | { |
| 2777 | } |
| 2778 | else |
| 2779 | elog(ERROR, "unrecognized policy type %u", policyType); |
| 2780 | return subpath; |
| 2781 | } |
| 2782 | |
| 2783 | /* |
| 2784 | * turn_volatile_seggen_to_singleqe |
no test coverage detected