Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f4ca323

Browse files
committed
I suspect that you are not the person to send this to, but I wasn't sure
where else to mail it. I am the maintainer of unixODBC, and we have a set of code in our project that started life as the Postgres windows ODBC driver, which has been ported back to unix. Anyway I have just fixed a memory leak in the driver, and I cant see any mention of the fix being done in the main Postgres code, so I thougth I would let you know. Its in the statement.c module, after the COMMIT statement has been executed in SC_Execute, the code was Nick Gorham
1 parent d891ca1 commit f4ca323

File tree

1 file changed

+56
-55
lines changed

1 file changed

+56
-55
lines changed

src/interfaces/odbc/statement.c

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static struct {
6262

6363

6464
RETCODE SQL_API SQLAllocStmt(HDBC hdbc,
65-
HSTMT FAR *phstmt)
65+
HSTMT FAR *phstmt)
6666
{
6767
static char *func="SQLAllocStmt";
6868
ConnectionClass *conn = (ConnectionClass *) hdbc;
@@ -88,12 +88,12 @@ StatementClass *stmt;
8888
}
8989

9090
if ( ! CC_add_statement(conn, stmt)) {
91-
conn->errormsg = "Maximum number of connections exceeded.";
92-
conn->errornumber = CONN_STMT_ALLOC_ERROR;
91+
conn->errormsg = "Maximum number of connections exceeded.";
92+
conn->errornumber = CONN_STMT_ALLOC_ERROR;
9393
CC_log_error(func, "", conn);
94-
SC_Destructor(stmt);
94+
SC_Destructor(stmt);
9595
*phstmt = SQL_NULL_HSTMT;
96-
return SQL_ERROR;
96+
return SQL_ERROR;
9797
}
9898

9999
*phstmt = (HSTMT) stmt;
@@ -111,7 +111,7 @@ StatementClass *stmt;
111111

112112

113113
RETCODE SQL_API SQLFreeStmt(HSTMT hstmt,
114-
UWORD fOption)
114+
UWORD fOption)
115115
{
116116
static char *func="SQLFreeStmt";
117117
StatementClass *stmt = (StatementClass *) hstmt;
@@ -151,22 +151,22 @@ StatementClass *stmt = (StatementClass *) hstmt;
151151
} else if (fOption == SQL_CLOSE) {
152152
/* this should discard all the results, but leave the statement */
153153
/* itself in place (it can be executed again) */
154-
if (!SC_recycle_statement(stmt)) {
154+
if (!SC_recycle_statement(stmt)) {
155155
// errormsg passed in above
156156
SC_log_error(func, "", stmt);
157-
return SQL_ERROR;
157+
return SQL_ERROR;
158158
}
159159

160160
} else if(fOption == SQL_RESET_PARAMS) {
161161
SC_free_params(stmt, STMT_FREE_PARAMS_ALL);
162162

163163
} else {
164-
stmt->errormsg = "Invalid option passed to SQLFreeStmt.";
165-
stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR;
164+
stmt->errormsg = "Invalid option passed to SQLFreeStmt.";
165+
stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR;
166166
SC_log_error(func, "", stmt);
167-
return SQL_ERROR;
167+
return SQL_ERROR;
168168
}
169-
169+
170170
return SQL_SUCCESS;
171171
}
172172

@@ -306,7 +306,7 @@ SC_Destructor(StatementClass *self)
306306
return TRUE;
307307
}
308308

309-
/* Free parameters and free the memory from the
309+
/* Free parameters and free the memory from the
310310
data-at-execution parameters that was allocated in SQLPutData.
311311
*/
312312
void
@@ -348,7 +348,7 @@ int i;
348348
}
349349

350350

351-
int
351+
int
352352
statement_type(char *statement)
353353
{
354354
int i;
@@ -365,14 +365,14 @@ int i;
365365
from SQLExecute if STMT_FINISHED, or
366366
from SQLFreeStmt(SQL_CLOSE)
367367
*/
368-
char
368+
char
369369
SC_recycle_statement(StatementClass *self)
370370
{
371371
ConnectionClass *conn;
372372

373373
mylog("recycle statement: self= %u\n", self);
374374

375-
/* This would not happen */
375+
/* This would not happen */
376376
if (self->status == STMT_EXECUTING) {
377377
self->errornumber = STMT_SEQUENCE_ERROR;
378378
self->errormsg = "Statement is currently executing a transaction.";
@@ -396,7 +396,7 @@ mylog("recycle statement: self= %u\n", self);
396396
If so, we have to rollback that transaction.
397397
*/
398398
conn = SC_get_conn(self);
399-
if ( ! CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) {
399+
if ( ! CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) {
400400

401401
CC_send_query(conn, "ABORT", NULL);
402402
CC_set_no_trans(conn);
@@ -470,7 +470,7 @@ mylog("recycle statement: self= %u\n", self);
470470
}
471471

472472
/* Pre-execute a statement (SQLPrepare/SQLDescribeCol) */
473-
void
473+
void
474474
SC_pre_execute(StatementClass *self)
475475
{
476476

@@ -485,11 +485,11 @@ SC_pre_execute(StatementClass *self)
485485
mylog(" preprocess: after status = FINISHED, so set PREMATURE\n");
486486
self->status = STMT_PREMATURE;
487487
}
488-
}
488+
}
489489
}
490490

491491
/* This is only called from SQLFreeStmt(SQL_UNBIND) */
492-
char
492+
char
493493
SC_unbind_cols(StatementClass *self)
494494
{
495495
Int2 lf;
@@ -508,7 +508,7 @@ Int2 lf;
508508
return 1;
509509
}
510510

511-
void
511+
void
512512
SC_clear_error(StatementClass *self)
513513
{
514514
self->errornumber = 0;
@@ -552,7 +552,7 @@ static char msg[4096];
552552
return msg;
553553
}
554554

555-
char
555+
char
556556
SC_get_error(StatementClass *self, int *number, char **message)
557557
{
558558
char rv;
@@ -576,13 +576,13 @@ char rv;
576576
}
577577

578578
/* Currently, the driver offers very simple bookmark support -- it is
579-
just the current row number. But it could be more sophisticated
579+
just the current row number. But it could be more sophisticated
580580
someday, such as mapping a key to a 32 bit value
581581
*/
582582
unsigned long
583583
SC_get_bookmark(StatementClass *self)
584584
{
585-
return (self->currTuple + 1);
585+
return (self->currTuple + 1);
586586
}
587587

588588
RETCODE
@@ -601,19 +601,19 @@ ColumnInfoClass *ci;
601601
ci = QR_get_fields(res); /* the column info */
602602

603603
mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, globals.use_declarefetch);
604-
604+
605605
if ( self->manual_result || ! globals.use_declarefetch) {
606606

607-
if (self->currTuple >= QR_get_num_tuples(res) -1 ||
607+
if (self->currTuple >= QR_get_num_tuples(res) -1 ||
608608
(self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1)) {
609609

610-
/* if at the end of the tuples, return "no data found"
611-
and set the cursor past the end of the result set
610+
/* if at the end of the tuples, return "no data found"
611+
and set the cursor past the end of the result set
612612
*/
613-
self->currTuple = QR_get_num_tuples(res);
613+
self->currTuple = QR_get_num_tuples(res);
614614
return SQL_NO_DATA_FOUND;
615615
}
616-
616+
617617
mylog("**** SQLFetch: manual_result\n");
618618
(self->currTuple)++;
619619
}
@@ -643,15 +643,15 @@ ColumnInfoClass *ci;
643643
self->last_fetch_count = 1;
644644

645645
/* If the bookmark column was bound then return a bookmark.
646-
Since this is used with SQLExtendedFetch, and the rowset size
646+
Since this is used with SQLExtendedFetch, and the rowset size
647647
may be greater than 1, and an application can use row or column wise
648648
binding, use the code in copy_and_convert_field() to handle that.
649649
*/
650650
if (self->bookmark.buffer) {
651651
char buf[32];
652652

653653
sprintf(buf, "%ld", SC_get_bookmark(self));
654-
result = copy_and_convert_field(self, 0, buf,
654+
result = copy_and_convert_field(self, 0, buf,
655655
SQL_C_ULONG, self->bookmark.buffer, 0, self->bookmark.used);
656656
}
657657

@@ -663,9 +663,9 @@ ColumnInfoClass *ci;
663663
self->bindings[lf].data_left = -1;
664664

665665
if (self->bindings[lf].buffer != NULL) {
666-
// this column has a binding
666+
// this column has a binding
667667

668-
// type = QR_get_field_type(res, lf);
668+
// type = QR_get_field_type(res, lf);
669669
type = CI_get_oid(ci, lf); /* speed things up */
670670

671671
mylog("type = %d\n", type);
@@ -759,13 +759,13 @@ QueryInfo qi;
759759
SC_log_error(func, "", self);
760760
return SQL_ERROR;
761761
}
762-
763-
ok = QR_command_successful(res);
764-
762+
763+
ok = QR_command_successful(res);
764+
765765
mylog("SQLExecute: ok = %d, status = %d\n", ok, QR_get_status(res));
766-
766+
767767
QR_Destructor(res);
768-
768+
769769
if (!ok) {
770770
self->errormsg = "Could not begin a transaction";
771771
self->errornumber = STMT_EXEC_ERROR;
@@ -805,32 +805,33 @@ QueryInfo qi;
805805
qi.cursor = self->cursor_name;
806806
qi.row_size = globals.fetch_max;
807807

808-
/* Most likely the rowset size will not be set by the application until
809-
after the statement is executed, so might as well use the cache size.
810-
The qr_next_tuple() function will correct for any discrepancies in
808+
/* Most likely the rowset size will not be set by the application until
809+
after the statement is executed, so might as well use the cache size.
810+
The qr_next_tuple() function will correct for any discrepancies in
811811
sizes and adjust the cache accordingly.
812812
*/
813813

814814
sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name);
815-
815+
816816
self->result = CC_send_query( conn, fetch, &qi);
817817
}
818818

819819
mylog(" done sending the query:\n");
820820

821821

822-
822+
823823
}
824-
else { // not a SELECT statement so don't use a cursor
824+
else { // not a SELECT statement so don't use a cursor
825825
mylog(" it's NOT a select statement: stmt=%u\n", self);
826826
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
827-
827+
828828
// If we are in autocommit, we must send the commit.
829829
if ( ! self->internal && CC_is_in_autocommit(conn) && STMT_UPDATE(self)) {
830-
CC_send_query(conn, "COMMIT", NULL);
831-
CC_set_no_trans(conn);
830+
res = CC_send_query(conn, "COMMIT", NULL);
831+
QR_Destructor(res);
832+
CC_set_no_trans(conn);
832833
}
833-
834+
834835
}
835836

836837
conn->status = oldstatus;
@@ -841,19 +842,19 @@ QueryInfo qi;
841842

842843
was_ok = QR_command_successful(self->result);
843844
was_nonfatal = QR_command_nonfatal(self->result);
844-
845+
845846
if ( was_ok)
846847
self->errornumber = STMT_OK;
847848
else
848849
self->errornumber = was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND;
849-
850+
850851
self->currTuple = -1; /* set cursor before the first tuple in the list */
851852
self->current_col = -1;
852853
self->rowset_start = -1;
853-
854+
854855
/* see if the query did return any result columns */
855856
numcols = QR_NumResultCols(self->result);
856-
857+
857858
/* now allocate the array to hold the binding info */
858859
if (numcols > 0) {
859860
extend_bindings(self, numcols);
@@ -864,7 +865,7 @@ QueryInfo qi;
864865
return SQL_ERROR;
865866
}
866867
}
867-
868+
868869
} else { /* Bad Error -- The error message will be in the Connection */
869870

870871
if (self->statement_type == STMT_TYPE_CREATE) {
@@ -927,7 +928,7 @@ SC_log_error(char *func, char *desc, StatementClass *self)
927928
qlog(" message='%s', command='%s', notice='%s'\n", nullcheck(res->message), nullcheck(res->command), nullcheck(res->notice));
928929
qlog(" status=%d, inTuples=%d\n", res->status, res->inTuples);
929930
}
930-
931+
931932
// Log the connection error if there is one
932933
CC_log_error(func, desc, self->hdbc);
933934
}

0 commit comments

Comments
 (0)