6060
6161static void pgsql_stmt_cancel (pdo_pgsql_stmt * S )
6262{
63+ if (S -> result ) {
64+ PQclear (S -> result );
65+ S -> result = NULL ;
66+ }
67+
6368 if (S -> is_running_unbuffered ) {
6469 PGcancel * cancel = PQgetCancel (S -> H -> server );
6570 char errbuf [256 ];
6671 PQcancel (cancel , errbuf , 256 );
6772 PQfreeCancel (cancel );
6873 S -> is_running_unbuffered = false;
6974 }
75+
76+ if (S -> is_unbuffered ) {
77+ /* https://postgresql.org/docs/current/libpq-async.html:
78+ * "PQsendQuery cannot be called again until PQgetResult has returned NULL"
79+ */
80+ while ((S -> result = PQgetResult (S -> H -> server ))) {
81+ PQclear (S -> result );
82+ S -> result = NULL ;
83+ }
84+ }
7085}
7186
7287static int pgsql_stmt_dtor (pdo_stmt_t * stmt )
@@ -76,12 +91,6 @@ static int pgsql_stmt_dtor(pdo_stmt_t *stmt)
7691 && IS_OBJ_VALID (EG (objects_store ).object_buckets [Z_OBJ_HANDLE (stmt -> database_object_handle )])
7792 && !(OBJ_FLAGS (Z_OBJ (stmt -> database_object_handle )) & IS_OBJ_FREE_CALLED );
7893
79- if (S -> result ) {
80- /* free the resource */
81- PQclear (S -> result );
82- S -> result = NULL ;
83- }
84-
8594 if (S -> stmt_name ) {
8695 if (S -> is_prepared && server_obj_usable ) {
8796 pdo_pgsql_db_handle * H = S -> H ;
@@ -156,10 +165,6 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt)
156165
157166 /* ensure that we free any previous unfetched results */
158167 pgsql_stmt_cancel (S );
159- if (S -> result ) {
160- PQclear (S -> result );
161- S -> result = NULL ;
162- }
163168
164169 S -> current_row = 0 ;
165170
@@ -541,10 +546,10 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt,
541546 S -> current_row = 0 ;
542547
543548 if (!stmt -> row_count ) {
544- /* libpq requires looping until getResult returns null */
545- PQgetResult (S -> H -> server );
546549 /* @todo receiving a result here is unexpected and should throw an error */
547550 S -> is_running_unbuffered = false;
551+ /* libpq requires looping until getResult returns null */
552+ pgsql_stmt_cancel (S );
548553 }
549554 }
550555 if (S -> current_row < stmt -> row_count ) {
0 commit comments