Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-03-20 Thread Alvaro Herrera
On 2020-Mar-19, Daniel Gustafsson wrote:

> Moving this patch to Ready for Committer.

Thanks, pushed.

-- 
Álvaro Herrerahttps://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services




Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-03-19 Thread Daniel Gustafsson
> On 15 Jan 2020, at 00:04, Alvaro Herrera  wrote:
> 
> On 2020-Jan-14, Tom Lane wrote:
> 
>> I can't get terribly excited about persuading that test to cover this
>> trivial little bit of logic, but if you are, I won't stand in the way.
> 
> Hmm, that's a good point actually: the patch changed several places to
> inject the FOREIGN keyword, so in order to cover them all it would need
> several additional regexps, not just one.  I'm not sure that
> 002_pg_dump.pl is prepared to do that without unsightly contortions.

I agree that it doesn't seem worth holding up this patch for that, even though
it would be nice if we do add a test at some point.

> Anyway, other than that minor omission the patch seemed good to me, so I
> don't oppose Tomas pushing the version I posted yesterday.  Or I can, if
> he prefers that.

This patch still applies with some offsets and a bit of fuzz, and looking over
the patch I agree with Alvaro.

Moving this patch to Ready for Committer.

cheers ./daniel



Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-01-14 Thread Alvaro Herrera
On 2020-Jan-14, Tom Lane wrote:

> I can't get terribly excited about persuading that test to cover this
> trivial little bit of logic, but if you are, I won't stand in the way.

Hmm, that's a good point actually: the patch changed several places to
inject the FOREIGN keyword, so in order to cover them all it would need
several additional regexps, not just one.  I'm not sure that
002_pg_dump.pl is prepared to do that without unsightly contortions.

Anyway, other than that minor omission the patch seemed good to me, so I
don't oppose Tomas pushing the version I posted yesterday.  Or I can, if
he prefers that.

-- 
Álvaro Herrerahttps://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services




Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-01-14 Thread Tom Lane
Alvaro Herrera  writes:
>> On Mon, Jan 13, 2020 at 7:52 PM Tom Lane  wrote:
>>> Isn't the change in the TAP test output sufficient?

> Yeah, I think there should be at least one regexp in t/002_pg_dump.pl to
> verify ALTER FOREIGN TABLE is being produced.
> I wonder if Tom is thinking about Luis' other pg_dump patch for foreign
> tables, which includes some changes to src/test/modules/test_pg_dump.

No, I was just reacting to the comment that the TAP test was failing,
and assuming that that meant the patch had already changed the expected
output.  Looking at the patch now, I suppose that just means it had
incautiously changed whitespace or something for the non-foreign case.

I can't get terribly excited about persuading that test to cover this
trivial little bit of logic, but if you are, I won't stand in the way.

regards, tom lane




Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-01-14 Thread Alvaro Herrera
On 2020-Jan-14, vignesh C wrote:

> On Mon, Jan 13, 2020 at 7:52 PM Tom Lane  wrote:
> >
> > vignesh C  writes:
> > > On Thu, Sep 26, 2019 at 7:17 PM Luis Carril  
> > > wrote:
> > >>> Your patch is failing the pg_dump TAP tests.  Please use
> > >>> configure --enable-tap-tests, fix the problems, then resubmit.
> >
> > >> Fixed, I've attached a new version.
> >
> > > Will it be possible to add a test case for this, can we validate by
> > > adding one test?
> >
> > Isn't the change in the TAP test output sufficient?
> 
> I could not see any expected file output changes in the patch. Should
> we modify the existing test to validate this.

Yeah, I think there should be at least one regexp in t/002_pg_dump.pl to
verify ALTER FOREIGN TABLE is being produced.

I wonder if Tom is thinking about Luis' other pg_dump patch for foreign
tables, which includes some changes to src/test/modules/test_pg_dump.

-- 
Álvaro Herrerahttps://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services




Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-01-13 Thread vignesh C
On Mon, Jan 13, 2020 at 7:52 PM Tom Lane  wrote:
>
> vignesh C  writes:
> > On Thu, Sep 26, 2019 at 7:17 PM Luis Carril  wrote:
> >>> Your patch is failing the pg_dump TAP tests.  Please use
> >>> configure --enable-tap-tests, fix the problems, then resubmit.
>
> >> Fixed, I've attached a new version.
>
> > Will it be possible to add a test case for this, can we validate by
> > adding one test?
>
> Isn't the change in the TAP test output sufficient?
>

I could not see any expected file output changes in the patch. Should
we modify the existing test to validate this.

Regards,
Vignesh
EnterpriseDB: http://www.enterprisedb.com




Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-01-13 Thread Alvaro Herrera
On 2020-Jan-11, Tomas Vondra wrote:

> Hi,
> 
> On Thu, Sep 26, 2019 at 01:47:28PM +, Luis Carril wrote:
> > 
> > I don't disagree with adding FOREIGN, though.
> > 
> > Your patch is failing the pg_dump TAP tests.  Please use
> > configure --enable-tap-tests, fix the problems, then resubmit.
> > 
> > Fixed, I've attached a new version.
> 
> This seems like a fairly small and non-controversial patch (I agree with
> Alvaro that having the optional FOREIGN seems won't hurt). So barring
> objections I'll polish it a bit and push sometime next week.

If we're messing with that code, we may as well reduce cognitive load a
little bit and unify all those multiple consecutive appendStringInfo
calls into one.  (My guess is that this was previously not possible
because there were multiple fmtId() calls in the argument list, but
that's no longer the case.)

-- 
Álvaro Herrerahttps://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
>From e369a559b2f96e3e73cf1bc4a1fefc9890243a7c Mon Sep 17 00:00:00 2001
From: Alvaro Herrera 
Date: Mon, 13 Jan 2020 12:33:21 -0300
Subject: [PATCH v3] pg_dump: Add FOREIGN to ALTER statements, if appropriate

Author: Luis Carril
Discussion: https://postgr.es/m/lejpr01mb0185a19b2e7c98e5e2a031f5e7...@lejpr01mb0185.deuprd01.prod.outlook.de
---
 src/bin/pg_dump/pg_dump.c | 90 ---
 1 file changed, 47 insertions(+), 43 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 799b6988b7..2866c55e96 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -15583,6 +15583,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	{
 		char	   *ftoptions = NULL;
 		char	   *srvname = NULL;
+		char	   *foreign = "";
 
 		switch (tbinfo->relkind)
 		{
@@ -15616,6 +15617,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
 	PQclear(res);
 	destroyPQExpBuffer(query);
+
+	foreign = "FOREIGN ";
 	break;
 }
 			case RELKIND_MATVIEW:
@@ -15957,11 +15960,10 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	continue;
 
 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-  qualrelname);
-appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
-  fmtId(constr->dobj.name));
-appendPQExpBuffer(q, "%s;\n", constr->condef);
+appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s %s;\n",
+  foreign, qualrelname,
+  fmtId(constr->dobj.name),
+  constr->condef);
 appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
 	 "SET conislocal = false\n"
 	 "WHERE contype = 'c' AND conname = ");
@@ -15978,7 +15980,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 {
 	TableInfo  *parentRel = parents[k];
 
-	appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT %s;\n",
+	appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s INHERIT %s;\n", foreign,
 	  qualrelname,
 	  fmtQualifiedDumpable(parentRel));
 }
@@ -16084,9 +16086,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			if (!shouldPrintColumn(dopt, tbinfo, j) &&
 tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
 			{
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-  qualrelname);
-appendPQExpBuffer(q, "ALTER COLUMN %s SET NOT NULL;\n",
+appendPQExpBuffer(q,
+  "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET NOT NULL;\n",
+  foreign, qualrelname,
   fmtId(tbinfo->attnames[j]));
 			}
 
@@ -16097,11 +16099,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			 */
 			if (tbinfo->attstattarget[j] >= 0)
 			{
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-  qualrelname);
-appendPQExpBuffer(q, "ALTER COLUMN %s ",
-  fmtId(tbinfo->attnames[j]));
-appendPQExpBuffer(q, "SET STATISTICS %d;\n",
+appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STATISTICS %d;\n",
+  foreign, qualrelname,
+  fmtId(tbinfo->attnames[j]),
   tbinfo->attstattarget[j]);
 			}
 
@@ -16134,11 +16134,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
  */
 if (storage != NULL)
 {
-	appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-	  qualrelname);
-	appendPQExpBuffer(q, "ALTER COLUMN %s ",
-	  fmtId(tbinfo->attnames[j]));
-	appendPQExpBuffer(q, "SET STORAGE %s;\n",
+	appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STORAGE %s;\n",
+	  foreign, qualrelname,
+	  fmtId(tbinfo->attnames[j]),
 	  storage);
 }
 			}
@@ -16148,11 +16146,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			 */
 			if (tbinfo->attoptions[j][0] != '\0')
 			{
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-  qualrelname);
-appendPQExpBuffer(q, "ALTER COLUMN %s ",
-  

Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-01-13 Thread Tom Lane
vignesh C  writes:
> On Thu, Sep 26, 2019 at 7:17 PM Luis Carril  wrote:
>>> Your patch is failing the pg_dump TAP tests.  Please use
>>> configure --enable-tap-tests, fix the problems, then resubmit.

>> Fixed, I've attached a new version.

> Will it be possible to add a test case for this, can we validate by
> adding one test?

Isn't the change in the TAP test output sufficient?

regards, tom lane




Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-01-13 Thread vignesh C
On Thu, Sep 26, 2019 at 7:17 PM Luis Carril  wrote:
>
>
> I don't disagree with adding FOREIGN, though.
>
> Your patch is failing the pg_dump TAP tests.  Please use
> configure --enable-tap-tests, fix the problems, then resubmit.
>
> Fixed, I've attached a new version.

Will it be possible to add a test case for this, can we validate by
adding one test?

Regards,
Vignesh
EnterpriseDB: http://www.enterprisedb.com




Re: Add FOREIGN to ALTER TABLE in pg_dump

2020-01-10 Thread Tomas Vondra

Hi,

On Thu, Sep 26, 2019 at 01:47:28PM +, Luis Carril wrote:


I don't disagree with adding FOREIGN, though.

Your patch is failing the pg_dump TAP tests.  Please use
configure --enable-tap-tests, fix the problems, then resubmit.

Fixed, I've attached a new version.



This seems like a fairly small and non-controversial patch (I agree with
Alvaro that having the optional FOREIGN seems won't hurt). So barring
objections I'll polish it a bit and push sometime next week.

regards

--
Tomas Vondra  http://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services 





Re: Add FOREIGN to ALTER TABLE in pg_dump

2019-09-26 Thread Luis Carril

I don't disagree with adding FOREIGN, though.

Your patch is failing the pg_dump TAP tests.  Please use
configure --enable-tap-tests, fix the problems, then resubmit.

Fixed, I've attached a new version.


Cheers
Luis M Carril

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index f01fea5b91..65abc22e7a 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -15550,6 +15550,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	{
 		char	   *ftoptions = NULL;
 		char	   *srvname = NULL;
+		char	   *foreign = "";
 
 		switch (tbinfo->relkind)
 		{
@@ -15583,6 +15584,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
 	PQclear(res);
 	destroyPQExpBuffer(query);
+
+	foreign = "FOREIGN ";
 	break;
 }
 			case RELKIND_MATVIEW:
@@ -15924,7 +15927,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	continue;
 
 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ", foreign,
   qualrelname);
 appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
   fmtId(constr->dobj.name));
@@ -15945,7 +15948,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 {
 	TableInfo  *parentRel = parents[k];
 
-	appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT %s;\n",
+	appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s INHERIT %s;\n", foreign,
 	  qualrelname,
 	  fmtQualifiedDumpable(parentRel));
 }
@@ -16051,7 +16054,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			if (!shouldPrintColumn(dopt, tbinfo, j) &&
 tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
 			{
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ", foreign,
   qualrelname);
 appendPQExpBuffer(q, "ALTER COLUMN %s SET NOT NULL;\n",
   fmtId(tbinfo->attnames[j]));
@@ -16064,7 +16067,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			 */
 			if (tbinfo->attstattarget[j] >= 0)
 			{
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ", foreign,
   qualrelname);
 appendPQExpBuffer(q, "ALTER COLUMN %s ",
   fmtId(tbinfo->attnames[j]));
@@ -16101,7 +16104,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
  */
 if (storage != NULL)
 {
-	appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+	appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ", foreign,
 	  qualrelname);
 	appendPQExpBuffer(q, "ALTER COLUMN %s ",
 	  fmtId(tbinfo->attnames[j]));
@@ -16115,7 +16118,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			 */
 			if (tbinfo->attoptions[j][0] != '\0')
 			{
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ", foreign,
   qualrelname);
 appendPQExpBuffer(q, "ALTER COLUMN %s ",
   fmtId(tbinfo->attnames[j]));
@@ -16238,6 +16241,7 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
 	PQExpBuffer delq;
 	char	   *qualrelname;
 	char	   *tag;
+	char	   *foreign;
 
 	/* Skip if table definition not to be dumped */
 	if (!tbinfo->dobj.dump || dopt->dataOnly)
@@ -16252,13 +16256,15 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
 
 	qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
 
-	appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+	foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
+
+	appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ", foreign,
 	  qualrelname);
 	appendPQExpBuffer(q, "ALTER COLUMN %s SET DEFAULT %s;\n",
 	  fmtId(tbinfo->attnames[adnum - 1]),
 	  adinfo->adef_expr);
 
-	appendPQExpBuffer(delq, "ALTER TABLE %s ",
+	appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
 	  qualrelname);
 	appendPQExpBuffer(delq, "ALTER COLUMN %s DROP DEFAULT;\n",
 	  fmtId(tbinfo->attnames[adnum - 1]));
@@ -16564,6 +16570,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 	PQExpBuffer q;
 	PQExpBuffer delq;
 	char	   *tag = NULL;
+	char	   *foreign;
 
 	/* Skip if not to be dumped */
 	if (!coninfo->dobj.dump || dopt->dataOnly)
@@ -16572,6 +16579,8 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
 
+	foreign = tbinfo && tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
+
 	if (coninfo->contype == 'p' ||
 		coninfo->contype == 'u' ||
 		coninfo->contype == 'x')
@@ -16590,7 +16599,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 			binary_upgrade_set_pg_class_oids(fout, q,
 			 indxinfo->dobj.catId.oid, true);
 
-		appendPQExpBuffer(q, "ALTER TABLE ONLY %s\n",
+		appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
 		  fmtQualifiedDumpable(tbinfo));
 		appendPQExpBuffer(q, "ADD CONSTRAINT %s ",
 		  fmtId(coninfo->dobj.name));
@@ -16680,7 +16689,7 @@ 

Re: Add FOREIGN to ALTER TABLE in pg_dump

2019-09-25 Thread Alvaro Herrera
On 2019-Jul-12, Luis Carril wrote:

> Hello,
> pg_dump creates plain ALTER TABLE statements even if the table is a 
> foreign table, which for someone reading the dump is confusing.
> This also made a difference when applying the dump if there is any plugin 
> installed that hooks on ProcessUtility, because the plugin could react 
> differently to ALTER TABLE than to ALTER FOREIGN TABLE.  Opinions?

I think such a hook would be bogus, because it would miss anything done
by a user manually.

I don't disagree with adding FOREIGN, though.

Your patch is failing the pg_dump TAP tests.  Please use
configure --enable-tap-tests, fix the problems, then resubmit.

> An unrelated question: if I apply pgindent to a file (in this case 
> pg_dump.c) and get a bunch of changes on the indentation that are not related 
> to my patch, which is the accepted policy? A different patch first with only 
> the indentation?  Maybe, am I using pgindent wrong?

We don't typically accept pgindent-only changes at random points in
the devel cycle.

I would suggest to run pgindent over the file and "git add -p" only the
changes that are relevant to your patch, discard the rest.
(Alternative: run pgindent, commit that, then apply your patch, pgindent
again and "git commit --amend", then "git rebase -i" and discard the
first pgindent commit.  Your patch ends up pgindent-correct without
disturbing the rest of the file/tree).

-- 
Álvaro Herrerahttps://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services




Add FOREIGN to ALTER TABLE in pg_dump

2019-07-12 Thread Luis Carril
Hello,
pg_dump creates plain ALTER TABLE statements even if the table is a foreign 
table, which for someone reading the dump is confusing.
This also made a difference when applying the dump if there is any plugin 
installed that hooks on ProcessUtility, because the plugin could react 
differently to ALTER TABLE than to ALTER FOREIGN TABLE.  Opinions?

An unrelated question: if I apply pgindent to a file (in this case 
pg_dump.c) and get a bunch of changes on the indentation that are not related 
to my patch, which is the accepted policy? A different patch first with only 
the indentation?  Maybe, am I using pgindent wrong?

Cheers
Luis M Carril
From a5b439b7dfdc1f9bab8d2cf1fc95a8eaedb1d83e Mon Sep 17 00:00:00 2001
From: Luis Carril 
Date: Fri, 12 Jul 2019 12:51:17 +0200
Subject: [PATCH] Add FOREIGN to ALTER statements

---
 src/bin/pg_dump/pg_dump.c | 40 ---
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 806fc78f04..72951f9a0a 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -15535,6 +15535,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	{
 		char	   *ftoptions = NULL;
 		char	   *srvname = NULL;
+		char	   *foreign = "";
 
 		switch (tbinfo->relkind)
 		{
@@ -15568,6 +15569,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
 	PQclear(res);
 	destroyPQExpBuffer(query);
+
+	foreign = "FOREIGN";
 	break;
 }
 			case RELKIND_MATVIEW:
@@ -15909,7 +15912,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	continue;
 
 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+appendPQExpBuffer(q, "ALTER %s TABLE ONLY %s ", foreign,
   qualrelname);
 appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
   fmtId(constr->dobj.name));
@@ -15930,7 +15933,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 {
 	TableInfo  *parentRel = parents[k];
 
-	appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT %s;\n",
+	appendPQExpBuffer(q, "ALTER %s TABLE ONLY %s INHERIT %s;\n", foreign,
 	  qualrelname,
 	  fmtQualifiedDumpable(parentRel));
 }
@@ -16036,7 +16039,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			if (!shouldPrintColumn(dopt, tbinfo, j) &&
 tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
 			{
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+appendPQExpBuffer(q, "ALTER %s TABLE ONLY %s ", foreign,
   qualrelname);
 appendPQExpBuffer(q, "ALTER COLUMN %s SET NOT NULL;\n",
   fmtId(tbinfo->attnames[j]));
@@ -16049,7 +16052,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			 */
 			if (tbinfo->attstattarget[j] >= 0)
 			{
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+appendPQExpBuffer(q, "ALTER %s TABLE ONLY %s ", foreign,
   qualrelname);
 appendPQExpBuffer(q, "ALTER COLUMN %s ",
   fmtId(tbinfo->attnames[j]));
@@ -16086,7 +16089,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
  */
 if (storage != NULL)
 {
-	appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+	appendPQExpBuffer(q, "ALTER %s TABLE ONLY %s ", foreign,
 	  qualrelname);
 	appendPQExpBuffer(q, "ALTER COLUMN %s ",
 	  fmtId(tbinfo->attnames[j]));
@@ -16100,7 +16103,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			 */
 			if (tbinfo->attoptions[j][0] != '\0')
 			{
-appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+appendPQExpBuffer(q, "ALTER %s TABLE ONLY %s ", foreign,
   qualrelname);
 appendPQExpBuffer(q, "ALTER COLUMN %s ",
   fmtId(tbinfo->attnames[j]));
@@ -16223,6 +16226,7 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
 	PQExpBuffer delq;
 	char	   *qualrelname;
 	char	   *tag;
+	char	   *foreign;
 
 	/* Skip if table definition not to be dumped */
 	if (!tbinfo->dobj.dump || dopt->dataOnly)
@@ -16237,13 +16241,15 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
 
 	qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
 
-	appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+	foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN" : "";
+
+	appendPQExpBuffer(q, "ALTER %s TABLE ONLY %s ", foreign,
 	  qualrelname);
 	appendPQExpBuffer(q, "ALTER COLUMN %s SET DEFAULT %s;\n",
 	  fmtId(tbinfo->attnames[adnum - 1]),
 	  adinfo->adef_expr);
 
-	appendPQExpBuffer(delq, "ALTER TABLE %s ",
+	appendPQExpBuffer(delq, "ALTER %s TABLE %s ", foreign,
 	  qualrelname);
 	appendPQExpBuffer(delq, "ALTER COLUMN %s DROP DEFAULT;\n",
 	  fmtId(tbinfo->attnames[adnum - 1]));
@@ -16536,6 +16542,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 	PQExpBuffer q;
 	PQExpBuffer delq;
 	char	   *tag = NULL;
+	char	   *foreign = NULL;
 
 	/* Skip if not to be dumped */
 	if (!coninfo->dobj.dump ||