Skip to content

Commit 6852741

Browse files
author
Hiroshi Inoue
committed
[2002-03-28]
1) Prepare to separate 4 kinds of Descriptor handles. 2) Detect the transaction status more naturally. 3) Improve Parse Statement functionality for the use of updatable cursors. 4) Improve updatable cursors. 5) Implement SQLGetDescField() and improve SQLColAttribute(). 6) etc.
1 parent e6774dc commit 6852741

40 files changed

+2696
-1291
lines changed

src/interfaces/odbc/bind.c

Lines changed: 234 additions & 113 deletions
Large diffs are not rendered by default.

src/interfaces/odbc/bind.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ struct ParameterInfoClass_
5050
};
5151

5252
BindInfoClass *create_empty_bindings(int num_columns);
53-
void extend_bindings(StatementClass *stmt, int num_columns);
53+
void extend_column_bindings(ARDFields *opts, int num_columns);
54+
void reset_a_column_binding(ARDFields *opts, int icol);
55+
void extend_parameter_bindings(APDFields *opts, int num_columns);
56+
void reset_a_parameter_binding(APDFields *opts, int ipar);
5457

5558
#endif

src/interfaces/odbc/connection.c

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,8 @@ CC_Constructor()
298298
/* Statements under this conn will inherit these options */
299299

300300
InitializeStatementOptions(&rv->stmtOptions);
301-
302-
301+
InitializeARDFields(&rv->ardOptions);
302+
InitializeAPDFields(&rv->apdOptions);
303303
}
304304
return rv;
305305
}
@@ -381,8 +381,6 @@ CC_begin(ConnectionClass *self)
381381
{
382382
ret = QR_command_successful(res);
383383
QR_Destructor(res);
384-
if (ret)
385-
CC_set_in_trans(self);
386384
}
387385
else
388386
return FALSE;
@@ -403,9 +401,6 @@ CC_commit(ConnectionClass *self)
403401
{
404402
QResultClass *res = CC_send_query(self, "COMMIT", NULL, CLEAR_RESULT_ON_ABORT);
405403
mylog("CC_commit: sending COMMIT!\n");
406-
407-
CC_set_no_trans(self);
408-
409404
if (res != NULL)
410405
{
411406
ret = QR_command_successful(res);
@@ -429,9 +424,6 @@ CC_abort(ConnectionClass *self)
429424
{
430425
QResultClass *res = CC_send_query(self, "ROLLBACK", NULL, CLEAR_RESULT_ON_ABORT);
431426
mylog("CC_abort: sending ABORT!\n");
432-
433-
CC_set_no_trans(self);
434-
435427
if (res != NULL)
436428
QR_Destructor(res);
437429
else
@@ -1118,6 +1110,23 @@ CC_get_error(ConnectionClass *self, int *number, char **message)
11181110
}
11191111

11201112

1113+
void CC_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+
void CC_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+
11211130
/*
11221131
* The "result_in" is only used by QR_next_tuple() to fetch another group of rows into
11231132
* 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)
11341143
*retres = NULL,
11351144
*res = NULL;
11361145
BOOL clear_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));
11381148
char swallow,
11391149
*wq;
11401150
int id;
@@ -1146,7 +1156,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
11461156
query_completed = FALSE,
11471157
before_64 = PG_VERSION_LT(self, 6.4),
11481158
aborted = FALSE,
1149-
used_passed_result_object = FALSE;
1159+
used_passed_result_object = FALSE,
1160+
set_no_trans;
11501161

11511162
/* ERROR_MSG_LENGTH is suffcient */
11521163
static char msgbuffer[ERROR_MSG_LENGTH + 1];
@@ -1173,7 +1184,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
11731184
{
11741185
self->errornumber = CONNECTION_COULD_NOT_SEND;
11751186
self->errormsg = "Could not send Query to backend";
1176-
CC_set_no_trans(self);
1187+
CC_on_abort(self, TRUE);
11771188
return NULL;
11781189
}
11791190

@@ -1182,18 +1193,20 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
11821193
{
11831194
self->errornumber = CONNECTION_COULD_NOT_SEND;
11841195
self->errormsg = "Could not send Query to backend";
1185-
CC_set_no_trans(self);
1196+
CC_on_abort(self, TRUE);
11861197
return NULL;
11871198
}
11881199

1200+
if (issue_begin)
1201+
SOCK_put_n_char(sock, "begin;", 6);
11891202
SOCK_put_string(sock, query);
11901203
SOCK_flush_output(sock);
11911204

11921205
if (SOCK_get_errcode(sock) != 0)
11931206
{
11941207
self->errornumber = CONNECTION_COULD_NOT_SEND;
11951208
self->errormsg = "Could not send Query to backend";
1196-
CC_set_no_trans(self);
1209+
CC_on_abort(self, TRUE);
11971210
return NULL;
11981211
}
11991212

@@ -1230,7 +1243,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
12301243
self->errormsg = "No response from the backend";
12311244

12321245
mylog("send_query: 'id' - %s\n", self->errormsg);
1233-
CC_set_no_trans(self);
1246+
CC_on_abort(self, TRUE);
12341247
ReadyToReturn = TRUE;
12351248
retres = NULL;
12361249
break;
@@ -1254,7 +1267,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
12541267
self->errornumber = CONNECTION_NO_RESPONSE;
12551268
self->errormsg = "No response from backend while receiving a portal query command";
12561269
mylog("send_query: 'C' - %s\n", self->errormsg);
1257-
CC_set_no_trans(self);
1270+
CC_on_abort(self, TRUE);
12581271
ReadyToReturn = TRUE;
12591272
retres = NULL;
12601273
}
@@ -1270,6 +1283,24 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
12701283

12711284
mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer);
12721285

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+
12731304
if (QR_command_successful(res))
12741305
QR_set_status(res, PGRES_COMMAND_OK);
12751306
QR_set_command(res, cmdbuffer);
@@ -1352,14 +1383,15 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
13521383
qlog("ERROR from backend during send_query: '%s'\n", msgbuffer);
13531384

13541385
/* We should report that an error occured. Zoltan */
1355-
1386+
set_no_trans = FALSE;
13561387
if (!strncmp(msgbuffer, "FATAL", 5))
13571388
{
13581389
self->errornumber = CONNECTION_SERVER_REPORTED_ERROR;
1359-
CC_set_no_trans(self);
1390+
set_no_trans = TRUE;
13601391
}
13611392
else
13621393
self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
1394+
CC_on_abort(self, set_no_trans);
13631395
QR_set_status(res, PGRES_FATAL_ERROR);
13641396
QR_set_message(res, msgbuffer);
13651397
QR_set_aborted(res, TRUE);
@@ -1377,9 +1409,6 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
13771409
if (query_completed)
13781410
{
13791411
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);
13831412
if (!res->next)
13841413
{
13851414
self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
@@ -1388,6 +1417,9 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
13881417
retres = NULL;
13891418
break;
13901419
}
1420+
if (create_keyset)
1421+
QR_set_haskeyset(res->next);
1422+
mylog("send_query: 'T' no result_in: res = %u\n", res->next);
13911423
res = res->next;
13921424

13931425
if (qi)
@@ -1448,7 +1480,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
14481480
default:
14491481
self->errornumber = CONNECTION_BACKEND_CRAZY;
14501482
self->errormsg = "Unexpected protocol character from backend (send_query)";
1451-
CC_set_no_trans(self);
1483+
CC_on_abort(self, TRUE);
14521484

14531485
mylog("send_query: error - %s\n", self->errormsg);
14541486
ReadyToReturn = TRUE;
@@ -1536,7 +1568,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
15361568
{
15371569
self->errornumber = CONNECTION_COULD_NOT_SEND;
15381570
self->errormsg = "Could not send function to backend";
1539-
CC_set_no_trans(self);
1571+
CC_on_abort(self, TRUE);
15401572
return FALSE;
15411573
}
15421574

@@ -1545,7 +1577,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
15451577
{
15461578
self->errornumber = CONNECTION_COULD_NOT_SEND;
15471579
self->errormsg = "Could not send function to backend";
1548-
CC_set_no_trans(self);
1580+
CC_on_abort(self, TRUE);
15491581
return FALSE;
15501582
}
15511583

@@ -1594,6 +1626,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
15941626
case 'E':
15951627
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
15961628
self->errormsg = msgbuffer;
1629+
CC_on_abort(self, FALSE);
15971630

15981631
mylog("send_function(V): 'E' - %s\n", self->errormsg);
15991632
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_
16061639
default:
16071640
self->errornumber = CONNECTION_BACKEND_CRAZY;
16081641
self->errormsg = "Unexpected protocol character from backend (send_function, args)";
1609-
CC_set_no_trans(self);
1642+
CC_on_abort(self, TRUE);
16101643

16111644
mylog("send_function: error - %s\n", self->errormsg);
16121645
return FALSE;
@@ -1640,7 +1673,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
16401673
case 'E':
16411674
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
16421675
self->errormsg = msgbuffer;
1643-
1676+
CC_on_abort(self, FALSE);
16441677
mylog("send_function(G): 'E' - %s\n", self->errormsg);
16451678
qlog("ERROR from backend during send_function: '%s'\n", self->errormsg);
16461679

@@ -1661,7 +1694,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
16611694
default:
16621695
self->errornumber = CONNECTION_BACKEND_CRAZY;
16631696
self->errormsg = "Unexpected protocol character from backend (send_function, result)";
1664-
CC_set_no_trans(self);
1697+
CC_on_abort(self, TRUE);
16651698

16661699
mylog("send_function: error - %s\n", self->errormsg);
16671700
return FALSE;

src/interfaces/odbc/connection.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <stdlib.h>
1515
#include <string.h>
16+
#include "descriptor.h"
1617

1718

1819
typedef enum
@@ -242,6 +243,8 @@ struct ConnectionClass_
242243
HENV henv; /* environment this connection was created
243244
* on */
244245
StatementOptions stmtOptions;
246+
ARDFields ardOptions;
247+
APDFields apdOptions;
245248
char *errormsg;
246249
int errornumber;
247250
CONN_Status status;
@@ -315,8 +318,11 @@ void CC_lookup_pg_version(ConnectionClass *conn);
315318
void CC_initialize_pg_version(ConnectionClass *conn);
316319
void CC_log_error(const char *func, const char *desc, const ConnectionClass *self);
317320
int CC_get_max_query_len(const ConnectionClass *self);
321+
void CC_on_commit(ConnectionClass *conn, BOOL set_no_trans);
322+
void CC_on_abort(ConnectionClass *conn, BOOL set_no_trans);
318323

319324
/* CC_send_query_options */
320325
#define CLEAR_RESULT_ON_ABORT 1L
321326
#define CREATE_KEYSET (1L << 1) /* create keyset for updatable curosrs */
327+
#define GO_INTO_TRANSACTION (1L << 2) /* issue begin in advance */
322328
#endif

0 commit comments

Comments
 (0)