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

Commitfa559a8

Browse files
committed
Adjust indexscan planning logic to keep RestrictInfo nodes associated
with index qual clauses in the Path representation. This saves a littlework during createplan and (probably more importantly) allows reuse ofcached selectivity estimates during indexscan planning. Also fix latentbug: wrong plan would have been generated for a 'special operator' usedin a nestloop-inner-indexscan join qual, because the special operatorwould not have gotten into the list of quals to recheck. This bug isonly latent because at present the special-operator code could nevertrigger on a join qual, but sooner or later someone will want to do it.
1 parent5d472f6 commitfa559a8

File tree

11 files changed

+400
-188
lines changed

11 files changed

+400
-188
lines changed

‎src/backend/nodes/outfuncs.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.227 2004/01/0518:04:38 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.228 2004/01/0523:39:53 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -968,8 +968,9 @@ _outIndexPath(StringInfo str, IndexPath *node)
968968
_outPathInfo(str, (Path*)node);
969969

970970
WRITE_NODE_FIELD(indexinfo);
971-
WRITE_NODE_FIELD(indexqual);
972-
WRITE_NODE_FIELD(indexjoinclauses);
971+
WRITE_NODE_FIELD(indexclauses);
972+
WRITE_NODE_FIELD(indexquals);
973+
WRITE_BOOL_FIELD(isjoininner);
973974
WRITE_ENUM_FIELD(indexscandir,ScanDirection);
974975
WRITE_FLOAT_FIELD(rows,"%.0f");
975976
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
* Portions Copyright (c) 1994, Regents of the University of California
5050
*
5151
* IDENTIFICATION
52-
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.120 2004/01/0505:07:35 tgl Exp $
52+
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.121 2004/01/0523:39:54 tgl Exp $
5353
*
5454
*-------------------------------------------------------------------------
5555
*/
@@ -238,6 +238,9 @@ cost_nonsequential_access(double relpages)
238238
* Any additional quals evaluated as qpquals may reduce the number of returned
239239
* tuples, but they won't reduce the number of tuples we have to fetch from
240240
* the table, so they don't reduce the scan cost.
241+
*
242+
* NOTE: as of 7.5, indexQuals is a list of RestrictInfo nodes, where formerly
243+
* it was a list of bare clause expressions.
241244
*/
242245
void
243246
cost_index(Path*path,Query*root,

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

Lines changed: 77 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.154 2004/01/0505:07:35 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.155 2004/01/0523:39:54 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -76,7 +76,7 @@ static bool match_index_to_operand(Node *operand, int indexcol,
7676
RelOptInfo*rel,IndexOptInfo*index);
7777
staticboolmatch_special_index_operator(Expr*clause,Oidopclass,
7878
boolindexkey_on_left);
79-
staticList*expand_indexqual_condition(Expr*clause,Oidopclass);
79+
staticList*expand_indexqual_condition(RestrictInfo*rinfo,Oidopclass);
8080
staticList*prefix_quals(Node*leftop,Oidopclass,
8181
Const*prefix,Pattern_Prefix_Statuspstatus);
8282
staticList*network_prefix_quals(Node*leftop,Oidexpr_op,Oidopclass,
@@ -1418,8 +1418,7 @@ make_innerjoin_index_path(Query *root,
14181418
{
14191419
IndexPath*pathnode=makeNode(IndexPath);
14201420
List*indexquals,
1421-
*allclauses,
1422-
*l;
1421+
*allclauses;
14231422

14241423
/* XXX perhaps this code should be merged with create_index_path? */
14251424

@@ -1433,28 +1432,21 @@ make_innerjoin_index_path(Query *root,
14331432
*/
14341433
pathnode->path.pathkeys=NIL;
14351434

1436-
/* ConvertRestrictInfo nodes to indexquals the executor can handle */
1435+
/* Convertclauses to indexquals the executor can handle */
14371436
indexquals=expand_indexqual_conditions(index,clausegroups);
14381437

1439-
/*
1440-
* Also make a flattened list of the RestrictInfo nodes; createplan.c
1441-
* will need this later. We assume here that we can destructively
1442-
* modify the passed-in clausegroups list structure.
1443-
*/
1444-
allclauses=NIL;
1445-
foreach(l,clausegroups)
1446-
{
1447-
/* nconc okay here since same clause couldn't be in two sublists */
1448-
allclauses=nconc(allclauses, (List*)lfirst(l));
1449-
}
1438+
/* Flatten the clausegroups list to produce indexclauses list */
1439+
allclauses=flatten_clausegroups_list(clausegroups);
14501440

14511441
/*
14521442
* Note that we are making a pathnode for a single-scan indexscan;
1453-
* therefore, indexinfoand indexqual should be single-element lists.
1443+
* therefore, indexinfoetc should be single-element lists.
14541444
*/
14551445
pathnode->indexinfo=makeList1(index);
1456-
pathnode->indexqual=makeList1(indexquals);
1457-
pathnode->indexjoinclauses=makeList1(allclauses);
1446+
pathnode->indexclauses=makeList1(allclauses);
1447+
pathnode->indexquals=makeList1(indexquals);
1448+
1449+
pathnode->isjoininner= true;
14581450

14591451
/* We don't actually care what order the index scans in ... */
14601452
pathnode->indexscandir=NoMovementScanDirection;
@@ -1489,6 +1481,61 @@ make_innerjoin_index_path(Query *root,
14891481
return (Path*)pathnode;
14901482
}
14911483

1484+
/*
1485+
* flatten_clausegroups_list
1486+
* Given a list of lists of RestrictInfos, flatten it to a list
1487+
* of RestrictInfos.
1488+
*
1489+
* This is used to flatten out the result of group_clauses_by_indexkey()
1490+
* or one of its sibling routines, to produce an indexclauses list.
1491+
*/
1492+
List*
1493+
flatten_clausegroups_list(List*clausegroups)
1494+
{
1495+
List*allclauses=NIL;
1496+
List*l;
1497+
1498+
foreach(l,clausegroups)
1499+
{
1500+
allclauses=nconc(allclauses,listCopy((List*)lfirst(l)));
1501+
}
1502+
returnallclauses;
1503+
}
1504+
1505+
/*
1506+
* make_expr_from_indexclauses()
1507+
* Given an indexclauses structure, produce an ordinary boolean expression.
1508+
*
1509+
* This consists of stripping out the RestrictInfo nodes and inserting
1510+
* explicit AND and OR nodes as needed. There's not much to it, but
1511+
* the functionality is needed in a few places, so centralize the logic.
1512+
*/
1513+
Expr*
1514+
make_expr_from_indexclauses(List*indexclauses)
1515+
{
1516+
List*orclauses=NIL;
1517+
List*orlist;
1518+
1519+
/* There's no such thing as an indexpath with zero scans */
1520+
Assert(indexclauses!=NIL);
1521+
1522+
foreach(orlist,indexclauses)
1523+
{
1524+
List*andlist= (List*)lfirst(orlist);
1525+
1526+
/* Strip RestrictInfos */
1527+
andlist=get_actual_clauses(andlist);
1528+
/* Insert AND node if needed, and add to orclauses list */
1529+
orclauses=lappend(orclauses,make_ands_explicit(andlist));
1530+
}
1531+
1532+
if (length(orclauses)>1)
1533+
returnmake_orclause(orclauses);
1534+
else
1535+
return (Expr*)lfirst(orclauses);
1536+
}
1537+
1538+
14921539
/****************************************************************************
14931540
*---- ROUTINES TO CHECK OPERANDS ----
14941541
****************************************************************************/
@@ -1799,8 +1846,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
17991846
RestrictInfo*rinfo= (RestrictInfo*)lfirst(i);
18001847

18011848
FastConc(&resultquals,
1802-
expand_indexqual_condition(rinfo->clause,
1803-
curClass));
1849+
expand_indexqual_condition(rinfo,curClass));
18041850
}
18051851

18061852
clausegroups=lnext(clausegroups);
@@ -1816,10 +1862,13 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
18161862

18171863
/*
18181864
* expand_indexqual_condition --- expand a single indexqual condition
1865+
*
1866+
* The input is a single RestrictInfo, the output a list of RestrictInfos
18191867
*/
18201868
staticList*
1821-
expand_indexqual_condition(Expr*clause,Oidopclass)
1869+
expand_indexqual_condition(RestrictInfo*rinfo,Oidopclass)
18221870
{
1871+
Expr*clause=rinfo->clause;
18231872
/* we know these will succeed */
18241873
Node*leftop=get_leftop(clause);
18251874
Node*rightop=get_rightop(clause);
@@ -1883,7 +1932,7 @@ expand_indexqual_condition(Expr *clause, Oid opclass)
18831932
break;
18841933

18851934
default:
1886-
result=makeList1(clause);
1935+
result=makeList1(rinfo);
18871936
break;
18881937
}
18891938

@@ -1978,7 +2027,7 @@ prefix_quals(Node *leftop, Oid opclass,
19782027
elog(ERROR,"no = operator for opclass %u",opclass);
19792028
expr=make_opclause(oproid,BOOLOID, false,
19802029
(Expr*)leftop, (Expr*)prefix_const);
1981-
result=makeList1(expr);
2030+
result=makeList1(make_restrictinfo(expr, true, true));
19822031
returnresult;
19832032
}
19842033

@@ -1993,7 +2042,7 @@ prefix_quals(Node *leftop, Oid opclass,
19932042
elog(ERROR,"no >= operator for opclass %u",opclass);
19942043
expr=make_opclause(oproid,BOOLOID, false,
19952044
(Expr*)leftop, (Expr*)prefix_const);
1996-
result=makeList1(expr);
2045+
result=makeList1(make_restrictinfo(expr, true, true));
19972046

19982047
/*-------
19992048
* If we can create a string larger than the prefix, we can say
@@ -2009,7 +2058,7 @@ prefix_quals(Node *leftop, Oid opclass,
20092058
elog(ERROR,"no < operator for opclass %u",opclass);
20102059
expr=make_opclause(oproid,BOOLOID, false,
20112060
(Expr*)leftop, (Expr*)greaterstr);
2012-
result=lappend(result,expr);
2061+
result=lappend(result,make_restrictinfo(expr, true, true));
20132062
}
20142063

20152064
returnresult;
@@ -2080,7 +2129,7 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
20802129
(Expr*)leftop,
20812130
(Expr*)makeConst(datatype,-1,opr1right,
20822131
false, false));
2083-
result=makeList1(expr);
2132+
result=makeList1(make_restrictinfo(expr, true, true));
20842133

20852134
/* create clause "key <= network_scan_last( rightop )" */
20862135

@@ -2095,7 +2144,7 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
20952144
(Expr*)leftop,
20962145
(Expr*)makeConst(datatype,-1,opr2right,
20972146
false, false));
2098-
result=lappend(result,expr);
2147+
result=lappend(result,make_restrictinfo(expr, true, true));
20992148

21002149
returnresult;
21012150
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp