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

Commit8eb9998

Browse files
committed
Add a reference to the expression which has triggered creation of this pathkey.
For the sake of consistency in number of groups estimation in incremental sortwe need to have an information about expression which caused the pathkey. Itdoesn't guarantee correct estimation but at least estimation doesn't rely ona SQL string.
1 parent1bf29f5 commit8eb9998

File tree

5 files changed

+59
-13
lines changed

5 files changed

+59
-13
lines changed

‎contrib/postgres_fdw/postgres_fdw.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,7 @@ get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel)
976976
foreach(lc,useful_eclass_list)
977977
{
978978
EquivalenceClass*cur_ec=lfirst(lc);
979+
EquivalenceMember*em;
979980
PathKey*pathkey;
980981

981982
/* If redundant with what we did above, skip it. */
@@ -988,14 +989,15 @@ get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel)
988989
continue;
989990

990991
/* If no pushable expression for this rel, skip it. */
991-
if (find_em_for_rel(root,cur_ec,rel)==NULL)
992+
if ((em=find_em_for_rel(root,cur_ec,rel))==NULL)
992993
continue;
993994

994995
/* Looks like we can generate a pathkey, so let's do it. */
995996
pathkey=make_canonical_pathkey(root,cur_ec,
996997
linitial_oid(cur_ec->ec_opfamilies),
997998
BTLessStrategyNumber,
998-
false);
999+
false,
1000+
em->em_expr);/* TODO */
9991001
useful_pathkeys_list=lappend(useful_pathkeys_list,
10001002
list_make1(pathkey));
10011003
}

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,21 +2038,41 @@ cost_incremental_sort(Path *path,
20382038
foreach(l,pathkeys)
20392039
{
20402040
PathKey*key= (PathKey*)lfirst(l);
2041-
EquivalenceMember*member= (EquivalenceMember*)
2042-
linitial(key->pk_eclass->ec_members);
2041+
2042+
#ifdefUSE_ASSERT_CHECKING
2043+
ListCell*lc;
2044+
2045+
/* Be paranoid, but caring about performace don't check on prod */
2046+
foreach(lc,key->pk_eclass->ec_members)
2047+
{
2048+
if (find_ec_member_matching_expr(
2049+
key->pk_eclass,key->source_expr,
2050+
pull_varnos(root, (Node*)key->source_expr)))
2051+
break;
2052+
}
2053+
if (!lc)
2054+
/*
2055+
* XXX: Can we build PathKey over derived expression and does it
2056+
* trigger this error?
2057+
*/
2058+
elog(ERROR,"PathKey source expression must be a part of EQ class");
2059+
#endif
2060+
2061+
/* Reassure ourselves no one created pathkeys alternative way */
2062+
Assert(key->source_expr!=NULL);
20432063

20442064
/*
20452065
* Check if the expression contains Var with "varno 0" so that we
20462066
* don't call estimate_num_groups in that case.
20472067
*/
2048-
if (bms_is_member(0,pull_varnos(root, (Node*)member->em_expr)))
2068+
if (bms_is_member(0,pull_varnos(root, (Node*)key->source_expr)))
20492069
{
20502070
unknown_varno= true;
20512071
break;
20522072
}
20532073

20542074
/* expression not containing any Vars with "varno 0" */
2055-
presortedExprs=lappend(presortedExprs,member->em_expr);
2075+
presortedExprs=lappend(presortedExprs,key->source_expr);
20562076

20572077
if (foreach_current_index(l)+1 >=presorted_keys)
20582078
break;

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

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static bool right_merge_direction(PlannerInfo *root, PathKey *pathkey);
5454
PathKey*
5555
make_canonical_pathkey(PlannerInfo*root,
5656
EquivalenceClass*eclass,Oidopfamily,
57-
intstrategy,boolnulls_first)
57+
intstrategy,boolnulls_first,Expr*src_expr)
5858
{
5959
PathKey*pk;
6060
ListCell*lc;
@@ -89,6 +89,7 @@ make_canonical_pathkey(PlannerInfo *root,
8989
pk->pk_opfamily=opfamily;
9090
pk->pk_strategy=strategy;
9191
pk->pk_nulls_first=nulls_first;
92+
pk->source_expr=src_expr;
9293

9394
root->canon_pathkeys=lappend(root->canon_pathkeys,pk);
9495

@@ -241,7 +242,7 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
241242

242243
/* And finally we can find or create a PathKey node */
243244
returnmake_canonical_pathkey(root,eclass,opfamily,
244-
strategy,nulls_first);
245+
strategy,nulls_first,expr);
245246
}
246247

247248
/*
@@ -1117,7 +1118,8 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
11171118
outer_ec,
11181119
sub_pathkey->pk_opfamily,
11191120
sub_pathkey->pk_strategy,
1120-
sub_pathkey->pk_nulls_first);
1121+
sub_pathkey->pk_nulls_first,
1122+
(Expr*)outer_var);
11211123
}
11221124
}
11231125
else
@@ -1199,7 +1201,8 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
11991201
outer_ec,
12001202
sub_pathkey->pk_opfamily,
12011203
sub_pathkey->pk_strategy,
1202-
sub_pathkey->pk_nulls_first);
1204+
sub_pathkey->pk_nulls_first,
1205+
(Expr*)outer_var);
12031206
/* score = # of equivalence peers */
12041207
score=list_length(outer_ec->ec_members)-1;
12051208
/* +1 if it matches the proper query_pathkeys item */
@@ -1643,6 +1646,7 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
16431646
List*pathkeys=NIL;
16441647
intnClauses=list_length(mergeclauses);
16451648
EquivalenceClass**ecs;
1649+
Expr**exprs;
16461650
int*scores;
16471651
intnecs;
16481652
ListCell*lc;
@@ -1657,6 +1661,7 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
16571661
* duplicates) and their "popularity" scores.
16581662
*/
16591663
ecs= (EquivalenceClass**)palloc(nClauses*sizeof(EquivalenceClass*));
1664+
exprs= (Expr**)palloc(nClauses*sizeof(Expr*));
16601665
scores= (int*)palloc(nClauses*sizeof(int));
16611666
necs=0;
16621667

@@ -1666,14 +1671,21 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
16661671
EquivalenceClass*oeclass;
16671672
intscore;
16681673
ListCell*lc2;
1674+
Expr*expr;
16691675

16701676
/* get the outer eclass */
16711677
update_mergeclause_eclasses(root,rinfo);
16721678

16731679
if (rinfo->outer_is_left)
1680+
{
16741681
oeclass=rinfo->left_ec;
1682+
expr= (Expr*)linitial(((OpExpr*)rinfo->clause)->args);
1683+
}
16751684
else
1685+
{
16761686
oeclass=rinfo->right_ec;
1687+
expr= (Expr*)lsecond(((OpExpr*)rinfo->clause)->args);
1688+
}
16771689

16781690
/* reject duplicates */
16791691
for (j=0;j<necs;j++)
@@ -1697,6 +1709,8 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
16971709
}
16981710

16991711
ecs[necs]=oeclass;
1712+
exprs[necs]=expr;
1713+
17001714
scores[necs]=score;
17011715
necs++;
17021716
}
@@ -1798,7 +1812,8 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
17981812
ec,
17991813
linitial_oid(ec->ec_opfamilies),
18001814
BTLessStrategyNumber,
1801-
false);
1815+
false,
1816+
exprs[best_j]);
18021817
/* can't be redundant because no duplicate ECs */
18031818
Assert(!pathkey_is_redundant(pathkey,pathkeys));
18041819
pathkeys=lappend(pathkeys,pathkey);
@@ -1852,18 +1867,23 @@ make_inner_pathkeys_for_merge(PlannerInfo *root,
18521867
EquivalenceClass*oeclass;
18531868
EquivalenceClass*ieclass;
18541869
PathKey*pathkey;
1870+
Expr*src_expr;
18551871

18561872
update_mergeclause_eclasses(root,rinfo);
18571873

1874+
Assert(IsA(rinfo->clause,OpExpr)&&rinfo->orclause==NULL);
1875+
18581876
if (rinfo->outer_is_left)
18591877
{
18601878
oeclass=rinfo->left_ec;
18611879
ieclass=rinfo->right_ec;
1880+
src_expr= (Expr*)lsecond(((OpExpr*)rinfo->clause)->args);
18621881
}
18631882
else
18641883
{
18651884
oeclass=rinfo->right_ec;
18661885
ieclass=rinfo->left_ec;
1886+
src_expr= (Expr*)linitial(((OpExpr*)rinfo->clause)->args);
18671887
}
18681888

18691889
/* outer eclass should match current or next pathkeys */
@@ -1891,7 +1911,8 @@ make_inner_pathkeys_for_merge(PlannerInfo *root,
18911911
ieclass,
18921912
opathkey->pk_opfamily,
18931913
opathkey->pk_strategy,
1894-
opathkey->pk_nulls_first);
1914+
opathkey->pk_nulls_first,
1915+
src_expr);
18951916

18961917
/*
18971918
* Don't generate redundant pathkeys (which can happen if multiple

‎src/include/nodes/pathnodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,6 +1469,8 @@ typedef struct PathKey
14691469
Oidpk_opfamily;/* btree opfamily defining the ordering */
14701470
intpk_strategy;/* sort direction (ASC or DESC) */
14711471
boolpk_nulls_first;/* do NULLs come before normal values? */
1472+
1473+
Expr*source_expr;/* Expression, which triggered this creation */
14721474
}PathKey;
14731475

14741476
/*

‎src/include/optimizer/paths.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@ extern bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel);
264264
externList*append_pathkeys(List*target,List*source);
265265
externPathKey*make_canonical_pathkey(PlannerInfo*root,
266266
EquivalenceClass*eclass,Oidopfamily,
267-
intstrategy,boolnulls_first);
267+
intstrategy,boolnulls_first,
268+
Expr*src_expr);
268269
externvoidadd_paths_to_append_rel(PlannerInfo*root,RelOptInfo*rel,
269270
List*live_childrels);
270271

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp