Hi.

On 2018/04/06 7:35, Alvaro Herrera wrote:
> I seems pretty clear that putting get_matching_partitions() in
> catalog/partition.c is totally the wrong thing; it belongs wholly in
> partprune. I think the reason you put it there is that it requires
> access to a lot of internals that are static in partition.c.  In the
> attached not yet cleaned version of the patch, I have moved a whole lot
> of what you added to partition.c to partprune.c; and for the functions
> and struct declarations that were required to make it work, I created
> catalog/partition_internal.h.

Yes, I really wanted for most of the new code that this patch adds to land
in the planner, especially after Robert's comments here:

https://www.postgresql.org/message-id/CA%2BTgmoabi-29Vs8H0xkjtYB%3DcU%2BGVCrNwPz7okpa3KsoLmdEUQ%40mail.gmail.com

It would've been nice if we'd gotten the "reorganizing partitioning code"
thread resolved sooner.

> I changed a lot of code also, but cosmetic changes only.
> 
> I'll clean this up a bit more now, and try to commit shortly (or early
> tomorrow); wanted to share current status now in case I have to rush
> out.

Some comments on the code reorganizing part of the patch:

* Did you intentionally not put PartitionBoundInfoData and its accessor
macros in partition_internal.h.  partprune.c would not need to include
partition.h if we do that.

* Also, I wonder why you left PartitionPruneContext in partition.h.  Isn't
it better taken out to partprune.h?

I have done that in the attached.

* Why isn't gen_partprune_steps() in partprune.h?  I see only
prune_append_rel_partitions() exported out of partprune.c, but the runtime
patch needs gen_partprune_steps() to be called from createplan.c.

* I don't see get_matching_partitions() exported either.  Runtime pruning
patch needs that too.

Maybe you've thought something about these two items though.

Thanks,
Amit
diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index d5e91b111d..f89c99f544 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -24,7 +24,6 @@
 #include "catalog/indexing.h"
 #include "catalog/objectaddress.h"
 #include "catalog/partition.h"
-#include "catalog/partition_internal.h"
 #include "catalog/pg_collation.h"
 #include "catalog/pg_inherits.h"
 #include "catalog/pg_inherits_fn.h"
diff --git a/src/backend/optimizer/util/partprune.c 
b/src/backend/optimizer/util/partprune.c
index b0638d5aa6..93553b5d13 100644
--- a/src/backend/optimizer/util/partprune.c
+++ b/src/backend/optimizer/util/partprune.c
@@ -19,8 +19,6 @@
 
 #include "access/hash.h"
 #include "access/nbtree.h"
-#include "catalog/partition.h"
-#include "catalog/partition_internal.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_opfamily.h"
 #include "catalog/pg_type.h"
@@ -35,6 +33,7 @@
 #include "parser/parse_coerce.h"
 #include "parser/parsetree.h"
 #include "rewrite/rewriteManip.h"
+#include "utils/array.h"
 #include "utils/lsyscache.h"
 
 /*
diff --git a/src/include/catalog/partition.h b/src/include/catalog/partition.h
index 0bcaa36165..1c17553917 100644
--- a/src/include/catalog/partition.h
+++ b/src/include/catalog/partition.h
@@ -13,7 +13,7 @@
 #ifndef PARTITION_H
 #define PARTITION_H
 
-#include "fmgr.h"
+#include "catalog/partition_internal.h"
 #include "executor/tuptable.h"
 #include "nodes/execnodes.h"
 #include "parser/parse_node.h"
@@ -23,65 +23,6 @@
 #define HASH_PARTITION_SEED UINT64CONST(0x7A5B22367996DCFD)
 
 /*
- * PartitionBoundInfoData encapsulates a set of partition bounds. It is
- * usually associated with partitioned tables as part of its partition
- * descriptor, but may also be used to represent a virtual partitioned
- * table such as a partitioned joinrel within the planner.
- *
- * A list partition datum that is known to be NULL is never put into the
- * datums array. Instead, it is tracked using the null_index field.
- *
- * In the case of range partitioning, ndatums will typically be far less than
- * 2 * nparts, because a partition's upper bound and the next partition's lower
- * bound are the same in most common cases, and we only store one of them (the
- * upper bound).  In case of hash partitioning, ndatums will be same as the
- * number of partitions.
- *
- * For range and list partitioned tables, datums is an array of datum-tuples
- * with key->partnatts datums each.  For hash partitioned tables, it is an 
array
- * of datum-tuples with 2 datums, modulus and remainder, corresponding to a
- * given partition.
- *
- * The datums in datums array are arranged in increasing order as defined by
- * functions qsort_partition_rbound_cmp(), qsort_partition_list_value_cmp() and
- * qsort_partition_hbound_cmp() for range, list and hash partitioned tables
- * respectively. For range and list partitions this simply means that the
- * datums in the datums array are arranged in increasing order as defined by
- * the partition key's operator classes and collations.
- *
- * In the case of list partitioning, the indexes array stores one entry for
- * every datum, which is the index of the partition that accepts a given datum.
- * In case of range partitioning, it stores one entry per distinct range
- * datum, which is the index of the partition for which a given datum
- * is an upper bound.  In the case of hash partitioning, the number of the
- * entries in the indexes array is same as the greatest modulus amongst all
- * partitions.  For a given partition key datum-tuple, the index of the
- * partition which would accept that datum-tuple would be given by the entry
- * pointed by remainder produced when hash value of the datum-tuple is divided
- * by the greatest modulus.
- */
-
-typedef struct PartitionBoundInfoData
-{
-       char            strategy;               /* hash, list or range? */
-       int                     ndatums;                /* Length of the datums 
following array */
-       Datum     **datums;
-       PartitionRangeDatumKind **kind; /* The kind of each range bound datum;
-                                                                        * NULL 
for hash and list partitioned
-                                                                        * 
tables */
-       int                *indexes;            /* Partition indexes */
-       int                     null_index;             /* Index of the 
null-accepting partition; -1
-                                                                * if there 
isn't one */
-       int                     default_index;  /* Index of the default 
partition; -1 if there
-                                                                * isn't one */
-} PartitionBoundInfoData;
-
-typedef struct PartitionBoundInfoData *PartitionBoundInfo;
-
-#define partition_bound_accepts_nulls(bi) ((bi)->null_index != -1)
-#define partition_bound_has_default(bi) ((bi)->default_index != -1)
-
-/*
  * Information about partitions of a partitioned table.
  */
 typedef struct PartitionDescData
@@ -93,28 +34,6 @@ typedef struct PartitionDescData
 
 typedef struct PartitionDescData *PartitionDesc;
 
-/*
- * PartitionPruneContext
- *
- * Information about a partitioned table needed to perform partition pruning.
- */
-typedef struct PartitionPruneContext
-{
-       /* Partition key information */
-       char            strategy;
-       int                     partnatts;
-       Oid                *partopfamily;
-       Oid                *partopcintype;
-       Oid                *partcollation;
-       FmgrInfo   *partsupfunc;
-
-       /* Number of partitions */
-       int                     nparts;
-
-       /* Partition boundary info */
-       PartitionBoundInfo boundinfo;
-} PartitionPruneContext;
-
 extern void RelationBuildPartitionDesc(Relation relation);
 extern bool partition_bounds_equal(int partnatts, int16 *parttyplen,
                                           bool *parttypbyval, 
PartitionBoundInfo b1,
diff --git a/src/include/catalog/partition_internal.h 
b/src/include/catalog/partition_internal.h
index b21d422e75..e3b9123a2e 100644
--- a/src/include/catalog/partition_internal.h
+++ b/src/include/catalog/partition_internal.h
@@ -11,6 +11,9 @@
 #ifndef PARTITION_INTERNAL_H
 #define PARTITION_INTERNAL_H
 
+#include "fmgr.h"
+#include "nodes/parsenodes.h"
+
 /*
  * When qsort'ing partition bounds after reading from the catalog, each bound
  * is represented with one of the following structs.
@@ -40,6 +43,63 @@ typedef struct PartitionRangeBound
        bool            lower;                  /* this is the lower (vs upper) 
bound */
 } PartitionRangeBound;
 
+/*
+ * PartitionBoundInfoData encapsulates a set of partition bounds. It is
+ * usually associated with partitioned tables as part of its partition
+ * descriptor, but may also be used to represent a virtual partitioned
+ * table such as a partitioned joinrel within the planner.
+ *
+ * A list partition datum that is known to be NULL is never put into the
+ * datums array. Instead, it is tracked using the null_index field.
+ *
+ * In the case of range partitioning, ndatums will typically be far less than
+ * 2 * nparts, because a partition's upper bound and the next partition's lower
+ * bound are the same in most common cases, and we only store one of them (the
+ * upper bound).  In case of hash partitioning, ndatums will be same as the
+ * number of partitions.
+ *
+ * For range and list partitioned tables, datums is an array of datum-tuples
+ * with key->partnatts datums each.  For hash partitioned tables, it is an 
array
+ * of datum-tuples with 2 datums, modulus and remainder, corresponding to a
+ * given partition.
+ *
+ * The datums in datums array are arranged in increasing order as defined by
+ * functions qsort_partition_rbound_cmp(), qsort_partition_list_value_cmp() and
+ * qsort_partition_hbound_cmp() for range, list and hash partitioned tables
+ * respectively. For range and list partitions this simply means that the
+ * datums in the datums array are arranged in increasing order as defined by
+ * the partition key's operator classes and collations.
+ *
+ * In the case of list partitioning, the indexes array stores one entry for
+ * every datum, which is the index of the partition that accepts a given datum.
+ * In case of range partitioning, it stores one entry per distinct range
+ * datum, which is the index of the partition for which a given datum
+ * is an upper bound.  In the case of hash partitioning, the number of the
+ * entries in the indexes array is same as the greatest modulus amongst all
+ * partitions.  For a given partition key datum-tuple, the index of the
+ * partition which would accept that datum-tuple would be given by the entry
+ * pointed by remainder produced when hash value of the datum-tuple is divided
+ * by the greatest modulus.
+ */
+typedef struct PartitionBoundInfoData
+{
+       char            strategy;               /* hash, list or range? */
+       int                     ndatums;                /* Length of the datums 
following array */
+       Datum     **datums;
+       PartitionRangeDatumKind **kind; /* The kind of each range bound datum;
+                                                                        * NULL 
for hash and list partitioned
+                                                                        * 
tables */
+       int                *indexes;            /* Partition indexes */
+       int                     null_index;             /* Index of the 
null-accepting partition; -1
+                                                                * if there 
isn't one */
+       int                     default_index;  /* Index of the default 
partition; -1 if there
+                                                                * isn't one */
+} PartitionBoundInfoData;
+
+typedef struct PartitionBoundInfoData *PartitionBoundInfo;
+
+#define partition_bound_accepts_nulls(bi) ((bi)->null_index != -1)
+#define partition_bound_has_default(bi) ((bi)->default_index != -1)
 
 extern int get_hash_partition_greatest_modulus(PartitionBoundInfo b);
 extern int partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation,
diff --git a/src/include/optimizer/partprune.h 
b/src/include/optimizer/partprune.h
index 027016b32c..093ade24c3 100644
--- a/src/include/optimizer/partprune.h
+++ b/src/include/optimizer/partprune.h
@@ -14,8 +14,31 @@
 #ifndef PARTPRUNE_H
 #define PARTPRUNE_H
 
+#include "catalog/partition_internal.h"
 #include "nodes/relation.h"
 
+/*
+ * PartitionPruneContext
+ *
+ * Information about a partitioned table needed to perform partition pruning.
+ */
+typedef struct PartitionPruneContext
+{
+       /* Partition key information */
+       char            strategy;
+       int                     partnatts;
+       Oid                *partopfamily;
+       Oid                *partopcintype;
+       Oid                *partcollation;
+       FmgrInfo   *partsupfunc;
+
+       /* Number of partitions */
+       int                     nparts;
+
+       /* Partition boundary info */
+       PartitionBoundInfo boundinfo;
+} PartitionPruneContext;
+
 extern Relids prune_append_rel_partitions(RelOptInfo *rel);
 
 #endif                                                 /* PARTPRUNE_H */

Reply via email to