Re: why partition pruning doesn't work? - Mailing list pgsql-hackers
| From | Amit Langote |
|---|---|
| Subject | Re: why partition pruning doesn't work? |
| Date | |
| Msg-id | b804d3a6-1411-660d-a893-e2bf78231a9f@lab.ntt.co.jp Whole thread Raw |
| In response to | Re: why partition pruning doesn't work? (Tom Lane <tgl@sss.pgh.pa.us>) |
| Responses |
Re: why partition pruning doesn't work?
|
| List | pgsql-hackers |
On 2018/06/19 2:05, Tom Lane wrote:
> Amit Langote <Langote_Amit_f8@lab.ntt.co.jp> writes:
>> [ 0001-Open-partitioned-tables-during-Append-initialization.patch ]
>
> I took a look at this. While I'm in agreement with the general idea of
> holding open the partitioned relations' relcache entries throughout the
> query, I do not like anything about this patch:
Thanks for taking a look at it and sorry about the delay in replying.
> * It seems to be outright broken for the case that any of the partitioned
> relations are listed in nonleafResultRelations. If we're going to do it
> like this, we have to open every one of the partrels regardless of that.
Yes, that was indeed wrong.
> (I wonder whether we couldn't lose PlannedStmt.nonleafResultRelations
> altogether, in favor of merging the related code in InitPlan with this.
Hmm, PlannedStmt.nonleafResultRelations exists for the same reason as why
PlannedStmt.resultRelations does, that is,
/*
* initialize result relation stuff, and open/lock the result rels.
*
* We must do this before initializing the plan tree, else we might try to
* do a lock upgrade if a result rel is also a source rel.
*/
nonleafResultRelations contains members of partitioned_rels lists of all
ModifyTable nodes contained in a plan.
> That existing code is already a mighty ugly wart, and this patch makes
> it worse by adding new, related warts elsewhere.)
I just realized that there is a thinko in the following piece of code in
ExecLockNonLeafAppendTables
/* If this is a result relation, already locked in InitPlan */
foreach(l, stmt->nonleafResultRelations)
{
if (rti == lfirst_int(l))
{
is_result_rel = true;
break;
}
}
It should actually be:
/* If this is a result relation, already locked in InitPlan */
foreach(l, stmt->nonleafResultRelations)
{
Index nonleaf_rti = lfirst_int(l);
Oid nonleaf_relid = getrelid(nonleaf_rti,
estate->es_range_table);
if (relid == nonleaf_relid)
{
is_result_rel = true;
break;
}
}
RT indexes in, say, Append.partitioned_rels, are distinct from those in
PlannedStmt.nonleafResultRelations, so the existing test never succeeds,
as also evident from the coverage report:
https://coverage.postgresql.org/src/backend/executor/execUtils.c.gcov.html#864
I'm wondering if we couldn't just get rid of this code. If an input
partitioned tables is indeed also a result relation, then we would've
locked it in InitPlan with RowExclusiveLock and heap_opening it with a
weaker lock (RowShare/AccessShare) wouldn't hurt.
> * You've got *far* too much intimate knowledge of the possible callers
> in ExecOpenAppendPartitionedTables.
>
> Personally, what I would have this function do is return a List of
> the opened Relation pointers, and add a matching function to run through
> such a List and close the entries again, and make the callers responsible
> for stashing the List pointer in an appropriate field in their planstate.
OK, I rewrote it to work that way.
> Or maybe what we should do is drop ExecLockNonLeafAppendTables/
> ExecOpenAppendPartitionedTables entirely and teach InitPlan to do it.
Hmm, for InitPlan to do what ExecOpenAppendPartitionedTables does, we'd
have to have all the partitioned tables (contained in partitioned_rels
fields of all Append/MergeAppend/ModifyTable nodes of a plan) also listed
in a global list like rootResultRelations and nonleafResultRelations of
PlannedStmt.
Attached updated patch.
Thanks,
Amit
Attachment
pgsql-hackers by date: