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: