5656#define FLOAT8LABEL "float8"
5757#define FLOAT8OID 701
5858
59+ #ifndef HAVE_PQCLOSEPORTAL
60+ static bool pdo_pgsql_try_cmd (const char * cmd , pdo_pgsql_db_handle * H )
61+ {
62+ bool result = false;
63+ char * q = NULL ;
64+ PGresult * res = NULL ;
65+
66+ PGTransactionStatusType status = PQtransactionStatus (H -> server );
67+
68+ switch (status ) {
69+ case PQTRANS_ACTIVE :
70+ case PQTRANS_INERROR :
71+ break ;
72+ case PQTRANS_INTRANS : /* failure must not abort the caller's transaction */
73+ /* PQexec does not run the statements following a failed one */
74+ spprintf (& q , 0 , "SAVEPOINT pdo_pgsql_savepoint; %s; RELEASE SAVEPOINT pdo_pgsql_savepoint;" , cmd );
75+ res = PQexec (H -> server , q );
76+
77+ if (PQresultStatus (res ) != PGRES_COMMAND_OK ) {
78+ PQclear (PQexec (H -> server , "ROLLBACK TO SAVEPOINT pdo_pgsql_savepoint; RELEASE SAVEPOINT pdo_pgsql_savepoint" ));
79+ }
5980
81+ break ;
82+ default :
83+ res = PQexec (H -> server , cmd );
84+ }
85+
86+ if (PQresultStatus (res ) == PGRES_COMMAND_OK ) {
87+ result = true;
88+ }
89+
90+ if (q ) efree (q );
91+ if (res ) PQclear (res );
92+
93+ return result ;
94+ }
95+ #endif
6096
6197static int pgsql_stmt_dtor (pdo_stmt_t * stmt )
6298{
@@ -114,15 +150,16 @@ static int pgsql_stmt_dtor(pdo_stmt_t *stmt)
114150 }
115151
116152 if (S -> cursor_name ) {
117- if (server_obj_usable ) {
153+ if (S -> is_cursor_declared && server_obj_usable ) {
118154 pdo_pgsql_db_handle * H = S -> H ;
119- char * q = NULL ;
120- PGresult * res ;
121-
155+ #ifndef HAVE_PQCLOSEPORTAL
156+ char * q ;
122157 spprintf (& q , 0 , "CLOSE %s" , S -> cursor_name );
123- res = PQexec ( H -> server , q );
158+ pdo_pgsql_try_cmd ( q , H );
124159 efree (q );
125- if (res ) PQclear (res );
160+ #else
161+ PQclear (PQclosePortal (H -> server , S -> cursor_name ));
162+ #endif
126163 }
127164 efree (S -> cursor_name );
128165 S -> cursor_name = NULL ;
@@ -156,10 +193,19 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt)
156193 if (S -> cursor_name ) {
157194 char * q = NULL ;
158195
159- if (S -> is_prepared ) {
196+ if (S -> is_cursor_declared ) {
197+ #ifndef HAVE_PQCLOSEPORTAL
160198 spprintf (& q , 0 , "CLOSE %s" , S -> cursor_name );
161- PQclear (PQexec (H -> server , q ));
199+
200+ if (pdo_pgsql_try_cmd (q , H )) {
201+ S -> is_cursor_declared = false;
202+ }
203+
162204 efree (q );
205+ #else
206+ PQclear (PQclosePortal (H -> server , S -> cursor_name ));
207+ S -> is_cursor_declared = false;
208+ #endif
163209 }
164210
165211 spprintf (& q , 0 , "DECLARE %s SCROLL CURSOR WITH HOLD FOR %s" , S -> cursor_name , ZSTR_VAL (stmt -> active_query_string ));
@@ -175,7 +221,7 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt)
175221 PQclear (S -> result );
176222
177223 /* the cursor was declared correctly */
178- S -> is_prepared = 1 ;
224+ S -> is_cursor_declared = true ;
179225
180226 /* fetch to be able to get the number of tuples later, but don't advance the cursor pointer */
181227 spprintf (& q , 0 , "FETCH FORWARD 0 FROM %s" , S -> cursor_name );
0 commit comments