PostgreSQL Source Code git master
Loading...
Searching...
No Matches
inherit.h File Reference
#include "nodes/pathnodes.h"
Include dependency graph for inherit.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void expand_inherited_rtentry (PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte, Index rti)
 
Bitmapsetget_rel_all_updated_cols (PlannerInfo *root, RelOptInfo *rel)
 
bool apply_child_basequals (PlannerInfo *root, RelOptInfo *parentrel, RelOptInfo *childrel, RangeTblEntry *childRTE, AppendRelInfo *appinfo)
 

Function Documentation

◆ apply_child_basequals()

bool apply_child_basequals ( PlannerInfo root,
RelOptInfo parentrel,
RelOptInfo childrel,
RangeTblEntry childRTE,
AppendRelInfo appinfo 
)
extern

Definition at line 839 of file inherit.c.

842{
845 ListCell *lc;
846
847 /*
848 * The child rel's targetlist might contain non-Var expressions, which
849 * means that substitution into the quals could produce opportunities for
850 * const-simplification, and perhaps even pseudoconstant quals. Therefore,
851 * transform each RestrictInfo separately to see if it reduces to a
852 * constant or pseudoconstant. (We must process them separately to keep
853 * track of the security level of each qual.)
854 */
855 childquals = NIL;
857 foreach(lc, parentrel->baserestrictinfo)
858 {
859 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
861 ListCell *lc2;
862
863 Assert(IsA(rinfo, RestrictInfo));
865 (Node *) rinfo->clause,
866 1, &appinfo);
868 /* check for flat-out constant */
869 if (childqual && IsA(childqual, Const))
870 {
871 if (((Const *) childqual)->constisnull ||
873 {
874 /* Restriction reduces to constant FALSE or NULL */
875 return false;
876 }
877 /* Restriction reduces to constant TRUE, so drop it */
878 continue;
879 }
880 /* might have gotten an AND clause, if so flatten it */
881 foreach(lc2, make_ands_implicit((Expr *) childqual))
882 {
883 Node *onecq = (Node *) lfirst(lc2);
884 bool pseudoconstant;
886
887 /* check for pseudoconstant (no Vars or volatile functions) */
891 if (pseudoconstant)
892 {
893 /* tell createplan.c to check for gating quals */
894 root->hasPseudoConstantQuals = true;
895 }
896 /* reconstitute RestrictInfo with appropriate properties */
898 (Expr *) onecq,
899 rinfo->is_pushed_down,
900 rinfo->has_clone,
901 rinfo->is_clone,
903 rinfo->security_level,
904 NULL, NULL, NULL);
905
907 /* track minimum security level among child quals */
908 cq_min_security = Min(cq_min_security, childrinfo->security_level);
909 }
910 }
911
912 /*
913 * In addition to the quals inherited from the parent, we might have
914 * securityQuals associated with this particular child node. (Currently
915 * this can only happen in appendrels originating from UNION ALL;
916 * inheritance child tables don't have their own securityQuals, see
917 * expand_single_inheritance_child().) Pull any such securityQuals up
918 * into the baserestrictinfo for the child. This is similar to
919 * process_security_barrier_quals() for the parent rel, except that we
920 * can't make any general deductions from such quals, since they don't
921 * hold for the whole appendrel.
922 */
923 if (childRTE->securityQuals)
924 {
925 Index security_level = 0;
926
927 foreach(lc, childRTE->securityQuals)
928 {
929 List *qualset = (List *) lfirst(lc);
930 ListCell *lc2;
931
932 foreach(lc2, qualset)
933 {
934 Expr *qual = (Expr *) lfirst(lc2);
935
936 /* not likely that we'd see constants here, so no check */
939 true,
940 false, false,
941 false,
942 security_level,
943 NULL, NULL, NULL));
944 cq_min_security = Min(cq_min_security, security_level);
945 }
946 security_level++;
947 }
948 Assert(security_level <= root->qual_security_level);
949 }
950
951 /*
952 * OK, we've got all the baserestrictinfo quals for this child.
953 */
954 childrel->baserestrictinfo = childquals;
955 childrel->baserestrict_min_security = cq_min_security;
956
957 return true;
958}
Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos)
Definition appendinfo.c:201
#define Min(x, y)
Definition c.h:1091
#define Assert(condition)
Definition c.h:943
unsigned int Index
Definition c.h:698
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition clauses.c:2498
bool contain_volatile_functions(Node *clause)
Definition clauses.c:549
List * lappend(List *list, void *datum)
Definition list.c:339
List * make_ands_implicit(Expr *clause)
Definition makefuncs.c:810
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
static bool DatumGetBool(Datum X)
Definition postgres.h:100
static int fb(int x)
tree ctl root
Definition radixtree.h:1857
RestrictInfo * make_restrictinfo(PlannerInfo *root, Expr *clause, bool is_pushed_down, bool has_clone, bool is_clone, bool pseudoconstant, Index security_level, Relids required_relids, Relids incompatible_relids, Relids outer_relids)
Definition pg_list.h:54
Definition nodes.h:135
bool is_pushed_down
Definition pathnodes.h:2904
Index security_level
Definition pathnodes.h:2923
Expr * clause
Definition pathnodes.h:2901
bool contain_vars_of_level(Node *node, int levelsup)
Definition var.c:444

References adjust_appendrel_attrs(), Assert, RestrictInfo::clause, contain_vars_of_level(), contain_volatile_functions(), DatumGetBool(), eval_const_expressions(), fb(), RestrictInfo::has_clone, RestrictInfo::is_clone, RestrictInfo::is_pushed_down, IsA, lappend(), lfirst, make_ands_implicit(), make_restrictinfo(), Min, NIL, root, and RestrictInfo::security_level.

Referenced by build_simple_rel().

◆ expand_inherited_rtentry()

void expand_inherited_rtentry ( PlannerInfo root,
RelOptInfo rel,
RangeTblEntry rte,
Index  rti 
)
extern

Definition at line 88 of file inherit.c.

90{
93 LOCKMODE lockmode;
95 bool old_isParent = false;
96 int old_allMarkTypes = 0;
97
98 Assert(rte->inh); /* else caller error */
99
100 if (rte->rtekind == RTE_SUBQUERY)
101 {
103 return;
104 }
105
106 Assert(rte->rtekind == RTE_RELATION);
107
108 parentOID = rte->relid;
109
110 /*
111 * We used to check has_subclass() here, but there's no longer any need
112 * to, because subquery_planner already did.
113 */
114
115 /*
116 * The rewriter should already have obtained an appropriate lock on each
117 * relation named in the query, so we can open the parent relation without
118 * locking it. However, for each child relation we add to the query, we
119 * must obtain an appropriate lock, because this will be the first use of
120 * those relations in the parse/rewrite/plan pipeline. Child rels should
121 * use the same lockmode as their parent.
122 */
124 lockmode = rte->rellockmode;
125
126 /*
127 * If parent relation is selected FOR UPDATE/SHARE, we need to mark its
128 * PlanRowMark as isParent = true, and generate a new PlanRowMark for each
129 * child.
130 */
131 oldrc = get_plan_rowmark(root->rowMarks, rti);
132 if (oldrc)
133 {
134 old_isParent = oldrc->isParent;
135 oldrc->isParent = true;
136 /* Save initial value of allMarkTypes before children add to it */
137 old_allMarkTypes = oldrc->allMarkTypes;
138 }
139
140 /* Scan the inheritance set and expand it */
141 if (oldrelation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
142 {
144
145 perminfo = getRTEPermissionInfo(root->parse->rteperminfos, rte);
146
147 /*
148 * Partitioned table, so set up for partitioning.
149 */
151
152 /*
153 * Recursively expand and lock the partitions. While at it, also
154 * extract the partition key columns of all the partitioned tables.
155 */
158 perminfo->updatedCols,
159 oldrc, lockmode);
160 }
161 else
162 {
163 /*
164 * Ordinary table, so process traditional-inheritance children. (Note
165 * that partitioned tables are not allowed to have inheritance
166 * children, so it's not possible for both cases to apply.)
167 */
168 List *inhOIDs;
169 ListCell *l;
170
171 /* Scan for all members of inheritance set, acquire needed locks */
173
174 /*
175 * We used to special-case the situation where the table no longer has
176 * any children, by clearing rte->inh and exiting. That no longer
177 * works, because this function doesn't get run until after decisions
178 * have been made that depend on rte->inh. We have to treat such
179 * situations as normal inheritance. The table itself should always
180 * have been found, though.
181 */
182 Assert(inhOIDs != NIL);
184
185 /* Expand simple_rel_array and friends to hold child objects. */
187
188 /*
189 * Expand inheritance children in the order the OIDs were returned by
190 * find_all_inheritors.
191 */
192 foreach(l, inhOIDs)
193 {
198
199 /* Open rel if needed; we already have required locks */
200 if (childOID != parentOID)
202 else
204
205 /*
206 * It is possible that the parent table has children that are temp
207 * tables of other backends. We cannot safely access such tables
208 * (because of buffering issues), and the best thing to do seems
209 * to be to silently ignore them.
210 */
212 {
213 table_close(newrelation, lockmode);
214 continue;
215 }
216
217 /* Create RTE and AppendRelInfo, plus PlanRowMark if needed. */
221
222 /* Create the otherrel RelOptInfo too. */
224
225 /* Close child relations, but keep locks */
226 if (childOID != parentOID)
228 }
229 }
230
231 /*
232 * Some children might require different mark types, which would've been
233 * reported into oldrc. If so, add relevant entries to the top-level
234 * targetlist and update parent rel's reltarget. This should match what
235 * preprocess_targetlist() would have added if the mark types had been
236 * requested originally.
237 *
238 * (Someday it might be useful to fold these resjunk columns into the
239 * row-identity-column management used for UPDATE/DELETE. Today is not
240 * that day, however.)
241 */
242 if (oldrc)
243 {
244 int new_allMarkTypes = oldrc->allMarkTypes;
245 Var *var;
247 char resname[32];
248 List *newvars = NIL;
249
250 /* Add TID junk Var if needed, unless we had it already */
251 if (new_allMarkTypes & ~(1 << ROW_MARK_COPY) &&
252 !(old_allMarkTypes & ~(1 << ROW_MARK_COPY)))
253 {
254 /* Need to fetch TID */
255 var = makeVar(oldrc->rti,
257 TIDOID,
258 -1,
260 0);
261 snprintf(resname, sizeof(resname), "ctid%u", oldrc->rowmarkId);
262 tle = makeTargetEntry((Expr *) var,
263 list_length(root->processed_tlist) + 1,
265 true);
266 root->processed_tlist = lappend(root->processed_tlist, tle);
267 newvars = lappend(newvars, var);
268 }
269
270 /* Add whole-row junk Var if needed, unless we had it already */
271 if ((new_allMarkTypes & (1 << ROW_MARK_COPY)) &&
273 {
275 oldrc->rti,
276 0,
277 false);
278 snprintf(resname, sizeof(resname), "wholerow%u", oldrc->rowmarkId);
279 tle = makeTargetEntry((Expr *) var,
280 list_length(root->processed_tlist) + 1,
282 true);
283 root->processed_tlist = lappend(root->processed_tlist, tle);
284 newvars = lappend(newvars, var);
285 }
286
287 /* Add tableoid junk Var, unless we had it already */
288 if (!old_isParent)
289 {
290 var = makeVar(oldrc->rti,
292 OIDOID,
293 -1,
295 0);
296 snprintf(resname, sizeof(resname), "tableoid%u", oldrc->rowmarkId);
297 tle = makeTargetEntry((Expr *) var,
298 list_length(root->processed_tlist) + 1,
300 true);
301 root->processed_tlist = lappend(root->processed_tlist, tle);
302 newvars = lappend(newvars, var);
303 }
304
305 /*
306 * Add the newly added Vars to parent's reltarget. We needn't worry
307 * about the children's reltargets, they'll be made later.
308 */
310 }
311
313}
Bitmapset * bms_make_singleton(int x)
Definition bitmapset.c:216
static void expand_partitioned_rtentry(PlannerInfo *root, RelOptInfo *relinfo, RangeTblEntry *parentrte, Index parentRTindex, Relation parentrel, Bitmapset *parent_updatedCols, PlanRowMark *top_parentrc, LOCKMODE lockmode)
Definition inherit.c:320
static void expand_appendrel_subquery(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte, Index rti)
Definition inherit.c:797
static void expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte, Index parentRTindex, Relation parentrel, PlanRowMark *top_parentrc, Relation childrel, RangeTblEntry **childrte_p, Index *childRTindex_p)
Definition inherit.c:453
void add_vars_to_targetlist(PlannerInfo *root, List *vars, Relids where_needed)
Definition initsplan.c:290
int LOCKMODE
Definition lockdefs.h:26
#define NoLock
Definition lockdefs.h:34
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Definition makefuncs.c:66
Var * makeWholeRowVar(RangeTblEntry *rte, int varno, Index varlevelsup, bool allowScalar)
Definition makefuncs.c:137
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition makefuncs.c:289
char * pstrdup(const char *in)
Definition mcxt.c:1781
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
@ RTE_SUBQUERY
@ RTE_RELATION
#define planner_rt_fetch(rti, root)
Definition pathnodes.h:704
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
static int list_length(const List *l)
Definition pg_list.h:152
#define linitial_oid(l)
Definition pg_list.h:180
#define lfirst_oid(lc)
Definition pg_list.h:174
@ ROW_MARK_COPY
Definition plannodes.h:1562
#define snprintf
Definition port.h:260
#define InvalidOid
unsigned int Oid
PlanRowMark * get_plan_rowmark(List *rowmarks, Index rtindex)
Definition preptlist.c:528
#define RELATION_IS_OTHER_TEMP(relation)
Definition rel.h:669
void expand_planner_arrays(PlannerInfo *root, int add_size)
Definition relnode.c:183
RelOptInfo * build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
Definition relnode.c:212
#define TableOidAttributeNumber
Definition sysattr.h:26
#define SelfItemPointerAttributeNumber
Definition sysattr.h:21
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References add_vars_to_targetlist(), Assert, bms_make_singleton(), build_simple_rel(), expand_appendrel_subquery(), expand_partitioned_rtentry(), expand_planner_arrays(), expand_single_inheritance_child(), fb(), find_all_inheritors(), get_plan_rowmark(), getRTEPermissionInfo(), InvalidOid, lappend(), lfirst_oid, linitial_oid, list_length(), makeTargetEntry(), makeVar(), makeWholeRowVar(), NIL, NoLock, planner_rt_fetch, pstrdup(), RELATION_IS_OTHER_TEMP, root, ROW_MARK_COPY, RTE_RELATION, RTE_SUBQUERY, SelfItemPointerAttributeNumber, snprintf, table_close(), table_open(), and TableOidAttributeNumber.

Referenced by add_other_rels_to_query(), and expand_appendrel_subquery().

◆ get_rel_all_updated_cols()

Bitmapset * get_rel_all_updated_cols ( PlannerInfo root,
RelOptInfo rel 
)
extern

Definition at line 654 of file inherit.c.

655{
656 Index relid;
659 Bitmapset *updatedCols,
661
662 Assert(root->parse->commandType == CMD_UPDATE);
663 Assert(IS_SIMPLE_REL(rel));
664
665 /*
666 * We obtain updatedCols for the query's result relation. Then, if
667 * necessary, we map it to the column numbers of the relation for which
668 * they were requested.
669 */
670 relid = root->parse->resultRelation;
671 rte = planner_rt_fetch(relid, root);
672 perminfo = getRTEPermissionInfo(root->parse->rteperminfos, rte);
673
674 updatedCols = perminfo->updatedCols;
675
676 if (rel->relid != relid)
677 {
679
680 Assert(IS_OTHER_REL(rel));
681
683 updatedCols);
684 }
685
686 /*
687 * Now we must check to see if there are any generated columns that depend
688 * on the updatedCols, and add them to the result.
689 */
691 updatedCols);
692
693 return bms_union(updatedCols, extraUpdatedCols);
694}
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:251
static Bitmapset * translate_col_privs_multilevel(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *parent_rel, Bitmapset *parent_cols)
Definition inherit.c:758
@ CMD_UPDATE
Definition nodes.h:276
#define IS_SIMPLE_REL(rel)
Definition pathnodes.h:989
#define IS_OTHER_REL(rel)
Definition pathnodes.h:1004
Bitmapset * get_dependent_generated_columns(PlannerInfo *root, Index rti, Bitmapset *target_cols)
Definition plancat.c:2640
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
Definition relnode.c:544
Index relid
Definition pathnodes.h:1069

References Assert, bms_union(), CMD_UPDATE, fb(), find_base_rel(), get_dependent_generated_columns(), getRTEPermissionInfo(), IS_OTHER_REL, IS_SIMPLE_REL, planner_rt_fetch, RelOptInfo::relid, root, and translate_col_privs_multilevel().

Referenced by postgresPlanForeignModify().