mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Don't scan partitioned tables.
Partitioned tables do not contain any data; only their unpartitioned descendents need to be scanned. However, the partitioned tables still need to be locked, even though they're not scanned. To make that work, Append and MergeAppend relations now need to carry a list of (unscanned) partitioned relations that must be locked, and InitPlan must lock all partitioned result relations. Aside from the obvious advantage of avoiding some work at execution time, this has two other advantages. First, it may improve the planner's decision-making in some cases since the empty relation might throw things off. Second, it paves the way to getting rid of the storage for partitioned tables altogether. Amit Langote, reviewed by me. Discussion: http://postgr.es/m/6837c359-45c4-8044-34d1-736756335a15@lab.ntt.co.jp
This commit is contained in:
		@@ -107,6 +107,8 @@ typedef struct PlannerGlobal
 | 
			
		||||
 | 
			
		||||
	List	   *resultRelations;	/* "flat" list of integer RT indexes */
 | 
			
		||||
 | 
			
		||||
	List   *nonleafResultRelations; /* "flat" list of integer RT indexes */
 | 
			
		||||
 | 
			
		||||
	List	   *relationOids;	/* OIDs of relations the plan depends on */
 | 
			
		||||
 | 
			
		||||
	List	   *invalItems;		/* other dependencies, as PlanInvalItems */
 | 
			
		||||
@@ -248,6 +250,8 @@ typedef struct PlannerInfo
 | 
			
		||||
 | 
			
		||||
	List	   *append_rel_list;	/* list of AppendRelInfos */
 | 
			
		||||
 | 
			
		||||
	List	   *pcinfo_list;	/* list of PartitionedChildRelInfos */
 | 
			
		||||
 | 
			
		||||
	List	   *rowMarks;		/* list of PlanRowMarks */
 | 
			
		||||
 | 
			
		||||
	List	   *placeholder_list;		/* list of PlaceHolderInfos */
 | 
			
		||||
@@ -1116,6 +1120,8 @@ typedef struct CustomPath
 | 
			
		||||
typedef struct AppendPath
 | 
			
		||||
{
 | 
			
		||||
	Path		path;
 | 
			
		||||
	/* RT indexes of non-leaf tables in a partition tree */
 | 
			
		||||
	List	   *partitioned_rels;
 | 
			
		||||
	List	   *subpaths;		/* list of component Paths */
 | 
			
		||||
} AppendPath;
 | 
			
		||||
 | 
			
		||||
@@ -1134,6 +1140,8 @@ typedef struct AppendPath
 | 
			
		||||
typedef struct MergeAppendPath
 | 
			
		||||
{
 | 
			
		||||
	Path		path;
 | 
			
		||||
	/* RT indexes of non-leaf tables in a partition tree */
 | 
			
		||||
	List	   *partitioned_rels;
 | 
			
		||||
	List	   *subpaths;		/* list of component Paths */
 | 
			
		||||
	double		limit_tuples;	/* hard limit on output tuples, or -1 */
 | 
			
		||||
} MergeAppendPath;
 | 
			
		||||
@@ -1482,6 +1490,8 @@ typedef struct ModifyTablePath
 | 
			
		||||
	CmdType		operation;		/* INSERT, UPDATE, or DELETE */
 | 
			
		||||
	bool		canSetTag;		/* do we set the command tag/es_processed? */
 | 
			
		||||
	Index		nominalRelation;	/* Parent RT index for use of EXPLAIN */
 | 
			
		||||
	/* RT indexes of non-leaf tables in a partition tree */
 | 
			
		||||
	List	   *partitioned_rels;
 | 
			
		||||
	List	   *resultRelations;	/* integer list of RT indexes */
 | 
			
		||||
	List	   *subpaths;		/* Path(s) producing source data */
 | 
			
		||||
	List	   *subroots;		/* per-target-table PlannerInfos */
 | 
			
		||||
@@ -1836,10 +1846,10 @@ typedef struct SpecialJoinInfo
 | 
			
		||||
 *
 | 
			
		||||
 * When we expand an inheritable table or a UNION-ALL subselect into an
 | 
			
		||||
 * "append relation" (essentially, a list of child RTEs), we build an
 | 
			
		||||
 * AppendRelInfo for each child RTE.  The list of AppendRelInfos indicates
 | 
			
		||||
 * which child RTEs must be included when expanding the parent, and each
 | 
			
		||||
 * node carries information needed to translate Vars referencing the parent
 | 
			
		||||
 * into Vars referencing that child.
 | 
			
		||||
 * AppendRelInfo for each non-partitioned child RTE.  The list of
 | 
			
		||||
 * AppendRelInfos indicates which child RTEs must be included when expanding
 | 
			
		||||
 * the parent, and each node carries information needed to translate Vars
 | 
			
		||||
 * referencing the parent into Vars referencing that child.
 | 
			
		||||
 *
 | 
			
		||||
 * These structs are kept in the PlannerInfo node's append_rel_list.
 | 
			
		||||
 * Note that we just throw all the structs into one list, and scan the
 | 
			
		||||
@@ -1913,6 +1923,25 @@ typedef struct AppendRelInfo
 | 
			
		||||
	Oid			parent_reloid;	/* OID of parent relation */
 | 
			
		||||
} AppendRelInfo;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * For a partitioned table, this maps its RT index to the list of RT indexes
 | 
			
		||||
 * of the partitioned child tables in the partition tree.  We need to
 | 
			
		||||
 * separately store this information, because we do not create AppendRelInfos
 | 
			
		||||
 * for the partitioned child tables of a parent table, since AppendRelInfos
 | 
			
		||||
 * contain information that is unnecessary for the partitioned child tables.
 | 
			
		||||
 * The child_rels list must contain at least one element, because the parent
 | 
			
		||||
 * partitioned table is itself counted as a child.
 | 
			
		||||
 *
 | 
			
		||||
 * These structs are kept in the PlannerInfo node's pcinfo_list.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct PartitionedChildRelInfo
 | 
			
		||||
{
 | 
			
		||||
	NodeTag		type;
 | 
			
		||||
 | 
			
		||||
	Index		parent_relid;
 | 
			
		||||
	List	   *child_rels;
 | 
			
		||||
} PartitionedChildRelInfo;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * For each distinct placeholder expression generated during planning, we
 | 
			
		||||
 * store a PlaceHolderInfo node in the PlannerInfo node's placeholder_list.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user