Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

tidpath.c File Reference

#include "postgres.h"
#include "access/sysattr.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
Include dependency graph for tidpath.c:

Go to the source code of this file.

Functions

static bool IsTidEqualClause (OpExpr *node, int varno)
static bool IsTidEqualAnyClause (ScalarArrayOpExpr *node, int varno)
static ListTidQualFromExpr (Node *expr, int varno)
static ListTidQualFromRestrictinfo (List *restrictinfo, int varno)
void create_tidscan_paths (PlannerInfo *root, RelOptInfo *rel)

Function Documentation

void create_tidscan_paths ( PlannerInfo root,
RelOptInfo rel 
)

Definition at line 250 of file tidpath.c.

References add_path(), RelOptInfo::baserestrictinfo, create_tidscan_path(), RelOptInfo::lateral_relids, RelOptInfo::relid, and TidQualFromRestrictinfo().

Referenced by set_plain_rel_pathlist().

{
    Relids      required_outer;
    List       *tidquals;

    /*
     * We don't support pushing join clauses into the quals of a tidscan, but
     * it could still have required parameterization due to LATERAL refs in
     * its tlist.  (That can only happen if the tidscan is on a relation
     * pulled up out of a UNION ALL appendrel.)
     */
    required_outer = rel->lateral_relids;

    tidquals = TidQualFromRestrictinfo(rel->baserestrictinfo, rel->relid);

    if (tidquals)
        add_path(rel, (Path *) create_tidscan_path(root, rel, tidquals,
                                                   required_outer));
}

static bool IsTidEqualAnyClause ( ScalarArrayOpExpr node,
int  varno 
) [static]

Definition at line 117 of file tidpath.c.

References ScalarArrayOpExpr::args, Assert, is_pseudo_constant_clause(), IsA, linitial, list_length(), lsecond, ScalarArrayOpExpr::opno, SelfItemPointerAttributeNumber, TIDEqualOperator, TIDOID, ScalarArrayOpExpr::useOr, RangeQueryClause::var, Var::varattno, Var::varlevelsup, Var::varno, and Var::vartype.

Referenced by TidQualFromExpr().

{
    Node       *arg1,
               *arg2;

    /* Operator must be tideq */
    if (node->opno != TIDEqualOperator)
        return false;
    if (!node->useOr)
        return false;
    Assert(list_length(node->args) == 2);
    arg1 = linitial(node->args);
    arg2 = lsecond(node->args);

    /* CTID must be first argument */
    if (arg1 && IsA(arg1, Var))
    {
        Var        *var = (Var *) arg1;

        if (var->varattno == SelfItemPointerAttributeNumber &&
            var->vartype == TIDOID &&
            var->varno == varno &&
            var->varlevelsup == 0)
        {
            /* The other argument must be a pseudoconstant */
            if (is_pseudo_constant_clause(arg2))
                return true;    /* success */
        }
    }

    return false;
}

static bool IsTidEqualClause ( OpExpr node,
int  varno 
) [static]

Definition at line 65 of file tidpath.c.

References OpExpr::args, exprType(), is_pseudo_constant_clause(), IsA, linitial, list_length(), lsecond, OpExpr::opno, SelfItemPointerAttributeNumber, TIDEqualOperator, TIDOID, RangeQueryClause::var, Var::varattno, Var::varlevelsup, Var::varno, and Var::vartype.

Referenced by TidQualFromExpr().

{
    Node       *arg1,
               *arg2,
               *other;
    Var        *var;

    /* Operator must be tideq */
    if (node->opno != TIDEqualOperator)
        return false;
    if (list_length(node->args) != 2)
        return false;
    arg1 = linitial(node->args);
    arg2 = lsecond(node->args);

    /* Look for CTID as either argument */
    other = NULL;
    if (arg1 && IsA(arg1, Var))
    {
        var = (Var *) arg1;
        if (var->varattno == SelfItemPointerAttributeNumber &&
            var->vartype == TIDOID &&
            var->varno == varno &&
            var->varlevelsup == 0)
            other = arg2;
    }
    if (!other && arg2 && IsA(arg2, Var))
    {
        var = (Var *) arg2;
        if (var->varattno == SelfItemPointerAttributeNumber &&
            var->vartype == TIDOID &&
            var->varno == varno &&
            var->varlevelsup == 0)
            other = arg1;
    }
    if (!other)
        return false;
    if (exprType(other) != TIDOID)
        return false;           /* probably can't happen */

    /* The other argument must be a pseudoconstant */
    if (!is_pseudo_constant_clause(other))
        return false;

    return true;                /* success */
}

static List * TidQualFromExpr ( Node expr,
int  varno 
) [static]

Definition at line 166 of file tidpath.c.

References and_clause(), is_opclause, IsA, IsTidEqualAnyClause(), IsTidEqualClause(), lfirst, list_concat(), list_free(), list_make1, and or_clause().

Referenced by TidQualFromRestrictinfo().

{
    List       *rlst = NIL;
    ListCell   *l;

    if (is_opclause(expr))
    {
        /* base case: check for tideq opclause */
        if (IsTidEqualClause((OpExpr *) expr, varno))
            rlst = list_make1(expr);
    }
    else if (expr && IsA(expr, ScalarArrayOpExpr))
    {
        /* another base case: check for tid = ANY clause */
        if (IsTidEqualAnyClause((ScalarArrayOpExpr *) expr, varno))
            rlst = list_make1(expr);
    }
    else if (expr && IsA(expr, CurrentOfExpr))
    {
        /* another base case: check for CURRENT OF on this rel */
        if (((CurrentOfExpr *) expr)->cvarno == varno)
            rlst = list_make1(expr);
    }
    else if (and_clause(expr))
    {
        foreach(l, ((BoolExpr *) expr)->args)
        {
            rlst = TidQualFromExpr((Node *) lfirst(l), varno);
            if (rlst)
                break;
        }
    }
    else if (or_clause(expr))
    {
        foreach(l, ((BoolExpr *) expr)->args)
        {
            List       *frtn = TidQualFromExpr((Node *) lfirst(l), varno);

            if (frtn)
                rlst = list_concat(rlst, frtn);
            else
            {
                if (rlst)
                    list_free(rlst);
                rlst = NIL;
                break;
            }
        }
    }
    return rlst;
}

static List * TidQualFromRestrictinfo ( List restrictinfo,
int  varno 
) [static]

Definition at line 225 of file tidpath.c.

References RestrictInfo::clause, IsA, lfirst, and TidQualFromExpr().

Referenced by create_tidscan_paths().

{
    List       *rlst = NIL;
    ListCell   *l;

    foreach(l, restrictinfo)
    {
        RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);

        if (!IsA(rinfo, RestrictInfo))
            continue;           /* probably should never happen */
        rlst = TidQualFromExpr((Node *) rinfo->clause, varno);
        if (rlst)
            break;
    }
    return rlst;
}