Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wKX9S-00162v-0g for pgsql-hackers@arkaria.postgresql.org; Wed, 06 May 2026 07:58:38 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wKX9Q-00FaT5-2O for pgsql-hackers@arkaria.postgresql.org; Wed, 06 May 2026 07:58:36 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wKX9Q-00FaSx-1C for pgsql-hackers@lists.postgresql.org; Wed, 06 May 2026 07:58:36 +0000 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wKX9O-00000000mnU-0elS for pgsql-hackers@postgresql.org; Wed, 06 May 2026 07:58:36 +0000 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-35fb0bb27e7so4041712a91.1 for ; Wed, 06 May 2026 00:58:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778054312; x=1778659112; darn=postgresql.org; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=Iuxe/K2oSl3TuJj2SwjtGf6z6HWT3Ic9GO2xei4KKwE=; b=NprdpZDNvygCMKhoENjSGy0T4rOMBrh/CC1VZndY3K6FDADPa8NiUvIASY1ORn3uoa 0QfjpH8J5ryLxeZzqgANNruGWcqU7tMJlDyrYjEAw9IbDX0s2TPG1ckyCardw0MEwaVu uZUoBcRBu7vhLXh4lxVxJn9hJq+Pa0Q5lriSa+3Ydtz2SEb/LP1ahBEWSBOWnjvxwOjd LQTGZukECKYU8kT4kHKGaedTUWhdNaUtpTn100/HNut3JorDqkB0p/OSLC+rrVj7Vzeh BQgR2COZ6IeQZzdTwSS0wa0utbidPAivTFtg2m6lA7KPCHMI9s7wxn6xzUWnCpcGrIR6 UgEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778054312; x=1778659112; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Iuxe/K2oSl3TuJj2SwjtGf6z6HWT3Ic9GO2xei4KKwE=; b=qmbp6dER9VwmrAtngAnaZegaxnsXtLPtt0szGKHzbQMM5dmsGJJpwBvmY2d0sv7/uw QmVAPGY3cf4zVweMlvnI4ACsMJZlo8gOoJ9HUribcmAFdAfKgKt1OvMVv/O+DNLKSJEf AuH5CkYOq4vQ3MIPLYbkcVrZQLekBa3yr1B+fA7U3Jj58hECtzAekNVRJfib2Z2s+xVR 7HiuS1U8Wcp+6Kan0PiIUWhADwpacwNSoAqy2pCCrq8hFWTeIrEQhQ2kmu2KnbxoYFvv IUJPDN4GWyhghfIIuG2UTR8zLuBPfy1Tz02TEf5bqQZbmN867yNEHbHA6VW6xkrGjuBj yp4Q== X-Forwarded-Encrypted: i=1; AFNElJ+hDcgcUQJ8aRNdVLu0rbCFqz+LZSnFbLgOK8TGTJWVgfNcW1rDR0oVpFcr754o7fSU2FXCuXclrxsmMM33@postgresql.org X-Gm-Message-State: AOJu0YxD12SwtOLTGhjtGW9hDWgZ9U5Gls7Hf8hkT6+o+Hs5ir9G7wGb nxsT/SqK3gRxAj8MyE+pSY9da/uS/pV/wFRRzwHxV6QU0Xq4ckVzNlau X-Gm-Gg: AeBDieu6Dw1mWfqCH/ICjwg5BEInJp0lAcmfEFvBeLYj7De0V00ia4xmlJHlnou2+Hh 8V/LzFBeowkBH8wyCid4cjcN/1tz//psICCrO0D6gxSGFy7q1xbC8vOO75TBkj1wGzmQdhc/Een JiqZyQ72QOGCC3Oo6QtxXEjWhE9FZ2mngD4B8tG3xZUvzF13LjYBSuUnXGXKcWqmiRxYNyBSJ0S /jIzphjSDAxGCPBzfVK8eYt9M/fv0Fw1Ab0CEAT56wxMjZeHw+v9Yfj0UkSXUw1ZC6rcZZc1NPC H8YFLH+0twLD8iLxAwhmSxyRtG9S0VX8KrC9aqhIetBuuWPeR+pZfR3UNB37w570zkEjo/U2A5q 7MYEoEgQ4YXW/aZwzfGjykBJ+DQD1tEB2Hyn6sOim0N/wlqfCrpJTGWE50b08oSNDhKQUvHq1oN jJF/tTwJ/xprLFztueDapI1MClOq//qknl78d9WbHjxQ== X-Received: by 2002:a17:90b:2883:b0:365:7e7f:a229 with SMTP id 98e67ed59e1d1-365ab9b83cfmr2271154a91.5.1778054311727; Wed, 06 May 2026 00:58:31 -0700 (PDT) Received: from smtpclient.apple ([45.32.121.103]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-365b4f75f0csm1433493a91.9.2026.05.06.00.58.29 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 May 2026 00:58:30 -0700 (PDT) From: Chao Li Message-Id: <8B38AFCA-7FFA-44CF-B9A8-81BDCEAFB224@gmail.com> Content-Type: multipart/mixed; boundary="Apple-Mail=_F6B95087-E12D-4BE9-9FEE-95D17406FC2D" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.400.21\)) Subject: Re: Bug in ALTER SUBSCRIPTION ... SERVER / ... CONNECTION with broken old server Date: Wed, 6 May 2026 15:57:51 +0800 In-Reply-To: Cc: Ajin Cherian , PostgreSQL-development To: Zsolt Parragi References: <960DD2C4-A22C-463A-90ED-86E0FABD8D20@gmail.com> X-Mailer: Apple Mail (2.3864.400.21) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_F6B95087-E12D-4BE9-9FEE-95D17406FC2D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On May 6, 2026, at 04:53, Zsolt Parragi = wrote: >=20 > Hello >=20 > - server =3D GetForeignServer(subform->subserver); > + server =3D GetForeignServer(sub->serverid); >=20 > Couldn't we also move this inside the if? Ah, true. Both aclresult and server can be moved into the if. >=20 > +/* > + * Return the subscription's connection string, loading it into the > + * subscription memory context if necessary. > + * > + * GetSubscription must be called earlier to set sub->serverid, = because ACL > + * checks are performed there. > + */ > +char * > +GetSubscriptionConnInfo(Subscription *sub) >=20 > This is related to Ajin's comment earlier, the part about ACL check > seems incorrect to me. Yes, see my reply to Ajin in the previous email. PFA v3 - addressed Ajin and Zsolt=E2=80=99s comments. Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/ --Apple-Mail=_F6B95087-E12D-4BE9-9FEE-95D17406FC2D Content-Disposition: attachment; filename=v3-0001-Allow-altering-subscription-server-connection-wit.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v3-0001-Allow-altering-subscription-server-connection-wit.patch" Content-Transfer-Encoding: quoted-printable =46rom=20065d4574940bf931c070f264c00267ecb58db734=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20"Chao=20Li=20(Evan)"=20=0A= Date:=20Wed,=2022=20Apr=202026=2009:14:27=20+0800=0ASubject:=20[PATCH=20= v3]=20Allow=20altering=20subscription=20server/connection=20without=0A=20= resolving=20old=20conninfo=0A=0AWhen=20a=20subscription=20uses=20a=20= foreign=20server,=20GetSubscription()=20resolves=20the=0Apublisher=20= connection=20string=20immediately.=20That=20can=20fail=20if=20the=20= subscription=0Aowner=20no=20longer=20has=20USAGE=20on=20the=20server=20= or=20no=20longer=20has=20a=20valid=20user=0Amapping.=0A=0AThis=20becomes=20= a=20problem=20for=20ALTER=20SUBSCRIPTION=20commands=20such=20as=20...=20= SERVER=0Aor=20...=20CONNECTION,=20because=20they=20may=20need=20to=20= update=20the=20subscription=20away=0Afrom=20the=20broken=20= server/conninfo,=20but=20currently=20fail=20while=20trying=20to=20= resolve=0Athe=20old=20one=20first.=0A=0AFix=20this=20by=20storing=20the=20= subscription's=20server=20OID=20in=20the=20in-memory=0ASubscription=20= object=20and=20loading=20conninfo=20lazily=20only=20when=20it=20is=20= actually=0Aneeded.=20Add=20GetSubscriptionConninfo()=20to=20fetch=20the=20= connection=20string=20on=0Ademand=20in=20the=20subscription=20memory=20= context.=0A=0AThis=20allows=20ALTER=20SUBSCRIPTION=20...=20SERVER=20and=20= ...=20CONNECTION=20to=20succeed=0Awithout=20requiring=20access=20to=20= the=20previous=20server=20or=20user=20mapping,=20while=0Apreserving=20= the=20existing=20behavior=20for=20operations=20that=20really=20need=20to=20= connect=0Ato=20the=20publisher.=0A=0AAdd=20regression=20test=20coverage=20= for=20both=20cases.=0A=0AAuthor:=20Chao=20Li=20=0A= Reviewed-by:=20Ajin=20Cherian=20=0AReviewed-by:=20= Zsolt=20Parragi=20=0ADiscussion:=20= https://postgr.es/m/D908370F-2695-4231-851D-17179A6A6F2A@gmail.com=0A---=0A= =20src/backend/catalog/pg_subscription.c=20=20=20=20=20=20=20=20=20|=20= 67=20++++++++++++++-----=0A=20src/backend/commands/subscriptioncmds.c=20=20= =20=20=20=20=20|=20=209=20++-=0A=20= .../replication/logical/sequencesync.c=20=20=20=20=20=20=20=20|=20=202=20= +-=0A=20src/backend/replication/logical/tablesync.c=20=20=20|=20=202=20= +-=0A=20src/backend/replication/logical/worker.c=20=20=20=20=20=20|=20=20= 9=20+--=0A=20src/include/catalog/pg_subscription.h=20=20=20=20=20=20=20=20= =20|=20=202=20+=0A=20src/test/regress/expected/subscription.out=20=20=20=20= |=2033=20+++++++++=0A=20src/test/regress/regress.c=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20|=20=203=20+=0A=20= src/test/regress/sql/subscription.sql=20=20=20=20=20=20=20=20=20|=2027=20= ++++++++=0A=209=20files=20changed,=20130=20insertions(+),=2024=20= deletions(-)=0A=0Adiff=20--git=20a/src/backend/catalog/pg_subscription.c=20= b/src/backend/catalog/pg_subscription.c=0Aindex=20= 1f1fdc75af6..0f2594a702f=20100644=0A---=20= a/src/backend/catalog/pg_subscription.c=0A+++=20= b/src/backend/catalog/pg_subscription.c=0A@@=20-72,6=20+72,18=20@@=20= GetPublicationsStr(List=20*publications,=20StringInfo=20dest,=20bool=20= quote_literal)=0A=20=0A=20/*=0A=20=20*=20Fetch=20the=20subscription=20= from=20the=20syscache.=0A+=20*=0A+=20*=20If=20missing_ok=20is=20false,=20= throw=20an=20error=20if=20the=20subscription=20is=20not=20found.=0A+=20*=20= If=20true,=20return=20NULL=20in=20that=20case.=0A+=20*=0A+=20*=20If=20= the=20subscription=20uses=20a=20foreign=20server=20and=20aclcheck=20is=20= true,=20check=0A+=20*=20whether=20the=20subscription=20owner=20has=20= permission=20on=20that=20server=20and=20eagerly=0A+=20*=20load=20the=20= connection=20string=20into=20sub->conninfo.=0A+=20*=0A+=20*=20If=20the=20= subscription=20uses=20a=20foreign=20server=20and=20aclcheck=20is=20= false,=0A+=20*=20sub->conninfo=20is=20left=20NULL=20until=20it=20is=20= needed.=20Call=0A+=20*=20GetSubscriptionConnInfo()=20to=20fetch=20it=20= on=20demand.=20That=20accessor=20is=20also=20safe=0A+=20*=20to=20call=20= when=20sub->conninfo=20has=20already=20been=20populated.=0A=20=20*/=0A=20= Subscription=20*=0A=20GetSubscription(Oid=20subid,=20bool=20missing_ok,=20= bool=20aclcheck)=0A@@=20-118,32=20+130,32=20@@=20GetSubscription(Oid=20= subid,=20bool=20missing_ok,=20bool=20aclcheck)=0A=20=09= sub->retaindeadtuples=20=3D=20subform->subretaindeadtuples;=0A=20=09= sub->maxretention=20=3D=20subform->submaxretention;=0A=20=09= sub->retentionactive=20=3D=20subform->subretentionactive;=0A+=09= sub->serverid=20=3D=20subform->subserver;=0A+=09sub->conninfo=20=3D=20= NULL;=0A=20=0A=20=09/*=20Get=20conninfo=20*/=0A-=09if=20= (OidIsValid(subform->subserver))=0A+=09if=20(OidIsValid(sub->serverid))=0A= =20=09{=0A-=09=09AclResult=09aclresult;=0A-=09=09ForeignServer=20= *server;=0A-=0A-=09=09server=20=3D=20= GetForeignServer(subform->subserver);=0A-=0A=20=09=09/*=20recheck=20ACL=20= if=20requested=20*/=0A=20=09=09if=20(aclcheck)=0A=20=09=09{=0A+=09=09=09= AclResult=09aclresult;=0A+=09=09=09ForeignServer=20*server;=0A+=0A+=09=09= =09server=20=3D=20GetForeignServer(sub->serverid);=0A=20=09=09=09= aclresult=20=3D=20object_aclcheck(ForeignServerRelationId,=0A-=09=09=09=09= =09=09=09=09=09=09subform->subserver,=0A+=09=09=09=09=09=09=09=09=09=09= sub->serverid,=0A=20=09=09=09=09=09=09=09=09=09=09subform->subowner,=20= ACL_USAGE);=0A-=0A=20=09=09=09if=20(aclresult=20!=3D=20ACLCHECK_OK)=0A=20= =09=09=09=09ereport(ERROR,=0A-=09=09=09=09=09=09= (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),=0A-=09=09=09=09=09=09=20= errmsg("subscription=20owner=20\"%s\"=20does=20not=20have=20permission=20= on=20foreign=20server=20\"%s\"",=0A-=09=09=09=09=09=09=09=09= GetUserNameFromId(subform->subowner,=20false),=0A-=09=09=09=09=09=09=09=09= server->servername)));=0A-=09=09}=0A+=09=09=09=09=09=09= errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),=0A+=09=09=09=09=09=09= errmsg("subscription=20owner=20\"%s\"=20does=20not=20have=20permission=20= on=20foreign=20server=20\"%s\"",=0A+=09=09=09=09=09=09=09=20=20=20= GetUserNameFromId(subform->subowner,=20false),=0A+=09=09=09=09=09=09=09=20= =20=20server->servername));=0A=20=0A-=09=09sub->conninfo=20=3D=20= ForeignServerConnectionString(subform->subowner,=0A-=09=09=09=09=09=09=09= =09=09=09=09=09=09=20=20server);=0A+=09=09=09sub->conninfo=20=3D=20= ForeignServerConnectionString(subform->subowner,=0A+=09=09=09=09=09=09=09= =09=09=09=09=09=09=09=20=20server);=0A+=09=09}=0A=20=09}=0A=20=09else=0A=20= =09{=0A@@=20-197,6=20+209,31=20@@=20GetSubscription(Oid=20subid,=20bool=20= missing_ok,=20bool=20aclcheck)=0A=20=09return=20sub;=0A=20}=0A=20=0A+/*=0A= +=20*=20Return=20the=20subscription's=20connection=20string,=20loading=20= it=20into=20the=0A+=20*=20subscription=20memory=20context=20if=20= necessary.=0A+=20*=0A+=20*=20GetSubscription=20must=20be=20called=20= earlier=20to=20set=20sub->serverid,=20because=20ACL=0A+=20*=20checks=20= are=20performed=20there.=0A+=20*/=0A+char=20*=0A= +GetSubscriptionConnInfo(Subscription=20*sub)=0A+{=0A+=09MemoryContext=20= oldcxt;=0A+=0A+=09if=20(sub->conninfo)=0A+=09=09return=20sub->conninfo;=0A= +=0A+=09Assert(OidIsValid(sub->serverid));=0A+=0A+=09oldcxt=20=3D=20= MemoryContextSwitchTo(sub->cxt);=0A+=09sub->conninfo=20=3D=20= ForeignServerConnectionString(sub->owner,=0A+=09=09=09=09=09=09=09=09=09=09= =09=09=20=20GetForeignServer(sub->serverid));=0A+=09= MemoryContextSwitchTo(oldcxt);=0A+=0A+=09return=20sub->conninfo;=0A+}=0A= +=0A=20/*=0A=20=20*=20Return=20number=20of=20subscriptions=20defined=20= in=20given=20database.=0A=20=20*=20Used=20by=20dropdb()=20to=20check=20= if=20database=20can=20indeed=20be=20dropped.=0Adiff=20--git=20= a/src/backend/commands/subscriptioncmds.c=20= b/src/backend/commands/subscriptioncmds.c=0Aindex=20= 1e10d9d9a58..2b77f3e5592=20100644=0A---=20= a/src/backend/commands/subscriptioncmds.c=0A+++=20= b/src/backend/commands/subscriptioncmds.c=0A@@=20-1026,7=20+1026,8=20@@=20= AlterSubscription_refresh(Subscription=20*sub,=20bool=20copy_data,=0A=20=0A= =20=09/*=20Try=20to=20connect=20to=20the=20publisher.=20*/=0A=20=09= must_use_password=20=3D=20sub->passwordrequired=20&&=20= !sub->ownersuperuser;=0A-=09wrconn=20=3D=20walrcv_connect(sub->conninfo,=20= true,=20true,=20must_use_password,=0A+=09wrconn=20=3D=20= walrcv_connect(GetSubscriptionConnInfo(sub),=20true,=20true,=0A+=09=09=09= =09=09=09=09must_use_password,=0A=20=09=09=09=09=09=09=09sub->name,=20= &err);=0A=20=09if=20(!wrconn)=0A=20=09=09ereport(ERROR,=0A@@=20-1278,7=20= +1279,8=20@@=20AlterSubscription_refresh_seq(Subscription=20*sub)=0A=20=0A= =20=09/*=20Try=20to=20connect=20to=20the=20publisher.=20*/=0A=20=09= must_use_password=20=3D=20sub->passwordrequired=20&&=20= !sub->ownersuperuser;=0A-=09wrconn=20=3D=20walrcv_connect(sub->conninfo,=20= true,=20true,=20must_use_password,=0A+=09wrconn=20=3D=20= walrcv_connect(GetSubscriptionConnInfo(sub),=20true,=20true,=0A+=09=09=09= =09=09=09=09must_use_password,=0A=20=09=09=09=09=09=09=09sub->name,=20= &err);=0A=20=09if=20(!wrconn)=0A=20=09=09ereport(ERROR,=0A@@=20-2129,7=20= +2131,8=20@@=20AlterSubscription(ParseState=20*pstate,=20= AlterSubscriptionStmt=20*stmt,=0A=20=09=09=20*=20available.=0A=20=09=09=20= */=0A=20=09=09must_use_password=20=3D=20sub->passwordrequired=20&&=20= !sub->ownersuperuser;=0A-=09=09wrconn=20=3D=20= walrcv_connect(stmt->conninfo=20?=20stmt->conninfo=20:=20sub->conninfo,=0A= +=09=09wrconn=20=3D=20walrcv_connect(stmt->conninfo=20?=20stmt->conninfo=20= :=0A+=09=09=09=09=09=09=09=09GetSubscriptionConnInfo(sub),=0A=20=09=09=09= =09=09=09=09=09true,=20true,=20must_use_password,=20sub->name,=0A=20=09=09= =09=09=09=09=09=09&err);=0A=20=09=09if=20(!wrconn)=0Adiff=20--git=20= a/src/backend/replication/logical/sequencesync.c=20= b/src/backend/replication/logical/sequencesync.c=0Aindex=20= e2ff8d77b16..2ba521c5a43=20100644=0A---=20= a/src/backend/replication/logical/sequencesync.c=0A+++=20= b/src/backend/replication/logical/sequencesync.c=0A@@=20-711,7=20+711,7=20= @@=20LogicalRepSyncSequences(void)=0A=20=09=20*=20Establish=20the=20= connection=20to=20the=20publisher=20for=20sequence=20synchronization.=0A=20= =09=20*/=0A=20=09LogRepWorkerWalRcvConn=20=3D=0A-=09=09= walrcv_connect(MySubscription->conninfo,=20true,=20true,=0A+=09=09= walrcv_connect(GetSubscriptionConnInfo(MySubscription),=20true,=20true,=0A= =20=09=09=09=09=09=20=20=20must_use_password,=0A=20=09=09=09=09=09=20=20=20= app_name.data,=20&err);=0A=20=09if=20(LogRepWorkerWalRcvConn=20=3D=3D=20= NULL)=0Adiff=20--git=20a/src/backend/replication/logical/tablesync.c=20= b/src/backend/replication/logical/tablesync.c=0Aindex=20= eb718114297..d859b0d7311=20100644=0A---=20= a/src/backend/replication/logical/tablesync.c=0A+++=20= b/src/backend/replication/logical/tablesync.c=0A@@=20-1304,7=20+1304,7=20= @@=20LogicalRepSyncTableStart(XLogRecPtr=20*origin_startpos)=0A=20=09=20= *=20so=20that=20synchronous=20replication=20can=20distinguish=20them.=0A=20= =09=20*/=0A=20=09LogRepWorkerWalRcvConn=20=3D=0A-=09=09= walrcv_connect(MySubscription->conninfo,=20true,=20true,=0A+=09=09= walrcv_connect(GetSubscriptionConnInfo(MySubscription),=20true,=20true,=0A= =20=09=09=09=09=09=20=20=20must_use_password,=0A=20=09=09=09=09=09=20=20=20= slotname,=20&err);=0A=20=09if=20(LogRepWorkerWalRcvConn=20=3D=3D=20NULL)=0A= diff=20--git=20a/src/backend/replication/logical/worker.c=20= b/src/backend/replication/logical/worker.c=0Aindex=20= dd6fc38a41e..e2855b0d077=20100644=0A---=20= a/src/backend/replication/logical/worker.c=0A+++=20= b/src/backend/replication/logical/worker.c=0A@@=20-5105,7=20+5105,8=20@@=20= maybe_reread_subscription(void)=0A=20=09=20*=20'parallel'=20to=20any=20= other=20value=20or=20the=20server=20decides=20not=20to=20stream=20the=0A=20= =09=20*=20in-progress=20transaction.=0A=20=09=20*/=0A-=09if=20= (strcmp(newsub->conninfo,=20MySubscription->conninfo)=20!=3D=200=20||=0A= +=09if=20(strcmp(GetSubscriptionConnInfo(newsub),=0A+=09=09=09=20=20=20= GetSubscriptionConnInfo(MySubscription))=20!=3D=200=20||=0A=20=09=09= strcmp(newsub->name,=20MySubscription->name)=20!=3D=200=20||=0A=20=09=09= strcmp(newsub->slotname,=20MySubscription->slotname)=20!=3D=200=20||=0A=20= =09=09newsub->binary=20!=3D=20MySubscription->binary=20||=0A@@=20-5703,8=20= +5704,8=20@@=20run_apply_worker(void)=0A=20=09must_use_password=20=3D=20= MySubscription->passwordrequired=20&&=0A=20=09=09= !MySubscription->ownersuperuser;=0A=20=0A-=09LogRepWorkerWalRcvConn=20=3D=20= walrcv_connect(MySubscription->conninfo,=20true,=0A-=09=09=09=09=09=09=09= =09=09=09=09true,=20must_use_password,=0A+=09LogRepWorkerWalRcvConn=20=3D=20= walrcv_connect(GetSubscriptionConnInfo(MySubscription),=0A+=09=09=09=09=09= =09=09=09=09=09=09true,=20true,=20must_use_password,=0A=20=09=09=09=09=09= =09=09=09=09=09=09MySubscription->name,=20&err);=0A=20=0A=20=09if=20= (LogRepWorkerWalRcvConn=20=3D=3D=20NULL)=0A@@=20-5972,7=20+5973,7=20@@=20= SetupApplyOrSyncWorker(int=20worker_slot)=0A=20=0A=20=09/*=20Connect=20= to=20the=20origin=20and=20start=20the=20replication.=20*/=0A=20=09= elog(DEBUG1,=20"connecting=20to=20publisher=20using=20connection=20= string=20\"%s\"",=0A-=09=09=20MySubscription->conninfo);=0A+=09=09=20= GetSubscriptionConnInfo(MySubscription));=0A=20=0A=20=09/*=0A=20=09=20*=20= Setup=20callback=20for=20syscache=20so=20that=20we=20know=20when=20= something=20changes=20in=0Adiff=20--git=20= a/src/include/catalog/pg_subscription.h=20= b/src/include/catalog/pg_subscription.h=0Aindex=20= a6a2ad1e49c..4dfc6dfce17=20100644=0A---=20= a/src/include/catalog/pg_subscription.h=0A+++=20= b/src/include/catalog/pg_subscription.h=0A@@=20-164,6=20+164,7=20@@=20= typedef=20struct=20Subscription=0A=20=09=09=09=09=09=09=09=09=09=20*=20= and=20the=20retention=20duration=20has=20not=0A=20=09=09=09=09=09=09=09=09= =09=20*=20exceeded=20max_retention_duration,=20when=0A=20=09=09=09=09=09=09= =09=09=09=20*=20defined=20*/=0A+=09Oid=09=09=09serverid;=09=09/*=20Oid=20= of=20the=20foreign=20server,=20if=20any=20*/=0A=20=09char=09=20=20=20= *conninfo;=09=09/*=20Connection=20string=20to=20the=20publisher=20*/=0A=20= =09char=09=20=20=20*slotname;=09=09/*=20Name=20of=20the=20replication=20= slot=20*/=0A=20=09char=09=20=20=20*synccommit;=09=09/*=20Synchronous=20= commit=20setting=20for=20worker=20*/=0A@@=20-214,6=20+215,7=20@@=20= typedef=20struct=20Subscription=0A=20=0A=20extern=20Subscription=20= *GetSubscription(Oid=20subid,=20bool=20missing_ok,=0A=20=09=09=09=09=09=09= =09=09=09=20bool=20aclcheck);=0A+extern=20char=20= *GetSubscriptionConnInfo(Subscription=20*sub);=0A=20extern=20void=20= DisableSubscription(Oid=20subid);=0A=20=0A=20extern=20int=09= CountDBSubscriptions(Oid=20dbid);=0Adiff=20--git=20= a/src/test/regress/expected/subscription.out=20= b/src/test/regress/expected/subscription.out=0Aindex=20= 7e3cabdb93f..c0db7636713=20100644=0A---=20= a/src/test/regress/expected/subscription.out=0A+++=20= b/src/test/regress/expected/subscription.out=0A@@=20-174,16=20+174,49=20= @@=20WARNING:=20=20subscription=20was=20created,=20but=20is=20not=20= connected=0A=20HINT:=20=20To=20initiate=20replication,=20you=20must=20= manually=20create=20the=20replication=20slot,=20enable=20the=20= subscription,=20and=20alter=20the=20subscription=20to=20refresh=20= publications.=0A=20DROP=20USER=20MAPPING=20FOR=20= regress_subscription_user3=20SERVER=20test_server;=0A=20RESET=20SESSION=20= AUTHORIZATION;=0A+CREATE=20SERVER=20test_server2=20FOREIGN=20DATA=20= WRAPPER=20test_fdw;=0A+GRANT=20USAGE=20ON=20FOREIGN=20SERVER=20= test_server2=20TO=20regress_subscription_user3;=0A+SET=20SESSION=20= AUTHORIZATION=20regress_subscription_user3;=0A+CREATE=20USER=20MAPPING=20= FOR=20regress_subscription_user3=20SERVER=20test_server2=20OPTIONS(user=20= 'bar',=20password=20'secret');=0A+RESET=20SESSION=20AUTHORIZATION;=0A=20= REVOKE=20USAGE=20ON=20FOREIGN=20SERVER=20test_server=20FROM=20= regress_subscription_user3;=0A=20SET=20SESSION=20AUTHORIZATION=20= regress_subscription_user3;=0A=20--=20fail,=20must=20connect=20but=20= lacks=20USAGE=20on=20server,=20as=20well=20as=20user=20mapping=0A=20DROP=20= SUBSCRIPTION=20regress_testsub6;=0A=20ERROR:=20=20could=20not=20connect=20= to=20publisher=20when=20attempting=20to=20drop=20replication=20slot=20= "dummy":=20subscription=20owner=20"regress_subscription_user3"=20does=20= not=20have=20permission=20on=20foreign=20server=20"test_server"=0A=20= HINT:=20=20Use=20ALTER=20SUBSCRIPTION=20...=20DISABLE=20to=20disable=20= the=20subscription,=20and=20then=20use=20ALTER=20SUBSCRIPTION=20...=20= SET=20(slot_name=20=3D=20NONE)=20to=20disassociate=20it=20from=20the=20= slot.=0A+--=20ok,=20should=20not=20need=20to=20resolve=20conninfo=20for=20= the=20old=20broken=20server=0A+ALTER=20SUBSCRIPTION=20regress_testsub6=20= SERVER=20test_server2;=0A+SELECT=20fs.srvname=0A+=20=20FROM=20= pg_subscription=20s=0A+=20=20JOIN=20pg_foreign_server=20fs=20ON=20fs.oid=20= =3D=20s.subserver=0A+=20WHERE=20s.subname=20=3D=20'regress_testsub6';=0A= +=20=20=20srvname=20=20=20=20=0A+--------------=0A+=20test_server2=0A+(1=20= row)=0A+=0A+DROP=20USER=20MAPPING=20FOR=20regress_subscription_user3=20= SERVER=20test_server2;=0A+RESET=20SESSION=20AUTHORIZATION;=0A+REVOKE=20= USAGE=20ON=20FOREIGN=20SERVER=20test_server2=20FROM=20= regress_subscription_user3;=0A+SET=20SESSION=20AUTHORIZATION=20= regress_subscription_user3;=0A+--=20ok,=20should=20not=20need=20to=20= resolve=20conninfo=20for=20the=20current=20broken=20server=0A+ALTER=20= SUBSCRIPTION=20regress_testsub6=20CONNECTION=20= 'dbname=3Dregress_doesnotexist2=20password=3Dsecret';=0A+RESET=20SESSION=20= AUTHORIZATION;=0A+SELECT=20subserver=20=3D=200::oid=20AS=20= uses_conninfo,=20subconninfo=0A+=20=20FROM=20pg_subscription=0A+=20WHERE=20= subname=20=3D=20'regress_testsub6';=0A+=20uses_conninfo=20|=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20subconninfo=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=0A= +---------------+----------------------------------------------=0A+=20t=20= =20=20=20=20=20=20=20=20=20=20=20=20|=20dbname=3Dregress_doesnotexist2=20= password=3Dsecret=0A+(1=20row)=0A+=0A+SET=20SESSION=20AUTHORIZATION=20= regress_subscription_user3;=0A=20ALTER=20SUBSCRIPTION=20regress_testsub6=20= SET=20(slot_name=20=3D=20NONE);=0A=20DROP=20SUBSCRIPTION=20= regress_testsub6;=0A=20SET=20SESSION=20AUTHORIZATION=20= regress_subscription_user;=0A=20REVOKE=20CREATE=20ON=20DATABASE=20= REGRESSION=20FROM=20regress_subscription_user3;=0A+DROP=20SERVER=20= test_server2;=0A=20DROP=20SERVER=20test_server;=0A=20--=20fail,=20FDW=20= is=20dependent=0A=20DROP=20FUNCTION=20test_fdw_connection(oid,=20oid,=20= internal);=0Adiff=20--git=20a/src/test/regress/regress.c=20= b/src/test/regress/regress.c=0Aindex=202bcb5559a45..598635b6558=20100644=0A= ---=20a/src/test/regress/regress.c=0A+++=20b/src/test/regress/regress.c=0A= @@=20-31,6=20+31,7=20@@=0A=20#include=20"executor/executor.h"=0A=20= #include=20"executor/functions.h"=0A=20#include=20"executor/spi.h"=0A= +#include=20"foreign/foreign.h"=0A=20#include=20"funcapi.h"=0A=20= #include=20"mb/pg_wchar.h"=0A=20#include=20"miscadmin.h"=0A@@=20-735,6=20= +736,8=20@@=20PG_FUNCTION_INFO_V1(test_fdw_connection);=0A=20Datum=0A=20= test_fdw_connection(PG_FUNCTION_ARGS)=0A=20{=0A+=09/*=20Ensure=20the=20= test=20fails=20if=20no=20valid=20user=20mapping=20exists.=20*/=0A+=09= GetUserMapping(PG_GETARG_OID(0),=20PG_GETARG_OID(1));=0A=20=09= PG_RETURN_TEXT_P(cstring_to_text("dbname=3Dregress_doesnotexist=20= user=3Ddoesnotexist=20password=3Dsecret"));=0A=20}=0A=20=0Adiff=20--git=20= a/src/test/regress/sql/subscription.sql=20= b/src/test/regress/sql/subscription.sql=0Aindex=20= 6c3d9632e8a..73cb251e192=20100644=0A---=20= a/src/test/regress/sql/subscription.sql=0A+++=20= b/src/test/regress/sql/subscription.sql=0A@@=20-124,6=20+124,12=20@@=20= SET=20SESSION=20AUTHORIZATION=20regress_subscription_user3;=0A=20CREATE=20= SUBSCRIPTION=20regress_testsub6=20SERVER=20test_server=20PUBLICATION=20= testpub=20WITH=20(slot_name=20=3D=20'dummy',=20connect=20=3D=20false);=0A= =20=0A=20DROP=20USER=20MAPPING=20FOR=20regress_subscription_user3=20= SERVER=20test_server;=0A+RESET=20SESSION=20AUTHORIZATION;=0A+CREATE=20= SERVER=20test_server2=20FOREIGN=20DATA=20WRAPPER=20test_fdw;=0A+GRANT=20= USAGE=20ON=20FOREIGN=20SERVER=20test_server2=20TO=20= regress_subscription_user3;=0A+SET=20SESSION=20AUTHORIZATION=20= regress_subscription_user3;=0A+CREATE=20USER=20MAPPING=20FOR=20= regress_subscription_user3=20SERVER=20test_server2=20OPTIONS(user=20= 'bar',=20password=20'secret');=0A+=0A=20RESET=20SESSION=20AUTHORIZATION;=0A= =20REVOKE=20USAGE=20ON=20FOREIGN=20SERVER=20test_server=20FROM=20= regress_subscription_user3;=0A=20SET=20SESSION=20AUTHORIZATION=20= regress_subscription_user3;=0A@@=20-131,12=20+137,33=20@@=20SET=20= SESSION=20AUTHORIZATION=20regress_subscription_user3;=0A=20--=20fail,=20= must=20connect=20but=20lacks=20USAGE=20on=20server,=20as=20well=20as=20= user=20mapping=0A=20DROP=20SUBSCRIPTION=20regress_testsub6;=0A=20=0A+--=20= ok,=20should=20not=20need=20to=20resolve=20conninfo=20for=20the=20old=20= broken=20server=0A+ALTER=20SUBSCRIPTION=20regress_testsub6=20SERVER=20= test_server2;=0A+SELECT=20fs.srvname=0A+=20=20FROM=20pg_subscription=20s=0A= +=20=20JOIN=20pg_foreign_server=20fs=20ON=20fs.oid=20=3D=20s.subserver=0A= +=20WHERE=20s.subname=20=3D=20'regress_testsub6';=0A+=0A+DROP=20USER=20= MAPPING=20FOR=20regress_subscription_user3=20SERVER=20test_server2;=0A= +RESET=20SESSION=20AUTHORIZATION;=0A+REVOKE=20USAGE=20ON=20FOREIGN=20= SERVER=20test_server2=20FROM=20regress_subscription_user3;=0A+SET=20= SESSION=20AUTHORIZATION=20regress_subscription_user3;=0A+=0A+--=20ok,=20= should=20not=20need=20to=20resolve=20conninfo=20for=20the=20current=20= broken=20server=0A+ALTER=20SUBSCRIPTION=20regress_testsub6=20CONNECTION=20= 'dbname=3Dregress_doesnotexist2=20password=3Dsecret';=0A+RESET=20SESSION=20= AUTHORIZATION;=0A+SELECT=20subserver=20=3D=200::oid=20AS=20= uses_conninfo,=20subconninfo=0A+=20=20FROM=20pg_subscription=0A+=20WHERE=20= subname=20=3D=20'regress_testsub6';=0A+SET=20SESSION=20AUTHORIZATION=20= regress_subscription_user3;=0A+=0A=20ALTER=20SUBSCRIPTION=20= regress_testsub6=20SET=20(slot_name=20=3D=20NONE);=0A=20DROP=20= SUBSCRIPTION=20regress_testsub6;=0A=20=0A=20SET=20SESSION=20= AUTHORIZATION=20regress_subscription_user;=0A=20REVOKE=20CREATE=20ON=20= DATABASE=20REGRESSION=20FROM=20regress_subscription_user3;=0A=20=0A+DROP=20= SERVER=20test_server2;=0A=20DROP=20SERVER=20test_server;=0A=20=0A=20--=20= fail,=20FDW=20is=20dependent=0A--=20=0A2.50.1=20(Apple=20Git-155)=0A=0A= --Apple-Mail=_F6B95087-E12D-4BE9-9FEE-95D17406FC2D--