/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*-------------------------------------------------------------------------
 *
 * cdbpath.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#ifdef __cplusplus
extern "C" {
#endif

#include "catalog/pg_proc.h"    /* CDB_PROC_TIDTOI8 */
#include "catalog/pg_type.h"    /* INT8OID */
#include "miscadmin.h"          /* work_mem */
#include "nodes/makefuncs.h"    /* makeFuncExpr() */
#include "nodes/relation.h"     /* PlannerInfo, RelOptInfo, CdbRelDedupInfo */
#include "optimizer/cost.h"     /* cpu_tuple_cost */
#include "optimizer/pathnode.h" /* Path, pathnode_walker() */
#include "optimizer/paths.h"    /* compare_pathkeys() */

#include "parser/parse_expr.h"	/* exprType() */

#include "cdb/cdbdef.h"         /* CdbSwap() */
#include "cdb/cdbllize.h"       /* makeFlow() */
#include "cdb/cdbhash.h"        /* isGreenplumDbHashable() */

#include "cdb/cdbpath.h"        /* me */

#ifdef __cplusplus
}   /* extern "C" */
#endif

#ifdef small                    /* <socket.h> might #define small */
#undef small                    /*  but I want it for a variable name */
#endif


/*
 * cdbpath_cost_motion
 *    Fills in the cost estimate fields in a MotionPath node.
 */
void
cdbpath_cost_motion(PlannerInfo *root, CdbMotionPath *motionpath)
{
    Path   *subpath = motionpath->subpath;
    Cost    cost_per_row;
    Cost    motioncost;
    double  recvrows;
    double  sendrows;

    cost_per_row = (gp_motion_cost_per_row > 0.0)
                    ? gp_motion_cost_per_row
                    : 2.0 * cpu_tuple_cost;
    sendrows = cdbpath_rows(root, subpath);
    recvrows = cdbpath_rows(root, (Path *)motionpath);
    motioncost = cost_per_row * 0.5 * (sendrows + recvrows);

    motionpath->path.total_cost = motioncost + subpath->total_cost;
    motionpath->path.startup_cost = subpath->startup_cost;
    motionpath->path.memory = subpath->memory;
}                               /* cdbpath_cost_motion */


/*
 * cdbpath_create_motion_path
 *    Returns a Path that delivers the subpath result to the
 *    given locus, or NULL if it can't be done.
 *
 *    'pathkeys' must specify an ordering equal to or weaker than the
 *    subpath's existing ordering.
 *
 *    If no motion is needed, the caller's subpath is returned unchanged.
 *    Else if require_existing_order is true, NULL is returned if the
 *      motion would not preserve an ordering at least as strong as the
 *      specified ordering; also NULL is returned if pathkeys is NIL
 *      meaning the caller is just checking and doesn't want to add motion.
 *    Else a CdbMotionPath is returned having either the specified pathkeys
 *      (if given and the motion uses Merge Receive), or the pathkeys
 *      of the original subpath (if the motion is order-preserving), or no
 *      pathkeys otherwise (the usual case).
 */
Path *
cdbpath_create_motion_path(PlannerInfo     *root,
                           Path            *subpath,
                           List            *pathkeys,
                           bool             require_existing_order,
                           CdbPathLocus     locus)
{
    CdbMotionPath      *pathnode;

    UnusedArg(root);
    Assert(cdbpathlocus_is_valid(locus) &&
           cdbpathlocus_is_valid(subpath->locus));

    /* Moving subpath output to a single executor process (qDisp or qExec)? */
    if (CdbPathLocus_IsBottleneck(locus))
    {
        /* entry-->entry or singleQE-->singleQE?  No motion needed. */
        if (CdbPathLocus_IsEqual(subpath->locus, locus))
            return subpath;

        /* entry-->singleQE?  Don't move.  Slice's QE will run on entry db. */
        if (CdbPathLocus_IsEntry(subpath->locus))
            return subpath;

        /* singleQE-->entry?  Don't move.  Slice's QE will run on entry db. */
        if (CdbPathLocus_IsSingleQE(subpath->locus))
        {
            /* Create CdbMotionPath node to indicate that the slice must be
             * dispatched to a singleton gang running on the entry db.  We
             * merely use this node to note that the path has 'Entry' locus;
             * no corresponding Motion node will be created in the Plan tree.
             */
            Assert(CdbPathLocus_IsEntry(locus));

            pathnode = makeNode(CdbMotionPath);
            pathnode->path.pathtype = T_Motion;
            pathnode->path.parent = subpath->parent;
            pathnode->path.locus = locus;
            pathnode->path.pathkeys = pathkeys;
            pathnode->subpath = subpath;

            /* Costs, etc, are same as subpath. */
            pathnode->path.startup_cost = subpath->total_cost;
            pathnode->path.total_cost = subpath->total_cost;
            pathnode->path.memory = subpath->memory;
            pathnode->path.motionHazard = subpath->motionHazard;
            pathnode->path.rescannable = subpath->rescannable;
            return (Path *)pathnode;
        }

        /* No motion needed if subpath can run anywhere giving same output. */
        if (CdbPathLocus_IsGeneral(subpath->locus))
            return subpath;

        /* Fail if caller refuses motion. */
        if (require_existing_order &&
            !pathkeys)
            return NULL;

        /* replicated-->singleton would give redundant copies of the rows. */
        if (CdbPathLocus_IsReplicated(subpath->locus))
            goto invalid_motion_request;

        /* Must be partitioned-->singleton.
         *  If caller gave pathkeys, they'll be used for Merge Receive.
         *  If no pathkeys, Union Receive will arbitrarily interleave
         *  the rows from the subpath partitions in no special order.
         */
        if (!CdbPathLocus_IsPartitioned(subpath->locus))
            goto invalid_motion_request;
    }

    /* Output from a single process to be distributed over a gang? */
    else if (CdbPathLocus_IsBottleneck(subpath->locus))
    {
        /* Must be bottleneck-->partitioned or bottleneck-->replicated */
        if (!CdbPathLocus_IsPartitioned(locus) &&
            !CdbPathLocus_IsReplicated(locus))
            goto invalid_motion_request;

        /* Fail if caller disallows motion. */
        if (require_existing_order &&
            !pathkeys)
            return NULL;

        /* Each qExec receives a subset of the rows, with ordering preserved. */
        pathkeys = subpath->pathkeys;
    }

    /* Redistributing partitioned subpath output from one gang to another? */
    else if (CdbPathLocus_IsPartitioned(subpath->locus))
    {
        /* partitioned-->partitioned? */
        if (CdbPathLocus_IsPartitioned(locus))
        {
            /* No motion if subpath partitioning matches caller's request. */
            if (cdbpathlocus_compare(CdbPathLocus_Comparison_Equal, subpath->locus, locus))
                return subpath;
        }

        /* Must be partitioned-->replicated */
        else if (!CdbPathLocus_IsReplicated(locus))
            goto invalid_motion_request;

        /* Fail if caller insists on ordered result or no motion. */
        if (require_existing_order)
            return NULL;

        /* Output streams lose any ordering they had.
         * Only a qDisp or singleton qExec can merge sorted streams (for now).
         */
        pathkeys = NIL;
    }

    /* If subplan uses no tables, it can run on qDisp or a singleton qExec. */
    else if (CdbPathLocus_IsGeneral(subpath->locus))
    {
        /* No motion needed if general-->general or general-->replicated. */
        if (CdbPathLocus_IsGeneral(locus) ||
            CdbPathLocus_IsReplicated(locus))
            return subpath;

        /* Must be general-->partitioned. */
        if (!CdbPathLocus_IsPartitioned(locus))
            goto invalid_motion_request;

        /* Fail if caller wants no motion. */
        if (require_existing_order &&
            !pathkeys)
            return NULL;

        /* Since the motion is 1-to-many, the rows remain in the same order. */
        pathkeys = subpath->pathkeys;
    }

    /* Does subpath produce same multiset of rows on every qExec of its gang? */
    else if (CdbPathLocus_IsReplicated(subpath->locus))
    {
        /* No-op if replicated-->replicated. */
        if (CdbPathLocus_IsReplicated(locus))
            return subpath;

        /* Other destinations aren't used or supported at present. */
        goto invalid_motion_request;
    }
    else
        goto invalid_motion_request;

    /* Don't materialize before motion. */
    if (IsA(subpath, MaterialPath))
        subpath = ((MaterialPath *)subpath)->subpath;

	/*
	 * MPP-3300: materialize *before* motion can never help us, motion
	 * pushes data. other nodes pull. We relieve motion deadlocks by
	 * adding materialize nodes on top of motion nodes
	 */

    /* Create CdbMotionPath node. */
    pathnode = makeNode(CdbMotionPath);
    pathnode->path.pathtype = T_Motion;
    pathnode->path.parent = subpath->parent;
    pathnode->path.locus = locus;
    pathnode->path.pathkeys = pathkeys;
    pathnode->subpath = subpath;

    /* Cost of motion */
    cdbpath_cost_motion(root, pathnode);

    /* Tell operators above us that slack may be needed for deadlock safety. */
    pathnode->path.motionHazard = true;
    pathnode->path.rescannable = false;

    return (Path *)pathnode;

    /* Unexpected source or destination locus. */
invalid_motion_request:
    Assert(0);
    return NULL;
}                               /* cdbpath_create_motion_path */


/*
 * cdbpath_partkeyitem_eq_constant
 */
static inline List *
cdbpath_partkeyitem_eq_constant(CdbLocusType   locustype,
                                 List          *partkeyitem)
{
    if (locustype == CdbLocusType_Hashed)
    {
        if (CdbPathkeyEqualsConstant(partkeyitem))
            return partkeyitem;
    }
    else if (locustype == CdbLocusType_HashedOJ)
    {
        ListCell   *cell;
        foreach(cell, partkeyitem)
        {
            List   *pathkey = (List*)lfirst(cell);
            if (CdbPathkeyEqualsConstant(pathkey))
                return pathkey;
        }
    }
    else
        Assert(false);
    return NIL;
}                               /* cdbpath_partkeyitem_eq_constant */


/*
 * cdbpath_match_preds_to_partkey_tail
 *
 * Returns true if all of the locus's partitioning key expressions are
 * found as comparands of equijoin predicates in the mergeclause_list.
 *
 * NB: for mergeclause_list and pathkey structure assumptions, see:
 *          select_mergejoin_clauses() in joinpath.c
 *          find_mergeclauses_for_pathkeys() in pathkeys.c
 */

typedef struct
{
    PlannerInfo    *root;
    List           *mergeclause_list;
    CdbPathLocus    locus;
    CdbPathLocus   *colocus;
    bool            colocus_eq_locus;
} CdbpathMatchPredsContext;


static bool
cdbpath_match_preds_to_partkey_tail(CdbpathMatchPredsContext   *ctx,
                                    ListCell                   *partkeycell)
{
    List       *copathkey;
    List       *sublist;
    ListCell   *rcell;

    /* Get current item of partkey. */
    sublist = (List *)lfirst(partkeycell);

    /* Is there a "<partkey item> = <constant expr>" predicate?
     *
     *  If table T is distributed on cols (C,D,E) and query contains preds
     *          T.C = U.A AND T.D = <constant expr> AND T.E = U.B
     *  then we would like to report a match and return the colocus
     *          (U.A, <constant expr>, U.B)
     *  so the caller can join T and U by redistributing only U.
     *  (Note that "T.D = <constant expr>" won't be in the mergeclause_list
     *  because it isn't a join pred.)
     */
    copathkey = cdbpath_partkeyitem_eq_constant(ctx->locus.locustype, sublist);

    /* Look for an equijoin comparison to the partkey item. */
    if (!copathkey)
    {
        foreach(rcell, ctx->mergeclause_list)
        {
            RestrictInfo   *rinfo = (RestrictInfo *)lfirst(rcell);

            if (!rinfo->left_pathkey)
                cache_mergeclause_pathkeys(ctx->root, rinfo);

            if (CdbPathLocus_IsHashed(ctx->locus))
            {
                if (sublist == rinfo->left_pathkey)
                    copathkey = rinfo->right_pathkey;
                else if (sublist == rinfo->right_pathkey)
                    copathkey = rinfo->left_pathkey;
            }
            else if (CdbPathLocus_IsHashedOJ(ctx->locus))
            {
                if (list_member_ptr(sublist, rinfo->left_pathkey))
                    copathkey = rinfo->right_pathkey;
                else if (rinfo->left_pathkey != rinfo->right_pathkey &&
                    list_member_ptr(sublist, rinfo->right_pathkey))
                    copathkey = rinfo->left_pathkey;
            }

            if (copathkey)
                break;
        }

        /* Fail if didn't find a match for this partkey item. */
        if (!copathkey)
            return false;
    }

    /* Might need to build co-locus if locus is outer join source or result. */
    if (copathkey != sublist)
        ctx->colocus_eq_locus = false;

    /* Match remaining partkey items. */
    partkeycell = lnext(partkeycell);
    if (partkeycell)
    {
        if (!cdbpath_match_preds_to_partkey_tail(ctx, partkeycell))
            return false;
    }

    /* Success!  Matched all items.  Return co-locus if requested. */
    if (ctx->colocus)
    {
        if (ctx->colocus_eq_locus)
            *ctx->colocus = ctx->locus;
        else if (!partkeycell)
            CdbPathLocus_MakeHashed(ctx->colocus, list_make1(copathkey));
        else
        {
            ctx->colocus->partkey = lcons(copathkey, ctx->colocus->partkey);
            Assert(cdbpathlocus_is_valid(*ctx->colocus));
        }
    }
    return true;
}                               /* cdbpath_match_preds_to_partkey_tail */


/*
 * cdbpath_match_preds_to_partkey
 *
 * Returns true if an equijoin predicate is found in the mergeclause_list
 * for each item of the locus's partitioning key.
 *
 * (Also, a partkey item that is equal to a constant is treated as a match.)
 *
 * Readers may refer also to these related functions:
 *          select_mergejoin_clauses() in joinpath.c
 *          find_mergeclauses_for_pathkeys() in pathkeys.c
 */
static bool
cdbpath_match_preds_to_partkey(PlannerInfo     *root,
                               List            *mergeclause_list,
                               CdbPathLocus     locus,
                               CdbPathLocus    *colocus)            /* OUT */
{
    CdbpathMatchPredsContext ctx;

    if (!CdbPathLocus_IsHashed(locus) &&
        !CdbPathLocus_IsHashedOJ(locus))
        return false;

    Assert(cdbpathlocus_is_valid(locus));

    ctx.root                = root;
    ctx.mergeclause_list    = mergeclause_list;
    ctx.locus               = locus;
    ctx.colocus             = colocus;
    ctx.colocus_eq_locus    = true;

    return cdbpath_match_preds_to_partkey_tail(&ctx, list_head(locus.partkey));
}                               /* cdbpath_match_preds_to_partkey */


/*
 * cdbpath_match_preds_to_both_partkeys
 *
 * Returns true if the mergeclause_list contains equijoin
 * predicates between each item of the outer_locus partkey and
 * the corresponding item of the inner_locus partkey.
 *
 * Readers may refer also to these related functions:
 *          select_mergejoin_clauses() in joinpath.c
 *          find_mergeclauses_for_pathkeys() in pathkeys.c
 */
static bool
cdbpath_match_preds_to_both_partkeys(PlannerInfo   *root,
                                     List          *mergeclause_list,
                                     CdbPathLocus   outer_locus,
                                     CdbPathLocus   inner_locus)
{
    ListCell   *outercell;
    ListCell   *innercell;

    if (!mergeclause_list ||
        !outer_locus.partkey ||
        !inner_locus.partkey ||
        CdbPathLocus_Degree(outer_locus) != CdbPathLocus_Degree(inner_locus))
        return false;

    Assert(CdbPathLocus_IsHashed(outer_locus) ||
           CdbPathLocus_IsHashedOJ(outer_locus));
    Assert(CdbPathLocus_IsHashed(inner_locus) ||
           CdbPathLocus_IsHashedOJ(inner_locus));

    forboth(outercell, outer_locus.partkey, innercell, inner_locus.partkey)
    {
        List        *outersublist = (List *)lfirst(outercell);
        List        *innersublist = (List *)lfirst(innercell);
        ListCell    *rcell;
        foreach(rcell, mergeclause_list)
        {
            RestrictInfo   *rinfo = (RestrictInfo *)lfirst(rcell);

            if (!rinfo->left_pathkey)
                cache_mergeclause_pathkeys(root, rinfo);

            /* Skip predicate if neither side matches outer partkey item. */
            if (CdbPathLocus_IsHashed(outer_locus))
            {
                if (outersublist != rinfo->left_pathkey &&
                    outersublist != rinfo->right_pathkey)
                    continue;
            }
            else
            {
                Assert(CdbPathLocus_IsHashedOJ(outer_locus));
                if (!list_member_ptr(outersublist, rinfo->left_pathkey) &&
                    !list_member_ptr(outersublist, rinfo->right_pathkey))
                    continue;
            }

            /* Skip predicate if neither side matches inner partkey item. */
            if (innersublist == outersublist)
            {}                  /* do nothing */
            else if (CdbPathLocus_IsHashed(inner_locus))
            {
                if (innersublist != rinfo->left_pathkey &&
                    innersublist != rinfo->right_pathkey)
                    continue;
            }
            else
            {
                Assert(CdbPathLocus_IsHashedOJ(inner_locus));
                if (!list_member_ptr(innersublist, rinfo->left_pathkey) &&
                    !list_member_ptr(innersublist, rinfo->right_pathkey))
                    continue;
            }

            /* Found equijoin between outer partkey item & inner partkey item */
            break;
        }

        /* Fail if didn't find equijoin between this pair of partkey items. */
        if (!rcell)
            return false;
    }
    return true;
}                               /* cdbpath_match_preds_to_both_partkeys */



/*
 * cdb_pathkey_isGreenplumDbHashable
 *
 * Iterates through a list of PathKeyItems and determines if all of them
 * are GreenplumDbHashable.
 *
 */
static bool
cdbpath_pathkey_isGreenplumDbHashable(List *pathkey)
{
    ListCell *plcell = NULL;
    foreach(plcell, pathkey)
    {
        PathKeyItem *pki = (PathKeyItem*) lfirst(plcell);

        if (!isGreenplumDbHashable(exprType(pki->key)))
        {
            /* bail if any of the items are non-hashable */
            return false;
        }
    }

    return true;
}


/*
 * cdbpath_partkeys_from_preds
 *
 * Makes a CdbPathLocus for repartitioning, driven by
 * the equijoin predicates in the mergeclause_list.
 * Returns true if successful, or false if no usable equijoin predicates.
 *
 * Readers may refer also to these related functions:
 *      select_mergejoin_clauses() in joinpath.c
 *      make_pathkeys_for_mergeclauses() in pathkeys.c
 */
static bool
cdbpath_partkeys_from_preds(PlannerInfo    *root,
                            List           *mergeclause_list,
                            Path           *a_path,
                            CdbPathLocus   *a_locus,            /* OUT */
                            CdbPathLocus   *b_locus)            /* OUT */
{
    List       *a_partkey = NIL;
    List       *b_partkey = NIL;
    ListCell   *rcell;

    foreach(rcell, mergeclause_list)
    {
        RestrictInfo *rinfo = (RestrictInfo *)lfirst(rcell);

        if (!rinfo->left_pathkey)
        {
            cache_mergeclause_pathkeys(root, rinfo);
            Assert(rinfo->left_pathkey);
        }

        /*
         * skip non-hashable keys
         */
        if (!cdbpath_pathkey_isGreenplumDbHashable(rinfo->left_pathkey) ||
            !cdbpath_pathkey_isGreenplumDbHashable(rinfo->right_pathkey))
        {
            continue;
        }

        /* Left & right pathkeys are usually the same... */
        if (!b_partkey &&
            rinfo->left_pathkey == rinfo->right_pathkey)
        {
            if (!list_member_ptr(a_partkey, rinfo->left_pathkey))
                a_partkey = lappend(a_partkey, rinfo->left_pathkey);
        }

        /* ... except in outer join ON-clause. */
        else
        {
            List   *a_pathkey;
            List   *b_pathkey;

            if (bms_is_subset(rinfo->right_relids, a_path->parent->relids))
            {
                a_pathkey = rinfo->right_pathkey;
                b_pathkey = rinfo->left_pathkey;
            }
            else
            {
                a_pathkey = rinfo->left_pathkey;
                b_pathkey = rinfo->right_pathkey;
                Assert(bms_is_subset(rinfo->left_relids, a_path->parent->relids));
            }

            if (!b_partkey)
                b_partkey = list_copy(a_partkey);

            if (!list_member_ptr(a_partkey, a_pathkey) &&
                !list_member_ptr(b_partkey, b_pathkey))
            {
                a_partkey = lappend(a_partkey, a_pathkey);
                b_partkey = lappend(b_partkey, b_pathkey);
            }
        }

        if (list_length(a_partkey) >= 20)
            break;
    }

    if (!a_partkey)
        return false;

    CdbPathLocus_MakeHashed(a_locus, a_partkey);
    if (b_partkey)
        CdbPathLocus_MakeHashed(b_locus, b_partkey);
    else
        *b_locus = *a_locus;
    return true;
}                               /* cdbpath_partkeys_from_preds */


/*
 * cdbpath_motion_for_join
 *
 * Decides where a join should be done.  Adds Motion operators atop
 * the subpaths if needed to deliver their results to the join locus.
 * Returns the join locus if ok, or a null locus otherwise.
 *
 * mergeclause_list is a List of RestrictInfo.  Its members are
 * the equijoin predicates between the outer and inner rel.
 * It comes from select_mergejoin_clauses() in joinpath.c.
 */

typedef struct
{
        CdbPathLocus    locus;
        CdbPathLocus    move_to;
        double          bytes;
        Path           *path;
        bool            ok_to_replicate;
        bool            require_existing_order;
} CdbpathMfjRel;

CdbPathLocus
cdbpath_motion_for_join(PlannerInfo    *root,
                        JoinType        jointype,           /* JOIN_INNER/FULL/LEFT/RIGHT/IN */
                        Path          **p_outer_path,       /* INOUT */
                        Path          **p_inner_path,       /* INOUT */
                        List           *mergeclause_list,   /* equijoin RestrictInfo list */
                        List           *outer_pathkeys,
                        List           *inner_pathkeys,
                        bool            outer_require_existing_order,
                        bool            inner_require_existing_order)
{
    CdbpathMfjRel   outer;
    CdbpathMfjRel   inner;

    outer.path  = *p_outer_path;
    inner.path  = *p_inner_path;
    outer.locus = outer.path->locus;
    inner.locus = inner.path->locus;
    CdbPathLocus_MakeNull(&outer.move_to);
    CdbPathLocus_MakeNull(&inner.move_to);

    Assert(cdbpathlocus_is_valid(outer.locus) &&
           cdbpathlocus_is_valid(inner.locus));

    /* Caller can specify an ordering for each source path that is
     * the same as or weaker than the path's existing ordering.
     * Caller may insist that we do not add motion that would
     * lose the specified ordering property; otherwise the given
     * ordering is preferred but not required.
     * A required NIL ordering means no motion is allowed for that path.
     */
    outer.require_existing_order = outer_require_existing_order;
    inner.require_existing_order = inner_require_existing_order;

    /* Don't consider replicating the preserved rel of an outer join, or
     * the current-query rel of a join between current query and subquery.
     */
    outer.ok_to_replicate = true;
    inner.ok_to_replicate = true;
    switch (jointype)
    {
        case JOIN_INNER:
            break;
        case JOIN_IN:
        case JOIN_LEFT:
        case JOIN_LASJ:
        case JOIN_LASJ_NOTIN:
            outer.ok_to_replicate = false;
            break;
        case JOIN_RIGHT:
            inner.ok_to_replicate = false;
            break;
        case JOIN_FULL:
            outer.ok_to_replicate = false;
            inner.ok_to_replicate = false;
            break;
        default:
            Assert(0);
    }

    /* Get rel sizes. */
    outer.bytes = cdbpath_rows(root, outer.path) * outer.path->parent->width;
    inner.bytes = cdbpath_rows(root, inner.path) * inner.path->parent->width;

    /*
     * Motion not needed if either source is everywhere (e.g. a constant).
     *
     * But if a row is everywhere and is preserved in an outer join, we
     * don't want to preserve it in every qExec process where it is
     * unmatched, because that would produce duplicate null-augmented rows.
     * So in that case, bring all the partitions to a single qExec to be joined.
     * CDB TODO: Can this case be handled without introducing a bottleneck?
     */
    if (CdbPathLocus_IsGeneral(outer.locus))
    {
        if (!outer.ok_to_replicate &&
            CdbPathLocus_IsPartitioned(inner.locus))
            CdbPathLocus_MakeSingleQE(&inner.move_to);
        else
            return inner.locus;
    }
    else if (CdbPathLocus_IsGeneral(inner.locus))
    {
        if (!inner.ok_to_replicate &&
            CdbPathLocus_IsPartitioned(outer.locus))
            CdbPathLocus_MakeSingleQE(&outer.move_to);
        else
            return outer.locus;
    }

    /*
     * Is either source confined to a single process?
     *   NB: Motion to a single process (qDisp or qExec) is the only motion
     *   in which we may use Merge Receive to preserve an existing ordering.
     */
    else if (CdbPathLocus_IsBottleneck(outer.locus) ||
             CdbPathLocus_IsBottleneck(inner.locus))
    {                                       /* singleQE or entry db */
        CdbpathMfjRel  *single = &outer;
        CdbpathMfjRel  *other = &inner;
        bool            single_immovable = outer.require_existing_order &&
                                           !outer_pathkeys;
        bool            other_immovable = inner.require_existing_order &&
                                          !inner_pathkeys;

        /*
         * If each of the sources has a single-process locus, then assign both
         * sources and the join to run in the same process, without motion.
         * The slice will be run on the entry db if either source requires it.
         */
        if (CdbPathLocus_IsEntry(single->locus))
        {
            if (CdbPathLocus_IsBottleneck(other->locus))
                return single->locus;
        }
        else if (CdbPathLocus_IsSingleQE(single->locus))
        {
            if (CdbPathLocus_IsBottleneck(other->locus))
                return other->locus;
        }

        /* Let 'single' be the source whose locus is singleQE or entry. */
        else
        {
            CdbSwap(CdbpathMfjRel*, single, other);
            CdbSwap(bool, single_immovable, other_immovable);
        }
        Assert(CdbPathLocus_IsBottleneck(single->locus));
        Assert(CdbPathLocus_IsPartitioned(other->locus));

        /* If the bottlenecked rel can't be moved, bring the other rel to it. */
        if (single_immovable)
            other->move_to = single->locus;

        /* Redistribute single rel if joining on other rel's partitioning key */
        else if (cdbpath_match_preds_to_partkey(root,
                                                mergeclause_list,
                                                other->locus,
                                                &single->move_to))  /* OUT */
        {}

        /* Replicate single rel if cheaper than redistributing both rels. */
        else if (single->ok_to_replicate &&
                 single->bytes * root->config->cdbpath_segments < single->bytes + other->bytes)
            CdbPathLocus_MakeReplicated(&single->move_to);

        /* Redistribute both rels on equijoin cols. */
        else if (!other->require_existing_order &&
                 cdbpath_partkeys_from_preds(root,
                                             mergeclause_list,
                                             single->path,
                                             &single->move_to,  /* OUT */
                                             &other->move_to))  /* OUT */
        {}

        /* No usable equijoin preds, or caller imposed restrictions on motion.
         * Replicate single rel if cheaper than bottlenecking other rel.
         */
        else if (single->ok_to_replicate &&
                 single->bytes < other->bytes)
            CdbPathLocus_MakeReplicated(&single->move_to);

        /* Last resort: Move all partitions of other rel to single QE. */
        else
            other->move_to = single->locus;
    }                                       /* singleQE or entry */

    /*
     * Replicated paths shouldn't occur loose, for now.
     */
    else if (CdbPathLocus_IsReplicated(outer.locus) ||
             CdbPathLocus_IsReplicated(inner.locus))
    {
        Assert(false);
        goto fail;
    }

    /*
     * No motion if partitioned alike and joining on the partitioning keys.
     */
    else if (cdbpath_match_preds_to_both_partkeys(root, mergeclause_list,
                                                  outer.locus, inner.locus))
        return cdbpathlocus_join(outer.locus, inner.locus);

    /*
     * Kludge used internally for querying catalogs on segment dbs.
     * Each QE will join the catalogs that are local to its own segment.
     * The catalogs don't have partitioning keys.  No motion needed.
     */
    else if (CdbPathLocus_IsStrewn(outer.locus) &&
             CdbPathLocus_IsStrewn(inner.locus) &&
             cdbpathlocus_querysegmentcatalogs)
        return outer.locus;

    /*
     * Both sources are partitioned.  Redistribute or replicate one or both.
     */
    else
    {                                       /* partitioned */
        CdbpathMfjRel  *large = &outer;
        CdbpathMfjRel  *small = &inner;

        /* Which rel is bigger? */
        if (large->bytes < small->bytes)
            CdbSwap(CdbpathMfjRel*, large, small);

        /* If joining on larger rel's partitioning key, redistribute smaller. */
        if (!small->require_existing_order &&
            cdbpath_match_preds_to_partkey(root,
                                           mergeclause_list,
                                           large->locus,
                                           &small->move_to))    /* OUT */
        {}

        /* Replicate smaller rel if cheaper than redistributing larger rel.
         * But don't replicate a rel that is to be preserved in outer join.
         */
        else if (!small->require_existing_order &&
                 small->ok_to_replicate &&
                 small->bytes * root->config->cdbpath_segments < large->bytes)
            CdbPathLocus_MakeReplicated(&small->move_to);

        /* If joining on smaller rel's partitioning key, redistribute larger. */
        else if (!large->require_existing_order &&
                 cdbpath_match_preds_to_partkey(root,
                                                mergeclause_list,
                                                small->locus,
                                                &large->move_to))   /* OUT */
        {}

        /* Replicate smaller rel if cheaper than redistributing both rels. */
        else if (!small->require_existing_order &&
                 small->ok_to_replicate &&
                 small->bytes * root->config->cdbpath_segments < large->bytes + small->bytes)
            CdbPathLocus_MakeReplicated(&small->move_to);

        /* Redistribute both rels on equijoin cols. */
        else if (!small->require_existing_order &&
                 !large->require_existing_order &&
                 cdbpath_partkeys_from_preds(root,
                                             mergeclause_list,
                                             large->path,
                                             &large->move_to,
                                             &small->move_to))
        {}

        /* No usable equijoin preds, or couldn't consider the preferred motion.
         * Replicate one rel if possible.
         * MPP TODO: Consider number of seg dbs per host.
         */
        else if (!small->require_existing_order &&
                 small->ok_to_replicate)
            CdbPathLocus_MakeReplicated(&small->move_to);
        else if (!large->require_existing_order &&
                 large->ok_to_replicate)
            CdbPathLocus_MakeReplicated(&large->move_to);

        /* Last resort: Move both rels to a single qExec. */
        else
        {
            CdbPathLocus_MakeSingleQE(&outer.move_to);
            CdbPathLocus_MakeSingleQE(&inner.move_to);
        }
    }                                       /* partitioned */

    /*
     * Move outer.
     */
    if (!CdbPathLocus_IsNull(outer.move_to))
    {
        outer.path = cdbpath_create_motion_path(root,
                                                outer.path,
                                                outer_pathkeys,
                                                outer.require_existing_order,
                                                outer.move_to);
        if (!outer.path)            /* fail if outer motion not feasible */
            goto fail;
   }

    /*
     * Move inner.
     */
    if (!CdbPathLocus_IsNull(inner.move_to))
    {
        inner.path = cdbpath_create_motion_path(root,
                                                inner.path,
                                                inner_pathkeys,
                                                inner.require_existing_order,
                                                inner.move_to);
        if (!inner.path)            /* fail if inner motion not feasible */
            goto fail;
    }

    /*
     * Ok to join.  Give modified subpaths to caller.
     */
    *p_outer_path = outer.path;
    *p_inner_path = inner.path;

    /* Tell caller where the join will be done. */
    return cdbpathlocus_join(outer.path->locus, inner.path->locus);

fail:                           /* can't do this join */
    CdbPathLocus_MakeNull(&outer.move_to);
    return outer.move_to;
}                               /* cdbpath_motion_for_join */


/*
 * cdbpath_dedup_fixup
 *      Modify path to support unique rowid operation for subquery preds.
 */

typedef struct CdbpathDedupFixupContext
{
    PlannerInfo    *root;
    Relids          distinct_on_rowid_relids;
    List           *rowid_vars;
    int32           subplan_id;
    bool            need_subplan_id;
    bool            need_segment_id;
} CdbpathDedupFixupContext;

static CdbVisitOpt
cdbpath_dedup_fixup_walker(Path *path, void *context);


/* Drop Var nodes from a List unless they belong to a given set of relids. */
static List *
cdbpath_dedup_pickvars(List *vars, Relids relids_to_keep)
{
    ListCell       *cell;
    ListCell       *nextcell;
    ListCell       *prevcell = NULL;
    Var            *var;

    for (cell = list_head(vars); cell; cell = nextcell)
    {
        nextcell = lnext(cell);
        var = (Var *)lfirst(cell);
        Assert(IsA(var, Var));
        if (!bms_is_member(var->varno, relids_to_keep))
            vars = list_delete_cell(vars, cell, prevcell);
        else
            prevcell = cell;
    }
    return vars;
}                               /* cdbpath_dedup_pickvars */

static CdbVisitOpt
cdbpath_dedup_fixup_unique(UniquePath *uniquePath, CdbpathDedupFixupContext *ctx)
{
    Relids      downstream_relids = ctx->distinct_on_rowid_relids;
    List       *ctid_exprs = NIL;
    List       *other_vars = NIL;
    List       *partkey = NIL;
    List       *eq = NIL;
    ListCell   *cell;
    bool        save_need_segment_id = ctx->need_segment_id;

    Assert(!ctx->rowid_vars);

    /*
     * Leave this node unchanged unless it removes duplicates by row id.
     *
     * NB. If ctx->distinct_on_rowid_relids is nonempty, row id vars
     * could be added to our rel's targetlist while visiting the child
     * subtree.  Any such added columns should pass on safely through this
     * Unique op because they aren't added to the distinct_on_exprs list.
     */
    if (bms_is_empty(uniquePath->distinct_on_rowid_relids))
        return CdbVisit_Walk;   /* onward to visit the kids */

    /* No action needed if data is trivially unique. */
    if (uniquePath->umethod == UNIQUE_PATH_NOOP ||
        uniquePath->umethod == UNIQUE_PATH_LIMIT1)
        return CdbVisit_Walk;   /* onward to visit the kids */

    /* Find set of relids for which subpath must produce row ids. */
    ctx->distinct_on_rowid_relids = bms_union(ctx->distinct_on_rowid_relids,
                                              uniquePath->distinct_on_rowid_relids);

    /* Tell join ops below that row ids mustn't be left out of targetlists. */
    ctx->distinct_on_rowid_relids = bms_add_member(ctx->distinct_on_rowid_relids, 0);

    /* Notify descendants if we're going to insert a MotionPath below. */
    if (uniquePath->must_repartition)
        ctx->need_segment_id = true;

    /* Visit descendants to get list of row id vars and add to targetlists. */
    pathnode_walk_node(uniquePath->subpath, cdbpath_dedup_fixup_walker, ctx);

    /* Restore saved flag. */
    ctx->need_segment_id = save_need_segment_id;

    /* CDB TODO: we share kid's targetlist at present, so our tlist could
     * contain rowid vars which are no longer needed downstream.
     */

    /*
     * Build DISTINCT ON key for UniquePath, putting the ctid columns first
     * because those are usually more distinctive than the segment ids.
     * Also build repartitioning key if needed, using only the ctid columns.
     */
    foreach(cell, ctx->rowid_vars)
    {
        Var        *var = (Var *)lfirst(cell);

        Assert(IsA(var, Var) &&
               bms_is_member(var->varno, ctx->distinct_on_rowid_relids));

        /* Skip vars which aren't part of the row id for this Unique op. */
        if (!bms_is_member(var->varno, uniquePath->distinct_on_rowid_relids))
            continue;

        /* ctid? */
        if (var->varattno == SelfItemPointerAttributeNumber)
        {
            /*
             * The tid type has a full set of comparison operators, but
             * oddly its "=" operator is not marked hashable.  So 'ctid'
             * is directly usable for sorted duplicate removal; but we
             * cast it to 64-bit integer for hashed duplicate removal.
             */
            if (uniquePath->umethod == UNIQUE_PATH_HASH)
                ctid_exprs = lappend(ctid_exprs,
                                     makeFuncExpr(CDB_PROC_TIDTOI8, INT8OID,
                                                  list_make1(var),
                                                  COERCE_EXPLICIT_CAST));
            else
                ctid_exprs = lappend(ctid_exprs, var);

            /* Add to repartitioning key.  Can use tid type without coercion. */
            if (uniquePath->must_repartition)
            {
                List   *cpathkey;

                if (!eq)
                    eq = list_make1(makeString("="));
                cpathkey = cdb_make_pathkey_for_expr(ctx->root, (Node *)var, eq);
                partkey = lappend(partkey, cpathkey);
            }
        }

        /* other uniqueifiers such as gp_segment_id */
        else
            other_vars = lappend(other_vars, var);
    }

    Assert(ctid_exprs);
    uniquePath->distinct_on_exprs = list_concat(ctid_exprs, other_vars);

    /* To repartition, add a MotionPath below this UniquePath. */
    if (uniquePath->must_repartition)
    {
        CdbPathLocus    locus;

        Assert(partkey);
        CdbPathLocus_MakeHashed(&locus, partkey);

        uniquePath->subpath = cdbpath_create_motion_path(ctx->root,
                                                         uniquePath->subpath,
                                                         NIL,
                                                         false,
                                                         locus);
        Insist(uniquePath->subpath);
        uniquePath->path.locus = uniquePath->subpath->locus;
        uniquePath->path.motionHazard = uniquePath->subpath->motionHazard;
        uniquePath->path.rescannable = uniquePath->subpath->rescannable;
        list_free_deep(eq);
    }

    /* Prune row id var list to remove items not needed downstream. */
    ctx->rowid_vars = cdbpath_dedup_pickvars(ctx->rowid_vars, downstream_relids);

    bms_free(ctx->distinct_on_rowid_relids);
    ctx->distinct_on_rowid_relids = downstream_relids;
    return CdbVisit_Skip;       /* we visited kids already; done with subtree */
}                               /* cdbpath_dedup_fixup_unique */

static void
cdbpath_dedup_fixup_baserel(Path *path, CdbpathDedupFixupContext *ctx)
{
    RelOptInfo *rel = path->parent;
    List       *rowid_vars = NIL;
    Const      *con;
    Var        *var;

    Assert(!ctx->rowid_vars);

    /* Find or make a Var node referencing our 'ctid' system attribute. */
    var = find_indexkey_var(ctx->root, rel, SelfItemPointerAttributeNumber);
    rowid_vars = lappend(rowid_vars, var);

    /*
     * If below a Motion operator, make a Var node for our 'gp_segment_id' attr.
     *
     * Omit if the data is known to come from just one segment, or consists
     * only of constants (e.g. values scan) or immutable function results.
     */
    if (ctx->need_segment_id)
    {
        if (!CdbPathLocus_IsBottleneck(path->locus) &&
            !CdbPathLocus_IsGeneral(path->locus))
        {
	        var = find_indexkey_var(ctx->root, rel, GpSegmentIdAttributeNumber);
	        rowid_vars = lappend(rowid_vars, var);
        }
    }

    /*
     * If below an Append, add 'gp_subplan_id' pseudo column to the targetlist.
     *
     * set_plan_references() will later replace the pseudo column Var node
     * in our rel's targetlist with a copy of its defining expression, i.e.
     * the Const node built here.
     */
    if (ctx->need_subplan_id)
    {
        /* Make a Const node containing the current subplan id. */
        con = makeConst(INT4OID, -1, sizeof(int32), Int32GetDatum(ctx->subplan_id),
                        false, true);

        /* Set up a pseudo column whose value will be the constant. */
        var = cdb_define_pseudo_column(ctx->root, rel, "gp_subplan_id",
                                       (Expr *)con, sizeof(int32));

        /* Give downstream operators a Var referencing the pseudo column. */
        rowid_vars = lappend(rowid_vars, var);
    }

    /* Add these vars to the rel's list of result columns. */
    add_vars_to_targetlist(ctx->root, rowid_vars, ctx->distinct_on_rowid_relids);

    /* Recalculate width of the rel's result rows. */
    set_rel_width(ctx->root, rel);

    /*
     * Tell caller to add our vars to the DISTINCT ON key of the ancestral
     * UniquePath, and to the targetlists of any intervening ancestors.
     */
    ctx->rowid_vars = rowid_vars;
}                               /* cdbpath_dedup_fixup_baserel */

static void
cdbpath_dedup_fixup_joinrel(JoinPath *joinpath, CdbpathDedupFixupContext *ctx)
{
    RelOptInfo *rel = joinpath->path.parent;

    Assert(!ctx->rowid_vars);

    /* CDB TODO: Subpath id isn't needed from both outer and inner.
     * Don't request row id vars from rhs of EXISTS join.
     */

    /* Get row id vars from outer subpath. */
    if (joinpath->outerjoinpath)
        pathnode_walk_node(joinpath->outerjoinpath, cdbpath_dedup_fixup_walker, ctx);

    /* Get row id vars from inner subpath. */
    if (joinpath->innerjoinpath)
    {
        List   *outer_rowid_vars = ctx->rowid_vars;

        ctx->rowid_vars = NIL;
        pathnode_walk_node(joinpath->innerjoinpath, cdbpath_dedup_fixup_walker, ctx);

        /* Which rel has more rows?  Put its row id vars in front. */
        if (outer_rowid_vars &&
            ctx->rowid_vars &&
            cdbpath_rows(ctx->root, joinpath->outerjoinpath) >= cdbpath_rows(ctx->root, joinpath->innerjoinpath))
            ctx->rowid_vars = list_concat(outer_rowid_vars, ctx->rowid_vars);
        else
            ctx->rowid_vars = list_concat(ctx->rowid_vars, outer_rowid_vars);
    }

    /* Update joinrel's targetlist and adjust row width. */
    if (ctx->rowid_vars)
        build_joinrel_tlist(ctx->root, rel, ctx->rowid_vars);
}                               /* cdbpath_dedup_fixup_joinrel */

static void
cdbpath_dedup_fixup_motion(CdbMotionPath *motionpath, CdbpathDedupFixupContext *ctx)
{
    bool        save_need_segment_id = ctx->need_segment_id;

    /*
     * Motion could bring together rows which happen to have the same ctid
     * but are actually from different segments.  They must not be treated
     * as duplicates.  To distinguish them, let each row be labeled with
     * its originating segment id.
     */
    ctx->need_segment_id = true;

    /* Visit the upstream nodes. */
    pathnode_walk_node(motionpath->subpath, cdbpath_dedup_fixup_walker, ctx);

    /* Restore saved flag. */
    ctx->need_segment_id = save_need_segment_id;
}                               /* cdbpath_dedup_fixup_motion */

static void
cdbpath_dedup_fixup_append(AppendPath *appendPath, CdbpathDedupFixupContext *ctx)
{
    Relids      save_distinct_on_rowid_relids = ctx->distinct_on_rowid_relids;
    List       *appendrel_rowid_vars;
    ListCell   *cell;
    int         ncol;
    bool        save_need_subplan_id = ctx->need_subplan_id;

    Assert(!ctx->rowid_vars);

    /* Make a working copy of the set of relids for which row ids are needed. */
    ctx->distinct_on_rowid_relids = bms_copy(ctx->distinct_on_rowid_relids);

    /*
     * Append could bring together rows which happen to have the same ctid
     * but are actually from different tables or different branches of a
     * UNION ALL.  They must not be treated as duplicates.  To distinguish
     * them, let each row be labeled with an integer which will be different
     * for each branch of the Append.
     */
    ctx->need_subplan_id = true;

    /* Assign a dummy subplan id (not actually used) for the appendrel. */
    ctx->subplan_id++;

    /* Add placeholder columns to the appendrel's targetlist. */
    cdbpath_dedup_fixup_baserel((Path *)appendPath, ctx);
    ncol = list_length(appendPath->path.parent->reltargetlist);

    appendrel_rowid_vars = ctx->rowid_vars;
    ctx->rowid_vars = NIL;

    /* Update the parent and child rels. */
    foreach(cell, appendPath->subpaths)
    {
        Path       *subpath = (Path *)lfirst(cell);

        if (!subpath)
            continue;

        /* Assign a subplan id to this branch of the Append. */
        ctx->subplan_id++;

        /* Tell subpath to produce row ids. */
        ctx->distinct_on_rowid_relids =
            bms_add_members(ctx->distinct_on_rowid_relids,
                            subpath->parent->relids);

        /* Process one subpath. */
        pathnode_walk_node(subpath, cdbpath_dedup_fixup_walker, ctx);

        /*
         * Subpath and appendrel should have same number of result columns.
         * CDB TODO: Add dummy columns to other subpaths to keep their
         * targetlists in sync.
         */
        if (list_length(subpath->parent->reltargetlist) != ncol)
            ereport(ERROR, (errcode(ERRCODE_CDB_FEATURE_NOT_YET),
                                    errmsg("The query is not yet supported in "
                                           "this version of " PACKAGE_NAME "."),
                                    errdetail("Unsupported combination of "
                                              "UNION ALL of joined tables "
                                              "with subquery.")
                                    ));

        /* Don't need subpath's rowid_vars. */
        list_free(ctx->rowid_vars);
        ctx->rowid_vars = NIL;
    }

    /* Provide appendrel's row id vars to downstream operators. */
    ctx->rowid_vars = appendrel_rowid_vars;

    /* Restore saved values. */
    bms_free(ctx->distinct_on_rowid_relids);
    ctx->distinct_on_rowid_relids = save_distinct_on_rowid_relids;
    ctx->need_subplan_id = save_need_subplan_id;
}                               /* cdbpath_dedup_fixup_append */

	static CdbVisitOpt
cdbpath_dedup_fixup_walker(Path *path, void *context)
{
	CdbpathDedupFixupContext   *ctx = (CdbpathDedupFixupContext *)context;

	Assert(!ctx->rowid_vars);

	/* Watch for a UniquePath node calling for removal of dups by row id. */
	if (path->pathtype == T_Unique)
		return cdbpath_dedup_fixup_unique((UniquePath *)path, ctx);

	/* Leave node unchanged unless a downstream Unique op needs row ids. */
	if (!bms_overlap(path->parent->relids, ctx->distinct_on_rowid_relids))
		return CdbVisit_Walk;       /* visit descendants */

	/* Alter this node to produce row ids for an ancestral Unique operator. */
	switch (path->pathtype)
	{
		case T_Append:
			cdbpath_dedup_fixup_append((AppendPath *)path, ctx);
			break;

		case T_SeqScan:
		case T_ExternalScan:
		case T_AppendOnlyScan:
		case T_ParquetScan:
		case T_IndexScan:
		case T_BitmapHeapScan:
		case T_BitmapTableScan:
		case T_TidScan:
		case T_SubqueryScan:
		case T_FunctionScan:
		case T_ValuesScan:
		case T_CteScan:
			cdbpath_dedup_fixup_baserel(path, ctx);
			break;

		case T_HashJoin:
		case T_MergeJoin:
		case T_NestLoop:
			cdbpath_dedup_fixup_joinrel((JoinPath *)path, ctx);
			break;

		case T_Result:
		case T_Material:
			/* These nodes share child's RelOptInfo and don't need fixup. */
			return CdbVisit_Walk;           /* visit descendants */

		case T_Motion:
			cdbpath_dedup_fixup_motion((CdbMotionPath *)path, ctx);
			break;

		default:
			Insist(0);
	}
	return CdbVisit_Skip;       /* already visited kids, don't revisit them */
}                               /* cdbpath_dedup_fixup_walker */

void
cdbpath_dedup_fixup(PlannerInfo *root, Path *path)
{
    CdbpathDedupFixupContext    context;

    memset(&context, 0, sizeof(context));

    context.root = root;

    pathnode_walk_node(path, cdbpath_dedup_fixup_walker, &context);

    Assert(bms_is_empty(context.distinct_on_rowid_relids) &&
           !context.rowid_vars &&
           !context.need_segment_id &&
           !context.need_subplan_id);
}                               /* cdbpath_dedup_fixup */
