Skip to content

Commit 8fd3fdd

Browse files
committed
Simplify the planner's new representation of indexable clauses a little.
In commit 1a8d5af, I thought it'd be a good idea to define IndexClause.indexquals as NIL in the most common case where the given clause (IndexClause.rinfo) is usable exactly as-is. It'd be more consistent to define the indexquals in that case as being a one-element list containing IndexClause.rinfo, but I thought saving the palloc overhead for making such a list would be worthwhile. In hindsight, that was a great example of "premature optimization is the root of all evil": it's complicated everyplace that needs to deal with the indexquals, requiring duplicative code to handle both the simple case and the not-simple case. I'd initially found that tolerable but it's getting less so as I mop up some areas that I'd not touched in 1a8d5af. In any case, two more pallocs during a planner run are surely at the noise level (a conclusion confirmed by a bit of microbenchmarking). So let's change this decision before it becomes set in stone, and insist that IndexClause.indexquals always be a valid list of the actual index quals for the clause. Discussion: https://postgr.es/m/24586.1550106354@sss.pgh.pa.us
1 parent 86eea78 commit 8fd3fdd

File tree

4 files changed

+61
-115
lines changed

4 files changed

+61
-115
lines changed

src/backend/optimizer/path/indxpath.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,7 +2435,7 @@ match_clause_to_indexcol(PlannerInfo *root,
24352435
{
24362436
iclause = makeNode(IndexClause);
24372437
iclause->rinfo = rinfo;
2438-
iclause->indexquals = NIL;
2438+
iclause->indexquals = list_make1(rinfo);
24392439
iclause->lossy = false;
24402440
iclause->indexcol = indexcol;
24412441
iclause->indexcols = NIL;
@@ -2599,7 +2599,7 @@ match_opclause_to_indexcol(PlannerInfo *root,
25992599
{
26002600
iclause = makeNode(IndexClause);
26012601
iclause->rinfo = rinfo;
2602-
iclause->indexquals = NIL;
2602+
iclause->indexquals = list_make1(rinfo);
26032603
iclause->lossy = false;
26042604
iclause->indexcol = indexcol;
26052605
iclause->indexcols = NIL;
@@ -2819,7 +2819,7 @@ match_saopclause_to_indexcol(RestrictInfo *rinfo,
28192819
IndexClause *iclause = makeNode(IndexClause);
28202820

28212821
iclause->rinfo = rinfo;
2822-
iclause->indexquals = NIL;
2822+
iclause->indexquals = list_make1(rinfo);
28232823
iclause->lossy = false;
28242824
iclause->indexcol = indexcol;
28252825
iclause->indexcols = NIL;
@@ -3078,7 +3078,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
30783078
* usable as index quals.
30793079
*/
30803080
if (var_on_left && !iclause->lossy)
3081-
iclause->indexquals = NIL;
3081+
iclause->indexquals = list_make1(rinfo);
30823082
else
30833083
{
30843084
/*

src/backend/optimizer/plan/createplan.c

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3075,11 +3075,8 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
30753075

30763076
Assert(!rinfo->pseudoconstant);
30773077
subquals = lappend(subquals, rinfo->clause);
3078-
if (iclause->indexquals)
3079-
subindexquals = list_concat(subindexquals,
3080-
get_actual_clauses(iclause->indexquals));
3081-
else
3082-
subindexquals = lappend(subindexquals, rinfo->clause);
3078+
subindexquals = list_concat(subindexquals,
3079+
get_actual_clauses(iclause->indexquals));
30833080
if (rinfo->parent_ec)
30843081
subindexECs = lappend(subindexECs, rinfo->parent_ec);
30853082
}
@@ -4491,33 +4488,18 @@ fix_indexqual_references(PlannerInfo *root, IndexPath *index_path,
44914488
{
44924489
IndexClause *iclause = lfirst_node(IndexClause, lc);
44934490
int indexcol = iclause->indexcol;
4491+
ListCell *lc2;
44944492

4495-
if (iclause->indexquals == NIL)
4493+
foreach(lc2, iclause->indexquals)
44964494
{
4497-
/* rinfo->clause is directly usable as an indexqual */
4498-
Node *clause = (Node *) iclause->rinfo->clause;
4495+
RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
4496+
Node *clause = (Node *) rinfo->clause;
44994497

45004498
stripped_indexquals = lappend(stripped_indexquals, clause);
45014499
clause = fix_indexqual_clause(root, index, indexcol,
45024500
clause, iclause->indexcols);
45034501
fixed_indexquals = lappend(fixed_indexquals, clause);
45044502
}
4505-
else
4506-
{
4507-
/* Process the derived indexquals */
4508-
ListCell *lc2;
4509-
4510-
foreach(lc2, iclause->indexquals)
4511-
{
4512-
RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
4513-
Node *clause = (Node *) rinfo->clause;
4514-
4515-
stripped_indexquals = lappend(stripped_indexquals, clause);
4516-
clause = fix_indexqual_clause(root, index, indexcol,
4517-
clause, iclause->indexcols);
4518-
fixed_indexquals = lappend(fixed_indexquals, clause);
4519-
}
4520-
}
45214503
}
45224504

45234505
*stripped_indexquals_p = stripped_indexquals;

src/backend/utils/adt/selfuncs.c

Lines changed: 41 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,6 @@ static bool get_actual_variable_range(PlannerInfo *root,
197197
Oid sortop,
198198
Datum *min, Datum *max);
199199
static RelOptInfo *find_join_input_rel(PlannerInfo *root, Relids relids);
200-
static IndexQualInfo *deconstruct_indexqual(RestrictInfo *rinfo,
201-
IndexOptInfo *index, int indexcol);
202200
static List *add_predicate_to_quals(IndexOptInfo *index, List *indexQuals);
203201

204202

@@ -5263,16 +5261,13 @@ get_index_quals(List *indexclauses)
52635261
foreach(lc, indexclauses)
52645262
{
52655263
IndexClause *iclause = lfirst_node(IndexClause, lc);
5264+
ListCell *lc2;
52665265

5267-
if (iclause->indexquals == NIL)
5266+
foreach(lc2, iclause->indexquals)
52685267
{
5269-
/* rinfo->clause is directly usable as an indexqual */
5270-
result = lappend(result, iclause->rinfo);
5271-
}
5272-
else
5273-
{
5274-
/* report the derived indexquals */
5275-
result = list_concat(result, list_copy(iclause->indexquals));
5268+
RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
5269+
5270+
result = lappend(result, rinfo);
52765271
}
52775272
}
52785273
return result;
@@ -5282,83 +5277,58 @@ List *
52825277
deconstruct_indexquals(IndexPath *path)
52835278
{
52845279
List *result = NIL;
5285-
IndexOptInfo *index = path->indexinfo;
52865280
ListCell *lc;
52875281

52885282
foreach(lc, path->indexclauses)
52895283
{
52905284
IndexClause *iclause = lfirst_node(IndexClause, lc);
52915285
int indexcol = iclause->indexcol;
5292-
IndexQualInfo *qinfo;
5286+
ListCell *lc2;
52935287

5294-
if (iclause->indexquals == NIL)
5295-
{
5296-
/* rinfo->clause is directly usable as an indexqual */
5297-
qinfo = deconstruct_indexqual(iclause->rinfo, index, indexcol);
5298-
result = lappend(result, qinfo);
5299-
}
5300-
else
5288+
foreach(lc2, iclause->indexquals)
53015289
{
5302-
/* Process the derived indexquals */
5303-
ListCell *lc2;
5290+
RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
5291+
Expr *clause = rinfo->clause;
5292+
IndexQualInfo *qinfo;
53045293

5305-
foreach(lc2, iclause->indexquals)
5306-
{
5307-
RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
5294+
qinfo = (IndexQualInfo *) palloc(sizeof(IndexQualInfo));
5295+
qinfo->rinfo = rinfo;
5296+
qinfo->indexcol = indexcol;
53085297

5309-
qinfo = deconstruct_indexqual(rinfo, index, indexcol);
5310-
result = lappend(result, qinfo);
5298+
if (IsA(clause, OpExpr))
5299+
{
5300+
qinfo->clause_op = ((OpExpr *) clause)->opno;
5301+
qinfo->other_operand = get_rightop(clause);
53115302
}
5312-
}
5313-
}
5314-
return result;
5315-
}
5316-
5317-
static IndexQualInfo *
5318-
deconstruct_indexqual(RestrictInfo *rinfo, IndexOptInfo *index, int indexcol)
5319-
{
5320-
{
5321-
Expr *clause;
5322-
IndexQualInfo *qinfo;
5323-
5324-
clause = rinfo->clause;
5325-
5326-
qinfo = (IndexQualInfo *) palloc(sizeof(IndexQualInfo));
5327-
qinfo->rinfo = rinfo;
5328-
qinfo->indexcol = indexcol;
5303+
else if (IsA(clause, RowCompareExpr))
5304+
{
5305+
RowCompareExpr *rc = (RowCompareExpr *) clause;
53295306

5330-
if (IsA(clause, OpExpr))
5331-
{
5332-
qinfo->clause_op = ((OpExpr *) clause)->opno;
5333-
qinfo->other_operand = get_rightop(clause);
5334-
}
5335-
else if (IsA(clause, RowCompareExpr))
5336-
{
5337-
RowCompareExpr *rc = (RowCompareExpr *) clause;
5307+
qinfo->clause_op = linitial_oid(rc->opnos);
5308+
qinfo->other_operand = (Node *) rc->rargs;
5309+
}
5310+
else if (IsA(clause, ScalarArrayOpExpr))
5311+
{
5312+
ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
53385313

5339-
qinfo->clause_op = linitial_oid(rc->opnos);
5340-
qinfo->other_operand = (Node *) rc->rargs;
5341-
}
5342-
else if (IsA(clause, ScalarArrayOpExpr))
5343-
{
5344-
ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
5314+
qinfo->clause_op = saop->opno;
5315+
qinfo->other_operand = (Node *) lsecond(saop->args);
5316+
}
5317+
else if (IsA(clause, NullTest))
5318+
{
5319+
qinfo->clause_op = InvalidOid;
5320+
qinfo->other_operand = NULL;
5321+
}
5322+
else
5323+
{
5324+
elog(ERROR, "unsupported indexqual type: %d",
5325+
(int) nodeTag(clause));
5326+
}
53455327

5346-
qinfo->clause_op = saop->opno;
5347-
qinfo->other_operand = (Node *) lsecond(saop->args);
5348-
}
5349-
else if (IsA(clause, NullTest))
5350-
{
5351-
qinfo->clause_op = InvalidOid;
5352-
qinfo->other_operand = NULL;
5353-
}
5354-
else
5355-
{
5356-
elog(ERROR, "unsupported indexqual type: %d",
5357-
(int) nodeTag(clause));
5328+
result = lappend(result, qinfo);
53585329
}
5359-
5360-
return qinfo;
53615330
}
5331+
return result;
53625332
}
53635333

53645334
/*

src/include/nodes/pathnodes.h

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,26 +1185,20 @@ typedef struct IndexPath
11851185
* conditions is done by a planner support function attached to the
11861186
* indexclause's top-level function or operator.
11871187
*
1188-
* If indexquals is NIL, it means that rinfo->clause is directly usable as
1189-
* an indexqual. Otherwise indexquals contains one or more directly-usable
1190-
* indexqual conditions extracted from the given clause. The 'lossy' flag
1191-
* indicates whether the indexquals are semantically equivalent to the
1192-
* original clause, or form a weaker condition.
1193-
*
1194-
* Currently, entries in indexquals are RestrictInfos, but they could perhaps
1195-
* be bare clauses instead; the only advantage of making them RestrictInfos
1196-
* is the possibility of caching cost and selectivity information across
1197-
* multiple uses, and it's not clear that that's really worth the price of
1198-
* constructing RestrictInfos for them. Note however that the extended-stats
1199-
* machinery won't do anything with non-RestrictInfo clauses, so that would
1200-
* have to be fixed.
1188+
* indexquals is a list of RestrictInfos for the directly-usable index
1189+
* conditions associated with this IndexClause. In the simplest case
1190+
* it's a one-element list whose member is iclause->rinfo. Otherwise,
1191+
* it contains one or more directly-usable indexqual conditions extracted
1192+
* from the given clause. The 'lossy' flag indicates whether the
1193+
* indexquals are semantically equivalent to the original clause, or
1194+
* represent a weaker condition.
12011195
*
12021196
* Normally, indexcol is the index of the single index column the clause
12031197
* works on, and indexcols is NIL. But if the clause is a RowCompareExpr,
12041198
* indexcol is the index of the leading column, and indexcols is a list of
12051199
* all the affected columns. (Note that indexcols matches up with the
1206-
* columns of the actual indexable RowCompareExpr, which might be in
1207-
* indexquals rather than rinfo.)
1200+
* columns of the actual indexable RowCompareExpr in indexquals, which
1201+
* might be different from the original in rinfo.)
12081202
*
12091203
* An IndexPath's IndexClause list is required to be ordered by index
12101204
* column, i.e. the indexcol values must form a nondecreasing sequence.
@@ -1214,7 +1208,7 @@ typedef struct IndexClause
12141208
{
12151209
NodeTag type;
12161210
struct RestrictInfo *rinfo; /* original restriction or join clause */
1217-
List *indexquals; /* indexqual(s) derived from it, or NIL */
1211+
List *indexquals; /* indexqual(s) derived from it */
12181212
bool lossy; /* are indexquals a lossy version of clause? */
12191213
AttrNumber indexcol; /* index column the clause uses (zero-based) */
12201214
List *indexcols; /* multiple index columns, if RowCompare */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy