1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-26 01:22:12 +03:00

Cosmetic improvements for code related to partitionwise join.

Move have_partkey_equi_join and match_expr_to_partition_keys to
relnode.c, since they're used only there.  Refactor
build_joinrel_partition_info to split out the code that fills the
joinrel's partition key lists; this doesn't have any non-cosmetic
impact, but it seems like a useful separation of concerns.
Improve assorted nearby comments.

Amit Langote, with a little further editorialization by me

Discussion: https://postgr.es/m/CA+HiwqG2WVUGmLJqtR0tPFhniO=H=9qQ+Z3L_ZC+Y3-EVQHFGg@mail.gmail.com
This commit is contained in:
Tom Lane
2020-04-03 17:00:25 -04:00
parent 21dc48840c
commit 0568e7a2a4
5 changed files with 283 additions and 234 deletions

View File

@ -574,6 +574,24 @@ typedef struct PartitionSchemeData *PartitionScheme;
* we know we will need it at least once (to price the sequential scan)
* and may need it multiple times to price index scans.
*
* A join relation is considered to be partitioned if it is formed from a
* join of two relations that are partitioned, have matching partitioning
* schemes, and are joined on an equijoin of the partitioning columns.
* Under those conditions we can consider the join relation to be partitioned
* by either relation's partitioning keys, though some care is needed if
* either relation can be forced to null by outer-joining. For example, an
* outer join like (A LEFT JOIN B ON A.a = B.b) may produce rows with B.b
* NULL. These rows may not fit the partitioning conditions imposed on B.
* Hence, strictly speaking, the join is not partitioned by B.b and thus
* partition keys of an outer join should include partition key expressions
* from the non-nullable side only. However, if a subsequent join uses
* strict comparison operators (and all commonly-used equijoin operators are
* strict), the presence of nulls doesn't cause a problem: such rows couldn't
* match anything on the other side and thus they don't create a need to do
* any cross-partition sub-joins. Hence we can treat such values as still
* partitioning the join output for the purpose of additional partitionwise
* joining, so long as a strict join operator is used by the next join.
*
* If the relation is partitioned, these fields will be set:
*
* part_scheme - Partitioning scheme of the relation
@ -586,16 +604,15 @@ typedef struct PartitionSchemeData *PartitionScheme;
* this relation that are partitioned tables
* themselves, in hierarchical order
*
* Note: A base relation always has only one set of partition keys, but a join
* relation may have as many sets of partition keys as the number of relations
* being joined. partexprs and nullable_partexprs are arrays containing
* part_scheme->partnatts elements each. Each of these elements is a list of
* partition key expressions. For a base relation each list in partexprs
* contains only one expression and nullable_partexprs is not populated. For a
* join relation, partexprs and nullable_partexprs contain partition key
* expressions from non-nullable and nullable relations resp. Lists at any
* given position in those arrays together contain as many elements as the
* number of joining relations.
* The partexprs and nullable_partexprs arrays each contain
* part_scheme->partnatts elements. Each of the elements is a list of
* partition key expressions. For partitioned base relations, there is one
* expression in each partexprs element, and nullable_partexprs is empty.
* For partitioned join relations, each base relation within the join
* contributes one partition key expression per partitioning column;
* that expression goes in the partexprs[i] list if the base relation
* is not nullable by this join or any lower outer join, or in the
* nullable_partexprs[i] list if the base relation is nullable.
*----------
*/
typedef enum RelOptKind
@ -716,16 +733,16 @@ typedef struct RelOptInfo
Relids top_parent_relids; /* Relids of topmost parents (if "other"
* rel) */
/* used for partitioned relations */
PartitionScheme part_scheme; /* Partitioning scheme. */
int nparts; /* number of partitions */
/* used for partitioned relations: */
PartitionScheme part_scheme; /* Partitioning scheme */
int nparts; /* Number of partitions */
struct PartitionBoundInfoData *boundinfo; /* Partition bounds */
List *partition_qual; /* partition constraint */
List *partition_qual; /* Partition constraint, if not the root */
struct RelOptInfo **part_rels; /* Array of RelOptInfos of partitions,
* stored in the same order of bounds */
List **partexprs; /* Non-nullable partition key expressions. */
List **nullable_partexprs; /* Nullable partition key expressions. */
List *partitioned_child_rels; /* List of RT indexes. */
* stored in the same order as bounds */
List **partexprs; /* Non-nullable partition key expressions */
List **nullable_partexprs; /* Nullable partition key expressions */
List *partitioned_child_rels; /* List of RT indexes */
} RelOptInfo;
/*