Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m0pYs-0003Av-SY for pgsql-hackers@arkaria.postgresql.org; Tue, 06 Jul 2021 18:12:47 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1m0pYr-0000w4-An for pgsql-hackers@arkaria.postgresql.org; Tue, 06 Jul 2021 18:12:45 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m0pYq-0000vv-Vf for pgsql-hackers@lists.postgresql.org; Tue, 06 Jul 2021 18:12:45 +0000 Received: from mail-pf1-x42e.google.com ([2607:f8b0:4864:20::42e]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1m0pYm-0002Rw-09 for pgsql-hackers@lists.postgresql.org; Tue, 06 Jul 2021 18:12:43 +0000 Received: by mail-pf1-x42e.google.com with SMTP id f20so12335431pfa.1 for ; Tue, 06 Jul 2021 11:12:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :content-transfer-encoding:in-reply-to; bh=peQUg8T8Z3s4LJhkQuQ+Ci4gFh9ZmVqNFnLvosou3GA=; b=dkFha8xVFkj7kPE0ju41Pdq8MsGr4daHYr9OqZP7MBzOlNFz3k2/NmQ8HMESJMjwog sEZdxsMfmpB9EwWW4H1Js16IX8tvMXtv/SS/Aq/T2Y8ETFfhvq8B16xMKNjqEwO0BRoc GJA+Zyi5R0ML9ZiptkbbpwUsPmWsZJSqcFAxzlRfisa+ibT8QTHce/INMFyvgp6NBB2U ENygp/ow0C23ifyJZNOrJv9JEMCCBiUcDn/UYWQgnTNkcfoSTEJ+uewzGfap/x1HX1XI hpZIcLOYjN1R3ERrZ5SFAHaDLryxshqlmnZQw2l3fu0PIzMNQXNf4cItTPXHe2kH44DV 9ndQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=peQUg8T8Z3s4LJhkQuQ+Ci4gFh9ZmVqNFnLvosou3GA=; b=XGSMHqPZxJwCxcPk898gmISrgM5ZmWeeGR2AyCOIYcv9XD0GZlWPl5oE5FmBXlHecI pzDwrgwkOwfEqh63OSqcnymC86Y8VXbycezC6EVd4CpdyZHJi+SLaIZ78xxCV6wIfKDL W8hQkzFbxWqutHMTH+MzD2kTlWnbLAEv6D3TLS9zVnYri14OfkqbMwFeXlkEQ3kCfZG3 5AoyeFbGiLrDm93kjLVzuQPzMblnwrWJ3OUiLb4GTG3H4HsVYyRClPLSNje3eI55cgbd kC2YyOroqzTxQFyUZe8nE/85YbL6DwHS0uuydXY5uYGCMXhNCu/hl4sWjDEXsXlbGULs LO+A== X-Gm-Message-State: AOAM532hK2TI1h2l7DuYZ2McHk9mTPAE41QlvRkhS04civ76xegLEuhf /sE5c4s8pP6QHxMvJfH9SpK6Yw== X-Google-Smtp-Source: ABdhPJyjhgTJoog//GknbmCe8qb7LXFY9aipgc3R10BheCEUtxBBNkOkpEP2fXnnDHqAe1ocQuBzJw== X-Received: by 2002:a63:d211:: with SMTP id a17mr22094759pgg.265.1625595158916; Tue, 06 Jul 2021 11:12:38 -0700 (PDT) Received: from perhan.alvh.no-ip.org ([190.95.19.95]) by smtp.gmail.com with ESMTPSA id z3sm19481898pgl.77.2021.07.06.11.12.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jul 2021 11:12:37 -0700 (PDT) Received: by perhan.alvh.no-ip.org (Postfix, from userid 1000) id 21E162A2245; Tue, 6 Jul 2021 13:47:36 -0400 (-04) Date: Tue, 6 Jul 2021 13:47:36 -0400 From: Alvaro Herrera To: Boris Kolpackov Cc: pgsql-hackers@lists.postgresql.org Subject: Re: Pipeline mode and PQpipelineSync() Message-ID: <202107061747.tlss7f2somqf@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="wflx26a54bowwq3c" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --wflx26a54bowwq3c Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2021-Jul-06, Boris Kolpackov wrote: > Alvaro Herrera writes: > > > Ah, yes it does. I can reproduce this now. I thought PQconsumeInput > > was sufficient, but it's not: you have to have the PQgetResult in there > > too. Looking ... > > Any progress on fixing this? Can you please try with this patch? Thanks -- Álvaro Herrera 39°49'30"S 73°17'W — https://www.EnterpriseDB.com/ --wflx26a54bowwq3c Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="0001-fix-libpq-state-machine.patch" From c84b66821249631ba1654b22866ca54c49f238c4 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Tue, 6 Jul 2021 12:46:42 -0400 Subject: [PATCH] fix libpq state machine --- src/interfaces/libpq/fe-exec.c | 46 ++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index b13ddab393..1295a417c1 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -1223,7 +1223,8 @@ pqAllocCmdQueueEntry(PGconn *conn) /* * pqAppendCmdQueueEntry - * Append a caller-allocated command queue entry to the queue. + * Append a caller-allocated command queue entry to the queue, and update + * conn->asyncStatus as needed to account for it. * * The query itself must already have been put in the output buffer by the * caller. @@ -1239,6 +1240,33 @@ pqAppendCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry) conn->cmd_queue_tail->next = entry; conn->cmd_queue_tail = entry; + + switch (conn->pipelineStatus) + { + case PQ_PIPELINE_OFF: + case PQ_PIPELINE_ON: + /* + * If there's a result ready to be consumed, let it be so (that is, + * don't change away from READY or READY_MORE); otherwise we wait + * for some result to arrive from the server. + */ + if (conn->asyncStatus == PGASYNC_IDLE) + conn->asyncStatus = PGASYNC_BUSY; + break; + + /* + * If in aborted pipeline state, we don't expect anything from the + * server, so we have to let PQgetResult consume from the aborted + * queue right away. + */ + case PQ_PIPELINE_ABORTED: + if (conn->asyncStatus == PGASYNC_IDLE) + { + resetPQExpBuffer(&conn->errorMessage); + pqPipelineProcessQueue(conn); + } + break; + } } /* @@ -1375,7 +1403,6 @@ PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery) /* OK, it's launched! */ pqAppendCmdQueueEntry(conn, entry); - conn->asyncStatus = PGASYNC_BUSY; return 1; sendFailed: @@ -1510,10 +1537,6 @@ PQsendPrepare(PGconn *conn, /* if insufficient memory, query just winds up NULL */ entry->query = strdup(query); - pqAppendCmdQueueEntry(conn, entry); - - conn->asyncStatus = PGASYNC_BUSY; - /* * Give the data a push (in pipeline mode, only if we're past the size * threshold). In nonblock mode, don't complain if we're unable to send @@ -1522,6 +1545,8 @@ PQsendPrepare(PGconn *conn, if (pqPipelineFlush(conn) < 0) goto sendFailed; + pqAppendCmdQueueEntry(conn, entry); + return 1; sendFailed: @@ -1815,7 +1840,7 @@ PQsendQueryGuts(PGconn *conn, /* OK, it's launched! */ pqAppendCmdQueueEntry(conn, entry); - conn->asyncStatus = PGASYNC_BUSY; + return 1; sendFailed: @@ -2445,7 +2470,7 @@ PQsendDescribe(PGconn *conn, char desc_type, const char *desc_target) /* OK, it's launched! */ pqAppendCmdQueueEntry(conn, entry); - conn->asyncStatus = PGASYNC_BUSY; + return 1; sendFailed: @@ -3072,15 +3097,14 @@ PQpipelineSync(PGconn *conn) pqPutMsgEnd(conn) < 0) goto sendFailed; - pqAppendCmdQueueEntry(conn, entry); - /* * Give the data a push. In nonblock mode, don't complain if we're unable * to send it all; PQgetResult() will do any additional flushing needed. */ if (PQflush(conn) < 0) goto sendFailed; - conn->asyncStatus = PGASYNC_BUSY; + + pqAppendCmdQueueEntry(conn, entry); return 1; -- 2.20.1 --wflx26a54bowwq3c--