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 1w31cu-000pJa-0B for pgsql-hackers@arkaria.postgresql.org; Thu, 19 Mar 2026 00:52:40 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w31cs-00FhUS-1z for pgsql-hackers@arkaria.postgresql.org; Thu, 19 Mar 2026 00:52:38 +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 1w31cs-00FhUH-10 for pgsql-hackers@lists.postgresql.org; Thu, 19 Mar 2026 00:52:38 +0000 Received: from mail-ej1-x62a.google.com ([2a00:1450:4864:20::62a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w31cp-000000012MW-21D2 for pgsql-hackers@lists.postgresql.org; Thu, 19 Mar 2026 00:52:38 +0000 Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-b97b30fa5e5so62733466b.3 for ; Wed, 18 Mar 2026 17:52:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1773881554; cv=none; d=google.com; s=arc-20240605; b=UeLiTZ7nKpOpUgEOGma8l+afpzcOayzWIE+NUXAM7LK8I3H1hTBlGoOO1BDvl4H5vu eVPOxTkaOq9RCRcZWHjJ5JY1bhD06YjeOe8JfDaCpDhf5czyGMXW3seFmqQMm51iiWmV q2xjHWMMC1aNMfcRvcoBmrsq521gftDJzpygLHLyYF922wUEYItETgy9NBHiywZtx8PQ JuaVJeFdsnL6rWHnr5s9LbvpAjDInNdOr2Z11KyOBG8pimLFqSb+/9ww+r5AYJWRedvC CpDZGQV5QoChGkKbdhJOIYXin7AmHV3fw6445QPZCJAJ7xxfivMW0SUiZblyg86Tq+AN gZwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=MmgxL6oTP9eL4jq/7v47mDUSi3hs0VqQAoeDaRL6lhY=; fh=FgmKfO8VE03kmcDsXK+jJyjcqEiHNn+tGZ25hw3L++Q=; b=NlS89yQOzSnQTzG3BiKDZau5T4Suvd3gfT6wSZS6CkvKfsKFOTnACh0ncBP0ASXCG3 l/SnFXMY5Qh28eckEC/BQ59IxcXly/TC+gfSlwg+NOzxZpDnXg6CBvR0UKtUTxMDyvQR OVOCCuCT8NazxGr7fYNN6SOMwNdkpmvqVOQa4J35UI0GhY9YeuZ8ybKKsGcMgAcIGIvs y7i9Mqx0xUVM/zLZs/8SCpC54/eE7VLJtwo+WE0Zxz/AtB5p47v+k89cW6LviUT+I5t2 aAYrVTcvpaHI0s686RHucahKrn5kxcR+2r1oKl7tF/bq0Uq0UhSEXCAW4F3V0emHS3cx //fw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773881554; x=1774486354; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=MmgxL6oTP9eL4jq/7v47mDUSi3hs0VqQAoeDaRL6lhY=; b=KpjqPe9hOlEvCwncSJ4W2YHtsmpXI2xwo1e5GcQjknPszU9WicESPldcr1AFjwO/qC UZt6ufV3WEO4eVTDs/x5wS/aktMKr2UaF5xGUnLQ9UX+MaeQF2z8qw2wUwwpY6G/tBKY hEuEzgyUJpczVnrd+v/i6v4CL445xsR+hEhuxAcAe2/TziCj7rRAjNY+dtJyN9uG1rhB I+EnL3ZUqeBAJ3B6vyl7MWsDs2tFhGD9GFpNVSBlGgW/PzgUlsU9FMy+r6PplnQGpjYa Yt7oId1nrOCoF+6A4l8F3SddwGHvP+CkM52GQ6aKBP5eggb23ucoapKYE1epREGgtJO0 6YtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773881554; x=1774486354; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=MmgxL6oTP9eL4jq/7v47mDUSi3hs0VqQAoeDaRL6lhY=; b=k7iYsfCUshdwThfe7FljNOxBclU1Oia4zVpuZr4aVi5Y0X9/ihol7ILq6f8OMQM0V+ nbZ4bjXYMxZxMW+xlZate1A1mRYYmfo224WbbB4F/A/uX1lScFns5RIL0w1eKNR4CqhM hFQF8FcIIu3b2nf6zqY6Q9LYBWZHmL2AGCyAxfMZQFD2bcG/TN1hFqryyeTB1MVEUcIo 2D+YSQIMrpUHMoiDDSA11CAo680RUCuRt4dbWTWs8RLuF9qQJcixlYOP6EJruDBxHl+v dKXSTWVDJHexXPyJNhfcEcsMtU+c/C74FFRbPhixcBWyL6dZzlxd8G1ucthSBXw6VDD7 j6XQ== X-Forwarded-Encrypted: i=1; AJvYcCXzjb2uhkpy6kvucp45/P5g8cSlNe0WQRu25/hYedOj8PDX467NHTgxUGIYTMT2JX8k3nIzlBR/cQvDgwEJ@lists.postgresql.org X-Gm-Message-State: AOJu0Yz+5iD4LLgz/er9acUI+Z1jVV/d/yWNeWIhIf3XZvdsk9vnKQ0u oSNDe1L1QvKn5+JIFdalxuV1lQ1KpBVLE95H5fXUIz7Pa0QzFoLShzZ8Jf8G12nVAyWIHs554rx rVvwNX9hxzdf2COULsaOcN1GG5Z8uKmk= X-Gm-Gg: ATEYQzyAlRIoMOCOu9pNSd65qJ7BULalbYwh6Jcs8Fo1G4YxluNZGiTOGjlqcgfArnm FSKeo4Y1K8sPJDtAU2FiZcBEYZFZKeC3H1Aajo/I9VvGSw7HUuOdDtC3qdfPDEVRG8kqXkpxuRK kmN4dkC22YdrQwBUQJyOnyy//WYPfqbt4sJWeqFTfZT2eFfpd/GRsrt62/LkKvRKNGS/99fHsXF uBKhkSGNt3qDtijJceb+AzFaGVMcyk9LJ31E6F9kpI0WvUh6rH+XkUa4NiHgiFHMY94MCMaBE65 PsuhR6ko5zMz9LNo X-Received: by 2002:a17:907:60cc:b0:b98:40e:f335 with SMTP id a640c23a62f3a-b98040ef565mr283897666b.34.1773881553685; Wed, 18 Mar 2026 17:52:33 -0700 (PDT) MIME-Version: 1.0 References: <2155281.1767900170@sss.pgh.pa.us> <431484.1768433414@sss.pgh.pa.us> In-Reply-To: From: Sami Imseih Date: Wed, 18 Mar 2026 19:52:22 -0500 X-Gm-Features: AaiRm52m-X5daFLeJMFT6Cn93z2wosvXefNyqwAiR80BGerDhLuVHavYRgxALIs Message-ID: Subject: Re: Proposal to allow setting cursor options on Portals To: Dave Cramer Cc: Hannu Krosing , Robert Haas , Tom Lane , Jelte Fennema-Nio , Jacob Champion , PostgreSQL Hackers , Heikki Linnakangas Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, > Apparently that patch does not apply. Checked this one against master I spent some time today reviewing the discussion and testing the patch. I h= ave some comments: # 1. Remove protocol 3.3 version bump, since we will be using the protocol extension mechanism. Right? + * Test holdable cursors using protocol 3.3 cursor options in Bind message= . + */ +static void +test_holdable_cursor(PGconn *conn) +{ + PGresult *res; + + fprintf(stderr, "holdable cursor... "); + + /* Verify protocol 3.3 */ + if (PQfullProtocolVersion(conn) < 30003) + pg_fatal("protocol 3.3 required, got %d", PQfullProtocolVersion(conn)); + + if (strcmp(value, "3.3") =3D=3D 0) + { + *result =3D PG_PROTOCOL(3, 3); + return true; + } # 2. Handle case where _pq_.holdable_portal is rejected in pqGetNegotiateProtocolVersion3 I was testing on a patched client and unpatched server with a connection string of: "host=3Dlocalhost dbname=3Dpostgres holdable_portal=3D1" I received this error: ``` failed: received invalid protocol negotiation message: server reported an unsupported parameter that was not requested ("_pq_.holdable_portal") ``` The patch only checks _pq_.test_protocol_negotiation (the grease test parameter), but we also need to deal with the rejected extension parameters, rather than fall through to the err= or. @@ -1544,6 +1547,16 @@ pqGetNegotiateProtocolVersion3(PGconn *conn) strcmp(conn->workBuffer.data, "_pq_.test_protocol_negotiation") =3D=3D 0) { found_test_protocol_negotiation =3D true; + continue; + } + + /* + * Handle rejected protocol extensions we requested. Disabl= e the + * corresponding feature so the client doesn't try to use i= t. + */ + if (strcmp(conn->workBuffer.data, "_pq_.holdable_portal") = =3D=3D 0) + { + conn->holdable_portal_enabled =3D false; } else { The above is the change I tested with. This will be the pattern for other protocol extensions that will be added in the future as well. Also, should there also be an API such `PQholdablePortalEnabled` which takes a connection and returns if conn->holdable_portal_enabled is enabled? This lets the client detect at runtime whether the extension was enabled, or disabled because the server rejected it. # 3. Remove PQsendQueryPreparedWithCursorOptions This was also asked earlier [1], but I don't see an answer. Why do we need = this? Wouldn't PQsendBindWithCursorOption() be sufficient? # 4. PQsendBindWithCursorOptions a. Looking at other PQSend patterns, it looking like PQsendBindWithCursorOptions/PQsendQueryPreparedWithCursorOptions are missing `pqAppendCmdQueueEntry(conn, entry)` before returning. b. The last message type sent in `PQsendBindWithCursorOptions` is a describe, so the query class should be PGQUERY_DESCRIBE, right? c. Require a named portal (not just for the HOLD case). An unnamed portal will not be executed in this API, so subsequent calls to this API with an unnamed portal will just overwrite the last one. # 5. Replace hex with constants defined in libpq-fe.h which mirror parsenod= es.h for example 0x0020 =E2=86=92 PQ_CURSOR_OPT_HOLD, etc. Although I am not sure how these could remain in sync with core. # 6. In the test_holdable_cursor, can we use PQsendClosePortal() instead of "CLOSE"? Not for this patch, but it will be good to also have an API for FETCH. [1] [https://www.postgresql.org/message-id/CADK3HH%2B9V58vJzCkgvMwk2fyaCtYw= r-Dv5em7rXzgUiVrnpuFA%40mail.gmail.com] -- Sami Imseih Amazon Web Services (AWS)