Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9b27eab

Browse files
committed
Fix set_append_rel_pathlist() to deal intelligently with cases where
substituting a child rel's output expressions into the appendrel's restrictionclauses yields a pseudoconstant restriction. We might be able to skip scanningthat child rel entirely (if we get constant FALSE), or generate a one-timefilter. 8.3 more or less accidentally generated plans that weren't completelystupid in these cases, but that was only because an extra recursive level ofsubquery_planner() always occurred and allowed const-simplification to happen.8.4's ability to pull up appendrel members with non-Var outputs exposes thefact that we need to work harder here. Per gripe from Sergey Burladyan.
1 parentbf6570a commit9b27eab

File tree

4 files changed

+114
-58
lines changed

4 files changed

+114
-58
lines changed

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.183 2009/06/11 14:48:58 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.184 2009/07/06 18:26:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -29,6 +29,7 @@
2929
#include"optimizer/plancat.h"
3030
#include"optimizer/planner.h"
3131
#include"optimizer/prep.h"
32+
#include"optimizer/restrictinfo.h"
3233
#include"optimizer/var.h"
3334
#include"parser/parse_clause.h"
3435
#include"parser/parsetree.h"
@@ -318,6 +319,8 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
318319
intchildRTindex;
319320
RangeTblEntry*childRTE;
320321
RelOptInfo*childrel;
322+
List*childquals;
323+
Node*childqual;
321324
Path*childpath;
322325
ListCell*parentvars;
323326
ListCell*childvars;
@@ -342,10 +345,34 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
342345
* baserestrictinfo quals are needed before we can check for
343346
* constraint exclusion; so do that first and then check to see if we
344347
* can disregard this child.
348+
*
349+
* As of 8.4, the child rel's targetlist might contain non-Var
350+
* expressions, which means that substitution into the quals
351+
* could produce opportunities for const-simplification, and perhaps
352+
* even pseudoconstant quals. To deal with this, we strip the
353+
* RestrictInfo nodes, do the substitution, do const-simplification,
354+
* and then reconstitute the RestrictInfo layer.
345355
*/
346-
childrel->baserestrictinfo= (List*)
347-
adjust_appendrel_attrs((Node*)rel->baserestrictinfo,
348-
appinfo);
356+
childquals=get_all_actual_clauses(rel->baserestrictinfo);
357+
childquals= (List*)adjust_appendrel_attrs((Node*)childquals,
358+
appinfo);
359+
childqual=eval_const_expressions(root, (Node*)
360+
make_ands_explicit(childquals));
361+
if (childqual&&IsA(childqual,Const)&&
362+
(((Const*)childqual)->constisnull||
363+
!DatumGetBool(((Const*)childqual)->constvalue)))
364+
{
365+
/*
366+
* Restriction reduces to constant FALSE or constant NULL after
367+
* substitution, so this child need not be scanned.
368+
*/
369+
set_dummy_rel_pathlist(childrel);
370+
continue;
371+
}
372+
childquals=make_ands_implicit((Expr*)childqual);
373+
childquals=make_restrictinfos_from_actual_clauses(root,
374+
childquals);
375+
childrel->baserestrictinfo=childquals;
349376

350377
if (relation_excluded_by_constraints(root,childrel,childRTE))
351378
{

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

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*
2323
*
2424
* IDENTIFICATION
25-
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.171 2009/06/11 14:48:59 momjian Exp $
25+
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.172 2009/07/06 18:26:30 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -1636,57 +1636,7 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context)
16361636
Assert(!IsA(node,SpecialJoinInfo));
16371637
Assert(!IsA(node,AppendRelInfo));
16381638
Assert(!IsA(node,PlaceHolderInfo));
1639-
1640-
/*
1641-
* We have to process RestrictInfo nodes specially.
1642-
*/
1643-
if (IsA(node,RestrictInfo))
1644-
{
1645-
RestrictInfo*oldinfo= (RestrictInfo*)node;
1646-
RestrictInfo*newinfo=makeNode(RestrictInfo);
1647-
1648-
/* Copy all flat-copiable fields */
1649-
memcpy(newinfo,oldinfo,sizeof(RestrictInfo));
1650-
1651-
/* Recursively fix the clause itself */
1652-
newinfo->clause= (Expr*)
1653-
adjust_appendrel_attrs_mutator((Node*)oldinfo->clause,context);
1654-
1655-
/* and the modified version, if an OR clause */
1656-
newinfo->orclause= (Expr*)
1657-
adjust_appendrel_attrs_mutator((Node*)oldinfo->orclause,context);
1658-
1659-
/* adjust relid sets too */
1660-
newinfo->clause_relids=adjust_relid_set(oldinfo->clause_relids,
1661-
context->parent_relid,
1662-
context->child_relid);
1663-
newinfo->required_relids=adjust_relid_set(oldinfo->required_relids,
1664-
context->parent_relid,
1665-
context->child_relid);
1666-
newinfo->left_relids=adjust_relid_set(oldinfo->left_relids,
1667-
context->parent_relid,
1668-
context->child_relid);
1669-
newinfo->right_relids=adjust_relid_set(oldinfo->right_relids,
1670-
context->parent_relid,
1671-
context->child_relid);
1672-
1673-
/*
1674-
* Reset cached derivative fields, since these might need to have
1675-
* different values when considering the child relation.
1676-
*/
1677-
newinfo->eval_cost.startup=-1;
1678-
newinfo->norm_selec=-1;
1679-
newinfo->outer_selec=-1;
1680-
newinfo->left_ec=NULL;
1681-
newinfo->right_ec=NULL;
1682-
newinfo->left_em=NULL;
1683-
newinfo->right_em=NULL;
1684-
newinfo->scansel_cache=NIL;
1685-
newinfo->left_bucketsize=-1;
1686-
newinfo->right_bucketsize=-1;
1687-
1688-
return (Node*)newinfo;
1689-
}
1639+
Assert(!IsA(node,RestrictInfo));
16901640

16911641
/*
16921642
* NOTE: we do not need to recurse into sublinks, because they should

‎src/backend/optimizer/util/restrictinfo.c

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.60 2009/06/11 14:48:59 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.61 2009/07/06 18:26:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -271,6 +271,57 @@ make_restrictinfo_from_bitmapqual(Path *bitmapqual,
271271
returnresult;
272272
}
273273

274+
/*
275+
* make_restrictinfos_from_actual_clauses
276+
*
277+
* Given a list of implicitly-ANDed restriction clauses, produce a list
278+
* of RestrictInfo nodes. This is used to reconstitute the RestrictInfo
279+
* representation after doing transformations of a list of clauses.
280+
*
281+
* We assume that the clauses are relation-level restrictions and therefore
282+
* we don't have to worry about is_pushed_down, outerjoin_delayed, or
283+
* nullable_relids (these can be assumed true, false, and NULL, respectively).
284+
* We do take care to recognize pseudoconstant clauses properly.
285+
*/
286+
List*
287+
make_restrictinfos_from_actual_clauses(PlannerInfo*root,
288+
List*clause_list)
289+
{
290+
List*result=NIL;
291+
ListCell*l;
292+
293+
foreach(l,clause_list)
294+
{
295+
Expr*clause= (Expr*)lfirst(l);
296+
boolpseudoconstant;
297+
RestrictInfo*rinfo;
298+
299+
/*
300+
* It's pseudoconstant if it contains no Vars and no volatile
301+
* functions. We probably can't see any sublinks here, so
302+
* contain_var_clause() would likely be enough, but for safety
303+
* use contain_vars_of_level() instead.
304+
*/
305+
pseudoconstant=
306+
!contain_vars_of_level((Node*)clause,0)&&
307+
!contain_volatile_functions((Node*)clause);
308+
if (pseudoconstant)
309+
{
310+
/* tell createplan.c to check for gating quals */
311+
root->hasPseudoConstantQuals= true;
312+
}
313+
314+
rinfo=make_restrictinfo(clause,
315+
true,
316+
false,
317+
pseudoconstant,
318+
NULL,
319+
NULL);
320+
result=lappend(result,rinfo);
321+
}
322+
returnresult;
323+
}
324+
274325
/*
275326
* make_restrictinfo_internal
276327
*
@@ -481,6 +532,31 @@ get_actual_clauses(List *restrictinfo_list)
481532
returnresult;
482533
}
483534

535+
/*
536+
* get_all_actual_clauses
537+
*
538+
* Returns a list containing the bare clauses from 'restrictinfo_list'.
539+
*
540+
* This loses the distinction between regular and pseudoconstant clauses,
541+
* so be careful what you use it for.
542+
*/
543+
List*
544+
get_all_actual_clauses(List*restrictinfo_list)
545+
{
546+
List*result=NIL;
547+
ListCell*l;
548+
549+
foreach(l,restrictinfo_list)
550+
{
551+
RestrictInfo*rinfo= (RestrictInfo*)lfirst(l);
552+
553+
Assert(IsA(rinfo,RestrictInfo));
554+
555+
result=lappend(result,rinfo->clause);
556+
}
557+
returnresult;
558+
}
559+
484560
/*
485561
* extract_actual_clauses
486562
*

‎src/include/optimizer/restrictinfo.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/optimizer/restrictinfo.h,v 1.44 2009/05/09 22:51:41 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/optimizer/restrictinfo.h,v 1.45 2009/07/06 18:26:30 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -30,8 +30,11 @@ extern RestrictInfo *make_restrictinfo(Expr *clause,
3030
externList*make_restrictinfo_from_bitmapqual(Path*bitmapqual,
3131
boolis_pushed_down,
3232
boolinclude_predicates);
33+
externList*make_restrictinfos_from_actual_clauses(PlannerInfo*root,
34+
List*clause_list);
3335
externboolrestriction_is_or_clause(RestrictInfo*restrictinfo);
3436
externList*get_actual_clauses(List*restrictinfo_list);
37+
externList*get_all_actual_clauses(List*restrictinfo_list);
3538
externList*extract_actual_clauses(List*restrictinfo_list,
3639
boolpseudoconstant);
3740
externvoidextract_actual_join_clauses(List*restrictinfo_list,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp