From 4bb5a3edee1eaf33b3a6df6892650fc744d50827 Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Mon, 8 Feb 2016 15:08:49 +0900
Subject: [PATCH 02/10] Add partitioned table system catalog.

Named pg_partitioned_rel, it contains the following information:

 1. Partitioned table oid (pg_class.oid)
 2. Partition key level
 3. Partition strategy (list, range, etc.)
 4. Number of partition attributes
 5. Partition key (array of attnum of partition attributes)
 6. Partition key opclass info (array of opclass oids, one per key attribute)
 7. Partition key expressions (pg_node_tree corresponding to list of expressions)

Add a unique index on (partrelid, partlevel) and associated syscache. There is
also a non-unique index on just partrelid.
---
 doc/src/sgml/catalogs.sgml                 |  109 ++++++++++++++++++++++++++++
 src/backend/catalog/Makefile               |    2 +-
 src/backend/utils/cache/syscache.c         |   12 +++
 src/include/catalog/indexing.h             |    6 ++
 src/include/catalog/pg_partitioned_rel.h   |   69 ++++++++++++++++++
 src/include/utils/syscache.h               |    1 +
 src/test/regress/expected/sanity_check.out |    1 +
 7 files changed, 199 insertions(+), 1 deletions(-)
 create mode 100644 src/include/catalog/pg_partitioned_rel.h

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 412c845..db8d0ac 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -219,6 +219,11 @@
      </row>
 
      <row>
+      <entry><link linkend="catalog-pg-partitioned-rel"><structname>pg_partitioned_rel</structname></link></entry>
+      <entry>information about partitioned tables, including the partition key</entry>
+     </row>
+
+     <row>
       <entry><link linkend="catalog-pg-policy"><structname>pg_policy</structname></link></entry>
       <entry>row-security policies</entry>
      </row>
@@ -4537,6 +4542,110 @@
 
  </sect1>
 
+ <sect1 id="catalog-pg-partitioned-rel">
+  <title><structname>pg_partitioned_rel</structname></title>
+
+  <indexterm zone="catalog-pg-partitioned-rel">
+   <primary>pg_partitioned_rel</primary>
+  </indexterm>
+
+  <para>
+   The catalog <structname>pg_partitioned</structname> stores
+   information about the partition key of partitioned tables.
+  </para>
+
+  <table>
+   <title><structname>pg_partitioned_rel</> Columns</title>
+
+   <tgroup cols="4">
+    <thead>
+     <row>
+      <entry>Name</entry>
+      <entry>Type</entry>
+      <entry>References</entry>
+      <entry>Description</entry>
+     </row>
+    </thead>
+
+    <tbody>
+
+     <row>
+      <entry><structfield>partrelid</structfield></entry>
+      <entry><type>oid</type></entry>
+      <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
+      <entry>The OID of the <structname>pg_class</> entry for this partitioned table</entry>
+     </row>
+
+     <row>
+      <entry><structfield>partlevel</structfield></entry>
+      <entry><type>int2</type></entry>
+      <entry></entry>
+      <entry>
+       Partition key level; It's value is 0 for the top-level key and 1 for
+       the sub-partition key, if any
+      </entry>
+     </row>
+
+     <row>
+      <entry><structfield>partstrat</structfield></entry>
+      <entry><type>char</type></entry>
+      <entry></entry>
+      <entry>
+       Partitioning strategy (or method); <literal>l</> = list partitioned table,
+       <literal>r</> = range partitioned table
+      </entry>
+     </row>
+
+     <row>
+      <entry><structfield>partnatts</structfield></entry>
+      <entry><type>int2</type></entry>
+      <entry></entry>
+      <entry>The number of columns in partition key</entry>
+     </row>
+
+     <row>
+      <entry><structfield>partkey</structfield></entry>
+      <entry><type>int2vector</type></entry>
+      <entry><literal><link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.attnum</literal></entry>
+      <entry>
+       This is an array of <structfield>partnatts</structfield> values that
+       indicate which table columns are used as partition key.  For example,
+       a value of <literal>1 3</literal> would mean that the first and the
+       third table columns make up the partition key.  A zero in this array
+       indicates that the corresponding partition key column is an expression
+       over the table columns, rather than a simple column reference.
+      </entry>
+     </row>
+
+     <row>
+      <entry><structfield>partclass</structfield></entry>
+      <entry><type>oidvector</type></entry>
+      <entry><literal><link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.oid</literal></entry>
+      <entry>
+       For each column in the partition key, this contains the OID of
+       the operator class to use.  See
+       <link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link> for details.
+      </entry>
+     </row>
+
+     <row>
+      <entry><structfield>partexprs</structfield></entry>
+      <entry><type>pg_node_tree</type></entry>
+      <entry></entry>
+      <entry>
+       Expression trees (in <function>nodeToString()</function>
+       representation) for partition key columns that are not simple column
+       references.  This is a list with one element for each zero
+       entry in <structfield>indkey</>.  Null if all partition key columns
+       are simple references.
+      </entry>
+     </row>
+
+    </tbody>
+   </tgroup>
+  </table>
+ </sect1>
+
  <sect1 id="catalog-pg-policy">
   <title><structname>pg_policy</structname></title>
 
diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index 25130ec..df30415 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -41,7 +41,7 @@ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
 	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
 	pg_foreign_table.h pg_policy.h pg_replication_origin.h \
 	pg_default_acl.h pg_seclabel.h pg_shseclabel.h \
-	pg_collation.h pg_range.h pg_transform.h \
+	pg_collation.h pg_range.h pg_transform.h pg_partitioned_rel.h\
 	toasting.h indexing.h \
     )
 
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 65ffe84..f703668 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -48,6 +48,7 @@
 #include "catalog/pg_opclass.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_opfamily.h"
+#include "catalog/pg_partitioned_rel.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_range.h"
 #include "catalog/pg_rewrite.h"
@@ -568,6 +569,17 @@ static const struct cachedesc cacheinfo[] = {
 		},
 		8
 	},
+	{PartitionedRelRelationId,		/* PARTEDRELIDLEVEL */
+		PartitionedRelRelidLevelIndexId,
+		2,
+		{
+			Anum_pg_partitioned_rel_partrelid,
+			Anum_pg_partitioned_rel_partlevel,
+			0,
+			0
+		},
+		128
+	},
 	{ProcedureRelationId,		/* PROCNAMEARGSNSP */
 		ProcedureNameArgsNspIndexId,
 		3,
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index ab2c1a8..343204b 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -316,6 +316,12 @@ DECLARE_UNIQUE_INDEX(pg_replication_origin_roiident_index, 6001, on pg_replicati
 DECLARE_UNIQUE_INDEX(pg_replication_origin_roname_index, 6002, on pg_replication_origin using btree(roname text_pattern_ops));
 #define ReplicationOriginNameIndex 6002
 
+DECLARE_UNIQUE_INDEX(pg_partitioned_rel_partrelid_level_index, 3319, on pg_partitioned_rel using btree(partrelid oid_ops, partlevel int2_ops));
+#define PartitionedRelRelidLevelIndexId			3319
+
+DECLARE_INDEX(pg_partitioned_rel_partrelid_index, 3320, on pg_partitioned_rel using btree(partrelid oid_ops));
+#define PartitionedRelRelidIndexId          3320
+
 /* last step of initialization script: build the indexes declared above */
 BUILD_INDICES
 
diff --git a/src/include/catalog/pg_partitioned_rel.h b/src/include/catalog/pg_partitioned_rel.h
new file mode 100644
index 0000000..3f17451
--- /dev/null
+++ b/src/include/catalog/pg_partitioned_rel.h
@@ -0,0 +1,69 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_partitioned_rel.h
+ *	  definition of the system "partitioned" relation (pg_partitioned_rel)
+ *	  along with the relation's initial contents.
+ *
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/catalog/pg_partitioned_rel.h $
+ *
+ * NOTES
+ *	  the genbki.sh script reads this file and generates .bki
+ *	  information from the DATA() statements.
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_PARTITIONED_REL_H
+#define PG_PARTITIONED_REL_H
+
+#include "catalog/genbki.h"
+
+/* ----------------
+ *		pg_partitioned_rel definition.  cpp turns this into
+ *		typedef struct FormData_pg_partitioned_rel
+ * ----------------
+ */
+#define PartitionedRelRelationId 3318
+
+CATALOG(pg_partitioned_rel,3318) BKI_WITHOUT_OIDS
+{
+	Oid				partrelid;		/* partitioned table oid */
+	int16			partlevel;		/* partition key level*/
+	char			partstrat;		/* partition key strategy */
+	int16			partnatts;		/* number of partition key columns */
+
+	/* variable-length fields start here, but we allow direct access to indkey */
+	int2vector		partkey;		/* attribute numbers of partition key
+									 * columns */
+
+#ifdef CATALOG_VARLEN
+	oidvector		partclass;		/* operator class to compare keys */
+	pg_node_tree	partexprs;		/* expression trees for partition key members
+									 * that are not simple column references; one
+									 * for each zero entry in partkey[] */
+#endif
+} FormData_pg_partitioned_rel;
+
+/* ----------------
+ *      Form_pg_partitioned_rel corresponds to a pointer to a tuple with
+ *      the format of pg_partitioned_rel relation.
+ * ----------------
+ */
+typedef FormData_pg_partitioned_rel *Form_pg_partitioned_rel;
+
+/* ----------------
+ *      compiler constants for pg_partitioned_rel
+ * ----------------
+ */
+#define Natts_pg_partitioned_rel				7
+#define Anum_pg_partitioned_rel_partrelid		1
+#define Anum_pg_partitioned_rel_partlevel		2
+#define Anum_pg_partitioned_rel_partstrat		3
+#define Anum_pg_partitioned_rel_partnatts		4
+#define Anum_pg_partitioned_rel_partkey			5
+#define Anum_pg_partitioned_rel_partclass		6
+#define Anum_pg_partitioned_rel_partexprs		7
+
+#endif   /* PG_PARTITIONED_REL_H */
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 256615b..1c961c7 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -72,6 +72,7 @@ enum SysCacheIdentifier
 	OPEROID,
 	OPFAMILYAMNAMENSP,
 	OPFAMILYOID,
+	PARTEDRELIDLEVEL,
 	PROCNAMEARGSNSP,
 	PROCOID,
 	RANGETYPE,
diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
index eb0bc88..19e4e46 100644
--- a/src/test/regress/expected/sanity_check.out
+++ b/src/test/regress/expected/sanity_check.out
@@ -117,6 +117,7 @@ pg_namespace|t
 pg_opclass|t
 pg_operator|t
 pg_opfamily|t
+pg_partitioned_rel|t
 pg_pltemplate|t
 pg_policy|t
 pg_proc|t
-- 
1.7.1

