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.94.2) (envelope-from ) id 1rqLrw-00Bu4Y-AX for pgsql-jdbc@arkaria.postgresql.org; Fri, 29 Mar 2024 23:42:44 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rqLru-005c1n-TB for pgsql-jdbc@arkaria.postgresql.org; Fri, 29 Mar 2024 23:42:42 +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.94.2) (envelope-from ) id 1rqLru-005c1M-Kb for pgsql-jdbc@lists.postgresql.org; Fri, 29 Mar 2024 23:42:42 +0000 Received: from mail-oo1-xc36.google.com ([2607:f8b0:4864:20::c36]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rqLrr-007MoG-CP for pgsql-jdbc@lists.postgresql.org; Fri, 29 Mar 2024 23:42:41 +0000 Received: by mail-oo1-xc36.google.com with SMTP id 006d021491bc7-5a522ae3747so1060801eaf.1 for ; Fri, 29 Mar 2024 16:42:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711755757; x=1712360557; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=3vank1LO1A1Hq2Ngja1uoQbtXCE8FwbnojBOgFPsHlI=; b=XafFcegH2XXyRRfdZjqA3XLKs6kjl4bnwzoD67COTUjDxiNa209EXDZSC75wqEjnfy RWYoioCEPxJlcndQD2qUZ9eZW5LNi+RqzQwjtKz2xWpfNEWOA3nAujLHjdEszkAihx/E 7QJDznG8k+i7czzS7f3n3WPJkaAMbPnXQLv0SoVo4SVsMk4FsDbPFJj8xCHTQXJQdYEL 2VG5VpAdXZEWBwWO0mdAN9ac4LMU4nQBa3aG1nnDW9xAACW/ClHbnUWLfYIQnrpvRgNq 8wBAc3q74Sw9QElJQtt7O6rAxv6OVqMgakRxQUD2c1A7CBlgYV0a0mZMCxn0kFIsklGs jMJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711755757; x=1712360557; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=3vank1LO1A1Hq2Ngja1uoQbtXCE8FwbnojBOgFPsHlI=; b=quDv9kx+exil/7lrMkIZaqG97WWfKcY9O5Wp9Wg5BfG9e+hgyNwX30sctoqivqTpl2 mINRFNa9Y5w94Jl02RAEEZ+6RCaxe0rCNUE2TYFCuM+5HqGc7EEux5HQWV7Q0/kNo2Il z+O2rDW7zzOp/Q9lXKNitz6YLL5uvhXiWLffRBSGdi/lAVCZI+B9WXSMcYrA4yItfasi +3Rc+69LFi+Ly1uGYv7CIzFAAtnWMX6PPEN5XA+QS3qGIwnBQ6cDQBt+YrLXQo3D1D3T Gvslz4NgjOyV0wMvq2ByhM5dnUabw2x6mfq5HWOeMT5xmnTHiOngFCaH3IoFUWzjn13f RxNw== X-Forwarded-Encrypted: i=1; AJvYcCW3SjzotrIBwxjwRiykbCfkQBgTPlp8vc2/XD/lyMBO+5xKezem4nQBOQeD0iZb9gqEaHRq760c6exDi8QzwaaZj2QMRBWUjLTKGHmqJ/9G X-Gm-Message-State: AOJu0YxDqgFW4ff+QZCvDhK5p5uUAc/XKrGAOlUz8Cdggxnb9TeY27Cs UJMkIUjuzjfvH8S+CQmCQeynDtZZYk3eP58xdkFamqptdw4NvcAz5RVmmHroUktuV3sL8Q9TVRO fChkloZ2+xAbT8nO4wrlminG8Xxr/2F8zKuW0PA== X-Google-Smtp-Source: AGHT+IGgtNpGksSr/Sw9KJRFBt0faoacl/ortBp8gx9mtxlr9qOdhKhzgvyPVTjz4DM7dWxqmDT65JXla+PbIOyeyJQ= X-Received: by 2002:a4a:d28c:0:b0:5a6:27c:7607 with SMTP id h12-20020a4ad28c000000b005a6027c7607mr1497128oos.1.1711755756895; Fri, 29 Mar 2024 16:42:36 -0700 (PDT) MIME-Version: 1.0 References: <60ab210d02748b5da813007ab2504606d0fecaa1.camel@cybertec.at> <2950.1711729266@sss.pgh.pa.us> In-Reply-To: From: James Pang Date: Sat, 30 Mar 2024 07:42:26 +0800 Message-ID: Subject: Re: cached plan must not change result type To: Dave Cramer Cc: Tom Lane , pgsql-jdbc@lists.postgresql.org, Laurenz Albe Content-Type: multipart/alternative; boundary="000000000000d505210614d531dc" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000d505210614d531dc Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable we did DDL "alter table ... alter column increase varchar(512) to varchar(1024)", after that done, hours later, new query select on this table still failed this error. From this https://jdbc.postgresql.org/documentation/server-prepare/#re-execution-of-f= ailed-statements , looks like pgjdbc try to handle this exception and retry, but in our case, it did not happen. Could you direct me how to make this retry work? we only want new transactions,queries work that after the DDL changes. protected boolean willHealViaReparse(SQLException e) { if (e =3D=3D null || e.getSQLState() =3D=3D null) { return false; } // "prepared statement \"S_2\" does not exist" if (PSQLState.INVALID_SQL_STATEMENT_NAME.getState().equals(e.getSQLState())) { return true; } if (!PSQLState.NOT_IMPLEMENTED.getState().equals(e.getSQLState())) { return false; } if (!(e instanceof PSQLException)) { return false; } PSQLException pe =3D (PSQLException) e; ServerErrorMessage serverErrorMessage =3D pe.getServerErrorMessage(); if (serverErrorMessage =3D=3D null) { return false; } // "cached plan must not change result type" String routine =3D serverErrorMessage.getRoutine(); return "RevalidateCachedQuery".equals(routine) // 9.2+ || "RevalidateCachedPlan".equals(routine); // <=3D 9.1 } Thanks, James Dave Cramer =E6=96=BC 2024=E5=B9=B43=E6=9C=8830= =E6=97=A5=E9=80=B1=E5=85=AD =E4=B8=8A=E5=8D=8812:48=E5=AF=AB=E9=81=93=EF=BC= =9A > > > On Fri, 29 Mar 2024 at 12:21, Tom Lane wrote: > >> Dave Cramer writes: >> > This is really an issue that needs to be solved in the backend. The >> error >> > is coming from PostgreSQL and what should happen is that when you alte= r >> a >> > table that a server prepared statement relies on the backend should >> send a >> > message to tell us that all of the prepared statements that rely on ar= e >> now >> > invalid and we can reprepare them. >> >> This is something that can't change without a wire protocol change. >> There is nothing in the protocol that allows the backend to send out >> a message like "oh, that Describe I sent you awhile back? It might >> be a lie now" at random times. > > > I agree, but it's a known issue. I'm just pointing that it would be nice > to have. > We'd have to figure out the details. > > >> Also, what do you want to do about >> race conditions --- that is, what if you fire off an Execute only >> to find that one of those messages was already in flight to you? > > >> A non-racy way to handle it might be for Bind/Execute to refuse to >> run the query if its output has changed since the last Describe, >> which we could check after acquiring table locks during Bind. >> But we'd want to define "refuse" in a way that doesn't abort the >> transaction, and that's a concept that doesn't exist in the >> protocol at all. >> > > This actually sounds like the best option as we wouldn't have to fire off > a message, just refuse to run the Execute in a way that doesn't abort the > transaction. > > Dave > --000000000000d505210614d531dc Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
=C2=A0 =C2=A0we did DDL "alter table ... alter column= increase varchar(512) to varchar(1024)", after that done, hours later= , new query select on this table still failed this error.=C2=A0 From this= =C2=A0https://jdbc.postgresql.org/documentatio= n/server-prepare/#re-execution-of-failed-statements , looks like pgjdbc= try to handle this exception and retry, but in our case, it did not happen= .=C2=A0 Could you direct me how to make this retry work? we only want new t= ransactions,queries=C2=A0work that after the DDL changes.=C2=A0

protected boolean willHealViaReparse(SQLException e) {
=C2=A0 =C2=A0 i= f (e =3D=3D null || e.getSQLState() =3D=3D null) {
=C2=A0 =C2=A0 =C2=A0 = return false;
=C2=A0 =C2=A0 }

=C2=A0 =C2=A0 // "prepared sta= tement \"S_2\" does not exist"
=C2=A0 =C2=A0 if (PSQLStat= e.INVALID_SQL_STATEMENT_NAME.getState().equals(e.getSQLState())) {
=C2= =A0 =C2=A0 =C2=A0 return true;
=C2=A0 =C2=A0 }
=C2=A0 =C2=A0 if (!PSQ= LState.NOT_IMPLEMENTED.getState().equals(e.getSQLState())) {
=C2=A0 =C2= =A0 =C2=A0 return false;
=C2=A0 =C2=A0 }

=C2=A0 =C2=A0 if (!(e in= stanceof PSQLException)) {
=C2=A0 =C2=A0 =C2=A0 return false;
=C2=A0 = =C2=A0 }

=C2=A0 =C2=A0 PSQLException pe =3D (PSQLException) e;
=C2=A0 =C2=A0 ServerErrorMessage serverErrorMessage =3D pe.getServerError= Message();
=C2=A0 =C2=A0 if (serverErrorMessage =3D=3D null) {
=C2=A0= =C2=A0 =C2=A0 return false;
=C2=A0 =C2=A0 }
=C2=A0 =C2=A0 // "c= ached plan must not change result type"
=C2=A0 =C2=A0 String routin= e =3D serverErrorMessage.getRoutine();
=C2=A0 =C2=A0 return "Revali= dateCachedQuery".equals(routine) // 9.2+
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 || "RevalidateCachedPlan".equals(routine); // <=3D 9.1
= =C2=A0 }

Thanks,

James
Dave Cramer <davecramer@postgres.rocks> =E6=96=BC 2024= =E5=B9=B43=E6=9C=8830=E6=97=A5=E9=80=B1=E5=85=AD =E4=B8=8A=E5=8D=8812:48=E5= =AF=AB=E9=81=93=EF=BC=9A


On Fri, 29 Mar 2024 at 12:= 21, Tom Lane <tgl= @sss.pgh.pa.us> wrote:
Dave Cramer <davecramer@postgres.rocks> writes:
> This is really an issue that needs to be solved in the backend. The er= ror
> is coming from PostgreSQL and what should happen is that when you alte= r a
> table that a server prepared statement relies on the backend should se= nd a
> message to tell us that all of the prepared statements that rely on ar= e now
> invalid and we can reprepare them.

This is something that can't change without a wire protocol change.
There is nothing in the protocol that allows the backend to send out
a message like "oh, that Describe I sent you awhile back?=C2=A0 It mig= ht
be a lie now" at random times.=C2=A0

= I agree, but it's a known=C2=A0issue. I'm just pointing that it wou= ld be nice to have.
We'd have to figure out the details.
=C2=A0
Also, w= hat do you want to do about
race conditions --- that is, what if you fire off an Execute only
to find that one of those messages was already in flight to you?

A non-racy way to handle it might be for Bind/Execute to refuse to
run the query if its output has changed since the last Describe,
which we could check after acquiring table locks during Bind.
But we'd want to define "refuse" in a way that doesn't ab= ort the
transaction, and that's a concept that doesn't exist in the
protocol at all.

This actually sounds l= ike the best option as we wouldn't have to fire off a message, just ref= use to run the Execute in a way that doesn't abort the transaction.

Dave
--000000000000d505210614d531dc--