Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 480f1f4

Browse files
committedAug 15, 2017
Teach adjust_appendrel_attrs(_multilevel) to do multiple translations.
Currently, child relations are always base relations, so when we translate parent relids to child relids, we only need to translate a singler relid. However, the proposed partition-wise join feature will create child joins, which will mean we need to translate a set of parent relids to the corresponding child relids. This is preliminary refactoring to make that possible. Ashutosh Bapat. Review and testing of the larger patch set of which this is a part by Amit Langote, Rajkumar Raghuwanshi, Rafia Sabih, Thomas Munro, Dilip Kumar, and me. Some adjustments, mostly cosmetic, by me. Discussion: http://postgr.es/m/CA+TgmobQK80vtXjAsPZWWXd7c8u13G86gmuLupN+uUJjA+i4nA@mail.gmail.com
1 parent d57929a commit 480f1f4

File tree

5 files changed

+200
-72
lines changed

5 files changed

+200
-72
lines changed
 

‎src/backend/optimizer/path/allpaths.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
942942
Assert(IsA(rinfo, RestrictInfo));
943943
childqual = adjust_appendrel_attrs(root,
944944
(Node *) rinfo->clause,
945-
appinfo);
945+
1, &appinfo);
946946
childqual = eval_const_expressions(root, childqual);
947947
/* check for flat-out constant */
948948
if (childqual && IsA(childqual, Const))
@@ -1061,11 +1061,11 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
10611061
childrel->joininfo = (List *)
10621062
adjust_appendrel_attrs(root,
10631063
(Node *) rel->joininfo,
1064-
appinfo);
1064+
1, &appinfo);
10651065
childrel->reltarget->exprs = (List *)
10661066
adjust_appendrel_attrs(root,
10671067
(Node *) rel->reltarget->exprs,
1068-
appinfo);
1068+
1, &appinfo);
10691069

10701070
/*
10711071
* We have to make child entries in the EquivalenceClass data

‎src/backend/optimizer/path/equivclass.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,8 @@ generate_join_implied_equalities_broken(PlannerInfo *root,
13291329
if (IS_OTHER_REL(inner_rel) && result != NIL)
13301330
result = (List *) adjust_appendrel_attrs_multilevel(root,
13311331
(Node *) result,
1332-
inner_rel);
1332+
inner_rel->relids,
1333+
inner_rel->top_parent_relids);
13331334

13341335
return result;
13351336
}
@@ -2112,7 +2113,7 @@ add_child_rel_equivalences(PlannerInfo *root,
21122113
child_expr = (Expr *)
21132114
adjust_appendrel_attrs(root,
21142115
(Node *) cur_em->em_expr,
2115-
appinfo);
2116+
1, &appinfo);
21162117

21172118
/*
21182119
* Transform em_relids to match. Note we do *not* do

‎src/backend/optimizer/plan/planner.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,7 @@ inheritance_planner(PlannerInfo *root)
11421142
subroot->parse = (Query *)
11431143
adjust_appendrel_attrs(root,
11441144
(Node *) parse,
1145-
appinfo);
1145+
1, &appinfo);
11461146

11471147
/*
11481148
* If there are securityQuals attached to the parent, move them to the

‎src/backend/optimizer/prep/prepunion.c

Lines changed: 187 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@
5555
typedef struct
5656
{
5757
PlannerInfo *root;
58-
AppendRelInfo *appinfo;
58+
int nappinfos;
59+
AppendRelInfo **appinfos;
5960
} adjust_appendrel_attrs_context;
6061

6162
static Path *recurse_set_operations(Node *setOp, PlannerInfo *root,
@@ -107,7 +108,8 @@ static Bitmapset *translate_col_privs(const Bitmapset *parent_privs,
107108
List *translated_vars);
108109
static Node *adjust_appendrel_attrs_mutator(Node *node,
109110
adjust_appendrel_attrs_context *context);
110-
static Relids adjust_relid_set(Relids relids, Index oldrelid, Index newrelid);
111+
static Relids adjust_child_relids(Relids relids, int nappinfos,
112+
AppendRelInfo **appinfos);
111113
static List *adjust_inherited_tlist(List *tlist,
112114
AppendRelInfo *context);
113115

@@ -1775,10 +1777,10 @@ translate_col_privs(const Bitmapset *parent_privs,
17751777

17761778
/*
17771779
* adjust_appendrel_attrs
1778-
* Copy the specified query or expression and translate Vars referring
1779-
* to the parent rel of the specified AppendRelInfo to refer to the
1780-
* child rel instead. We also update rtindexes appearing outside Vars,
1781-
* such as resultRelation and jointree relids.
1780+
* Copy the specified query or expression and translate Vars referring to a
1781+
* parent rel to refer to the corresponding child rel instead. We also
1782+
* update rtindexes appearing outside Vars, such as resultRelation and
1783+
* jointree relids.
17821784
*
17831785
* Note: this is only applied after conversion of sublinks to subplans,
17841786
* so we don't need to cope with recursion into sub-queries.
@@ -1787,34 +1789,47 @@ translate_col_privs(const Bitmapset *parent_privs,
17871789
* maybe we should try to fold the two routines together.
17881790
*/
17891791
Node *
1790-
adjust_appendrel_attrs(PlannerInfo *root, Node *node, AppendRelInfo *appinfo)
1792+
adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos,
1793+
AppendRelInfo **appinfos)
17911794
{
17921795
Node *result;
17931796
adjust_appendrel_attrs_context context;
17941797

17951798
context.root = root;
1796-
context.appinfo = appinfo;
1799+
context.nappinfos = nappinfos;
1800+
context.appinfos = appinfos;
1801+
1802+
/* If there's nothing to adjust, don't call this function. */
1803+
Assert(nappinfos >= 1 && appinfos != NULL);
17971804

17981805
/*
17991806
* Must be prepared to start with a Query or a bare expression tree.
18001807
*/
18011808
if (node && IsA(node, Query))
18021809
{
18031810
Query *newnode;
1811+
int cnt;
18041812

18051813
newnode = query_tree_mutator((Query *) node,
18061814
adjust_appendrel_attrs_mutator,
18071815
(void *) &context,
18081816
QTW_IGNORE_RC_SUBQUERIES);
1809-
if (newnode->resultRelation == appinfo->parent_relid)
1817+
for (cnt = 0; cnt < nappinfos; cnt++)
18101818
{
1811-
newnode->resultRelation = appinfo->child_relid;
1812-
/* Fix tlist resnos too, if it's inherited UPDATE */
1813-
if (newnode->commandType == CMD_UPDATE)
1814-
newnode->targetList =
1815-
adjust_inherited_tlist(newnode->targetList,
1816-
appinfo);
1819+
AppendRelInfo *appinfo = appinfos[cnt];
1820+
1821+
if (newnode->resultRelation == appinfo->parent_relid)
1822+
{
1823+
newnode->resultRelation = appinfo->child_relid;
1824+
/* Fix tlist resnos too, if it's inherited UPDATE */
1825+
if (newnode->commandType == CMD_UPDATE)
1826+
newnode->targetList =
1827+
adjust_inherited_tlist(newnode->targetList,
1828+
appinfo);
1829+
break;
1830+
}
18171831
}
1832+
18181833
result = (Node *) newnode;
18191834
}
18201835
else
@@ -1827,16 +1842,27 @@ static Node *
18271842
adjust_appendrel_attrs_mutator(Node *node,
18281843
adjust_appendrel_attrs_context *context)
18291844
{
1830-
AppendRelInfo *appinfo = context->appinfo;
1845+
AppendRelInfo **appinfos = context->appinfos;
1846+
int nappinfos = context->nappinfos;
1847+
int cnt;
18311848

18321849
if (node == NULL)
18331850
return NULL;
18341851
if (IsA(node, Var))
18351852
{
18361853
Var *var = (Var *) copyObject(node);
1854+
AppendRelInfo *appinfo = NULL;
18371855

1838-
if (var->varlevelsup == 0 &&
1839-
var->varno == appinfo->parent_relid)
1856+
for (cnt = 0; cnt < nappinfos; cnt++)
1857+
{
1858+
if (var->varno == appinfos[cnt]->parent_relid)
1859+
{
1860+
appinfo = appinfos[cnt];
1861+
break;
1862+
}
1863+
}
1864+
1865+
if (var->varlevelsup == 0 && appinfo)
18401866
{
18411867
var->varno = appinfo->child_relid;
18421868
var->varnoold = appinfo->child_relid;
@@ -1916,29 +1942,54 @@ adjust_appendrel_attrs_mutator(Node *node,
19161942
{
19171943
CurrentOfExpr *cexpr = (CurrentOfExpr *) copyObject(node);
19181944

1919-
if (cexpr->cvarno == appinfo->parent_relid)
1920-
cexpr->cvarno = appinfo->child_relid;
1945+
for (cnt = 0; cnt < nappinfos; cnt++)
1946+
{
1947+
AppendRelInfo *appinfo = appinfos[cnt];
1948+
1949+
if (cexpr->cvarno == appinfo->parent_relid)
1950+
{
1951+
cexpr->cvarno = appinfo->child_relid;
1952+
break;
1953+
}
1954+
}
19211955
return (Node *) cexpr;
19221956
}
19231957
if (IsA(node, RangeTblRef))
19241958
{
19251959
RangeTblRef *rtr = (RangeTblRef *) copyObject(node);
19261960

1927-
if (rtr->rtindex == appinfo->parent_relid)
1928-
rtr->rtindex = appinfo->child_relid;
1961+
for (cnt = 0; cnt < nappinfos; cnt++)
1962+
{
1963+
AppendRelInfo *appinfo = appinfos[cnt];
1964+
1965+
if (rtr->rtindex == appinfo->parent_relid)
1966+
{
1967+
rtr->rtindex = appinfo->child_relid;
1968+
break;
1969+
}
1970+
}
19291971
return (Node *) rtr;
19301972
}
19311973
if (IsA(node, JoinExpr))
19321974
{
19331975
/* Copy the JoinExpr node with correct mutation of subnodes */
19341976
JoinExpr *j;
1977+
AppendRelInfo *appinfo;
19351978

19361979
j = (JoinExpr *) expression_tree_mutator(node,
19371980
adjust_appendrel_attrs_mutator,
19381981
(void *) context);
19391982
/* now fix JoinExpr's rtindex (probably never happens) */
1940-
if (j->rtindex == appinfo->parent_relid)
1941-
j->rtindex = appinfo->child_relid;
1983+
for (cnt = 0; cnt < nappinfos; cnt++)
1984+
{
1985+
appinfo = appinfos[cnt];
1986+
1987+
if (j->rtindex == appinfo->parent_relid)
1988+
{
1989+
j->rtindex = appinfo->child_relid;
1990+
break;
1991+
}
1992+
}
19421993
return (Node *) j;
19431994
}
19441995
if (IsA(node, PlaceHolderVar))
@@ -1951,9 +2002,8 @@ adjust_appendrel_attrs_mutator(Node *node,
19512002
(void *) context);
19522003
/* now fix PlaceHolderVar's relid sets */
19532004
if (phv->phlevelsup == 0)
1954-
phv->phrels = adjust_relid_set(phv->phrels,
1955-
appinfo->parent_relid,
1956-
appinfo->child_relid);
2005+
phv->phrels = adjust_child_relids(phv->phrels, context->nappinfos,
2006+
context->appinfos);
19572007
return (Node *) phv;
19582008
}
19592009
/* Shouldn't need to handle planner auxiliary nodes here */
@@ -1984,24 +2034,24 @@ adjust_appendrel_attrs_mutator(Node *node,
19842034
adjust_appendrel_attrs_mutator((Node *) oldinfo->orclause, context);
19852035

19862036
/* adjust relid sets too */
1987-
newinfo->clause_relids = adjust_relid_set(oldinfo->clause_relids,
1988-
appinfo->parent_relid,
1989-
appinfo->child_relid);
1990-
newinfo->required_relids = adjust_relid_set(oldinfo->required_relids,
1991-
appinfo->parent_relid,
1992-
appinfo->child_relid);
1993-
newinfo->outer_relids = adjust_relid_set(oldinfo->outer_relids,
1994-
appinfo->parent_relid,
1995-
appinfo->child_relid);
1996-
newinfo->nullable_relids = adjust_relid_set(oldinfo->nullable_relids,
1997-
appinfo->parent_relid,
1998-
appinfo->child_relid);
1999-
newinfo->left_relids = adjust_relid_set(oldinfo->left_relids,
2000-
appinfo->parent_relid,
2001-
appinfo->child_relid);
2002-
newinfo->right_relids = adjust_relid_set(oldinfo->right_relids,
2003-
appinfo->parent_relid,
2004-
appinfo->child_relid);
2037+
newinfo->clause_relids = adjust_child_relids(oldinfo->clause_relids,
2038+
context->nappinfos,
2039+
context->appinfos);
2040+
newinfo->required_relids = adjust_child_relids(oldinfo->required_relids,
2041+
context->nappinfos,
2042+
context->appinfos);
2043+
newinfo->outer_relids = adjust_child_relids(oldinfo->outer_relids,
2044+
context->nappinfos,
2045+
context->appinfos);
2046+
newinfo->nullable_relids = adjust_child_relids(oldinfo->nullable_relids,
2047+
context->nappinfos,
2048+
context->appinfos);
2049+
newinfo->left_relids = adjust_child_relids(oldinfo->left_relids,
2050+
context->nappinfos,
2051+
context->appinfos);
2052+
newinfo->right_relids = adjust_child_relids(oldinfo->right_relids,
2053+
context->nappinfos,
2054+
context->appinfos);
20052055

20062056
/*
20072057
* Reset cached derivative fields, since these might need to have
@@ -2033,19 +2083,36 @@ adjust_appendrel_attrs_mutator(Node *node,
20332083
}
20342084

20352085
/*
2036-
* Substitute newrelid for oldrelid in a Relid set
2086+
* Substitute child relids for parent relids in a Relid set. The array of
2087+
* appinfos specifies the substitutions to be performed.
20372088
*/
2038-
static Relids
2039-
adjust_relid_set(Relids relids, Index oldrelid, Index newrelid)
2089+
Relids
2090+
adjust_child_relids(Relids relids, int nappinfos, AppendRelInfo **appinfos)
20402091
{
2041-
if (bms_is_member(oldrelid, relids))
2092+
Bitmapset *result = NULL;
2093+
int cnt;
2094+
2095+
for (cnt = 0; cnt < nappinfos; cnt++)
20422096
{
2043-
/* Ensure we have a modifiable copy */
2044-
relids = bms_copy(relids);
2045-
/* Remove old, add new */
2046-
relids = bms_del_member(relids, oldrelid);
2047-
relids = bms_add_member(relids, newrelid);
2097+
AppendRelInfo *appinfo = appinfos[cnt];
2098+
2099+
/* Remove parent, add child */
2100+
if (bms_is_member(appinfo->parent_relid, relids))
2101+
{
2102+
/* Make a copy if we are changing the set. */
2103+
if (!result)
2104+
result = bms_copy(relids);
2105+
2106+
result = bms_del_member(result, appinfo->parent_relid);
2107+
result = bms_add_member(result, appinfo->child_relid);
2108+
}
20482109
}
2110+
2111+
/* If we made any changes, return the modified copy. */
2112+
if (result)
2113+
return result;
2114+
2115+
/* Otherwise, return the original set without modification. */
20492116
return relids;
20502117
}
20512118

@@ -2150,21 +2217,77 @@ adjust_inherited_tlist(List *tlist, AppendRelInfo *context)
21502217
* adjust_appendrel_attrs_multilevel
21512218
* Apply Var translations from a toplevel appendrel parent down to a child.
21522219
*
2153-
* In some cases we need to translate expressions referencing a baserel
2220+
* In some cases we need to translate expressions referencing a parent relation
21542221
* to reference an appendrel child that's multiple levels removed from it.
21552222
*/
21562223
Node *
21572224
adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node,
2158-
RelOptInfo *child_rel)
2225+
Relids child_relids,
2226+
Relids top_parent_relids)
21592227
{
2160-
AppendRelInfo *appinfo = find_childrel_appendrelinfo(root, child_rel);
2161-
RelOptInfo *parent_rel = find_base_rel(root, appinfo->parent_relid);
2228+
AppendRelInfo **appinfos;
2229+
Bitmapset *parent_relids = NULL;
2230+
int nappinfos;
2231+
int cnt;
2232+
2233+
Assert(bms_num_members(child_relids) == bms_num_members(top_parent_relids));
2234+
2235+
appinfos = find_appinfos_by_relids(root, child_relids, &nappinfos);
2236+
2237+
/* Construct relids set for the immediate parent of given child. */
2238+
for (cnt = 0; cnt < nappinfos; cnt++)
2239+
{
2240+
AppendRelInfo *appinfo = appinfos[cnt];
2241+
2242+
parent_relids = bms_add_member(parent_relids, appinfo->parent_relid);
2243+
}
2244+
2245+
/* Recurse if immediate parent is not the top parent. */
2246+
if (!bms_equal(parent_relids, top_parent_relids))
2247+
node = adjust_appendrel_attrs_multilevel(root, node, parent_relids,
2248+
top_parent_relids);
21622249

2163-
/* If parent is also a child, first recurse to apply its translations */
2164-
if (IS_OTHER_REL(parent_rel))
2165-
node = adjust_appendrel_attrs_multilevel(root, node, parent_rel);
2166-
else
2167-
Assert(parent_rel->reloptkind == RELOPT_BASEREL);
21682250
/* Now translate for this child */
2169-
return adjust_appendrel_attrs(root, node, appinfo);
2251+
node = adjust_appendrel_attrs(root, node, nappinfos, appinfos);
2252+
2253+
pfree(appinfos);
2254+
2255+
return node;
2256+
}
2257+
2258+
/*
2259+
* find_appinfos_by_relids
2260+
* Find AppendRelInfo structures for all relations specified by relids.
2261+
*
2262+
* The AppendRelInfos are returned in an array, which can be pfree'd by the
2263+
* caller. *nappinfos is set to the the number of entries in the array.
2264+
*/
2265+
AppendRelInfo **
2266+
find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos)
2267+
{
2268+
ListCell *lc;
2269+
AppendRelInfo **appinfos;
2270+
int cnt = 0;
2271+
2272+
*nappinfos = bms_num_members(relids);
2273+
appinfos = (AppendRelInfo **) palloc(sizeof(AppendRelInfo *) * *nappinfos);
2274+
2275+
foreach(lc, root->append_rel_list)
2276+
{
2277+
AppendRelInfo *appinfo = lfirst(lc);
2278+
2279+
if (bms_is_member(appinfo->child_relid, relids))
2280+
{
2281+
appinfos[cnt] = appinfo;
2282+
cnt++;
2283+
2284+
/* Stop when we have gathered all the AppendRelInfos. */
2285+
if (cnt == *nappinfos)
2286+
return appinfos;
2287+
}
2288+
}
2289+
2290+
/* Should have found the entries ... */
2291+
elog(ERROR, "did not find all requested child rels in append_rel_list");
2292+
return NULL; /* not reached */
21702293
}

‎src/include/optimizer/prep.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,13 @@ extern RelOptInfo *plan_set_operations(PlannerInfo *root);
5353
extern void expand_inherited_tables(PlannerInfo *root);
5454

5555
extern Node *adjust_appendrel_attrs(PlannerInfo *root, Node *node,
56-
AppendRelInfo *appinfo);
56+
int nappinfos, AppendRelInfo **appinfos);
5757

5858
extern Node *adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node,
59-
RelOptInfo *child_rel);
59+
Relids child_relids,
60+
Relids top_parent_relids);
61+
62+
extern AppendRelInfo **find_appinfos_by_relids(PlannerInfo *root,
63+
Relids relids, int *nappinfos);
6064

6165
#endif /* PREP_H */

0 commit comments

Comments
 (0)
Please sign in to comment.