35
35
#include "zend_exceptions.h"
36
36
#include "pgsql_driver_arginfo.h"
37
37
38
+ static int 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
register int i = strlen (message )- 1 ;
@@ -141,10 +143,12 @@ static ssize_t pgsql_lob_read(php_stream *stream, char *buf, size_t count)
141
143
static int pgsql_lob_close (php_stream * stream , int close_handle )
142
144
{
143
145
struct pdo_pgsql_lob_self * self = (struct pdo_pgsql_lob_self * )stream -> abstract ;
146
+ pdo_pgsql_db_handle * H = (pdo_pgsql_db_handle * )(Z_PDO_DBH_P (& self -> dbh ))-> driver_data ;
144
147
145
148
if (close_handle ) {
146
149
lo_close (self -> conn , self -> lfd );
147
150
}
151
+ zend_hash_index_del (H -> lob_streams , php_stream_get_resource_id (stream ));
148
152
zval_ptr_dtor (& self -> dbh );
149
153
efree (self );
150
154
return 0 ;
@@ -195,6 +199,7 @@ php_stream *pdo_pgsql_create_lob_stream(zval *dbh, int lfd, Oid oid)
195
199
196
200
if (stm ) {
197
201
Z_ADDREF_P (dbh );
202
+ zend_hash_index_add_ptr (H -> lob_streams , php_stream_get_resource_id (stm ), stm -> res );
198
203
return stm ;
199
204
}
200
205
@@ -203,10 +208,29 @@ php_stream *pdo_pgsql_create_lob_stream(zval *dbh, int lfd, Oid oid)
203
208
}
204
209
/* }}} */
205
210
211
+ void pdo_pgsql_close_lob_streams (pdo_dbh_t * dbh )
212
+ {
213
+ zend_resource * res ;
214
+ pdo_pgsql_db_handle * H = (pdo_pgsql_db_handle * )dbh -> driver_data ;
215
+ if (H -> lob_streams ) {
216
+ ZEND_HASH_REVERSE_FOREACH_PTR (H -> lob_streams , res ) {
217
+ if (res -> type >= 0 ) {
218
+ zend_list_close (res );
219
+ }
220
+ } ZEND_HASH_FOREACH_END ();
221
+ }
222
+ }
223
+
206
224
static int pgsql_handle_closer (pdo_dbh_t * dbh ) /* {{{ */
207
225
{
208
226
pdo_pgsql_db_handle * H = (pdo_pgsql_db_handle * )dbh -> driver_data ;
209
227
if (H ) {
228
+ if (H -> lob_streams ) {
229
+ pdo_pgsql_close_lob_streams (dbh );
230
+ zend_hash_destroy (H -> lob_streams );
231
+ pefree (H -> lob_streams , dbh -> is_persistent );
232
+ H -> lob_streams = NULL ;
233
+ }
210
234
if (H -> server ) {
211
235
PQfinish (H -> server );
212
236
H -> server = NULL ;
@@ -298,6 +322,8 @@ static zend_long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_l
298
322
zend_long ret = 1 ;
299
323
ExecStatusType qs ;
300
324
325
+ bool in_trans = pgsql_handle_in_transaction (dbh );
326
+
301
327
if (!(res = PQexec (H -> server , sql ))) {
302
328
/* fatal error */
303
329
pdo_pgsql_error (dbh , PGRES_FATAL_ERROR , NULL );
@@ -316,6 +342,9 @@ static zend_long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_l
316
342
ret = Z_L (0 );
317
343
}
318
344
PQclear (res );
345
+ if (in_trans && !pgsql_handle_in_transaction (dbh )) {
346
+ pdo_pgsql_close_lob_streams (dbh );
347
+ }
319
348
320
349
return ret ;
321
350
}
@@ -501,9 +530,7 @@ static int pdo_pgsql_check_liveness(pdo_dbh_t *dbh)
501
530
502
531
static int pgsql_handle_in_transaction (pdo_dbh_t * dbh )
503
532
{
504
- pdo_pgsql_db_handle * H ;
505
-
506
- H = (pdo_pgsql_db_handle * )dbh -> driver_data ;
533
+ pdo_pgsql_db_handle * H = (pdo_pgsql_db_handle * )dbh -> driver_data ;
507
534
508
535
return PQtransactionStatus (H -> server ) > PQTRANS_IDLE ;
509
536
}
@@ -536,7 +563,9 @@ static int pgsql_handle_commit(pdo_dbh_t *dbh)
536
563
537
564
/* When deferred constraints are used the commit could
538
565
fail, and a ROLLBACK implicitly ran. See bug #67462 */
539
- if (!ret ) {
566
+ if (ret ) {
567
+ pdo_pgsql_close_lob_streams (dbh );
568
+ } else {
540
569
dbh -> in_txn = pgsql_handle_in_transaction (dbh );
541
570
}
542
571
@@ -545,7 +574,13 @@ static int pgsql_handle_commit(pdo_dbh_t *dbh)
545
574
546
575
static int pgsql_handle_rollback (pdo_dbh_t * dbh )
547
576
{
548
- return pdo_pgsql_transaction_cmd ("ROLLBACK" , dbh );
577
+ int ret = pdo_pgsql_transaction_cmd ("ROLLBACK" , dbh );
578
+
579
+ if (ret ) {
580
+ pdo_pgsql_close_lob_streams (dbh );
581
+ }
582
+
583
+ return ret ;
549
584
}
550
585
551
586
/* {{{ Returns true if the copy worked fine or false if error */
@@ -1233,6 +1268,8 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{
1233
1268
}
1234
1269
1235
1270
H -> server = PQconnectdb (conn_str );
1271
+ H -> lob_streams = (HashTable * ) pemalloc (sizeof (HashTable ), dbh -> is_persistent );
1272
+ zend_hash_init (H -> lob_streams , 0 , NULL , NULL , 1 );
1236
1273
1237
1274
if (tmp_user ) {
1238
1275
zend_string_release_ex (tmp_user , 0 );
0 commit comments