This function has become very difficult to follow in the join case.
Don't insert the aggnode at the top of the plan if you are only going to pull it back out to put in the join node.
Don't throw away the parent node (or null for a replaced root) then have to find it again as the parent of aggnode.
Write the best possible handler for the join case, and afterwards think about what code could be shared with the single-table case.