/*
 * 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.
 */

/*-------------------------------------------------------------------------
 *
 * cdbpullup.c
 *    Provides routines supporting plan tree manipulation.
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "nodes/makefuncs.h"            /* makeVar() */
#include "nodes/plannodes.h"            /* Plan */
#include "optimizer/clauses.h"          /* expression_tree_walker/mutator */
#include "optimizer/tlist.h"            /* tlist_member() */
#include "parser/parse_expr.h"          /* exprType() and exprTypmod() */
#include "parser/parsetree.h"           /* get_tle_by_resno() */

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


/*
 * cdbpullup_colIdx
 *
 * Given a [potentially] projecting Plan operator and a vector
 * of attribute numbers in the plan's single subplan, create a
 * vector of attribute numbers in the plan's targetlist.
 *
 * Parameters:
 *      plan -> the Plan node
 *      subplan -> the Plan node's subplan
 *      numCols = number of colIdx array elements
 *      subplanColIdx (IN) -> array [0..numCols-1] of AttrNumber, designating
 *          entries in the targetlist of the Plan operator's subplan.
 *     *pProjectedColIdx (OUT) -> array [0..n-1] of AttrNumber, palloc'd
 *          by this function, where n is the function's return value; or
 *          NULL when n == 0.
 *
 * Returns the number of leading subplanColIdx entries for which matching
 * Var nodes were found in the plan's targetlist.
 */
int
cdbpullup_colIdx(struct Plan   *plan,
                 struct Plan   *subplan,
                 int            numCols,
                 AttrNumber    *subplanColIdx,
                 AttrNumber   **pProjectedColIdx)
{
    TargetEntry    *tle;
    int             i;
    bool            useExecutorVarFormat;

    Assert(pProjectedColIdx);
    *pProjectedColIdx = NULL;

    /*
     * Look at an arbitrary Var node in the upper Plan node's targetlist
     * to see if it has been adjusted by set_plan_references().
     *
     * Before set_plan_references(), if Var nodes are equal(), then
     * they are equivalent in meaning, more or less.  Afterwards
     * that is no longer the case; each Var node is implicitly tied to
     * a particular evaluation context (i.e. a certain Plan node's
     * targetlist), which means expr trees for different contexts are
     * incomparable.
     */

    useExecutorVarFormat = cdbpullup_exprHasSubplanRef((Expr *)plan->targetlist);

    /*
     * Translate the column index array.
     */
    for (i = 0; i < numCols; i++)
    {
        Index   kidTargetIdx = subplanColIdx[i];

        /*
         * Search our targetlist for a Var that references the specified
         * item of the subplan's targetlist.  All Var nodes (at least, all
         * that we expect to encounter here) are converted to this form by
         * set_plan_references() at the end of optimization.
         */
        if (useExecutorVarFormat)
            tle = cdbpullup_findSubplanRefInTargetList(kidTargetIdx, plan->targetlist);

        /*
         * Iff set_plan_references() hasn't been called yet, a different
         * procedure is necessary: search our own targetlist for a copy of
         * the designated expr from the subplan targetlist.
         */
        else
        {
            TargetEntry    *subtle;

            /* Get subplan's targetlist entry. */
            subtle = get_tle_by_resno(subplan->targetlist, kidTargetIdx);
            Assert(subtle);

            /* Look for matching expr in the given plan's targetlist. */
            tle = tlist_member_ignoring_RelabelType(subtle->expr, plan->targetlist);
        }

        /* Quit if the plan's projection doesn't include this column. */
        if (!tle)
            break;

        if (i == 0)
            *pProjectedColIdx = palloc(numCols * sizeof((*pProjectedColIdx)[0]));

        (*pProjectedColIdx)[i] = tle->resno;
    }

    return i;
}                               /* cdbpullup_colIdx */


/*
 * cdbpullup_expr
 *
 * Suppose there is a Plan node 'P' whose projection is defined by
 * a targetlist 'TL', and which has subplan 'S'.  Given TL and an
 * expr 'X0' whose Var nodes reference the result columns of S, this
 * function returns a new expr 'X1' that is a copy of X0 with Var nodes
 * adjusted to reference the columns of S after their passage through P.
 *
 * Parameters:
 *      expr -> X0, the expr in terms of the subplan S's targetlist
 *      targetlist -> TL (a List of TargetEntry), the plan P's targetlist
 *              (or can be a List of Expr)
 *      newvarlist -> an optional List of Expr, in 1-1 correspondence with
 *              targetlist.  If specified, instead of creating a Var node to
 *              reference a targetlist item, we plug in a copy of the
 *              corresponding newvarlist item.
 *      newvarno = varno to be used in new Var nodes.  Ignored if a non-NULL
 *              newvarlist is given.
 *
 * When calling this function on an expr which has NOT yet been transformed
 * by set_plan_references(), newvarno should be the RTE index assigned to
 * the result of the projection.
 *
 * When calling this function on an expr which HAS been transformed by
 * set_plan_references(), newvarno should usually be OUTER; or 0 if the
 * expr is to be used in the targetlist of an Agg or Group node.
 *
 * At present this function doesn't support pull-up from a subquery into a
 * containing query: there is no provision for adjusting the varlevelsup
 * field in Var nodes for outer references.  This could be added if needed.
 *
 * Returns X1, the expr recast in terms of the given targetlist; or
 * NULL if X0 references a column of S that is not projected in TL.
 */
struct pullUpExpr_context
{
    List   *targetlist;
    List   *newvarlist;
    Index   newvarno;
    Var    *notfound;
};

static Node*
pullUpExpr_mutator(Node *node, void *context)
{
    struct pullUpExpr_context  *ctx = (struct pullUpExpr_context *)context;
    TargetEntry    *tle;
    Node           *newnode;
    Var            *var;

    if (!node ||
        ctx->notfound)
        return NULL;

    /* Pull up Var. */
    if (IsA(node, Var))
    {
        var = (Var *)node;

        /* Outer reference?  Just copy it. */
        if (var->varlevelsup > 0)
            return (Node *)copyObject(var);

        if (!ctx->targetlist)
            goto fail;

        /* Is targetlist a List of TargetEntry?  (Plan nodes use this format) */
        if (IsA(linitial(ctx->targetlist), TargetEntry))
        {

            /* After set_plan_references(), search on varattno only. */
            if (var->varno == OUTER ||
                var->varno == INNER ||
                var->varno == 0)
                tle = cdbpullup_findSubplanRefInTargetList(var->varattno,
                                                           ctx->targetlist);
            /* Before set_plan_references(), search for exact match. */
            else
                tle = tlist_member((Node *)var, ctx->targetlist);

            /* Fail if P's result does not include this column. */
            if (!tle)
                goto fail;

            /* Substitute the corresponding entry from newvarlist, if given. */
            if (ctx->newvarlist)
                newnode = (Node *)copyObject(list_nth(ctx->newvarlist,
                                                      tle->resno - 1));

            /* Substitute a Var node referencing the targetlist entry. */
            else
                newnode = (Node *)cdbpullup_make_expr(ctx->newvarno,
                                    tle->resno,
                                    (Expr *)var,
                                    true);
        }

        /* Planner's RelOptInfo targetlists don't have TargetEntry nodes. */
        else
        {
            ListCell   *cell;
            Expr       *tlistexpr = NULL;
            AttrNumber  targetattno = 1;

            foreach(cell, ctx->targetlist)
            {
                tlistexpr = (Expr *)lfirst(cell);
	            if (equal(tlistexpr, var))
                    break;
                targetattno++;
            }
            if (!cell)
                goto fail;

            /* Substitute the corresponding entry from newvarlist, if given. */
            if (ctx->newvarlist)
                newnode = (Node *)copyObject(list_nth(ctx->newvarlist,
                                                      targetattno - 1));

            /* Substitute a Var node referencing the targetlist entry. */
            else
                newnode = (Node *)cdbpullup_make_expr(ctx->newvarno,
                                                    targetattno,
                                                    tlistexpr, true);
        }

        /* Make sure we haven't inadvertently changed the data type. */
        Assert(exprType(newnode) == exprType(node) &&
               exprTypmod(newnode) == exprTypmod(node));

        return newnode;
    }

    /* The whole expr might be in the targetlist of a Plan node. */
    else if (!IsA(node, List) &&
             ctx->targetlist &&
             IsA(linitial(ctx->targetlist), TargetEntry) &&
             NULL != (tle = tlist_member(node, ctx->targetlist)))
    {
        /* Substitute the corresponding entry from newvarlist, if given. */
        if (ctx->newvarlist)
            newnode = (Node *)copyObject(list_nth(ctx->newvarlist,
                                                  tle->resno - 1));

        /* Replace expr with a Var node referencing the targetlist entry. */
        else
            newnode = (Node *)cdbpullup_make_expr(ctx->newvarno,
                                tle->resno,
                                tle->expr, true);

        /* Make sure we haven't inadvertently changed the data type. */
        Assert(exprType(newnode) == exprType(node) &&
               exprTypmod(newnode) == exprTypmod(node));

        return newnode;
    }

    return expression_tree_mutator(node, pullUpExpr_mutator, context);

    /* Fail if P's result does not include a referenced column. */
fail:
    ctx->notfound = var;
    return NULL;
}                               /* pullUpExpr_mutator */

Expr *
cdbpullup_expr(Expr *expr, List *targetlist, List *newvarlist, Index newvarno)
{
    Expr       *newexpr;
    struct pullUpExpr_context   ctx;

    Assert(!targetlist || IsA(targetlist, List));
    Assert(!newvarlist || list_length(newvarlist) == list_length(targetlist));

    ctx.targetlist = targetlist;
    ctx.newvarlist = newvarlist;
    ctx.newvarno = newvarno;
    ctx.notfound = NULL;

    newexpr = (Expr *)pullUpExpr_mutator((Node *)expr, &ctx);

    if (ctx.notfound)
        newexpr = NULL;

    return newexpr;
}                               /* cdbpullup_expr */


/*
 * cdbpullup_exprHasSubplanRef
 *
 * Returns true if the expr's first Var is a reference to an item in the
 * targetlist of the associated Plan node's subplan.  If so, it can be
 * assumed that the Plan node and associated exprs have been processed
 * by set_plan_references(), and its Var nodes are in executor format.
 *
 * Returns false otherwise, which implies no conclusion about whether or
 * not set_plan_references() has been done.
 *
 * Note that a Var node that belongs to a Scan operator and refers to the
 * Scan's source relation or index, doesn't have its varno changed by
 * set_plan_references() to OUTER/INNER/0.  Think twice about using this
 * unless you know that the expr comes from an upper Plan node.
 */

/* Find any Var in an expr */
static bool
findAnyVar_walker(Node *node, void *ppVar)
{
    if (!node)
        return false;
    if (IsA(node, Var))
    {
        *(Var **)ppVar = (Var *)node;
        return true;
    }
    return expression_tree_walker(node, findAnyVar_walker, ppVar);
}

bool
cdbpullup_exprHasSubplanRef(Expr *expr)
{
    Var    *var;

    if (!findAnyVar_walker((Node *)expr, &var))
        return false;

    return var->varno == OUTER ||
           var->varno == INNER ||
           var->varno == 0;
}                               /* cdbpullup_exprHasSubplanRef */


/*
 * cdbpullup_findPathKeyItemInTargetList
 *
 * Searches the equivalence class 'pathkey' for a PathKeyItem that
 * uses no rels outside the 'relids' set, and either is a member of
 * 'targetlist', or uses no Vars that are not in 'targetlist'.
 *
 * If found, returns the chosen PathKeyItem and sets the output variables.
 * - If the item's Vars (if any) are in targetlist, but the item itself is not:
 *      *ptargetindex = 0
 * - Else if the targetlist is a List of TargetEntry nodes:
 *      *ptargetindex gets the matching TargetEntry's resno (which is the
 *          1-based position of the TargetEntry in the targetlist); or 0.
 * - Else if the targetlist is a plain List of Expr without TargetEntry nodes:
 *      *ptargetindex gets the 1-based position of the matching entry in the
 *          targetlist, or 0 if the expr is not in the targetlist.
 *
 * Otherwise returns NULL and sets *ptargetindex = 0.
 *
 * 'pathkey' is a List of PathKeyItem.
 * 'relids' is the set of relids that may occur in the targetlist exprs.
 * 'targetlist' is a List of TargetEntry or merely a List of Expr.
 *
 * NB: We ignore the presence or absence of a RelabelType node atop either
 * expr in determining whether a PathKeyItem expr matches a targetlist expr.
 *
 * (A RelabelType node might have been placed atop a PathKeyItem's expr to
 * match its type to the sortop's input operand type, when the types are
 * binary compatible but not identical... such as VARCHAR and TEXT.  The
 * RelabelType node merely documents the representational equivalence but
 * does not affect the semantics.  A RelabelType node might also be found
 * atop an argument of a function or operator, but generally not atop a
 * targetlist expr.)
 */
PathKeyItem *
cdbpullup_findPathKeyItemInTargetList(List         *pathkey,
                                      Relids        relids,
                                      List         *targetlist,
                                      AttrNumber   *ptargetindex)   // OUT (optional)
{
    ListCell   *pathkeycell;

    if (ptargetindex)
       *ptargetindex = 0;

    foreach(pathkeycell, pathkey)
    {
        PathKeyItem    *item = (PathKeyItem *)lfirst(pathkeycell);
        TargetEntry    *tle;

        Assert(IsA(item, PathKeyItem));

        /* Constant expr?  Return it. */
        if (item->cdb_num_relids == 0)
            return item;

        /* Bail if targetlist is empty. */
        if (!targetlist)
            break;

        /* Consider this item if all of its rels are in 'relids'. */
        if (bms_is_subset(item->cdb_key_relids, relids))
        {
            Expr       *key = (Expr *)item->key;

            /* Ignore possible RelabelType node atop the PathKeyItem expr. */
            if (IsA(key, RelabelType))
                key = ((RelabelType *)key)->arg;

            /* Return this item if the whole expr is in targetlist. */
            if (IsA(linitial(targetlist), TargetEntry))
            {
                /* This targetlist is a List of TargetEntry. */
                tle = tlist_member_ignoring_RelabelType(key, targetlist);
                if (tle)
                {
                    if (ptargetindex)
                        *ptargetindex = tle->resno;
                    return item;
                }
            }

            /* Planner's RelOptInfo targetlists don't have TargetEntry nodes. */
            else
            {
                ListCell   *cell;
                AttrNumber  targetindex = 1;

                foreach(cell, targetlist)
                {
                    Expr   *expr = (Expr *)lfirst(cell);

                    if (IsA(expr, RelabelType))
                        expr = ((RelabelType *)expr)->arg;

		            if (equal(expr, key))
                    {
                        if (ptargetindex)
                            *ptargetindex = targetindex;
                        return item;
                    }
                    targetindex++;
                }
            }

            /* Return this item if all referenced Vars are in targetlist. */
            if (!IsA(key, Var) &&
                !cdbpullup_missingVarWalker((Node *)key, targetlist))
                return item;
        }
    }
    return NULL;
}                               /* cdbpullup_findPathKeyItemInTargetList */


/*
 * cdbpullup_findSubplanRefInTargetList
 *
 * Given a targetlist, returns ptr to first TargetEntry whose expr is a
 * Var node having the specified varattno, and having its varno in executor
 * format (varno is OUTER, INNER, or 0) as set by set_plan_references().
 * Returns NULL if no such TargetEntry is found.
 */
TargetEntry *
cdbpullup_findSubplanRefInTargetList(AttrNumber varattno, List *targetlist)
{
    ListCell       *cell;
    TargetEntry    *tle;
    Var            *var;

    foreach(cell, targetlist)
    {
        tle = (TargetEntry *)lfirst(cell);
        if (IsA(tle->expr, Var))
        {
            var = (Var *)tle->expr;
            if (var->varattno == varattno)
            {
                if (var->varno == OUTER ||
                    var->varno == INNER ||
                    var->varno == 0)
                    return tle;
            }
        }
    }
    return NULL;
}                               /* cdbpullup_findSubplanRefInTargetList */


/*
 * cdbpullup_isExprCoveredByTargetlist
 *
 * Returns true if 'expr' is in 'targetlist', or if 'expr' contains no
 * Var node of the current query level that is not in 'targetlist'.
 *
 * If 'expr' is a List, returns false if the above condition is false for
 * some member of the list.
 *
 * 'targetlist' is a List of TargetEntry.
 *
 * NB:  A Var in the expr is considered as matching a Var in the targetlist
 * without regard for whether or not there is a RelabelType node atop the
 * targetlist Var.
 *
 * See also: cdbpullup_missing_var_walker
 */
bool
cdbpullup_isExprCoveredByTargetlist(Expr *expr, List *targetlist)
{
    ListCell   *cell;

    /* List of Expr?  Verify that all items are covered. */
    if (IsA(expr, List))
    {
        foreach(cell, (List *)expr)
        {
            Expr   *item = (Expr *)lfirst(cell);

            /* The whole expr or all of its Vars must be in targetlist. */
            if (!tlist_member_ignoring_RelabelType(item, targetlist) &&
                cdbpullup_missingVarWalker((Node *)item, targetlist))
                return false;
        }
    }

    /* The whole expr or all of its Vars must be in targetlist. */
    else if (!tlist_member_ignoring_RelabelType(expr, targetlist) &&
             cdbpullup_missingVarWalker((Node *)expr, targetlist))
        return false;

    /* expr is evaluable on rows projected thru targetlist */
    return true;
}                               /* cdbpullup_isExprCoveredByTlist */


/*
 * cdbpullup_make_var
 *
 * Returns a new Var node with given 'varno' and 'varattno', and varlevelsup=0.
 *
 * The caller must provide an 'oldexpr' from which we obtain the vartype and
 * vartypmod for the new Var node.  If 'oldexpr' is a Var node, all fields are
 * copied except for varno, varattno and varlevelsup.
 *
 * The parameter modifyOld determines if varnoold and varoattno are modified or
 * not. Rule of thumb is to use modifyOld = false if called before setrefs.
 *
 * Copying an existing Var node preserves its varnoold and varoattno fields,
 * which are used by EXPLAIN to display the table and column name.
 * Also these fields are tested by equal(), so they may need to be set
 * correctly for successful lookups by list_member(), tlist_member(),
 * make_canonical_pathkey(), etc.
 */
Expr *
cdbpullup_make_expr(Index varno, AttrNumber varattno, Expr *oldexpr, bool modifyOld)
{
    Assert(oldexpr);
    
    /* If caller provided an old Var node, copy and modify it. */
    if (IsA(oldexpr, Var))
    {
        Var        *var = (Var *)copyObject(oldexpr);
        var->varno = varno;
        var->varattno = varattno;
        if (modifyOld)
        {
        	var->varoattno = varattno;
        	var->varnoold = varno;
        }
        var->varlevelsup = 0;
        return (Expr *) var;
    }
    else if (IsA(oldexpr, Const))
    {
    	Const *constExpr = copyObject(oldexpr);
    	return (Expr *) constExpr;
    }
    /* Make a new Var node. */
    else
    {
    	Var *var = NULL;
    	Assert(!IsA(oldexpr, Const));
    	Assert(!IsA(oldexpr, Var));
        var = makeVar(varno,
                      varattno,
                      exprType((Node *)oldexpr),
                      exprTypmod((Node *)oldexpr),
                      0);
        var->varnoold = varno;      /* assuming it wasn't ever a plain Var */
        var->varoattno = varattno;
        return (Expr *) var;
    }
}                               /* cdbpullup_make_var */


/*
 * cdbpullup_missingVarWalker
 *
 * Returns true if some Var in expr is not in targetlist.
 * 'targetlist' is either a List of TargetEntry, or a plain List of Expr.
 *
 * NB:  A Var in the expr is considered as matching a Var in the targetlist
 * without regard for whether or not there is a RelabelType node atop the
 * targetlist Var.
 *
 * See also: cdbpullup_isExprCoveredByTargetlist
 */
bool
cdbpullup_missingVarWalker(Node *node, void *targetlist)
{
    if (!node)
        return false;

    if (IsA(node, Var))
    {
        if (!targetlist)
            return true;

        /* is targetlist a List of TargetEntry? */
        if (IsA(linitial(targetlist), TargetEntry))
        {
            if (tlist_member_ignoring_RelabelType((Expr *)node, (List *)targetlist))
                return false;   /* this Var ok - go on to check rest of expr */
        }

        /* targetlist must be a List of Expr */
        else if (list_member((List *)targetlist, node))
            return false;       /* this Var ok - go on to check rest of expr */

        return true;            /* Var is not in targetlist - quit the walk */
    }

    return expression_tree_walker(node, cdbpullup_missingVarWalker, targetlist);
}                               /* cdbpullup_missingVarWalker */


/*
 * cdbpullup_targetentry
 *
 * Given a TargetEntry from a subplan's targetlist, this function returns a
 * new TargetEntry that can be used to pull the result value up into the
 * parent plan's projection.
 *
 * Parameters:
 *      subplan_targetentry is an item in the targetlist of the subplan S.
 *      newresno is the attribute number of the new TargetEntry (its
 *          position in P's targetlist).
 *      newvarno should be OUTER; except it should be 0 if P is an Agg or
 *          Group node.  It is ignored if useExecutorVarFormat is false.
 *      useExecutorVarFormat must be true if called after optimization,
 *          when set_plan_references() has been called and Var nodes have
 *          been adjusted to refer to items in the subplan's targetlist.
 *          It must be false before the end of optimization, when Var
 *          nodes are still in parser format, referring to RTE items.
 */
TargetEntry *
cdbpullup_targetentry(TargetEntry  *subplan_targetentry,
                      AttrNumber    newresno,
                      Index         newvarno,
                      bool          useExecutorVarFormat)
{
    TargetEntry    *kidtle = subplan_targetentry;
    TargetEntry    *newtle;

    /* After optimization, a Var's referent depends on the owning Plan node. */
    if (useExecutorVarFormat)
    {
        /* Copy the subplan's TargetEntry, without its expr. */
        newtle = flatCopyTargetEntry(kidtle);

        /* Make a Var node referencing the subplan's targetlist entry. */
        newtle->expr = cdbpullup_make_expr(newvarno,
        		kidtle->resno,
        		kidtle->expr,
        		true);
    }

    /* Until then, a Var's referent is the same anywhere in a Query. */
    else
        newtle = copyObject(kidtle);

    newtle->resno = newresno;
    return newtle;
}                               /* cdbpullup_targetentry */


/*
 * cdbpullup_targetlist
 *
 * Return a targetlist that can be attached to a parent plan yielding
 * the same projection as the given subplan.
 */
List *
cdbpullup_targetlist(struct Plan *subplan, bool useExecutorVarFormat)
{
    ListCell   *cell;
    List       *targetlist = NIL;
    AttrNumber  resno = 1;

    foreach(cell, subplan->targetlist)
    {
        TargetEntry    *kidtle = (TargetEntry *)lfirst(cell);
        TargetEntry    *newtle = cdbpullup_targetentry(kidtle,
                                                       resno++,
                                                       OUTER,
                                                       useExecutorVarFormat);

        targetlist = lappend(targetlist, newtle);
    }

    return targetlist;
}                               /* cdbpullup_targetlist */

