agora inbox for [email protected]
help / color / mirror / Atom feedFrom: amit <[email protected]>
Subject: [PATCH 4/8] psql and pg_dump support for partitions.
Date: Tue, 12 Jul 2016 17:50:33 +0900
Takes care of both the partition bound deparse stuff and handling
parent-partition relationship (filtering pg_inherits entries pertaining
to partitions and handling appropriately).
---
src/backend/utils/adt/ruleutils.c | 82 +++++++++++++++++++
src/bin/pg_dump/common.c | 86 ++++++++++++++++++++
src/bin/pg_dump/pg_dump.c | 118 ++++++++++++++++++++++++++--
src/bin/pg_dump/pg_dump.h | 12 +++
src/bin/psql/describe.c | 85 +++++++++++++++++---
src/test/regress/expected/create_table.out | 40 ++++++++++
src/test/regress/sql/create_table.sql | 12 +++
7 files changed, 415 insertions(+), 20 deletions(-)
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 9004878..99add8e 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -8447,6 +8447,88 @@ get_rule_expr(Node *node, deparse_context *context,
}
break;
+ case T_PartitionBoundSpec:
+ {
+ PartitionBoundSpec *spec = (PartitionBoundSpec *) node;
+ ListCell *cell;
+ char *sep;
+
+ switch (spec->strategy)
+ {
+ case PARTITION_STRATEGY_LIST:
+ Assert(spec->listdatums != NIL);
+
+ appendStringInfoString(buf, "FOR VALUES");
+ appendStringInfoString(buf, " IN (");
+ sep = "";
+ foreach (cell, spec->listdatums)
+ {
+ Const *val = lfirst(cell);
+
+ appendStringInfoString(buf, sep);
+ get_const_expr(val, context, -1);
+ sep = ", ";
+ }
+
+ appendStringInfoString(buf, ")");
+ break;
+
+ case PARTITION_STRATEGY_RANGE:
+ Assert(spec->lowerdatums != NIL &&
+ spec->upperdatums != NIL &&
+ list_length(spec->lowerdatums) ==
+ list_length(spec->upperdatums));
+
+ appendStringInfoString(buf, "FOR VALUES");
+ appendStringInfoString(buf, " FROM");
+ appendStringInfoString(buf, " (");
+ sep = "";
+ foreach (cell, spec->lowerdatums)
+ {
+ PartitionRangeDatum *datum = lfirst(cell);
+ Const *val;
+
+ appendStringInfoString(buf, sep);
+ if (datum->infinite)
+ appendStringInfoString(buf, "UNBOUNDED");
+ else
+ {
+ val = (Const *) datum->value;
+ get_const_expr(val, context, -1);
+ }
+ sep = ", ";
+ }
+ appendStringInfoString(buf, ")");
+
+ appendStringInfoString(buf, " TO");
+ appendStringInfoString(buf, " (");
+ sep = "";
+ foreach (cell, spec->upperdatums)
+ {
+ PartitionRangeDatum *datum = lfirst(cell);
+ Const *val;
+
+ appendStringInfoString(buf, sep);
+ if (datum->infinite)
+ appendStringInfoString(buf, "UNBOUNDED");
+ else
+ {
+ val = (Const *) datum->value;
+ get_const_expr(val, context, -1);
+ }
+ sep = ", ";
+ }
+ appendStringInfoString(buf, ")");
+ break;
+
+ default:
+ elog(ERROR, "unrecognized partition strategy: %d",
+ (int) spec->strategy);
+ break;
+ }
+ }
+ break;
+
case T_List:
{
char *sep;
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 3e20f02..22f1806 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -68,6 +68,8 @@ static int numextmembers;
static void flagInhTables(TableInfo *tbinfo, int numTables,
InhInfo *inhinfo, int numInherits);
+static void flagPartitions(TableInfo *tblinfo, int numTables,
+ PartInfo *partinfo, int numPartitions);
static void flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int numTables);
static DumpableObject **buildIndexArray(void *objArray, int numObjs,
Size objSize);
@@ -75,6 +77,8 @@ static int DOCatalogIdCompare(const void *p1, const void *p2);
static int ExtensionMemberIdCompare(const void *p1, const void *p2);
static void findParentsByOid(TableInfo *self,
InhInfo *inhinfo, int numInherits);
+static void findPartitionParentByOid(TableInfo *self, PartInfo *partinfo,
+ int numPartitions);
static int strInArray(const char *pattern, char **arr, int arr_size);
@@ -93,8 +97,10 @@ getSchemaData(Archive *fout, int *numTablesPtr)
NamespaceInfo *nspinfo;
ExtensionInfo *extinfo;
InhInfo *inhinfo;
+ PartInfo *partinfo;
int numAggregates;
int numInherits;
+ int numPartitions;
int numRules;
int numProcLangs;
int numCasts;
@@ -232,6 +238,10 @@ getSchemaData(Archive *fout, int *numTablesPtr)
inhinfo = getInherits(fout, &numInherits);
if (g_verbose)
+ write_msg(NULL, "reading partition information\n");
+ partinfo = getPartitions(fout, &numPartitions);
+
+ if (g_verbose)
write_msg(NULL, "reading event triggers\n");
getEventTriggers(fout, &numEventTriggers);
@@ -245,6 +255,11 @@ getSchemaData(Archive *fout, int *numTablesPtr)
write_msg(NULL, "finding inheritance relationships\n");
flagInhTables(tblinfo, numTables, inhinfo, numInherits);
+ /* Link tables to partition parents, mark parents as interesting */
+ if (g_verbose)
+ write_msg(NULL, "finding partition relationships\n");
+ flagPartitions(tblinfo, numTables, partinfo, numPartitions);
+
if (g_verbose)
write_msg(NULL, "reading column info for interesting tables\n");
getTableAttrs(fout, tblinfo, numTables);
@@ -323,6 +338,43 @@ flagInhTables(TableInfo *tblinfo, int numTables,
}
}
+/* flagPartitions -
+ * Fill in parent link fields of every target table that is partition,
+ * and mark parents of partitions as interesting
+ *
+ * modifies tblinfo
+ */
+static void
+flagPartitions(TableInfo *tblinfo, int numTables,
+ PartInfo *partinfo, int numPartitions)
+{
+ int i;
+
+ for (i = 0; i < numTables; i++)
+ {
+ /* Some kinds are never partitions */
+ if (tblinfo[i].relkind == RELKIND_SEQUENCE ||
+ tblinfo[i].relkind == RELKIND_VIEW ||
+ tblinfo[i].relkind == RELKIND_MATVIEW)
+ continue;
+
+ /* Don't bother computing anything for non-target tables, either */
+ if (!tblinfo[i].dobj.dump)
+ continue;
+
+ /* Find the parent TableInfo and save */
+ findPartitionParentByOid(&tblinfo[i], partinfo, numPartitions);
+
+ /* Mark the parent as interesting for getTableAttrs */
+ if (tblinfo[i].partitionOf)
+ {
+ tblinfo[i].partitionOf->interesting = true;
+ addObjectDependency(&tblinfo[i].dobj,
+ tblinfo[i].partitionOf->dobj.dumpId);
+ }
+ }
+}
+
/* flagInhAttrs -
* for each dumpable table in tblinfo, flag its inherited attributes
*
@@ -924,6 +976,40 @@ findParentsByOid(TableInfo *self,
}
/*
+ * findPartitionParentByOid
+ * find a partition's parent in tblinfo[]
+ */
+static void
+findPartitionParentByOid(TableInfo *self, PartInfo *partinfo,
+ int numPartitions)
+{
+ Oid oid = self->dobj.catId.oid;
+ int i;
+
+ for (i = 0; i < numPartitions; i++)
+ {
+ if (partinfo[i].partrelid == oid)
+ {
+ TableInfo *parent;
+
+ parent = findTableByOid(partinfo[i].partparent);
+ if (parent == NULL)
+ {
+ write_msg(NULL, "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n",
+ partinfo[i].partparent,
+ self->dobj.name,
+ oid);
+ exit_nicely(1);
+ }
+ self->partitionOf = parent;
+
+ /* While we're at it, also save the partdef */
+ self->partitiondef = partinfo[i].partdef;
+ }
+ }
+}
+
+/*
* parseOidArray
* parse a string of numbers delimited by spaces into a character array
*
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index d32d0ff..467c243 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -5610,9 +5610,16 @@ getInherits(Archive *fout, int *numInherits)
/* Make sure we are in proper schema */
selectSourceSchema(fout, "pg_catalog");
- /* find all the inheritance information */
-
- appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
+ /*
+ * Find all the inheritance information, excluding implicit inheritance
+ * via partitioning. We handle that case using getPartitions(), because
+ * we want more information about partitions than just the parent-child
+ * relationship.
+ */
+ appendPQExpBufferStr(query,
+ "SELECT inhrelid, inhparent "
+ "FROM pg_inherits "
+ "WHERE inhparent NOT IN (SELECT oid FROM pg_class WHERE relkind = 'P')");
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -5639,6 +5646,70 @@ getInherits(Archive *fout, int *numInherits)
}
/*
+ * getPartitions
+ * read all the partition inheritance and partition bound information
+ * from the system catalogs return them in the PartInfo* structure
+ *
+ * numPartitions is set to the number of pairs read in
+ */
+PartInfo *
+getPartitions(Archive *fout, int *numPartitions)
+{
+ PGresult *res;
+ int ntups;
+ int i;
+ PQExpBuffer query = createPQExpBuffer();
+ PartInfo *partinfo;
+
+ int i_partrelid;
+ int i_partparent;
+ int i_partbound;
+
+ /* Before version 10, there are no partitions */
+ if (fout->remoteVersion < 100000)
+ {
+ *numPartitions = 0;
+ return NULL;
+ }
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema(fout, "pg_catalog");
+
+ /* find the inheritance and boundary information about partitions */
+
+ appendPQExpBufferStr(query,
+ "SELECT inhrelid as partrelid, inhparent AS partparent,"
+ " pg_get_expr(relpartbound, inhrelid) AS partbound"
+ " FROM pg_class c, pg_inherits"
+ " WHERE c.oid = inhrelid AND c.relispartition");
+
+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+
+ ntups = PQntuples(res);
+
+ *numPartitions = ntups;
+
+ partinfo = (PartInfo *) pg_malloc(ntups * sizeof(PartInfo));
+
+ i_partrelid = PQfnumber(res, "partrelid");
+ i_partparent = PQfnumber(res, "partparent");
+ i_partbound = PQfnumber(res, "partbound");
+
+ for (i = 0; i < ntups; i++)
+ {
+ partinfo[i].partrelid = atooid(PQgetvalue(res, i, i_partrelid));
+ partinfo[i].partparent = atooid(PQgetvalue(res, i, i_partparent));
+ partinfo[i].partdef = pg_strdup(PQgetvalue(res, i, i_partbound));
+ }
+
+ PQclear(res);
+
+ destroyPQExpBuffer(query);
+
+ return partinfo;
+}
+
+/*
* getIndexes
* get information about every index on a dumpable table
*
@@ -14217,6 +14288,17 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
if (tbinfo->reloftype && !dopt->binary_upgrade)
appendPQExpBuffer(q, " OF %s", tbinfo->reloftype);
+ if (tbinfo->partitionOf && !dopt->binary_upgrade)
+ {
+ TableInfo *parentRel = tbinfo->partitionOf;
+
+ appendPQExpBuffer(q, " PARTITION OF ");
+ if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
+ appendPQExpBuffer(q, "%s.",
+ fmtId(parentRel->dobj.namespace->dobj.name));
+ appendPQExpBufferStr(q, fmtId(parentRel->dobj.name));
+ }
+
if (tbinfo->relkind != RELKIND_MATVIEW)
{
/* Dump the attributes */
@@ -14245,8 +14327,11 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
(!tbinfo->inhNotNull[j] ||
dopt->binary_upgrade));
- /* Skip column if fully defined by reloftype */
- if (tbinfo->reloftype &&
+ /*
+ * Skip column if fully defined by reloftype or the
+ * partition parent.
+ */
+ if ((tbinfo->reloftype || tbinfo->partitionOf) &&
!has_default && !has_notnull && !dopt->binary_upgrade)
continue;
@@ -14275,7 +14360,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
}
/* Attribute type */
- if (tbinfo->reloftype && !dopt->binary_upgrade)
+ if ((tbinfo->reloftype || tbinfo->partitionOf) &&
+ !dopt->binary_upgrade)
{
appendPQExpBufferStr(q, " WITH OPTIONS");
}
@@ -14333,15 +14419,22 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
if (actual_atts)
appendPQExpBufferStr(q, "\n)");
- else if (!(tbinfo->reloftype && !dopt->binary_upgrade))
+ else if (!((tbinfo->reloftype || tbinfo->partitionOf) &&
+ !dopt->binary_upgrade))
{
/*
* We must have a parenthesized attribute list, even though
- * empty, when not using the OF TYPE syntax.
+ * empty, when not using the OF TYPE or PARTITION OF syntax.
*/
appendPQExpBufferStr(q, " (\n)");
}
+ if (tbinfo->partitiondef && !dopt->binary_upgrade)
+ {
+ appendPQExpBufferStr(q, "\n");
+ appendPQExpBufferStr(q, tbinfo->partitiondef);
+ }
+
if (numParents > 0 && !dopt->binary_upgrade)
{
appendPQExpBufferStr(q, "\nINHERITS (");
@@ -14511,6 +14604,15 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
tbinfo->reloftype);
}
+ if (tbinfo->partitionOf)
+ {
+ appendPQExpBufferStr(q, "\n-- For binary upgrade, set up partitions this way.\n");
+ appendPQExpBuffer(q, "ALTER TABLE ONLY %s ATTACH PARTITION %s %s;\n",
+ fmtId(tbinfo->partitionOf->dobj.name),
+ tbinfo->dobj.name,
+ tbinfo->partitiondef);
+ }
+
appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
"SET relfrozenxid = '%u', relminmxid = '%u'\n"
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index e9849ef..a7cb00a 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -322,6 +322,8 @@ typedef struct _tableInfo
struct _tableDataInfo *dataObj; /* TableDataInfo, if dumping its data */
int numTriggers; /* number of triggers for table */
struct _triggerInfo *triggers; /* array of TriggerInfo structs */
+ struct _tableInfo *partitionOf; /* TableInfo for the partition parent */
+ char *partitiondef; /* partition key definition */
} TableInfo;
typedef struct _attrDefInfo
@@ -460,6 +462,15 @@ typedef struct _inhInfo
Oid inhparent; /* OID of its parent */
} InhInfo;
+/* PartInfo isn't a DumpableObject, just temporary state */
+typedef struct _partInfo
+{
+ Oid partrelid; /* OID of a partition */
+ Oid partparent; /* OID of its parent */
+ char *partdef; /* partition bound definition */
+} PartInfo;
+
+
typedef struct _prsInfo
{
DumpableObject dobj;
@@ -625,6 +636,7 @@ extern ConvInfo *getConversions(Archive *fout, int *numConversions);
extern TableInfo *getTables(Archive *fout, int *numTables);
extern void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables);
extern InhInfo *getInherits(Archive *fout, int *numInherits);
+extern PartInfo *getPartitions(Archive *fout, int *numPartitions);
extern void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables);
extern void getConstraints(Archive *fout, TableInfo tblinfo[], int numTables);
extern RuleInfo *getRules(Archive *fout, int *numRules);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 9b08bae..0d34927 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -1774,6 +1774,34 @@ describeOneTableDetails(const char *schemaname,
}
/* Make footers */
+ if (pset.sversion >= 90600)
+ {
+ /* Get the partition information */
+ PGresult *result;
+ char *parent_name;
+ char *partdef;
+
+ printfPQExpBuffer(&buf,
+ "SELECT inhparent::pg_catalog.regclass, pg_get_expr(c.relpartbound, inhrelid)"
+ " FROM pg_catalog.pg_class c"
+ " JOIN pg_catalog.pg_inherits"
+ " ON c.oid = inhrelid"
+ " WHERE c.oid = '%s' AND c.relispartition;", oid);
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+
+ if (PQntuples(result) > 0)
+ {
+ parent_name = PQgetvalue(result, 0, 0);
+ partdef = PQgetvalue(result, 0, 1);
+ printfPQExpBuffer(&tmpbuf, _("Partition of: %s %s"), parent_name,
+ partdef);
+ printTableAddFooter(&cont, tmpbuf.data);
+ PQclear(result);
+ }
+ }
+
if (tableinfo.relkind == 'P')
{
/* Get the partition key information */
@@ -2535,8 +2563,12 @@ describeOneTableDetails(const char *schemaname,
PQclear(result);
}
- /* print inherited tables */
- printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid=i.inhparent AND i.inhrelid = '%s' ORDER BY inhseqno;", oid);
+ /* print inherited tables (exclude, if parent is a partitioned table) */
+ printfPQExpBuffer(&buf,
+ "SELECT c.oid::pg_catalog.regclass"
+ " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i"
+ " WHERE c.oid=i.inhparent AND i.inhrelid = '%s'"
+ " AND c.relkind != 'P' ORDER BY inhseqno;", oid);
result = PSQLexec(buf.data);
if (!result)
@@ -2565,9 +2597,23 @@ describeOneTableDetails(const char *schemaname,
PQclear(result);
}
- /* print child tables */
- if (pset.sversion >= 80300)
- printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid=i.inhrelid AND i.inhparent = '%s' ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;", oid);
+ /* print child tables (with additional info if partitions) */
+ if (pset.sversion >= 100000)
+ printfPQExpBuffer(&buf,
+ "SELECT c.oid::pg_catalog.regclass, pg_get_expr(c.relpartbound, c.oid)"
+ " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i"
+ " WHERE c.oid=i.inhrelid AND"
+ " i.inhparent = '%s' AND"
+ " EXISTS (SELECT 1 FROM pg_class c WHERE c.oid = '%s')"
+ " ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;", oid, oid);
+ else if (pset.sversion >= 80300)
+ printfPQExpBuffer(&buf,
+ "SELECT c.oid::pg_catalog.regclass"
+ " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i"
+ " WHERE c.oid=i.inhrelid AND"
+ " i.inhparent = '%s' AND"
+ " EXISTS (SELECT 1 FROM pg_class c WHERE c.oid = '%s')"
+ " ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;", oid, oid);
else
printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid=i.inhrelid AND i.inhparent = '%s' ORDER BY c.relname;", oid);
@@ -2582,24 +2628,39 @@ describeOneTableDetails(const char *schemaname,
/* print the number of child tables, if any */
if (tuples > 0)
{
- printfPQExpBuffer(&buf, _("Number of child tables: %d (Use \\d+ to list them.)"), tuples);
+ if (tableinfo.relkind != 'P')
+ printfPQExpBuffer(&buf, _("Number of child tables: %d (Use \\d+ to list them.)"), tuples);
+ else
+ printfPQExpBuffer(&buf, _("Number of partitions: %d (Use \\d+ to list them.)"), tuples);
printTableAddFooter(&cont, buf.data);
}
}
else
{
/* display the list of child tables */
- const char *ct = _("Child tables");
+ const char *ct = tableinfo.relkind != 'P' ? _("Child tables") : _("Partitions");
int ctw = pg_wcswidth(ct, strlen(ct), pset.encoding);
for (i = 0; i < tuples; i++)
{
- if (i == 0)
- printfPQExpBuffer(&buf, "%s: %s",
- ct, PQgetvalue(result, i, 0));
+ if (tableinfo.relkind != 'P')
+ {
+ if (i == 0)
+ printfPQExpBuffer(&buf, "%s: %s",
+ ct, PQgetvalue(result, i, 0));
+ else
+ printfPQExpBuffer(&buf, "%*s %s",
+ ctw, "", PQgetvalue(result, i, 0));
+ }
else
- printfPQExpBuffer(&buf, "%*s %s",
- ctw, "", PQgetvalue(result, i, 0));
+ {
+ if (i == 0)
+ printfPQExpBuffer(&buf, "%s: %s %s",
+ ct, PQgetvalue(result, i, 0), PQgetvalue(result, i, 1));
+ else
+ printfPQExpBuffer(&buf, "%*s %s %s",
+ ctw, "", PQgetvalue(result, i, 0), PQgetvalue(result, i, 1));
+ }
if (i < tuples - 1)
appendPQExpBufferChar(&buf, ',');
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index 01124e1..1f56bcb 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -591,6 +591,46 @@ ERROR: column "c" named in partition key does not exist
CREATE TABLE part_c PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE ((b));
-- create a level-2 partition
CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10);
+-- Partition bound in describe output
+\d part_b
+ Table "public.part_b"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ a | text | | |
+ b | integer | | not null | 1
+Partition of: parted FOR VALUES IN ('b')
+Check constraints:
+ "check_a" CHECK (length(a) > 0)
+ "part_b_b_check" CHECK (b >= 0)
+
+-- Both partition bound and partition key in describe output
+\d part_c
+ Table "public.part_c"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ a | text | | |
+ b | integer | | not null | 0
+Partition of: parted FOR VALUES IN ('c')
+Partition key: RANGE (b)
+Check constraints:
+ "check_a" CHECK (length(a) > 0)
+Number of partitions: 1 (Use \d+ to list them.)
+
+-- Show partition count in the parent's describe output
+-- Tempted to include \d+ output listing partitions with bound info but
+-- output could vary depending on the order in which partition oids are
+-- returned.
+\d parted
+ Table "public.parted"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ a | text | | |
+ b | integer | | not null | 0
+Partition key: LIST (a)
+Check constraints:
+ "check_a" CHECK (length(a) > 0)
+Number of partitions: 3 (Use \d+ to list them.)
+
-- partitions cannot be dropped directly
DROP TABLE part_a;
-- need to specify CASCADE to drop partitions along with the parent
diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
index 683b852..c28b7b3 100644
--- a/src/test/regress/sql/create_table.sql
+++ b/src/test/regress/sql/create_table.sql
@@ -562,6 +562,18 @@ CREATE TABLE part_c PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (
-- create a level-2 partition
CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10);
+-- Partition bound in describe output
+\d part_b
+
+-- Both partition bound and partition key in describe output
+\d part_c
+
+-- Show partition count in the parent's describe output
+-- Tempted to include \d+ output listing partitions with bound info but
+-- output could vary depending on the order in which partition oids are
+-- returned.
+\d parted
+
-- partitions cannot be dropped directly
DROP TABLE part_a;
--
1.7.1
--------------38C0D572AC793CAA7276C062
Content-Type: text/x-diff;
name="0005-Teach-a-few-places-to-use-partition-check-quals-16.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename*0="0005-Teach-a-few-places-to-use-partition-check-quals-16.patc";
filename*1="h"
view thread (12+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH 4/8] psql and pg_dump support for partitions.
In-Reply-To: <no-message-id-67002@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox