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.98.2) (envelope-from ) id 1x8svy-00000001aAJ-0biq for pgsql-hackers@arkaria.postgresql.org; Tue, 22 Sep 2026 05:20:50 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1x8svx-0000000DdnD-0xRx for pgsql-hackers@arkaria.postgresql.org; Tue, 22 Sep 2026 05:20:49 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1x8svw-0000000Ddmz-2aLs for pgsql-hackers@lists.postgresql.org; Tue, 22 Sep 2026 05:20:48 +0000 Received: from mail-pz2-x10.google.com ([2607:f8b0:4864:3b::10]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1x8svt-00000000c7c-2wbT for pgsql-hackers@lists.postgresql.org; Tue, 22 Sep 2026 05:20:47 +0000 Received: by mail-pz2-x10.google.com with SMTP id 41be03b00d2f7-cc1cea4c79fso1596057a12.0 for ; Mon, 21 Sep 2026 22:20:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790054445; x=1790659245; darn=lists.postgresql.org; h=references:to:cc:in-reply-to:date:subject:mime-version:content-type :message-id:from:from:to:cc:subject:date:message-id:reply-to :content-type; bh=37CPj5tVT0sXeWvlt9hC/oKyg2iHvrX8YBvE40Z7vW4=; b=CWD7KFwpACd0g2s/ONjO8bjaV0H7n20i5F2dyblud4oJx9vhwrWehwsiFHIUpMKxbs 1jheWU3KT+W/qJUJD/DyfmfUbvfBAYO3q4UaIRSekoMMYrN54DHrYv/By8qf+GSPYKue geiH7kew5HGa0RnfsBIX9gQZxEu8JPiXwsX1e6ry7kqiWzayKyvDnkrpEVcc4Bzi0LUb nrx+9E0E9khHHRYsSaEjYKdZiK/mjbbDG5EmsMqlSel0z5Bdr3CKFJMrdDX9Oh6pbffi KGOdJ5spLPU18/uQGnb5vc9Do+yURoFFWLT7ZKztXfnLS+JQWCYiA8G0RESjgM/YJhlb K0zA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790054445; x=1790659245; h=references:to:cc:in-reply-to:date:subject:mime-version:content-type :message-id:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=37CPj5tVT0sXeWvlt9hC/oKyg2iHvrX8YBvE40Z7vW4=; b=foKORsS9REJotlbRemPLHBfRjYCIWhuIxpiZjkgqtDJn2qo3TsLS9WSk8doSLPoxZL mHh1QJ0dFeydKCpRZO9/q4m1lhHs2JRmljjQv7dVJoxjcdg0aKdvLsy21naHcf8z5cqg YayNwa8qXbdxO2w60AEeuVriJ4fBSG5/FDIB3zhmnO+lYvGTQrxdZxNL99HckTSYHein bLm1PaFQcIRDSRurVF+5entjFKwxq48gPqACvuMf+oUNXI+XAEXUN3YXTT+ct2C1yu9a 6SI9XcHurnHuTX4nK0HyK2v9nFDfDskGagGk00O7XGffBvhHpcBbI7jE5sICB7XO0r2s GI3A== X-Forwarded-Encrypted: i=1; AKwUvBzenZTxg7m7Wymo54DgeDM8urlx2h3rjRW6XKHa5az2eXhQasAkRwNJjyAtcf6oYlRRp00drwmiA81QEFsM@lists.postgresql.org X-Gm-Message-State: AFuF++mhRrGpcgjOURCiPcisSdjyz2+5Zgq25KSLXbWacbmNeZ7GdbZa BFNHBa4srbpizKJYlQs335HKqf8bhreEW5c3pdFchJvtQXzaOCi7SBnI X-Gm-Gg: AYBFou1btoFaLlCtGpmqYvgmAcOkx5m9j8Q3OvI6gjYLpsI24+20cCs3JOKvzZIe7wJ 5SUr5VfyouJ8fidLEcJ76n+P/pEYt8wS3EmIyWuxYqGmRIxGj+k+K0CrjlGPTl8BPlQnApwR1zt OXcLtmFLp05ZaK9M4XYFM/7AcsikEnVXZMiDW3EzIA0op4jMCNqWRIVM55Wy/G3dd5rY2FvLCy4 ffXcPoGume+fId8Z3lL977/I/4XnKCJIBmIV1V3MYvphcsZ9n9xrjVTgAyf2ujR8iN9d6aEN72/ WecFnidlAXzXiYHRuWQzkhplgA+pE1U0nvSKT4HYBwsAX42PvrZhEUXTZOi5MZB0eYel8WIMZY2 g1bs+1hwbzo1A44oJT/E52CV75TgFVKnvZS5ofRnwYNYNXs3h+wgREF0OlZ3x8knemPg70bYuLN P5zm5wrmQon/lkdxAhdonmPBmggFzL8Jyc8Nk99obaWQktDS9BW6dNjiaHA8WgCk3QUDtlt+yAv TpDmgX0 X-Received: by 2002:a17:90b:558c:b0:39e:6c6a:2093 with SMTP id 98e67ed59e1d1-3a073251e47mr12801a91.52.1790054445212; Mon, 21 Sep 2026 22:20:45 -0700 (PDT) Received: from smtpclient.apple ([185.135.79.161]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3a070ceaef3sm210042a91.1.2026.09.21.22.20.42 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Sep 2026 22:20:43 -0700 (PDT) From: Chao Li Message-Id: <1D4D684B-C1EC-4630-9794-F13950C9B15F@gmail.com> Content-Type: multipart/mixed; boundary="Apple-Mail=_721EFD83-D344-4FA7-A873-4068A2B74AC5" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.700.51.1.1\)) Subject: Re: pg_walinspect: fix LSN validation messages and empty range handling Date: Tue, 22 Sep 2026 13:20:08 +0800 In-Reply-To: Cc: Bharath Rupireddy , PostgreSQL Hackers , Michael Paquier To: Kiran Kaki References: <7B8F5F12-98A5-4618-867A-904EA1334FD4@gmail.com> <8949F1E9-C296-47B4-ADC0-C5276388DB10@gmail.com> <4179E230-F999-437E-B964-94659F0AD3D7@gmail.com> X-Mailer: Apple Mail (2.3864.700.51.1.1) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_721EFD83-D344-4FA7-A873-4068A2B74AC5 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Sep 22, 2026, at 10:06, Kiran Kaki wrote: >=20 > Hi @Chao Li >=20 > On Mon, Sep 21, 2026 at 3:51=E2=80=AFPM Chao Li = wrote: >> Thanks for reviewing and updating v2. >>=20 >>>=20 >>> While here, do we also need to fix AlterSubscription()'s skip WAL >>> location and ParseVariableDouble()'s min and max bound messages? = Maybe >>> separately. >>>=20 >>=20 >> Yeah, we can do that. As those two functions are in core, and 0001 = changes the extension, I put the new changes to 0002. >>=20 >> PFA v3. >=20 > Tested both patches on master (d39fda1cc4). They apply cleanly, build > without warnings, and the full suite passes (363 ok, 0 failed). I also > confirmed each reworded message at runtime, including the inclusive > boundaries they describe. >=20 > 0001 is unchanged since v1, only the commit message differs. Looks = good to me. >=20 > For 0002, the comment above that check already says "at least a future > LSN" and came in with the code in 208c5d65bb, so the reworded message > matches what the check was always meant to do. Looks good to me. >=20 > One suggestion, not a blocker. The new tests only cover the cases that > fail. The lower bound is already covered by the existing "Test zero > interval" case in 001_basic.pl, but the upper bound and the equal LSN > case are not, so they would still pass if those bounds were made > exclusive. Two additions would close that: >=20 > psql_like( > $node, > '\set WATCH_INTERVAL 1000000' . "\n" . '\echo :WATCH_INTERVAL', > qr/^1000000$/m, > 'WATCH_INTERVAL accepts its upper bound'); >=20 > -- ok - LSN equal to the replication origin is accepted > ALTER SUBSCRIPTION regress_testsub SKIP (lsn =3D '0/12346'); > ALTER SUBSCRIPTION regress_testsub SKIP (lsn =3D NONE); >=20 > The second line just resets the value so the rest of the file's = expected > output is unaffected. Integrated the tests into v4. PFA v4: * 0001 unchanged * 0002 added the tests that Kiran suggested Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/ --Apple-Mail=_721EFD83-D344-4FA7-A873-4068A2B74AC5 Content-Disposition: attachment; filename=v4-0001-Fix-input-LSN-validation-error-messages-in-pg_wal.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v4-0001-Fix-input-LSN-validation-error-messages-in-pg_wal.patch" Content-Transfer-Encoding: quoted-printable =46rom=20190fe2e1887cc480ea496bbe09ebb1ece34631b3=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20"Chao=20Li=20(Evan)"=20=0A= Date:=20Sun,=2020=20Sep=202026=2009:39:56=20+0800=0ASubject:=20[PATCH=20= v4=201/2]=20Fix=20input=20LSN=20validation=20error=20messages=20in=0A=20= pg_walinspect.=0A=0ACommit=205c1b6628075a=20changed=20the=20input=20LSN=20= validation=20checks=20to=20allow=20an=20input=0ALSN=20equal=20to=20the=20= current=20LSN,=20and=20a=20start=20LSN=20equal=20to=20the=20end=20LSN.=20= However,=0Athe=20corresponding=20error=20messages=20continued=20to=20say=20= that=20the=20LSNs=20had=20to=20be=0Aless=20than=20the=20current=20LSN=20= or=20the=20end=20LSN.=0A=0AFix=20this=20oversight=20by=20changing=20= those=20messages=20from=20"must=20be=20less=20than"=20to=0A"must=20be=20= less=20than=20or=20equal=20to",=20matching=20the=20actual=20validation=20= conditions.=0ASimilar=20wording=20is=20used=20elsewhere=20in=20the=20= code.=0A=0ANot=20back-patched,=20as=20the=20fix=20is=20not=20critical=20= and=20the=20inaccuracy=20went=20unnoticed=0Afor=20years.=0A=0AAuthor:=20= Chao=20Li=20=0AReviewed-by:=20Kiran=20Kaki=20= =0AReviewed-by:=20Bharath=20Rupireddy=20= =0ADiscussion:=20= https://postgr.es/m/7B8F5F12-98A5-4618-867A-904EA1334FD4@gmail.com=0A---=0A= =20contrib/pg_walinspect/expected/oldextversions.out=20|=20=204=20++--=0A= =20contrib/pg_walinspect/expected/pg_walinspect.out=20=20|=2014=20= +++++++-------=0A=20contrib/pg_walinspect/pg_walinspect.c=20=20=20=20=20=20= =20=20=20=20=20=20=20|=2010=20+++++-----=0A=203=20files=20changed,=2014=20= insertions(+),=2014=20deletions(-)=0A=0Adiff=20--git=20= a/contrib/pg_walinspect/expected/oldextversions.out=20= b/contrib/pg_walinspect/expected/oldextversions.out=0Aindex=20= 89953af3d0e..fd65ed149c6=20100644=0A---=20= a/contrib/pg_walinspect/expected/oldextversions.out=0A+++=20= b/contrib/pg_walinspect/expected/oldextversions.out=0A@@=20-43,9=20+43,9=20= @@=20SELECT=20COUNT(*)=20>=3D=201=20AS=20ok=20FROM=20= pg_get_wal_stats_till_end_of_wal(:'wal_lsn1');=0A=20=0A=20--=20Failures=20= with=20start=20LSNs.=0A=20SELECT=20*=20FROM=20= pg_get_wal_records_info_till_end_of_wal('FFFFFFFF/FFFFFFFF');=0A-ERROR:=20= =20WAL=20start=20LSN=20must=20be=20less=20than=20current=20LSN=0A+ERROR:=20= =20WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20to=20= current=20LSN=0A=20SELECT=20*=20FROM=20= pg_get_wal_stats_till_end_of_wal('FFFFFFFF/FFFFFFFF');=0A-ERROR:=20=20= WAL=20start=20LSN=20must=20be=20less=20than=20current=20LSN=0A+ERROR:=20=20= WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20to=20current=20= LSN=0A=20--=20Move=20to=20new=20version=201.1.=0A=20ALTER=20EXTENSION=20= pg_walinspect=20UPDATE=20TO=20'1.1';=0A=20--=20List=20what=20version=20= 1.1=20contains.=0Adiff=20--git=20= a/contrib/pg_walinspect/expected/pg_walinspect.out=20= b/contrib/pg_walinspect/expected/pg_walinspect.out=0Aindex=20= f955ff5d3c5..b9abeeebdfd=20100644=0A---=20= a/contrib/pg_walinspect/expected/pg_walinspect.out=0A+++=20= b/contrib/pg_walinspect/expected/pg_walinspect.out=0A@@=20-29,14=20= +29,14=20@@=20SELECT=20*=20FROM=20pg_get_wal_block_info('0/0',=20= :'wal_lsn1');=0A=20ERROR:=20=20could=20not=20read=20WAL=20at=20LSN=20= 0/00000000=0A=20--=20Start=20LSN=20>=20End=20LSN.=0A=20SELECT=20*=20FROM=20= pg_get_wal_records_info(:'wal_lsn2',=20:'wal_lsn1');=0A-ERROR:=20=20WAL=20= start=20LSN=20must=20be=20less=20than=20end=20LSN=0A+ERROR:=20=20WAL=20= start=20LSN=20must=20be=20less=20than=20or=20equal=20to=20end=20LSN=0A=20= SELECT=20*=20FROM=20pg_get_wal_stats(:'wal_lsn2',=20:'wal_lsn1');=0A= -ERROR:=20=20WAL=20start=20LSN=20must=20be=20less=20than=20end=20LSN=0A= +ERROR:=20=20WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20= to=20end=20LSN=0A=20SELECT=20*=20FROM=20= pg_get_wal_block_info(:'wal_lsn2',=20:'wal_lsn1');=0A-ERROR:=20=20WAL=20= start=20LSN=20must=20be=20less=20than=20end=20LSN=0A+ERROR:=20=20WAL=20= start=20LSN=20must=20be=20less=20than=20or=20equal=20to=20end=20LSN=0A=20= --=20LSNs=20with=20the=20highest=20value=20possible.=0A=20SELECT=20*=20= FROM=20pg_get_wal_record_info('FFFFFFFF/FFFFFFFF');=0A-ERROR:=20=20WAL=20= input=20LSN=20must=20be=20less=20than=20current=20LSN=0A+ERROR:=20=20WAL=20= input=20LSN=20must=20be=20less=20than=20or=20equal=20to=20current=20LSN=0A= =20--=20Success=20with=20end=20LSNs.=0A=20SELECT=20COUNT(*)=20>=3D=201=20= AS=20ok=20FROM=20pg_get_wal_records_info(:'wal_lsn1',=20= 'FFFFFFFF/FFFFFFFF');=0A=20=20ok=20=0A@@=20-58,11=20+58,11=20@@=20SELECT=20= COUNT(*)=20>=3D=201=20AS=20ok=20FROM=20= pg_get_wal_block_info(:'wal_lsn1',=20'FFFFFFFF/FFF=0A=20=0A=20--=20= Failures=20with=20start=20LSNs.=0A=20SELECT=20*=20FROM=20= pg_get_wal_records_info('FFFFFFFF/FFFFFFFE',=20'FFFFFFFF/FFFFFFFF');=0A= -ERROR:=20=20WAL=20start=20LSN=20must=20be=20less=20than=20current=20LSN=0A= +ERROR:=20=20WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20= to=20current=20LSN=0A=20SELECT=20*=20FROM=20= pg_get_wal_stats('FFFFFFFF/FFFFFFFE',=20'FFFFFFFF/FFFFFFFF');=0A-ERROR:=20= =20WAL=20start=20LSN=20must=20be=20less=20than=20current=20LSN=0A+ERROR:=20= =20WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20to=20= current=20LSN=0A=20SELECT=20*=20FROM=20= pg_get_wal_block_info('FFFFFFFF/FFFFFFFE',=20'FFFFFFFF/FFFFFFFF');=0A= -ERROR:=20=20WAL=20start=20LSN=20must=20be=20less=20than=20current=20LSN=0A= +ERROR:=20=20WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20= to=20current=20LSN=0A=20--=20= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=20--=20Tests=20= for=20all=20function=20executions=0A=20--=20= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0Adiff=20--git=20= a/contrib/pg_walinspect/pg_walinspect.c=20= b/contrib/pg_walinspect/pg_walinspect.c=0Aindex=20= a172f9e2b40..6edd6f8cb35=20100644=0A---=20= a/contrib/pg_walinspect/pg_walinspect.c=0A+++=20= b/contrib/pg_walinspect/pg_walinspect.c=0A@@=20-488,7=20+488,7=20@@=20= pg_get_wal_record_info(PG_FUNCTION_ARGS)=0A=20=09if=20(lsn=20>=20= curr_lsn)=0A=20=09=09ereport(ERROR,=0A=20=09=09=09=09= (errcode(ERRCODE_INVALID_PARAMETER_VALUE),=0A-=09=09=09=09=20errmsg("WAL=20= input=20LSN=20must=20be=20less=20than=20current=20LSN"),=0A+=09=09=09=09=20= errmsg("WAL=20input=20LSN=20must=20be=20less=20than=20or=20equal=20to=20= current=20LSN"),=0A=20=09=09=09=09=20errdetail("Current=20WAL=20LSN=20on=20= the=20database=20system=20is=20at=20%X/%08X.",=0A=20=09=09=09=09=09=09=20= =20=20LSN_FORMAT_ARGS(curr_lsn))));=0A=20=0A@@=20-530,14=20+530,14=20@@=20= ValidateInputLSNs(XLogRecPtr=20start_lsn,=20XLogRecPtr=20*end_lsn)=0A=20=09= if=20(start_lsn=20>=20curr_lsn)=0A=20=09=09ereport(ERROR,=0A=20=09=09=09=09= (errcode(ERRCODE_INVALID_PARAMETER_VALUE),=0A-=09=09=09=09=20errmsg("WAL=20= start=20LSN=20must=20be=20less=20than=20current=20LSN"),=0A+=09=09=09=09=20= errmsg("WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20to=20= current=20LSN"),=0A=20=09=09=09=09=20errdetail("Current=20WAL=20LSN=20on=20= the=20database=20system=20is=20at=20%X/%08X.",=0A=20=09=09=09=09=09=09=20= =20=20LSN_FORMAT_ARGS(curr_lsn))));=0A=20=0A=20=09if=20(start_lsn=20>=20= *end_lsn)=0A=20=09=09ereport(ERROR,=0A=20=09=09=09=09= (errcode(ERRCODE_INVALID_PARAMETER_VALUE),=0A-=09=09=09=09=20errmsg("WAL=20= start=20LSN=20must=20be=20less=20than=20end=20LSN")));=0A+=09=09=09=09=20= errmsg("WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20to=20= end=20LSN")));=0A=20=0A=20=09if=20(*end_lsn=20>=20curr_lsn)=0A=20=09=09= *end_lsn=20=3D=20curr_lsn;=0A@@=20-836,7=20+836,7=20@@=20= pg_get_wal_records_info_till_end_of_wal(PG_FUNCTION_ARGS)=0A=20=09if=20= (start_lsn=20>=20end_lsn)=0A=20=09=09ereport(ERROR,=0A=20=09=09=09=09= (errcode(ERRCODE_INVALID_PARAMETER_VALUE),=0A-=09=09=09=09=20errmsg("WAL=20= start=20LSN=20must=20be=20less=20than=20current=20LSN"),=0A+=09=09=09=09=20= errmsg("WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20to=20= current=20LSN"),=0A=20=09=09=09=09=20errdetail("Current=20WAL=20LSN=20on=20= the=20database=20system=20is=20at=20%X/%08X.",=0A=20=09=09=09=09=09=09=20= =20=20LSN_FORMAT_ARGS(end_lsn))));=0A=20=0A@@=20-855,7=20+855,7=20@@=20= pg_get_wal_stats_till_end_of_wal(PG_FUNCTION_ARGS)=0A=20=09if=20= (start_lsn=20>=20end_lsn)=0A=20=09=09ereport(ERROR,=0A=20=09=09=09=09= (errcode(ERRCODE_INVALID_PARAMETER_VALUE),=0A-=09=09=09=09=20errmsg("WAL=20= start=20LSN=20must=20be=20less=20than=20current=20LSN"),=0A+=09=09=09=09=20= errmsg("WAL=20start=20LSN=20must=20be=20less=20than=20or=20equal=20to=20= current=20LSN"),=0A=20=09=09=09=09=20errdetail("Current=20WAL=20LSN=20on=20= the=20database=20system=20is=20at=20%X/%08X.",=0A=20=09=09=09=09=09=09=20= =20=20LSN_FORMAT_ARGS(end_lsn))));=0A=20=0A--=20=0A2.50.1=20(Apple=20= Git-155)=0A=0A= --Apple-Mail=_721EFD83-D344-4FA7-A873-4068A2B74AC5 Content-Disposition: attachment; filename=v4-0002-Fix-inaccurate-inclusive-bound-error-messages.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v4-0002-Fix-inaccurate-inclusive-bound-error-messages.patch" Content-Transfer-Encoding: quoted-printable =46rom=2068804988701962e4fe97709ba437058373d1653c=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20"Chao=20Li=20(Evan)"=20=0A= Date:=20Mon,=2021=20Sep=202026=2017:31:14=20+0800=0ASubject:=20[PATCH=20= v4=202/2]=20Fix=20inaccurate=20inclusive-bound=20error=20messages.=0A=0A= ALTER=20SUBSCRIPTION=20...=20SKIP=20accepts=20a=20skip=20LSN=20equal=20= to=20the=20replication=0Aorigin's=20progress,=20but=20its=20error=20= message=20said=20that=20the=20skip=20LSN=20must=20be=0Agreater=20than=20= the=20origin=20LSN.=20Likewise,=20ParseVariableDouble()=20accepts=0A= values=20at=20either=20end=20of=20its=20documented=20[min,max]=20range,=20= but=20its=0Amessages=20said=20that=20they=20had=20to=20be=20strictly=20= inside=20the=20range.=0A=0AAdjust=20the=20messages=20to=20describe=20the=20= inclusive=20bounds=20accurately,=20and=0Aadd=20coverage=20for=20both=20= cases.=0A=0ASuggested-by:=20Bharath=20Rupireddy=20= =0AAuthor:=20Chao=20Li=20= =0AReviewed-by:=20Kiran=20Kaki=20=0A= Discussion:=20= https://postgr.es/m/7B8F5F12-98A5-4618-867A-904EA1334FD4@gmail.com=0A---=0A= =20src/backend/commands/subscriptioncmds.c=20=20=20=20|=20=202=20+-=0A=20= src/bin/psql/t/001_basic.pl=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= |=2015=20+++++++++++++++=0A=20src/bin/psql/variables.c=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20|=20=204=20++--=0A=20= src/test/regress/expected/subscription.out=20|=2012=20++++++++++++=0A=20= src/test/regress/sql/subscription.sql=20=20=20=20=20=20|=2012=20= ++++++++++++=0A=205=20files=20changed,=2042=20insertions(+),=203=20= deletions(-)=0A=0Adiff=20--git=20= a/src/backend/commands/subscriptioncmds.c=20= b/src/backend/commands/subscriptioncmds.c=0Aindex=20= 22a61dca65d..27a5b55e964=20100644=0A---=20= a/src/backend/commands/subscriptioncmds.c=0A+++=20= b/src/backend/commands/subscriptioncmds.c=0A@@=20-2419,7=20+2419,7=20@@=20= AlterSubscription(ParseState=20*pstate,=20AlterSubscriptionStmt=20*stmt,=0A= =20=09=09=09=09=09if=20(XLogRecPtrIsValid(remote_lsn)=20&&=20opts.lsn=20= <=20remote_lsn)=0A=20=09=09=09=09=09=09ereport(ERROR,=0A=20=09=09=09=09=09= =09=09=09(errcode(ERRCODE_INVALID_PARAMETER_VALUE),=0A-=09=09=09=09=09=09= =09=09=20errmsg("skip=20WAL=20location=20(LSN=20%X/%08X)=20must=20be=20= greater=20than=20origin=20LSN=20%X/%08X",=0A+=09=09=09=09=09=09=09=09=20= errmsg("skip=20WAL=20location=20(LSN=20%X/%08X)=20must=20be=20greater=20= than=20or=20equal=20to=20origin=20LSN=20%X/%08X",=0A=20=09=09=09=09=09=09= =09=09=09=09LSN_FORMAT_ARGS(opts.lsn),=0A=20=09=09=09=09=09=09=09=09=09=09= LSN_FORMAT_ARGS(remote_lsn))));=0A=20=09=09=09=09}=0Adiff=20--git=20= a/src/bin/psql/t/001_basic.pl=20b/src/bin/psql/t/001_basic.pl=0Aindex=20= 028df33ce8a..3ea0e226a36=20100644=0A---=20a/src/bin/psql/t/001_basic.pl=0A= +++=20b/src/bin/psql/t/001_basic.pl=0A@@=20-452,6=20+452,21=20@@=20= psql_fails_like(=0A=20=09'\set=20WATCH_INTERVAL=201e500',=0A=20=09qr/is=20= out=20of=20range/,=0A=20=09'WATCH_INTERVAL=20variable=20is=20out=20of=20= range');=0A+psql_like(=0A+=09$node,=0A+=09'\set=20WATCH_INTERVAL=20= 1000000'=20.=20"\n"=20.=20'\echo=20:WATCH_INTERVAL',=0A+=09= qr/^1000000$/m,=0A+=09'WATCH_INTERVAL=20accepts=20its=20upper=20bound');=0A= +psql_fails_like(=0A+=09$node,=0A+=09'\set=20WATCH_INTERVAL=20-1',=0A+=09= qr/must=20be=20greater=20than=20or=20equal=20to=200\.00/,=0A+=09= 'WATCH_INTERVAL=20variable=20is=20below=20its=20lower=20bound');=0A= +psql_fails_like(=0A+=09$node,=0A+=09'\set=20WATCH_INTERVAL=201000001',=0A= +=09qr/must=20be=20less=20than=20or=20equal=20to=201000000\.00/,=0A+=09= 'WATCH_INTERVAL=20variable=20is=20above=20its=20upper=20bound');=0A=20= psql_like($node,=20'\echo=20:WATCH_INTERVAL',=0A=20=09qr/^2$/m,=20= 'WATCH_INTERVAL=20variable=20was=20not=20altered');=0A=20=0Adiff=20--git=20= a/src/bin/psql/variables.c=20b/src/bin/psql/variables.c=0Aindex=20= 8060f2959cc..2c9a191a69b=20100644=0A---=20a/src/bin/psql/variables.c=0A= +++=20b/src/bin/psql/variables.c=0A@@=20-215,14=20+215,14=20@@=20= ParseVariableDouble(const=20char=20*value,=20const=20char=20*name,=20= double=20*result,=20double=0A=20=09=09if=20(dblval=20<=20min)=0A=20=09=09= {=0A=20=09=09=09if=20(name)=0A-=09=09=09=09pg_log_error("invalid=20value=20= \"%s\"=20for=20variable=20\"%s\":=20must=20be=20greater=20than=20%.2f",=0A= +=09=09=09=09pg_log_error("invalid=20value=20\"%s\"=20for=20variable=20= \"%s\":=20must=20be=20greater=20than=20or=20equal=20to=20%.2f",=0A=20=09=09= =09=09=09=09=09=20value,=20name,=20min);=0A=20=09=09=09return=20false;=0A= =20=09=09}=0A=20=09=09else=20if=20(dblval=20>=20max)=0A=20=09=09{=0A=20=09= =09=09if=20(name)=0A-=09=09=09=09pg_log_error("invalid=20value=20\"%s\"=20= for=20variable=20\"%s\":=20must=20be=20less=20than=20%.2f",=0A+=09=09=09=09= pg_log_error("invalid=20value=20\"%s\"=20for=20variable=20\"%s\":=20must=20= be=20less=20than=20or=20equal=20to=20%.2f",=0A=20=09=09=09=09=09=09=09=20= value,=20name,=20max);=0A=20=09=09=09return=20false;=0A=20=09=09}=0Adiff=20= --git=20a/src/test/regress/expected/subscription.out=20= b/src/test/regress/expected/subscription.out=0Aindex=20= 681dc66dca6..d2ca288f9e2=20100644=0A---=20= a/src/test/regress/expected/subscription.out=0A+++=20= b/src/test/regress/expected/subscription.out=0A@@=20-294,6=20+294,18=20= @@=20ALTER=20SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20= '0/12345');=0A=20=0A=20--=20ok=20-=20with=20lsn=20=3D=20NONE=0A=20ALTER=20= SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20NONE);=0A+--=20fail=20= -=20LSN=20must=20not=20be=20behind=20the=20replication=20origin=0A+RESET=20= SESSION=20AUTHORIZATION;=0A+SELECT=20pg_replication_origin_advance(=0A+=20= =20=20=20'pg_'=20||=20(SELECT=20oid=20FROM=20pg_subscription=20WHERE=20= subname=20=3D=20'regress_testsub'),=0A+=20=20=20=20'0/12346')=20\gset=0A= +--=20ok=20-=20LSN=20equal=20to=20the=20replication=20origin=20is=20= accepted=0A+ALTER=20SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20= '0/12346');=0A+ALTER=20SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20= NONE);=0A+--=20fail=20-=20LSN=20behind=20the=20replication=20origin=20is=20= rejected=0A+ALTER=20SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20= '0/12345');=0A+ERROR:=20=20skip=20WAL=20location=20(LSN=200/00012345)=20= must=20be=20greater=20than=20or=20equal=20to=20origin=20LSN=200/00012346=0A= +SET=20SESSION=20AUTHORIZATION=20regress_subscription_user;=0A=20--=20= fail=0A=20ALTER=20SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20= '0/0');=0A=20ERROR:=20=20invalid=20WAL=20location=20(LSN):=200/0=0Adiff=20= --git=20a/src/test/regress/sql/subscription.sql=20= b/src/test/regress/sql/subscription.sql=0Aindex=20= cfeebaf9302..0ac491a70b6=20100644=0A---=20= a/src/test/regress/sql/subscription.sql=0A+++=20= b/src/test/regress/sql/subscription.sql=0A@@=20-231,6=20+231,18=20@@=20= ALTER=20SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20'0/12345');=0A= =20--=20ok=20-=20with=20lsn=20=3D=20NONE=0A=20ALTER=20SUBSCRIPTION=20= regress_testsub=20SKIP=20(lsn=20=3D=20NONE);=0A=20=0A+--=20fail=20-=20= LSN=20must=20not=20be=20behind=20the=20replication=20origin=0A+RESET=20= SESSION=20AUTHORIZATION;=0A+SELECT=20pg_replication_origin_advance(=0A+=20= =20=20=20'pg_'=20||=20(SELECT=20oid=20FROM=20pg_subscription=20WHERE=20= subname=20=3D=20'regress_testsub'),=0A+=20=20=20=20'0/12346')=20\gset=0A= +--=20ok=20-=20LSN=20equal=20to=20the=20replication=20origin=20is=20= accepted=0A+ALTER=20SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20= '0/12346');=0A+ALTER=20SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20= NONE);=0A+--=20fail=20-=20LSN=20behind=20the=20replication=20origin=20is=20= rejected=0A+ALTER=20SUBSCRIPTION=20regress_testsub=20SKIP=20(lsn=20=3D=20= '0/12345');=0A+SET=20SESSION=20AUTHORIZATION=20= regress_subscription_user;=0A+=0A=20--=20fail=0A=20ALTER=20SUBSCRIPTION=20= regress_testsub=20SKIP=20(lsn=20=3D=20'0/0');=0A=20=0A--=20=0A2.50.1=20= (Apple=20Git-155)=0A=0A= --Apple-Mail=_721EFD83-D344-4FA7-A873-4068A2B74AC5--