| 2843 | } |
| 2844 | |
| 2845 | static SplitUpdatePath * |
| 2846 | make_splitupdate_path(PlannerInfo *root, Path *subpath, Index rti) |
| 2847 | { |
| 2848 | RangeTblEntry *rte; |
| 2849 | PathTarget *splitUpdatePathTarget; |
| 2850 | SplitUpdatePath *splitupdatepath; |
| 2851 | DMLActionExpr *actionExpr; |
| 2852 | |
| 2853 | /* Suppose we already hold locks before caller */ |
| 2854 | rte = planner_rt_fetch(rti, root); |
| 2855 | |
| 2856 | /* |
| 2857 | * Firstly, Trigger is not supported officially by Cloudberry. |
| 2858 | * |
| 2859 | * Secondly, the update trigger is processed in ExecUpdate. |
| 2860 | * however, splitupdate will execute ExecSplitUpdate_Insert |
| 2861 | * or ExecDelete instead of ExecUpdate. So the update trigger |
| 2862 | * will not be triggered in a split plan. |
| 2863 | * |
| 2864 | * PostgreSQL fires the row-level DELETE, INSERT, and BEFORE |
| 2865 | * UPDATE triggers, but not row-level AFTER UPDATE triggers, |
| 2866 | * if you UPDATE a partitioning key column. |
| 2867 | * Doing a similar thing doesn't help Cloudberry likely, the |
| 2868 | * behavior would be uncertain since some triggers happen on |
| 2869 | * segments and they may require cross segments data changes. |
| 2870 | * |
| 2871 | * So an update trigger is not allowed when updating the |
| 2872 | * distribution key. |
| 2873 | */ |
| 2874 | if (has_update_triggers(rte->relid, false)) |
| 2875 | ereport(ERROR, |
| 2876 | (errcode(ERRCODE_GP_FEATURE_NOT_YET), |
| 2877 | errmsg("UPDATE on distributed key column not allowed on relation with update triggers"))); |
| 2878 | |
| 2879 | /* Add action column at the end of targetlist */ |
| 2880 | actionExpr = makeNode(DMLActionExpr); |
| 2881 | splitUpdatePathTarget = copy_pathtarget(subpath->pathtarget); |
| 2882 | add_column_to_pathtarget(splitUpdatePathTarget, (Expr *) actionExpr, 0); |
| 2883 | |
| 2884 | /* populate information generated above into splitupdate node */ |
| 2885 | splitupdatepath = makeNode(SplitUpdatePath); |
| 2886 | splitupdatepath->path.pathtype = T_SplitUpdate; |
| 2887 | splitupdatepath->path.parent = subpath->parent; |
| 2888 | splitupdatepath->path.pathtarget = splitUpdatePathTarget; |
| 2889 | splitupdatepath->path.param_info = NULL; |
| 2890 | splitupdatepath->path.parallel_aware = false; |
| 2891 | splitupdatepath->path.parallel_safe = subpath->parallel_safe; |
| 2892 | splitupdatepath->path.parallel_workers = subpath->parallel_workers; |
| 2893 | splitupdatepath->path.rows = 2 * subpath->rows; |
| 2894 | splitupdatepath->path.startup_cost = subpath->startup_cost; |
| 2895 | splitupdatepath->path.total_cost = subpath->total_cost; |
| 2896 | splitupdatepath->path.pathkeys = subpath->pathkeys; |
| 2897 | splitupdatepath->path.locus = subpath->locus; |
| 2898 | splitupdatepath->subpath = subpath; |
| 2899 | splitupdatepath->resultRelation = rti; |
| 2900 | |
| 2901 | return splitupdatepath; |
| 2902 | } |
no test coverage detected