PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 "optimizer/restrictinfo.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 ListTidQualFromBaseRestrictinfo (RelOptInfo *rel)
 
void create_tidscan_paths (PlannerInfo *root, RelOptInfo *rel)
 

Function Documentation

void create_tidscan_paths ( PlannerInfo root,
RelOptInfo rel 
)

Definition at line 253 of file tidpath.c.

References add_path(), create_tidscan_path(), RelOptInfo::lateral_relids, and TidQualFromBaseRestrictinfo().

Referenced by set_plain_rel_pathlist().

254 {
255  Relids required_outer;
256  List *tidquals;
257 
258  /*
259  * We don't support pushing join clauses into the quals of a tidscan, but
260  * it could still have required parameterization due to LATERAL refs in
261  * its tlist.
262  */
263  required_outer = rel->lateral_relids;
264 
265  tidquals = TidQualFromBaseRestrictinfo(rel);
266 
267  if (tidquals)
268  add_path(rel, (Path *) create_tidscan_path(root, rel, tidquals,
269  required_outer));
270 }
void add_path(RelOptInfo *parent_rel, Path *new_path)
Definition: pathnode.c:412
static List * TidQualFromBaseRestrictinfo(RelOptInfo *rel)
Definition: tidpath.c:223
Relids lateral_relids
Definition: relation.h:550
TidPath * create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, List *tidquals, Relids required_outer)
Definition: pathnode.c:1172
Definition: pg_list.h:45
Definition: relation.h:948
static bool IsTidEqualAnyClause ( ScalarArrayOpExpr node,
int  varno 
)
static

Definition at line 118 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().

119 {
120  Node *arg1,
121  *arg2;
122 
123  /* Operator must be tideq */
124  if (node->opno != TIDEqualOperator)
125  return false;
126  if (!node->useOr)
127  return false;
128  Assert(list_length(node->args) == 2);
129  arg1 = linitial(node->args);
130  arg2 = lsecond(node->args);
131 
132  /* CTID must be first argument */
133  if (arg1 && IsA(arg1, Var))
134  {
135  Var *var = (Var *) arg1;
136 
138  var->vartype == TIDOID &&
139  var->varno == varno &&
140  var->varlevelsup == 0)
141  {
142  /* The other argument must be a pseudoconstant */
143  if (is_pseudo_constant_clause(arg2))
144  return true; /* success */
145  }
146  }
147 
148  return false;
149 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Index varlevelsup
Definition: primnodes.h:173
Definition: nodes.h:509
AttrNumber varattno
Definition: primnodes.h:168
Definition: primnodes.h:163
#define lsecond(l)
Definition: pg_list.h:116
#define TIDOID
Definition: pg_type.h:332
#define linitial(l)
Definition: pg_list.h:111
Oid vartype
Definition: primnodes.h:170
bool is_pseudo_constant_clause(Node *clause)
Definition: clauses.c:2196
Index varno
Definition: primnodes.h:166
#define Assert(condition)
Definition: c.h:676
static int list_length(const List *l)
Definition: pg_list.h:89
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
#define TIDEqualOperator
Definition: pg_operator.h:162
static bool IsTidEqualClause ( OpExpr node,
int  varno 
)
static

Definition at line 66 of file tidpath.c.

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

Referenced by TidQualFromExpr().

67 {
68  Node *arg1,
69  *arg2,
70  *other;
71  Var *var;
72 
73  /* Operator must be tideq */
74  if (node->opno != TIDEqualOperator)
75  return false;
76  if (list_length(node->args) != 2)
77  return false;
78  arg1 = linitial(node->args);
79  arg2 = lsecond(node->args);
80 
81  /* Look for CTID as either argument */
82  other = NULL;
83  if (arg1 && IsA(arg1, Var))
84  {
85  var = (Var *) arg1;
87  var->vartype == TIDOID &&
88  var->varno == varno &&
89  var->varlevelsup == 0)
90  other = arg2;
91  }
92  if (!other && arg2 && IsA(arg2, Var))
93  {
94  var = (Var *) arg2;
96  var->vartype == TIDOID &&
97  var->varno == varno &&
98  var->varlevelsup == 0)
99  other = arg1;
100  }
101  if (!other)
102  return false;
103  if (exprType(other) != TIDOID)
104  return false; /* probably can't happen */
105 
106  /* The other argument must be a pseudoconstant */
107  if (!is_pseudo_constant_clause(other))
108  return false;
109 
110  return true; /* success */
111 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Index varlevelsup
Definition: primnodes.h:173
Definition: nodes.h:509
AttrNumber varattno
Definition: primnodes.h:168
Definition: primnodes.h:163
#define lsecond(l)
Definition: pg_list.h:116
#define TIDOID
Definition: pg_type.h:332
#define linitial(l)
Definition: pg_list.h:111
Oid vartype
Definition: primnodes.h:170
bool is_pseudo_constant_clause(Node *clause)
Definition: clauses.c:2196
Index varno
Definition: primnodes.h:166
#define NULL
Definition: c.h:229
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
static int list_length(const List *l)
Definition: pg_list.h:89
Oid opno
Definition: primnodes.h:496
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
List * args
Definition: primnodes.h:502
#define TIDEqualOperator
Definition: pg_operator.h:162
static List * TidQualFromBaseRestrictinfo ( RelOptInfo rel)
static

Definition at line 223 of file tidpath.c.

References RelOptInfo::baserestrictinfo, RestrictInfo::clause, lfirst, NIL, RelOptInfo::relid, restriction_is_securely_promotable(), and TidQualFromExpr().

Referenced by create_tidscan_paths().

224 {
225  List *rlst = NIL;
226  ListCell *l;
227 
228  foreach(l, rel->baserestrictinfo)
229  {
230  RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
231 
232  /*
233  * If clause must wait till after some lower-security-level
234  * restriction clause, reject it.
235  */
236  if (!restriction_is_securely_promotable(rinfo, rel))
237  continue;
238 
239  rlst = TidQualFromExpr((Node *) rinfo->clause, rel->relid);
240  if (rlst)
241  break;
242  }
243  return rlst;
244 }
#define NIL
Definition: pg_list.h:69
List * baserestrictinfo
Definition: relation.h:585
Definition: nodes.h:509
static List * TidQualFromExpr(Node *expr, int varno)
Definition: tidpath.c:167
Index relid
Definition: relation.h:553
Expr * clause
Definition: relation.h:1747
#define lfirst(lc)
Definition: pg_list.h:106
bool restriction_is_securely_promotable(RestrictInfo *restrictinfo, RelOptInfo *rel)
Definition: restrictinfo.c:310
Definition: pg_list.h:45
static List * TidQualFromExpr ( Node expr,
int  varno 
)
static

Definition at line 167 of file tidpath.c.

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

Referenced by TidQualFromBaseRestrictinfo().

168 {
169  List *rlst = NIL;
170  ListCell *l;
171 
172  if (is_opclause(expr))
173  {
174  /* base case: check for tideq opclause */
175  if (IsTidEqualClause((OpExpr *) expr, varno))
176  rlst = list_make1(expr);
177  }
178  else if (expr && IsA(expr, ScalarArrayOpExpr))
179  {
180  /* another base case: check for tid = ANY clause */
181  if (IsTidEqualAnyClause((ScalarArrayOpExpr *) expr, varno))
182  rlst = list_make1(expr);
183  }
184  else if (expr && IsA(expr, CurrentOfExpr))
185  {
186  /* another base case: check for CURRENT OF on this rel */
187  if (((CurrentOfExpr *) expr)->cvarno == varno)
188  rlst = list_make1(expr);
189  }
190  else if (and_clause(expr))
191  {
192  foreach(l, ((BoolExpr *) expr)->args)
193  {
194  rlst = TidQualFromExpr((Node *) lfirst(l), varno);
195  if (rlst)
196  break;
197  }
198  }
199  else if (or_clause(expr))
200  {
201  foreach(l, ((BoolExpr *) expr)->args)
202  {
203  List *frtn = TidQualFromExpr((Node *) lfirst(l), varno);
204 
205  if (frtn)
206  rlst = list_concat(rlst, frtn);
207  else
208  {
209  if (rlst)
210  list_free(rlst);
211  rlst = NIL;
212  break;
213  }
214  }
215  }
216  return rlst;
217 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Definition: nodes.h:509
List * list_concat(List *list1, List *list2)
Definition: list.c:321
static List * TidQualFromExpr(Node *expr, int varno)
Definition: tidpath.c:167
#define list_make1(x1)
Definition: pg_list.h:139
static bool IsTidEqualClause(OpExpr *node, int varno)
Definition: tidpath.c:66
#define is_opclause(clause)
Definition: clauses.h:20
bool and_clause(Node *clause)
Definition: clauses.c:314
static bool IsTidEqualAnyClause(ScalarArrayOpExpr *node, int varno)
Definition: tidpath.c:118
bool or_clause(Node *clause)
Definition: clauses.c:280
#define lfirst(lc)
Definition: pg_list.h:106
void list_free(List *list)
Definition: list.c:1133
Definition: pg_list.h:45