35
35
#include "zend_exceptions.h"
36
36
#include "pgsql_driver_arginfo.h"
37
37
38
+ static bool pgsql_handle_in_transaction (pdo_dbh_t * dbh );
39
+
38
40
static char * _pdo_pgsql_trim_message (const char * message , int persistent )
39
41
{
40
42
size_t i = strlen (message )- 1 ;
@@ -140,10 +142,12 @@ static ssize_t pgsql_lob_read(php_stream *stream, char *buf, size_t count)
140
142
static int pgsql_lob_close (php_stream * stream , int close_handle )
141
143
{
142
144
struct pdo_pgsql_lob_self * self = (struct pdo_pgsql_lob_self * )stream -> abstract ;
145
+ pdo_pgsql_db_handle * H = (pdo_pgsql_db_handle * )(Z_PDO_DBH_P (& self -> dbh ))-> driver_data ;
143
146
144
147
if (close_handle ) {
145
148
lo_close (self -> conn , self -> lfd );
146
149
}
150
+ zend_hash_index_del (H -> lob_streams , php_stream_get_resource_id (stream ));
147
151
zval_ptr_dtor (& self -> dbh );
148
152
efree (self );
149
153
return 0 ;
@@ -194,6 +198,7 @@ php_stream *pdo_pgsql_create_lob_stream(zval *dbh, int lfd, Oid oid)
194
198
195
199
if (stm ) {
196
200
Z_ADDREF_P (dbh );
201
+ zend_hash_index_add_ptr (H -> lob_streams , php_stream_get_resource_id (stm ), stm -> res );
197
202
return stm ;
198
203
}
199
204
@@ -202,10 +207,29 @@ php_stream *pdo_pgsql_create_lob_stream(zval *dbh, int lfd, Oid oid)
202
207
}
203
208
/* }}} */
204
209
210
+ void pdo_pgsql_close_lob_streams (pdo_dbh_t * dbh )
211
+ {
212
+ zend_resource * res ;
213
+ pdo_pgsql_db_handle * H = (pdo_pgsql_db_handle * )dbh -> driver_data ;
214
+ if (H -> lob_streams ) {
215
+ ZEND_HASH_REVERSE_FOREACH_PTR (H -> lob_streams , res ) {
216
+ if (res -> type >= 0 ) {
217
+ zend_list_close (res );
218
+ }
219
+ } ZEND_HASH_FOREACH_END ();
220
+ }
221
+ }
222
+
205
223
static void pgsql_handle_closer (pdo_dbh_t * dbh ) /* {{{ */
206
224
{
207
225
pdo_pgsql_db_handle * H = (pdo_pgsql_db_handle * )dbh -> driver_data ;
208
226
if (H ) {
227
+ if (H -> lob_streams ) {
228
+ pdo_pgsql_close_lob_streams (dbh );
229
+ zend_hash_destroy (H -> lob_streams );
230
+ pefree (H -> lob_streams , dbh -> is_persistent );
231
+ H -> lob_streams = NULL ;
232
+ }
209
233
if (H -> server ) {
210
234
PQfinish (H -> server );
211
235
H -> server = NULL ;
@@ -295,6 +319,8 @@ static zend_long pgsql_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
295
319
zend_long ret = 1 ;
296
320
ExecStatusType qs ;
297
321
322
+ bool in_trans = pgsql_handle_in_transaction (dbh );
323
+
298
324
if (!(res = PQexec (H -> server , ZSTR_VAL (sql )))) {
299
325
/* fatal error */
300
326
pdo_pgsql_error (dbh , PGRES_FATAL_ERROR , NULL );
@@ -313,6 +339,9 @@ static zend_long pgsql_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
313
339
ret = Z_L (0 );
314
340
}
315
341
PQclear (res );
342
+ if (in_trans && !pgsql_handle_in_transaction (dbh )) {
343
+ pdo_pgsql_close_lob_streams (dbh );
344
+ }
316
345
317
346
return ret ;
318
347
}
@@ -503,9 +532,7 @@ static zend_result pdo_pgsql_check_liveness(pdo_dbh_t *dbh)
503
532
504
533
static bool pgsql_handle_in_transaction (pdo_dbh_t * dbh )
505
534
{
506
- pdo_pgsql_db_handle * H ;
507
-
508
- H = (pdo_pgsql_db_handle * )dbh -> driver_data ;
535
+ pdo_pgsql_db_handle * H = (pdo_pgsql_db_handle * )dbh -> driver_data ;
509
536
510
537
return PQtransactionStatus (H -> server ) > PQTRANS_IDLE ;
511
538
}
@@ -538,7 +565,9 @@ static bool pgsql_handle_commit(pdo_dbh_t *dbh)
538
565
539
566
/* When deferred constraints are used the commit could
540
567
fail, and a ROLLBACK implicitly ran. See bug #67462 */
541
- if (!ret ) {
568
+ if (ret ) {
569
+ pdo_pgsql_close_lob_streams (dbh );
570
+ } else {
542
571
dbh -> in_txn = pgsql_handle_in_transaction (dbh );
543
572
}
544
573
@@ -547,7 +576,13 @@ static bool pgsql_handle_commit(pdo_dbh_t *dbh)
547
576
548
577
static bool pgsql_handle_rollback (pdo_dbh_t * dbh )
549
578
{
550
- return pdo_pgsql_transaction_cmd ("ROLLBACK" , dbh );
579
+ int ret = pdo_pgsql_transaction_cmd ("ROLLBACK" , dbh );
580
+
581
+ if (ret ) {
582
+ pdo_pgsql_close_lob_streams (dbh );
583
+ }
584
+
585
+ return ret ;
551
586
}
552
587
553
588
/* {{{ Returns true if the copy worked fine or false if error */
@@ -1242,6 +1277,8 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{
1242
1277
}
1243
1278
1244
1279
H -> server = PQconnectdb (conn_str );
1280
+ H -> lob_streams = (HashTable * ) pemalloc (sizeof (HashTable ), dbh -> is_persistent );
1281
+ zend_hash_init (H -> lob_streams , 0 , NULL , NULL , 1 );
1245
1282
1246
1283
if (tmp_user ) {
1247
1284
zend_string_release_ex (tmp_user , 0 );
0 commit comments