@@ -1380,10 +1380,7 @@ pqAppendCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry)
1380
1380
* state, we don't have to do anything.
1381
1381
*/
1382
1382
if (conn -> asyncStatus == PGASYNC_IDLE )
1383
- {
1384
- pqClearConnErrorState (conn );
1385
1383
pqPipelineProcessQueue (conn );
1386
- }
1387
1384
break ;
1388
1385
}
1389
1386
}
@@ -1730,8 +1727,10 @@ PQsendQueryStart(PGconn *conn, bool newQuery)
1730
1727
1731
1728
/*
1732
1729
* If this is the beginning of a query cycle, reset the error state.
1730
+ * However, in pipeline mode with something already queued, the error
1731
+ * buffer belongs to that command and we shouldn't clear it.
1733
1732
*/
1734
- if (newQuery )
1733
+ if (newQuery && conn -> cmd_queue_head == NULL )
1735
1734
pqClearConnErrorState (conn );
1736
1735
1737
1736
/* Don't try to send if we know there's no live connection. */
@@ -2149,11 +2148,8 @@ PQgetResult(PGconn *conn)
2149
2148
/*
2150
2149
* We're about to return the NULL that terminates the round of
2151
2150
* results from the current query; prepare to send the results
2152
- * of the next query when we're called next. Also, since this
2153
- * is the start of the results of the next query, clear any
2154
- * prior error message.
2151
+ * of the next query when we're called next.
2155
2152
*/
2156
- pqClearConnErrorState (conn );
2157
2153
pqPipelineProcessQueue (conn );
2158
2154
}
2159
2155
break ;
@@ -2362,18 +2358,21 @@ PQexecStart(PGconn *conn)
2362
2358
if (!conn )
2363
2359
return false;
2364
2360
2361
+ /*
2362
+ * Since this is the beginning of a query cycle, reset the error state.
2363
+ * However, in pipeline mode with something already queued, the error
2364
+ * buffer belongs to that command and we shouldn't clear it.
2365
+ */
2366
+ if (conn -> cmd_queue_head == NULL )
2367
+ pqClearConnErrorState (conn );
2368
+
2365
2369
if (conn -> pipelineStatus != PQ_PIPELINE_OFF )
2366
2370
{
2367
2371
appendPQExpBufferStr (& conn -> errorMessage ,
2368
2372
libpq_gettext ("synchronous command execution functions are not allowed in pipeline mode\n" ));
2369
2373
return false;
2370
2374
}
2371
2375
2372
- /*
2373
- * Since this is the beginning of a query cycle, reset the error state.
2374
- */
2375
- pqClearConnErrorState (conn );
2376
-
2377
2376
/*
2378
2377
* Silently discard any prior query result that application didn't eat.
2379
2378
* This is probably poor design, but it's here for backward compatibility.
@@ -2928,8 +2927,11 @@ PQfn(PGconn *conn,
2928
2927
2929
2928
/*
2930
2929
* Since this is the beginning of a query cycle, reset the error state.
2930
+ * However, in pipeline mode with something already queued, the error
2931
+ * buffer belongs to that command and we shouldn't clear it.
2931
2932
*/
2932
- pqClearConnErrorState (conn );
2933
+ if (conn -> cmd_queue_head == NULL )
2934
+ pqClearConnErrorState (conn );
2933
2935
2934
2936
if (conn -> pipelineStatus != PQ_PIPELINE_OFF )
2935
2937
{
@@ -3099,6 +3101,12 @@ pqPipelineProcessQueue(PGconn *conn)
3099
3101
conn -> cmd_queue_head == NULL )
3100
3102
return ;
3101
3103
3104
+ /*
3105
+ * Reset the error state. This and the next couple of steps correspond to
3106
+ * what PQsendQueryStart didn't do for this query.
3107
+ */
3108
+ pqClearConnErrorState (conn );
3109
+
3102
3110
/* Initialize async result-accumulation state */
3103
3111
pqClearAsyncResult (conn );
3104
3112
@@ -3809,9 +3817,11 @@ PQsetnonblocking(PGconn *conn, int arg)
3809
3817
* behavior. this is ok because either they are making a transition _from_
3810
3818
* or _to_ blocking mode, either way we can block them.
3811
3819
*
3812
- * Clear error state in case pqFlush adds to it.
3820
+ * Clear error state in case pqFlush adds to it, unless we're actively
3821
+ * pipelining, in which case it seems best not to.
3813
3822
*/
3814
- pqClearConnErrorState (conn );
3823
+ if (conn -> cmd_queue_head == NULL )
3824
+ pqClearConnErrorState (conn );
3815
3825
3816
3826
/* if we are going from blocking to non-blocking flush here */
3817
3827
if (pqFlush (conn ))
@@ -4003,7 +4013,8 @@ PQescapeStringConn(PGconn *conn,
4003
4013
return 0 ;
4004
4014
}
4005
4015
4006
- pqClearConnErrorState (conn );
4016
+ if (conn -> cmd_queue_head == NULL )
4017
+ pqClearConnErrorState (conn );
4007
4018
4008
4019
return PQescapeStringInternal (conn , to , from , length , error ,
4009
4020
conn -> client_encoding ,
@@ -4041,7 +4052,8 @@ PQescapeInternal(PGconn *conn, const char *str, size_t len, bool as_ident)
4041
4052
if (!conn )
4042
4053
return NULL ;
4043
4054
4044
- pqClearConnErrorState (conn );
4055
+ if (conn -> cmd_queue_head == NULL )
4056
+ pqClearConnErrorState (conn );
4045
4057
4046
4058
/* Scan the string for characters that must be escaped. */
4047
4059
for (s = str ; (s - str ) < len && * s != '\0' ; ++ s )
@@ -4306,7 +4318,8 @@ PQescapeByteaConn(PGconn *conn,
4306
4318
if (!conn )
4307
4319
return NULL ;
4308
4320
4309
- pqClearConnErrorState (conn );
4321
+ if (conn -> cmd_queue_head == NULL )
4322
+ pqClearConnErrorState (conn );
4310
4323
4311
4324
return PQescapeByteaInternal (conn , from , from_length , to_length ,
4312
4325
conn -> std_strings ,
0 commit comments