Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3c16d09

Browse files
author
Hiroshi Inoue
committed
The version is now 7.01.0010.
1) Handle parameter array. 2) Allow re-use of the connection handle after SQLDisconnect. 3) Reject NULL if no indicator specified. 4) Improve the handling of '_' in table name. 5) Unify internal begin/commit/abort operations. 6) Change SQLTables() to return null not "" for the table_owner. 7) Fix a bug about parameter handling reported by Benoit Menendez. 8) Add cast in handling ODBC date/time escape sequences. 9) Fix a bug about cache_size handing in declare/fetch mode. [ODBC3.0 related] 10) Improve the handling of descriptor handles(ODBC3.0). 11) Improve the type handling of some types for ODBC3.0. [Thanks to Marcelo Aceto for his useful patches] 12) Allow nested ODBC escape. 13) Allow changing autocommit on/off inside the transaction block. 14) Improve the handling of ODBC scalar functions.
1 parent b6db89a commit 3c16d09

21 files changed

+1263
-600
lines changed

src/interfaces/odbc/bind.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ PGAPI_BindParameter(
134134
stmt->parameters[ipar].EXEC_buffer = NULL;
135135
}
136136

137+
if (pcbValue && stmt->options.param_offset_ptr)
138+
pcbValue += (*stmt->options.param_offset_ptr >> 2);
137139
/* Data at exec macro only valid for C char/binary data */
138140
if (pcbValue && (*pcbValue == SQL_DATA_AT_EXEC ||
139141
*pcbValue <= SQL_LEN_DATA_AT_EXEC_OFFSET))

src/interfaces/odbc/connection.c

Lines changed: 92 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,6 @@ CC_Destructor(ConnectionClass *self)
309309

310310
mylog("after CC_Cleanup\n");
311311

312-
#ifdef MULTIBYTE
313-
if (self->client_encoding)
314-
free(self->client_encoding);
315-
if (self->server_encoding)
316-
free(self->server_encoding);
317-
#endif /* MULTIBYTE */
318312
/* Free up statement holders */
319313
if (self->stmts)
320314
{
@@ -323,23 +317,6 @@ CC_Destructor(ConnectionClass *self)
323317
}
324318
mylog("after free statement holders\n");
325319

326-
/* Free cached table info */
327-
if (self->col_info)
328-
{
329-
int i;
330-
331-
for (i = 0; i < self->ntables; i++)
332-
{
333-
if (self->col_info[i]->result) /* Free the SQLColumns
334-
* result structure */
335-
QR_Destructor(self->col_info[i]->result);
336-
337-
free(self->col_info[i]);
338-
}
339-
free(self->col_info);
340-
}
341-
342-
343320
free(self);
344321

345322
mylog("exit CC_Destructor\n");
@@ -380,29 +357,77 @@ CC_clear_error(ConnectionClass *self)
380357
}
381358

382359

360+
/*
361+
* Used to begin a transaction.
362+
*/
363+
char
364+
CC_begin(ConnectionClass *self)
365+
{
366+
char ret = TRUE;
367+
if (!CC_is_in_trans(self))
368+
{
369+
QResultClass *res = CC_send_query(self, "BEGIN", NULL);
370+
mylog("CC_begin: sending BEGIN!\n");
371+
372+
if (res != NULL)
373+
{
374+
ret = (!QR_aborted(res) && QR_command_successful(res));
375+
QR_Destructor(res);
376+
if (ret)
377+
CC_set_in_trans(self);
378+
}
379+
else
380+
ret = FALSE;
381+
}
382+
383+
return ret;
384+
}
385+
386+
/*
387+
* Used to commit a transaction.
388+
* We are almost always in the middle of a transaction.
389+
*/
390+
char
391+
CC_commit(ConnectionClass *self)
392+
{
393+
char ret = FALSE;
394+
if (CC_is_in_trans(self))
395+
{
396+
QResultClass *res = CC_send_query(self, "COMMIT", NULL);
397+
mylog("CC_commit: sending COMMIT!\n");
398+
399+
CC_set_no_trans(self);
400+
401+
if (res != NULL)
402+
{
403+
ret = QR_command_successful(res);
404+
QR_Destructor(res);
405+
}
406+
else
407+
ret = FALSE;
408+
}
409+
410+
return ret;
411+
}
412+
383413
/*
384414
* Used to cancel a transaction.
385415
* We are almost always in the middle of a transaction.
386416
*/
387417
char
388418
CC_abort(ConnectionClass *self)
389419
{
390-
QResultClass *res;
391-
392420
if (CC_is_in_trans(self))
393421
{
394-
res = NULL;
395-
422+
QResultClass *res = CC_send_query(self, "ROLLBACK", NULL);
396423
mylog("CC_abort: sending ABORT!\n");
397424

398-
res = CC_send_query(self, "ABORT", NULL);
399425
CC_set_no_trans(self);
400426

401427
if (res != NULL)
402428
QR_Destructor(res);
403429
else
404430
return FALSE;
405-
406431
}
407432

408433
return TRUE;
@@ -461,6 +486,37 @@ CC_cleanup(ConnectionClass *self)
461486
}
462487
#endif
463488

489+
self->status = CONN_NOT_CONNECTED;
490+
self->transact_status = CONN_IN_AUTOCOMMIT;
491+
memset(&self->connInfo, 0, sizeof(ConnInfo));
492+
#ifdef DRIVER_CURSOR_IMPLEMENT
493+
self->connInfo.updatable_cursors = 1;
494+
#endif /* DRIVER_CURSOR_IMPLEMENT */
495+
memcpy(&(self->connInfo.drivers), &globals, sizeof(globals));
496+
#ifdef MULTIBYTE
497+
if (self->client_encoding)
498+
free(self->client_encoding);
499+
self->client_encoding = NULL;
500+
if (self->server_encoding)
501+
free(self->server_encoding);
502+
self->server_encoding = NULL;
503+
#endif /* MULTIBYTE */
504+
/* Free cached table info */
505+
if (self->col_info)
506+
{
507+
int i;
508+
509+
for (i = 0; i < self->ntables; i++)
510+
{
511+
if (self->col_info[i]->result) /* Free the SQLColumns result structure */
512+
QR_Destructor(self->col_info[i]->result);
513+
514+
free(self->col_info[i]);
515+
}
516+
free(self->col_info);
517+
self->col_info = NULL;
518+
}
519+
self->ntables = 0;
464520
mylog("exit CC_Cleanup\n");
465521
return TRUE;
466522
}
@@ -516,7 +572,6 @@ md5_auth_send(ConnectionClass *self, const char *salt)
516572
ConnInfo *ci = &(self->connInfo);
517573
SocketClass *sock = self->sock;
518574

519-
mylog("MD5 user=%s password=%s\n", ci->username, ci->password);
520575
if (!(pwd1 = malloc(MD5_PASSWD_LEN + 1)))
521576
return 1;
522577
if (!EncryptMD5(ci->password, ci->username, strlen(ci->username), pwd1))
@@ -601,9 +656,10 @@ CC_connect(ConnectionClass *self, char do_password)
601656
ci->drivers.conn_settings,
602657
encoding ? encoding : "");
603658
#else
604-
qlog(" extra_systable_prefixes='%s', conn_settings='%s'\n",
659+
qlog(" extra_systable_prefixes='%s', conn_settings='%s', protocol='%s'\n",
605660
ci->drivers.extra_systable_prefixes,
606-
ci->drivers.conn_settings);
661+
ci->drivers.conn_settings,
662+
ci->protocol);
607663
#endif
608664

609665
if (self->status != CONN_NOT_CONNECTED)
@@ -1037,7 +1093,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
10371093
ReadyToReturn,
10381094
tuples_return = FALSE,
10391095
query_completed = FALSE,
1040-
before_64 = PG_VERSION_LT(self, 6.4);
1096+
before_64 = PG_VERSION_LT(self, 6.4),
1097+
used_passed_result_object = FALSE;
10411098

10421099
/* ERROR_MSG_LENGTH is suffcient */
10431100
static char msgbuffer[ERROR_MSG_LENGTH + 1];
@@ -1289,6 +1346,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
12891346
else
12901347
{ /* next fetch, so reuse an existing result */
12911348

1349+
used_passed_result_object = TRUE;
12921350
/*
12931351
* called from QR_next_tuple and must return
12941352
* immediately.
@@ -1373,9 +1431,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
13731431
QR_Destructor(res);
13741432
if (result_in && retres != result_in)
13751433
{
1376-
if (qi && qi->result_in)
1377-
;
1378-
else
1434+
if (!used_passed_result_object)
13791435
QR_Destructor(result_in);
13801436
}
13811437
return retres;

src/interfaces/odbc/connection.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ ConnectionClass *CC_Constructor(void);
292292
char CC_Destructor(ConnectionClass *self);
293293
int CC_cursor_count(ConnectionClass *self);
294294
char CC_cleanup(ConnectionClass *self);
295+
char CC_begin(ConnectionClass *self);
296+
char CC_commit(ConnectionClass *self);
295297
char CC_abort(ConnectionClass *self);
296298
int CC_set_translation(ConnectionClass *self);
297299
char CC_connect(ConnectionClass *self, char do_password);

0 commit comments

Comments
 (0)