Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a191a16

Browse files
committed
Change the planner-to-executor API so that the planner tells the executor
which comparison operators to use for plan nodes involving tuple comparison (Agg, Group, Unique, SetOp). Formerly the executor looked up the default equality operator for the datatype, which was really pretty shaky, since it's possible that the data being fed to the node is sorted according to some nondefault operator class that could have an incompatible idea of equality. The planner knows what it has sorted by and therefore can provide the right equality operator to use. Also, this change moves a couple of catalog lookups out of the executor and into the planner, which should help startup time for pre-planned queries by some small amount. Modify the planner to remove some other cavalier assumptions about always being able to use the default operators. Also add "nulls first/last" info to the Plan node for a mergejoin --- neither the executor nor the planner can cope yet, but at least the API is in place.
1 parent 5f6d735 commit a191a16

25 files changed

+722
-263
lines changed

src/backend/executor/execGrouping.c

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execGrouping.c,v 1.22 2007/01/05 22:19:27 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execGrouping.c,v 1.23 2007/01/10 18:06:02 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -183,65 +183,56 @@ execTuplesUnequal(TupleTableSlot *slot1,
183183
* The result is a palloc'd array.
184184
*/
185185
FmgrInfo *
186-
execTuplesMatchPrepare(TupleDesc tupdesc,
187-
int numCols,
188-
AttrNumber *matchColIdx)
186+
execTuplesMatchPrepare(int numCols,
187+
Oid *eqOperators)
189188
{
190-
FmgrInfo *eqfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo));
189+
FmgrInfo *eqFunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo));
191190
int i;
192191

193192
for (i = 0; i < numCols; i++)
194193
{
195-
AttrNumber att = matchColIdx[i];
196-
Oid typid = tupdesc->attrs[att - 1]->atttypid;
194+
Oid eq_opr = eqOperators[i];
197195
Oid eq_function;
198196

199-
eq_function = equality_oper_funcid(typid);
200-
fmgr_info(eq_function, &eqfunctions[i]);
197+
eq_function = get_opcode(eq_opr);
198+
fmgr_info(eq_function, &eqFunctions[i]);
201199
}
202200

203-
return eqfunctions;
201+
return eqFunctions;
204202
}
205203

206204
/*
207205
* execTuplesHashPrepare
208206
* Look up the equality and hashing functions needed for a TupleHashTable.
209207
*
210208
* This is similar to execTuplesMatchPrepare, but we also need to find the
211-
* hash functions associated with the equality operators. *eqfunctions and
212-
* *hashfunctions receive the palloc'd result arrays.
209+
* hash functions associated with the equality operators. *eqFunctions and
210+
* *hashFunctions receive the palloc'd result arrays.
213211
*/
214212
void
215-
execTuplesHashPrepare(TupleDesc tupdesc,
216-
int numCols,
217-
AttrNumber *matchColIdx,
218-
FmgrInfo **eqfunctions,
219-
FmgrInfo **hashfunctions)
213+
execTuplesHashPrepare(int numCols,
214+
Oid *eqOperators,
215+
FmgrInfo **eqFunctions,
216+
FmgrInfo **hashFunctions)
220217
{
221218
int i;
222219

223-
*eqfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo));
224-
*hashfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo));
220+
*eqFunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo));
221+
*hashFunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo));
225222

226223
for (i = 0; i < numCols; i++)
227224
{
228-
AttrNumber att = matchColIdx[i];
229-
Oid typid = tupdesc->attrs[att - 1]->atttypid;
230-
Operator optup;
231-
Oid eq_opr;
225+
Oid eq_opr = eqOperators[i];
232226
Oid eq_function;
233227
Oid hash_function;
234228

235-
optup = equality_oper(typid, false);
236-
eq_opr = oprid(optup);
237-
eq_function = oprfuncid(optup);
238-
ReleaseSysCache(optup);
229+
eq_function = get_opcode(eq_opr);
239230
hash_function = get_op_hash_function(eq_opr);
240231
if (!OidIsValid(hash_function)) /* should not happen */
241232
elog(ERROR, "could not find hash function for hash operator %u",
242233
eq_opr);
243-
fmgr_info(eq_function, &(*eqfunctions)[i]);
244-
fmgr_info(hash_function, &(*hashfunctions)[i]);
234+
fmgr_info(eq_function, &(*eqFunctions)[i]);
235+
fmgr_info(hash_function, &(*hashFunctions)[i]);
245236
}
246237
}
247238

src/backend/executor/nodeAgg.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
* Portions Copyright (c) 1994, Regents of the University of California
6262
*
6363
* IDENTIFICATION
64-
* $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.148 2007/01/09 02:14:11 tgl Exp $
64+
* $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.149 2007/01/10 18:06:02 tgl Exp $
6565
*
6666
*-------------------------------------------------------------------------
6767
*/
@@ -1270,16 +1270,14 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
12701270
if (node->numCols > 0)
12711271
{
12721272
if (node->aggstrategy == AGG_HASHED)
1273-
execTuplesHashPrepare(ExecGetScanType(&aggstate->ss),
1274-
node->numCols,
1275-
node->grpColIdx,
1273+
execTuplesHashPrepare(node->numCols,
1274+
node->grpOperators,
12761275
&aggstate->eqfunctions,
12771276
&aggstate->hashfunctions);
12781277
else
12791278
aggstate->eqfunctions =
1280-
execTuplesMatchPrepare(ExecGetScanType(&aggstate->ss),
1281-
node->numCols,
1282-
node->grpColIdx);
1279+
execTuplesMatchPrepare(node->numCols,
1280+
node->grpOperators);
12831281
}
12841282

12851283
/*
@@ -1519,6 +1517,13 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
15191517
&peraggstate->inputtypeLen,
15201518
&peraggstate->inputtypeByVal);
15211519

1520+
/*
1521+
* Look up the sorting and comparison operators to use. XXX it's
1522+
* pretty bletcherous to be making this sort of semantic decision
1523+
* in the executor. Probably the parser should decide this and
1524+
* record it in the Aggref node ... or at latest, do it in the
1525+
* planner.
1526+
*/
15221527
eq_function = equality_oper_funcid(inputTypes[0]);
15231528
fmgr_info(eq_function, &(peraggstate->equalfn));
15241529
peraggstate->sortOperator = ordering_oper_opid(inputTypes[0]);

src/backend/executor/nodeGroup.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* locate group boundaries.
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/executor/nodeGroup.c,v 1.66 2007/01/05 22:19:28 momjian Exp $
18+
* $PostgreSQL: pgsql/src/backend/executor/nodeGroup.c,v 1.67 2007/01/10 18:06:02 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -211,9 +211,8 @@ ExecInitGroup(Group *node, EState *estate, int eflags)
211211
* Precompute fmgr lookup data for inner loop
212212
*/
213213
grpstate->eqfunctions =
214-
execTuplesMatchPrepare(ExecGetScanType(&grpstate->ss),
215-
node->numCols,
216-
node->grpColIdx);
214+
execTuplesMatchPrepare(node->numCols,
215+
node->grpOperators);
217216

218217
return grpstate;
219218
}

src/backend/executor/nodeMergejoin.c

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.84 2007/01/05 22:19:28 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.85 2007/01/10 18:06:02 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -156,50 +156,47 @@ typedef struct MergeJoinClauseData
156156
* the two expressions from the original clause.
157157
*
158158
* In addition to the expressions themselves, the planner passes the btree
159-
* opfamily OID and btree strategy number (BTLessStrategyNumber or
160-
* BTGreaterStrategyNumber) that identify the intended merge semantics for
161-
* each merge key. The mergejoinable operator is an equality operator in
162-
* this opfamily, and the two inputs are guaranteed to be ordered in either
163-
* increasing or decreasing (respectively) order according to this opfamily.
164-
* This allows us to obtain the needed comparison functions from the opfamily.
159+
* opfamily OID, btree strategy number (BTLessStrategyNumber or
160+
* BTGreaterStrategyNumber), and nulls-first flag that identify the intended
161+
* merge semantics for each merge key. The mergejoinable operator is an
162+
* equality operator in this opfamily, and the two inputs are guaranteed to be
163+
* ordered in either increasing or decreasing (respectively) order according
164+
* to this opfamily. This allows us to obtain the needed comparison functions
165+
* from the opfamily.
165166
*/
166167
static MergeJoinClause
167-
MJExamineQuals(List *mergeclauses, List *mergefamilies, List *mergestrategies,
168+
MJExamineQuals(List *mergeclauses,
169+
Oid *mergefamilies,
170+
int *mergestrategies,
171+
bool *mergenullsfirst,
168172
PlanState *parent)
169173
{
170174
MergeJoinClause clauses;
171175
int nClauses = list_length(mergeclauses);
172176
int iClause;
173177
ListCell *cl;
174-
ListCell *cf;
175-
ListCell *cs;
176178

177179
clauses = (MergeJoinClause) palloc0(nClauses * sizeof(MergeJoinClauseData));
178180

179181
iClause = 0;
180-
cf = list_head(mergefamilies);
181-
cs = list_head(mergestrategies);
182182
foreach(cl, mergeclauses)
183183
{
184184
OpExpr *qual = (OpExpr *) lfirst(cl);
185185
MergeJoinClause clause = &clauses[iClause];
186-
Oid opfamily;
187-
StrategyNumber opstrategy;
186+
Oid opfamily = mergefamilies[iClause];
187+
StrategyNumber opstrategy = mergestrategies[iClause];
188+
bool nulls_first = mergenullsfirst[iClause];
188189
int op_strategy;
189190
Oid op_lefttype;
190191
Oid op_righttype;
191192
bool op_recheck;
192193
RegProcedure cmpproc;
193194
AclResult aclresult;
194195

195-
opfamily = lfirst_oid(cf);
196-
cf = lnext(cf);
197-
opstrategy = lfirst_int(cs);
198-
cs = lnext(cs);
199-
200196
/* Later we'll support both ascending and descending sort... */
201197
Assert(opstrategy == BTLessStrategyNumber);
202198
clause->cmpstrategy = MERGEFUNC_CMP;
199+
Assert(!nulls_first);
203200

204201
if (!IsA(qual, OpExpr))
205202
elog(ERROR, "mergejoin clause is not an OpExpr");
@@ -1525,8 +1522,9 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags)
15251522
*/
15261523
mergestate->mj_NumClauses = list_length(node->mergeclauses);
15271524
mergestate->mj_Clauses = MJExamineQuals(node->mergeclauses,
1528-
node->mergefamilies,
1529-
node->mergestrategies,
1525+
node->mergeFamilies,
1526+
node->mergeStrategies,
1527+
node->mergeNullsFirst,
15301528
(PlanState *) mergestate);
15311529

15321530
/*

src/backend/executor/nodeSetOp.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*
2222
*
2323
* IDENTIFICATION
24-
* $PostgreSQL: pgsql/src/backend/executor/nodeSetOp.c,v 1.23 2007/01/05 22:19:28 momjian Exp $
24+
* $PostgreSQL: pgsql/src/backend/executor/nodeSetOp.c,v 1.24 2007/01/10 18:06:02 tgl Exp $
2525
*
2626
*-------------------------------------------------------------------------
2727
*/
@@ -267,9 +267,8 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags)
267267
* Precompute fmgr lookup data for inner loop
268268
*/
269269
setopstate->eqfunctions =
270-
execTuplesMatchPrepare(ExecGetResultType(&setopstate->ps),
271-
node->numCols,
272-
node->dupColIdx);
270+
execTuplesMatchPrepare(node->numCols,
271+
node->dupOperators);
273272

274273
return setopstate;
275274
}

src/backend/executor/nodeUnique.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeUnique.c,v 1.54 2007/01/05 22:19:28 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeUnique.c,v 1.55 2007/01/10 18:06:02 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -159,9 +159,8 @@ ExecInitUnique(Unique *node, EState *estate, int eflags)
159159
* Precompute fmgr lookup data for inner loop
160160
*/
161161
uniquestate->eqfunctions =
162-
execTuplesMatchPrepare(ExecGetResultType(&uniquestate->ps),
163-
node->numCols,
164-
node->uniqColIdx);
162+
execTuplesMatchPrepare(node->numCols,
163+
node->uniqOperators);
165164

166165
return uniquestate;
167166
}

src/backend/nodes/copyfuncs.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.360 2007/01/09 02:14:11 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.361 2007/01/10 18:06:02 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -439,6 +439,7 @@ static MergeJoin *
439439
_copyMergeJoin(MergeJoin *from)
440440
{
441441
MergeJoin *newnode = makeNode(MergeJoin);
442+
int numCols;
442443

443444
/*
444445
* copy node superclass fields
@@ -449,8 +450,10 @@ _copyMergeJoin(MergeJoin *from)
449450
* copy remainder of node
450451
*/
451452
COPY_NODE_FIELD(mergeclauses);
452-
COPY_NODE_FIELD(mergefamilies);
453-
COPY_NODE_FIELD(mergestrategies);
453+
numCols = list_length(from->mergeclauses);
454+
COPY_POINTER_FIELD(mergeFamilies, numCols * sizeof(Oid));
455+
COPY_POINTER_FIELD(mergeStrategies, numCols * sizeof(int));
456+
COPY_POINTER_FIELD(mergeNullsFirst, numCols * sizeof(bool));
454457

455458
return newnode;
456459
}
@@ -528,6 +531,7 @@ _copyGroup(Group *from)
528531

529532
COPY_SCALAR_FIELD(numCols);
530533
COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber));
534+
COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid));
531535

532536
return newnode;
533537
}
@@ -545,7 +549,10 @@ _copyAgg(Agg *from)
545549
COPY_SCALAR_FIELD(aggstrategy);
546550
COPY_SCALAR_FIELD(numCols);
547551
if (from->numCols > 0)
552+
{
548553
COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber));
554+
COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid));
555+
}
549556
COPY_SCALAR_FIELD(numGroups);
550557

551558
return newnode;
@@ -569,6 +576,7 @@ _copyUnique(Unique *from)
569576
*/
570577
COPY_SCALAR_FIELD(numCols);
571578
COPY_POINTER_FIELD(uniqColIdx, from->numCols * sizeof(AttrNumber));
579+
COPY_POINTER_FIELD(uniqOperators, from->numCols * sizeof(Oid));
572580

573581
return newnode;
574582
}
@@ -612,6 +620,7 @@ _copySetOp(SetOp *from)
612620
COPY_SCALAR_FIELD(cmd);
613621
COPY_SCALAR_FIELD(numCols);
614622
COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber));
623+
COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid));
615624
COPY_SCALAR_FIELD(flagColIdx);
616625

617626
return newnode;
@@ -1356,6 +1365,7 @@ _copyInClauseInfo(InClauseInfo *from)
13561365
COPY_BITMAPSET_FIELD(lefthand);
13571366
COPY_BITMAPSET_FIELD(righthand);
13581367
COPY_NODE_FIELD(sub_targetlist);
1368+
COPY_NODE_FIELD(in_operators);
13591369

13601370
return newnode;
13611371
}

src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* Portions Copyright (c) 1994, Regents of the University of California
1919
*
2020
* IDENTIFICATION
21-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.294 2007/01/09 02:14:12 tgl Exp $
21+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.295 2007/01/10 18:06:03 tgl Exp $
2222
*
2323
*-------------------------------------------------------------------------
2424
*/
@@ -638,6 +638,7 @@ _equalInClauseInfo(InClauseInfo *a, InClauseInfo *b)
638638
COMPARE_BITMAPSET_FIELD(lefthand);
639639
COMPARE_BITMAPSET_FIELD(righthand);
640640
COMPARE_NODE_FIELD(sub_targetlist);
641+
COMPARE_NODE_FIELD(in_operators);
641642

642643
return true;
643644
}

0 commit comments

Comments
 (0)