@@ -298,8 +298,8 @@ CC_Constructor()
298
298
/* Statements under this conn will inherit these options */
299
299
300
300
InitializeStatementOptions(&rv->stmtOptions);
301
-
302
-
301
+ InitializeARDFields(&rv->ardOptions);
302
+ InitializeAPDFields(&rv->apdOptions);
303
303
}
304
304
return rv;
305
305
}
@@ -381,8 +381,6 @@ CC_begin(ConnectionClass *self)
381
381
{
382
382
ret = QR_command_successful(res);
383
383
QR_Destructor(res);
384
- if (ret)
385
- CC_set_in_trans(self);
386
384
}
387
385
else
388
386
return FALSE;
@@ -403,9 +401,6 @@ CC_commit(ConnectionClass *self)
403
401
{
404
402
QResultClass *res = CC_send_query(self, "COMMIT", NULL, CLEAR_RESULT_ON_ABORT);
405
403
mylog("CC_commit: sending COMMIT!\n");
406
-
407
- CC_set_no_trans(self);
408
-
409
404
if (res != NULL)
410
405
{
411
406
ret = QR_command_successful(res);
@@ -429,9 +424,6 @@ CC_abort(ConnectionClass *self)
429
424
{
430
425
QResultClass *res = CC_send_query(self, "ROLLBACK", NULL, CLEAR_RESULT_ON_ABORT);
431
426
mylog("CC_abort: sending ABORT!\n");
432
-
433
- CC_set_no_trans(self);
434
-
435
427
if (res != NULL)
436
428
QR_Destructor(res);
437
429
else
@@ -1118,6 +1110,23 @@ CC_get_error(ConnectionClass *self, int *number, char **message)
1118
1110
}
1119
1111
1120
1112
1113
+ voidCC_on_commit(ConnectionClass *conn, BOOL set_no_trans)
1114
+ {
1115
+ if (CC_is_in_trans(conn))
1116
+ {
1117
+ if (set_no_trans)
1118
+ CC_set_no_trans(conn);
1119
+ }
1120
+ }
1121
+ voidCC_on_abort(ConnectionClass *conn, BOOL set_no_trans)
1122
+ {
1123
+ if (CC_is_in_trans(conn))
1124
+ {
1125
+ if (set_no_trans)
1126
+ CC_set_no_trans(conn);
1127
+ }
1128
+ }
1129
+
1121
1130
/*
1122
1131
*The "result_in" is only used by QR_next_tuple() to fetch another group of rows into
1123
1132
*the same existing QResultClass (this occurs when the tuple cache is depleted and
@@ -1134,7 +1143,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1134
1143
*retres = NULL,
1135
1144
*res = NULL;
1136
1145
BOOLclear_result_on_abort = ((flag & CLEAR_RESULT_ON_ABORT) != 0),
1137
- create_keyset = ((flag & CREATE_KEYSET) != 0);
1146
+ create_keyset = ((flag & CREATE_KEYSET) != 0),
1147
+ issue_begin = ((flag & GO_INTO_TRANSACTION) != 0 && !CC_is_in_trans(self));
1138
1148
charswallow,
1139
1149
*wq;
1140
1150
intid;
@@ -1146,7 +1156,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1146
1156
query_completed = FALSE,
1147
1157
before_64 = PG_VERSION_LT(self, 6.4),
1148
1158
aborted = FALSE,
1149
- used_passed_result_object = FALSE;
1159
+ used_passed_result_object = FALSE,
1160
+ set_no_trans;
1150
1161
1151
1162
/* ERROR_MSG_LENGTH is suffcient */
1152
1163
static char msgbuffer[ERROR_MSG_LENGTH + 1];
@@ -1173,7 +1184,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1173
1184
{
1174
1185
self->errornumber = CONNECTION_COULD_NOT_SEND;
1175
1186
self->errormsg = "Could not send Query to backend";
1176
- CC_set_no_trans (self);
1187
+ CC_on_abort (self, TRUE );
1177
1188
return NULL;
1178
1189
}
1179
1190
@@ -1182,18 +1193,20 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1182
1193
{
1183
1194
self->errornumber = CONNECTION_COULD_NOT_SEND;
1184
1195
self->errormsg = "Could not send Query to backend";
1185
- CC_set_no_trans (self);
1196
+ CC_on_abort (self, TRUE );
1186
1197
return NULL;
1187
1198
}
1188
1199
1200
+ if (issue_begin)
1201
+ SOCK_put_n_char(sock, "begin;", 6);
1189
1202
SOCK_put_string(sock, query);
1190
1203
SOCK_flush_output(sock);
1191
1204
1192
1205
if (SOCK_get_errcode(sock) != 0)
1193
1206
{
1194
1207
self->errornumber = CONNECTION_COULD_NOT_SEND;
1195
1208
self->errormsg = "Could not send Query to backend";
1196
- CC_set_no_trans (self);
1209
+ CC_on_abort (self, TRUE );
1197
1210
return NULL;
1198
1211
}
1199
1212
@@ -1230,7 +1243,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1230
1243
self->errormsg = "No response from the backend";
1231
1244
1232
1245
mylog("send_query: 'id' - %s\n", self->errormsg);
1233
- CC_set_no_trans (self);
1246
+ CC_on_abort (self, TRUE );
1234
1247
ReadyToReturn = TRUE;
1235
1248
retres = NULL;
1236
1249
break;
@@ -1254,7 +1267,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1254
1267
self->errornumber = CONNECTION_NO_RESPONSE;
1255
1268
self->errormsg = "No response from backend while receiving a portal query command";
1256
1269
mylog("send_query: 'C' - %s\n", self->errormsg);
1257
- CC_set_no_trans (self);
1270
+ CC_on_abort (self, TRUE );
1258
1271
ReadyToReturn = TRUE;
1259
1272
retres = NULL;
1260
1273
}
@@ -1270,6 +1283,24 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1270
1283
1271
1284
mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer);
1272
1285
1286
+ if (strnicmp(cmdbuffer, "BEGIN", 5) == 0)
1287
+ {
1288
+ CC_set_in_trans(self);
1289
+ if (issue_begin)
1290
+ {
1291
+ issue_begin = FALSE;
1292
+ continue;
1293
+ }
1294
+ }
1295
+ else if (strnicmp(cmdbuffer, "COMMIT", 6) == 0)
1296
+ CC_on_commit(self, TRUE);
1297
+ else if (strnicmp(cmdbuffer, "ROLLBACK", 8) == 0)
1298
+ CC_on_abort(self, TRUE);
1299
+ else if (strnicmp(cmdbuffer, "END", 3) == 0)
1300
+ CC_on_commit(self, TRUE);
1301
+ else if (strnicmp(cmdbuffer, "ABORT", 5) == 0)
1302
+ CC_on_abort(self, TRUE);
1303
+
1273
1304
if (QR_command_successful(res))
1274
1305
QR_set_status(res, PGRES_COMMAND_OK);
1275
1306
QR_set_command(res, cmdbuffer);
@@ -1352,14 +1383,15 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1352
1383
qlog("ERROR from backend during send_query: '%s'\n", msgbuffer);
1353
1384
1354
1385
/* We should report that an error occured. Zoltan */
1355
-
1386
+ set_no_trans = FALSE;
1356
1387
if (!strncmp(msgbuffer, "FATAL", 5))
1357
1388
{
1358
1389
self->errornumber = CONNECTION_SERVER_REPORTED_ERROR;
1359
- CC_set_no_trans(self) ;
1390
+ set_no_trans = TRUE ;
1360
1391
}
1361
1392
else
1362
1393
self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
1394
+ CC_on_abort(self, set_no_trans);
1363
1395
QR_set_status(res, PGRES_FATAL_ERROR);
1364
1396
QR_set_message(res, msgbuffer);
1365
1397
QR_set_aborted(res, TRUE);
@@ -1377,9 +1409,6 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1377
1409
if (query_completed)
1378
1410
{
1379
1411
res->next = QR_Constructor();
1380
- if (create_keyset)
1381
- QR_set_haskeyset(res->next);
1382
- mylog("send_query: 'T' no result_in: res = %u\n", res->next);
1383
1412
if (!res->next)
1384
1413
{
1385
1414
self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
@@ -1388,6 +1417,9 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1388
1417
retres = NULL;
1389
1418
break;
1390
1419
}
1420
+ if (create_keyset)
1421
+ QR_set_haskeyset(res->next);
1422
+ mylog("send_query: 'T' no result_in: res = %u\n", res->next);
1391
1423
res = res->next;
1392
1424
1393
1425
if (qi)
@@ -1448,7 +1480,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
1448
1480
default:
1449
1481
self->errornumber = CONNECTION_BACKEND_CRAZY;
1450
1482
self->errormsg = "Unexpected protocol character from backend (send_query)";
1451
- CC_set_no_trans (self);
1483
+ CC_on_abort (self, TRUE );
1452
1484
1453
1485
mylog("send_query: error - %s\n", self->errormsg);
1454
1486
ReadyToReturn = TRUE;
@@ -1536,7 +1568,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
1536
1568
{
1537
1569
self->errornumber = CONNECTION_COULD_NOT_SEND;
1538
1570
self->errormsg = "Could not send function to backend";
1539
- CC_set_no_trans (self);
1571
+ CC_on_abort (self, TRUE );
1540
1572
return FALSE;
1541
1573
}
1542
1574
@@ -1545,7 +1577,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
1545
1577
{
1546
1578
self->errornumber = CONNECTION_COULD_NOT_SEND;
1547
1579
self->errormsg = "Could not send function to backend";
1548
- CC_set_no_trans (self);
1580
+ CC_on_abort (self, TRUE );
1549
1581
return FALSE;
1550
1582
}
1551
1583
@@ -1594,6 +1626,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
1594
1626
case 'E':
1595
1627
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
1596
1628
self->errormsg = msgbuffer;
1629
+ CC_on_abort(self, FALSE);
1597
1630
1598
1631
mylog("send_function(V): 'E' - %s\n", self->errormsg);
1599
1632
qlog("ERROR from backend during send_function: '%s'\n", self->errormsg);
@@ -1606,7 +1639,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
1606
1639
default:
1607
1640
self->errornumber = CONNECTION_BACKEND_CRAZY;
1608
1641
self->errormsg = "Unexpected protocol character from backend (send_function, args)";
1609
- CC_set_no_trans (self);
1642
+ CC_on_abort (self, TRUE );
1610
1643
1611
1644
mylog("send_function: error - %s\n", self->errormsg);
1612
1645
return FALSE;
@@ -1640,7 +1673,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
1640
1673
case 'E':
1641
1674
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
1642
1675
self->errormsg = msgbuffer;
1643
-
1676
+ CC_on_abort(self, FALSE);
1644
1677
mylog("send_function(G): 'E' - %s\n", self->errormsg);
1645
1678
qlog("ERROR from backend during send_function: '%s'\n", self->errormsg);
1646
1679
@@ -1661,7 +1694,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
1661
1694
default:
1662
1695
self->errornumber = CONNECTION_BACKEND_CRAZY;
1663
1696
self->errormsg = "Unexpected protocol character from backend (send_function, result)";
1664
- CC_set_no_trans (self);
1697
+ CC_on_abort (self, TRUE );
1665
1698
1666
1699
mylog("send_function: error - %s\n", self->errormsg);
1667
1700
return FALSE;