#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"
Go to the source code of this file.
Functions | |
| static bool | IsTidEqualClause (OpExpr *node, int varno) |
| static bool | IsTidEqualAnyClause (ScalarArrayOpExpr *node, int varno) |
| static List * | TidQualFromExpr (Node *expr, int varno) |
| static List * | TidQualFromRestrictinfo (List *restrictinfo, int varno) |
| void | create_tidscan_paths (PlannerInfo *root, RelOptInfo *rel) |
| 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;
}
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 */
}
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;
}
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;
}
1.7.1