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

Commit8df08c8

Browse files
committed
Reimplement planner's handling of MIN/MAX aggregate optimization (again).
Instead of playing cute games with pathkeys, just build a directrepresentation of the intended sub-select, and feed it throughquery_planner to get a Path for the index access. This is a bit slowerthan 9.1's previous method, since we'll duplicate most of the overhead ofquery_planner; but since the whole optimization only applies to rathersimple single-table queries, that probably won't be much of a problem inpractice. The advantage is that we get to do the right thing when there'sa partial index that needs the implicit IS NOT NULL clause to be usable.Also, although this makes planagg.c be a bit more closely tied to theordering of operations in grouping_planner, we can get rid of some couplingto lower-level parts of the planner. Per complaint from Marti Raudsepp.
1 parent6d8096e commit8df08c8

File tree

12 files changed

+263
-545
lines changed

12 files changed

+263
-545
lines changed

‎src/backend/nodes/copyfuncs.c

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,22 +1930,6 @@ _copyPlaceHolderInfo(PlaceHolderInfo *from)
19301930
returnnewnode;
19311931
}
19321932

1933-
/*
1934-
* _copyMinMaxAggInfo
1935-
*/
1936-
staticMinMaxAggInfo*
1937-
_copyMinMaxAggInfo(MinMaxAggInfo*from)
1938-
{
1939-
MinMaxAggInfo*newnode=makeNode(MinMaxAggInfo);
1940-
1941-
COPY_SCALAR_FIELD(aggfnoid);
1942-
COPY_SCALAR_FIELD(aggsortop);
1943-
COPY_NODE_FIELD(target);
1944-
COPY_NODE_FIELD(pathkeys);
1945-
1946-
returnnewnode;
1947-
}
1948-
19491933
/* ****************************************************************
19501934
*parsenodes.h copy functions
19511935
* ****************************************************************
@@ -4129,9 +4113,6 @@ copyObject(void *from)
41294113
caseT_PlaceHolderInfo:
41304114
retval=_copyPlaceHolderInfo(from);
41314115
break;
4132-
caseT_MinMaxAggInfo:
4133-
retval=_copyMinMaxAggInfo(from);
4134-
break;
41354116

41364117
/*
41374118
* VALUE NODES

‎src/backend/nodes/equalfuncs.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -886,17 +886,6 @@ _equalPlaceHolderInfo(PlaceHolderInfo *a, PlaceHolderInfo *b)
886886
return true;
887887
}
888888

889-
staticbool
890-
_equalMinMaxAggInfo(MinMaxAggInfo*a,MinMaxAggInfo*b)
891-
{
892-
COMPARE_SCALAR_FIELD(aggfnoid);
893-
COMPARE_SCALAR_FIELD(aggsortop);
894-
COMPARE_NODE_FIELD(target);
895-
COMPARE_NODE_FIELD(pathkeys);
896-
897-
return true;
898-
}
899-
900889

901890
/*
902891
* Stuff from parsenodes.h
@@ -2690,9 +2679,6 @@ equal(void *a, void *b)
26902679
caseT_PlaceHolderInfo:
26912680
retval=_equalPlaceHolderInfo(a,b);
26922681
break;
2693-
caseT_MinMaxAggInfo:
2694-
retval=_equalMinMaxAggInfo(a,b);
2695-
break;
26962682

26972683
caseT_List:
26982684
caseT_IntList:

‎src/backend/nodes/outfuncs.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1914,7 +1914,10 @@ _outMinMaxAggInfo(StringInfo str, MinMaxAggInfo *node)
19141914
WRITE_OID_FIELD(aggfnoid);
19151915
WRITE_OID_FIELD(aggsortop);
19161916
WRITE_NODE_FIELD(target);
1917-
WRITE_NODE_FIELD(pathkeys);
1917+
/* We intentionally omit subroot --- too large, not interesting enough */
1918+
WRITE_NODE_FIELD(path);
1919+
WRITE_FLOAT_FIELD(pathcost,"%.2f");
1920+
WRITE_NODE_FIELD(param);
19181921
}
19191922

19201923
staticvoid

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@
4141
#defineIsBooleanOpfamily(opfamily) \
4242
((opfamily) == BOOL_BTREE_FAM_OID || (opfamily) == BOOL_HASH_FAM_OID)
4343

44+
/* Whether to use ScalarArrayOpExpr to build index qualifications */
45+
typedefenum
46+
{
47+
SAOP_FORBID,/* Do not use ScalarArrayOpExpr */
48+
SAOP_ALLOW,/* OK to use ScalarArrayOpExpr */
49+
SAOP_REQUIRE/* Require ScalarArrayOpExpr */
50+
}SaOpControl;
4451

4552
/* Whether we are looking for plain indexscan, bitmap scan, or either */
4653
typedefenum
@@ -78,6 +85,11 @@ static PathClauseUsage *classify_index_clause_usage(Path *path,
7885
List**clauselist);
7986
staticvoidfind_indexpath_quals(Path*bitmapqual,List**quals,List**preds);
8087
staticintfind_list_position(Node*node,List**nodelist);
88+
staticList*group_clauses_by_indexkey(IndexOptInfo*index,
89+
List*clauses,List*outer_clauses,
90+
Relidsouter_relids,
91+
SaOpControlsaop_control,
92+
bool*found_clause);
8193
staticboolmatch_clause_to_indexcol(IndexOptInfo*index,
8294
intindexcol,
8395
RestrictInfo*rinfo,
@@ -1060,7 +1072,7 @@ find_list_position(Node *node, List **nodelist)
10601072
* from multiple places. Defend against redundant outputs by using
10611073
* list_append_unique_ptr (pointer equality should be good enough).
10621074
*/
1063-
List*
1075+
staticList*
10641076
group_clauses_by_indexkey(IndexOptInfo*index,
10651077
List*clauses,List*outer_clauses,
10661078
Relidsouter_relids,

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

Lines changed: 6 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -905,39 +905,6 @@ make_pathkeys_for_sortclauses(PlannerInfo *root,
905905
returnpathkeys;
906906
}
907907

908-
/****************************************************************************
909-
*PATHKEYS AND AGGREGATES
910-
****************************************************************************/
911-
912-
/*
913-
* make_pathkeys_for_aggregate
914-
*Generate a pathkeys list (always a 1-item list) that represents
915-
*the sort order needed by a MIN/MAX aggregate
916-
*
917-
* This is only called before EquivalenceClass merging, so we can assume
918-
* we are not supposed to canonicalize.
919-
*/
920-
List*
921-
make_pathkeys_for_aggregate(PlannerInfo*root,
922-
Expr*aggtarget,
923-
Oidaggsortop)
924-
{
925-
PathKey*pathkey;
926-
927-
/*
928-
* We arbitrarily set nulls_first to false. Actually, a MIN/MAX agg can
929-
* use either nulls ordering option, but that is dealt with elsewhere.
930-
*/
931-
pathkey=make_pathkey_from_sortop(root,
932-
aggtarget,
933-
aggsortop,
934-
false,/* nulls_first */
935-
0,
936-
true,
937-
false);
938-
returnlist_make1(pathkey);
939-
}
940-
941908
/****************************************************************************
942909
*PATHKEYS AND MERGECLAUSES
943910
****************************************************************************/
@@ -1407,11 +1374,10 @@ make_inner_pathkeys_for_merge(PlannerInfo *root,
14071374
*PATHKEY USEFULNESS CHECKS
14081375
*
14091376
* We only want to remember as many of the pathkeys of a path as have some
1410-
* potential use, which can include subsequent mergejoins, meeting the query's
1411-
* requested output ordering, or implementing MIN/MAX aggregates. This
1412-
* ensures that add_path() won't consider a path to have a usefully different
1413-
* ordering unless it really is useful. These routines check for usefulness
1414-
* of given pathkeys.
1377+
* potential use, either for subsequent mergejoins or for meeting the query's
1378+
* requested output ordering. This ensures that add_path() won't consider
1379+
* a path to have a usefully different ordering unless it really is useful.
1380+
* These routines check for usefulness of given pathkeys.
14151381
****************************************************************************/
14161382

14171383
/*
@@ -1553,50 +1519,6 @@ pathkeys_useful_for_ordering(PlannerInfo *root, List *pathkeys)
15531519
return0;/* path ordering not useful */
15541520
}
15551521

1556-
/*
1557-
* pathkeys_useful_for_minmax
1558-
*Count the number of pathkeys that are useful for implementing
1559-
*some MIN/MAX aggregate.
1560-
*
1561-
* Like pathkeys_useful_for_ordering, this is a yes-or-no affair, but
1562-
* there could be several MIN/MAX aggregates and we can match to any one.
1563-
*
1564-
* We can't use pathkeys_contained_in() because we would like to match
1565-
* pathkeys regardless of the nulls_first setting. However, we know that
1566-
* MIN/MAX aggregates will have at most one item in their pathkeys, so it's
1567-
* not too complicated to match by brute force.
1568-
*/
1569-
staticint
1570-
pathkeys_useful_for_minmax(PlannerInfo*root,List*pathkeys)
1571-
{
1572-
PathKey*pathkey;
1573-
ListCell*lc;
1574-
1575-
if (pathkeys==NIL)
1576-
return0;/* unordered path */
1577-
pathkey= (PathKey*)linitial(pathkeys);
1578-
1579-
foreach(lc,root->minmax_aggs)
1580-
{
1581-
MinMaxAggInfo*mminfo= (MinMaxAggInfo*)lfirst(lc);
1582-
PathKey*mmpathkey;
1583-
1584-
/* Ignore minmax agg if its pathkey turned out to be redundant */
1585-
if (mminfo->pathkeys==NIL)
1586-
continue;
1587-
1588-
Assert(list_length(mminfo->pathkeys)==1);
1589-
mmpathkey= (PathKey*)linitial(mminfo->pathkeys);
1590-
1591-
if (mmpathkey->pk_eclass==pathkey->pk_eclass&&
1592-
mmpathkey->pk_opfamily==pathkey->pk_opfamily&&
1593-
mmpathkey->pk_strategy==pathkey->pk_strategy)
1594-
return1;
1595-
}
1596-
1597-
return0;/* path ordering not useful */
1598-
}
1599-
16001522
/*
16011523
* truncate_useless_pathkeys
16021524
*Shorten the given pathkey list to just the useful pathkeys.
@@ -1608,15 +1530,11 @@ truncate_useless_pathkeys(PlannerInfo *root,
16081530
{
16091531
intnuseful;
16101532
intnuseful2;
1611-
intnuseful3;
16121533

16131534
nuseful=pathkeys_useful_for_merging(root,rel,pathkeys);
16141535
nuseful2=pathkeys_useful_for_ordering(root,pathkeys);
16151536
if (nuseful2>nuseful)
16161537
nuseful=nuseful2;
1617-
nuseful3=pathkeys_useful_for_minmax(root,pathkeys);
1618-
if (nuseful3>nuseful)
1619-
nuseful=nuseful3;
16201538

16211539
/*
16221540
* Note: not safe to modify input list destructively, but we can avoid
@@ -1642,8 +1560,8 @@ truncate_useless_pathkeys(PlannerInfo *root,
16421560
*
16431561
* We could make the test more complex, for example checking to see if any of
16441562
* the joinclauses are really mergejoinable, but that likely wouldn't win
1645-
* often enough to repay the extra cycles.Queries withnojoin, sort, or
1646-
*aggregate at allare reasonably common, so this much work seems worthwhile.
1563+
* often enough to repay the extra cycles.Queries withneither ajoin nor
1564+
*a sortare reasonably common, though, so this much work seems worthwhile.
16471565
*/
16481566
bool
16491567
has_useful_pathkeys(PlannerInfo*root,RelOptInfo*rel)
@@ -1652,7 +1570,5 @@ has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel)
16521570
return true;/* might be able to use pathkeys for merging */
16531571
if (root->query_pathkeys!=NIL)
16541572
return true;/* might be able to use them for ordering */
1655-
if (root->minmax_aggs!=NIL)
1656-
return true;/* might be able to use them for MIN/MAX */
16571573
return false;/* definitely useless */
16581574
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp