aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/common.c3
-rw-r--r--src/bin/pg_dump/pg_dump.c42
-rw-r--r--src/bin/pg_dump/pg_dump.h2
-rw-r--r--src/fe_utils/simple_list.c21
-rw-r--r--src/include/fe_utils/simple_list.h19
5 files changed, 82 insertions, 5 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 02a865f456f..3549f7bc082 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -412,6 +412,9 @@ flagInhIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
addObjectDependency(&attachinfo[k].dobj,
parentidx->indextable->dobj.dumpId);
+ /* keep track of the list of partitions in the parent index */
+ simple_ptr_list_append(&parentidx->partattaches, &attachinfo[k].dobj);
+
k++;
}
}
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index f01fea5b913..2a087d7a1ca 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7115,6 +7115,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
+ indxinfo[j].partattaches = (SimplePtrList) { NULL, NULL };
contype = *(PQgetvalue(res, j, i_contype));
if (contype == 'p' || contype == 'u' || contype == 'x')
@@ -7256,6 +7257,7 @@ getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
i_conoid,
i_conname,
i_confrelid,
+ i_conindid,
i_condef;
int ntups;
@@ -7281,7 +7283,7 @@ getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
resetPQExpBuffer(query);
if (fout->remoteVersion >= 110000)
appendPQExpBuffer(query,
- "SELECT tableoid, oid, conname, confrelid, "
+ "SELECT tableoid, oid, conname, confrelid, conindid, "
"pg_catalog.pg_get_constraintdef(oid) AS condef "
"FROM pg_catalog.pg_constraint "
"WHERE conrelid = '%u'::pg_catalog.oid "
@@ -7290,7 +7292,7 @@ getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
tbinfo->dobj.catId.oid);
else
appendPQExpBuffer(query,
- "SELECT tableoid, oid, conname, confrelid, "
+ "SELECT tableoid, oid, conname, confrelid, 0 as conindid, "
"pg_catalog.pg_get_constraintdef(oid) AS condef "
"FROM pg_catalog.pg_constraint "
"WHERE conrelid = '%u'::pg_catalog.oid "
@@ -7304,12 +7306,15 @@ getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
i_conoid = PQfnumber(res, "oid");
i_conname = PQfnumber(res, "conname");
i_confrelid = PQfnumber(res, "confrelid");
+ i_conindid = PQfnumber(res, "conindid");
i_condef = PQfnumber(res, "condef");
constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
for (j = 0; j < ntups; j++)
{
+ TableInfo *reftable;
+
constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
@@ -7326,6 +7331,39 @@ getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
constrinfo[j].condeferred = false;
constrinfo[j].conislocal = true;
constrinfo[j].separate = true;
+
+ /*
+ * Restoring an FK that points to a partitioned table requires
+ * that all partition indexes have been attached beforehand.
+ * Ensure that happens by making the constraint depend on each
+ * index partition attach object.
+ */
+ reftable = findTableByOid(constrinfo[j].confrelid);
+ if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
+ {
+ IndxInfo *refidx;
+ Oid indexOid = atooid(PQgetvalue(res, j, i_conindid));
+
+ if (indexOid != InvalidOid)
+ {
+ for (int k = 0; k < reftable->numIndexes; k++)
+ {
+ SimplePtrListCell *cell;
+
+ /* not our index? */
+ if (reftable->indexes[k].dobj.catId.oid != indexOid)
+ continue;
+
+ refidx = &reftable->indexes[k];
+ for (cell = refidx->partattaches.head; cell;
+ cell = cell->next)
+ addObjectDependency(&constrinfo[j].dobj,
+ ((DumpableObject *)
+ cell->ptr)->dumpId);
+ break;
+ }
+ }
+ }
}
PQclear(res);
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index ec5a924b8fa..7b2c1524a5a 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -367,6 +367,8 @@ typedef struct _indxInfo
bool indisclustered;
bool indisreplident;
Oid parentidx; /* if partitioned, parent index OID */
+ SimplePtrList partattaches; /* if partitioned, partition attach objects */
+
/* if there is an associated constraint object, its dumpId: */
DumpId indexconstraint;
} IndxInfo;
diff --git a/src/fe_utils/simple_list.c b/src/fe_utils/simple_list.c
index cfdb7dc87af..b5f45126af7 100644
--- a/src/fe_utils/simple_list.c
+++ b/src/fe_utils/simple_list.c
@@ -152,3 +152,24 @@ simple_string_list_not_touched(SimpleStringList *list)
}
return NULL;
}
+
+/*
+ * Append a pointer to the list.
+ *
+ * Caller must ensure that the pointer remains valid.
+ */
+void
+simple_ptr_list_append(SimplePtrList *list, void *ptr)
+{
+ SimplePtrListCell *cell;
+
+ cell = (SimplePtrListCell *) pg_malloc(sizeof(SimplePtrListCell));
+ cell->next = NULL;
+ cell->ptr = ptr;
+
+ if (list->tail)
+ list->tail->next = cell;
+ else
+ list->head = cell;
+ list->tail = cell;
+}
diff --git a/src/include/fe_utils/simple_list.h b/src/include/fe_utils/simple_list.h
index 75738becf42..103fd88c74f 100644
--- a/src/include/fe_utils/simple_list.h
+++ b/src/include/fe_utils/simple_list.h
@@ -2,9 +2,9 @@
*
* Simple list facilities for frontend code
*
- * Data structures for simple lists of OIDs and strings. The support for
- * these is very primitive compared to the backend's List facilities, but
- * it's all we need in, eg, pg_dump.
+ * Data structures for simple lists of OIDs, strings, and pointers. The
+ * support for these is very primitive compared to the backend's List
+ * facilities, but it's all we need in, eg, pg_dump.
*
*
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
@@ -43,6 +43,17 @@ typedef struct SimpleStringList
SimpleStringListCell *tail;
} SimpleStringList;
+typedef struct SimplePtrListCell
+{
+ struct SimplePtrListCell *next;
+ void *ptr;
+} SimplePtrListCell;
+
+typedef struct SimplePtrList
+{
+ SimplePtrListCell *head;
+ SimplePtrListCell *tail;
+} SimplePtrList;
extern void simple_oid_list_append(SimpleOidList *list, Oid val);
extern bool simple_oid_list_member(SimpleOidList *list, Oid val);
@@ -54,4 +65,6 @@ extern void simple_string_list_destroy(SimpleStringList *list);
extern const char *simple_string_list_not_touched(SimpleStringList *list);
+extern void simple_ptr_list_append(SimplePtrList *list, void *val);
+
#endif /* SIMPLE_LIST_H */