From 5888c4a52ca636f629dbf11969c13c3373a10242 Mon Sep 17 00:00:00 2001 From: William Rogers Date: Fri, 22 May 2015 20:10:10 -0500 Subject: [PATCH 1/7] Correction to SQLGetData string length handling According to http://download.oracle.com/otn_hosted_doc/timesten/703/TimesTen-Documentation/ms.odbc.pdf and https://msdn.microsoft.com/en-us/library/ms710980(v=vs.85).aspx, the string length should not include the NULL character at the end. Previous behavior would likely work without problems for any language that uses C-style null terminated strings, but adds a null character in the string when using the driver with a language that does not use C-style strings. --- src/odbc/odbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c index 86f8bd0..faf1974 100644 --- a/src/odbc/odbc.c +++ b/src/odbc/odbc.c @@ -1797,7 +1797,7 @@ static SQLRETURN SQL_API _SQLGetData( { char *str = mdb_col_to_string(mdb, mdb->pg_buf, col->cur_value_start, col->col_type, col->cur_value_len); - int len = strlen(str) + 1; // including \0 + int len = strlen(str); if (stmt->pos >= len) { free(str); return SQL_NO_DATA; From bcc7ad5a7adb5e7c2bd56952675ad3cc488d3814 Mon Sep 17 00:00:00 2001 From: William Rogers Date: Sun, 24 May 2015 16:49:44 -0500 Subject: [PATCH 2/7] Fixed memory leak in _SQLFreeEnv Memory allocated for the _henv structure was not being freed which caused a small memory leak. --- src/odbc/odbc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c index faf1974..469603e 100644 --- a/src/odbc/odbc.c +++ b/src/odbc/odbc.c @@ -1300,6 +1300,7 @@ static SQLRETURN SQL_API _SQLFreeEnv( return SQL_ERROR; } g_ptr_array_free(env->connections, TRUE); + g_free(env); return SQL_SUCCESS; } From 9276aca34753509e1a1fecfba1dab0d7f002425c Mon Sep 17 00:00:00 2001 From: William Rogers Date: Sun, 24 May 2015 17:05:41 -0500 Subject: [PATCH 3/7] Consolidated calls to mdb_sql_reset SQL engine was being reset in both dump_results functions. Rather than having several different functions responsible for resetting the engine depending on the circumstances, the reset now only occurs in run_query, the same function where the query is executed. --- src/util/mdb-sql.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/util/mdb-sql.c b/src/util/mdb-sql.c index b431a61..046caec 100644 --- a/src/util/mdb-sql.c +++ b/src/util/mdb-sql.c @@ -205,14 +205,14 @@ run_query(FILE *out, MdbSQL *sql, char *mybuf, char *delimiter) else printf("Index scanning %s using %s\n", table->name, table->scan_idx->name); } - if (noexec) { - mdb_sql_reset(sql); - return; + /* If noexec != on, dump results */ + if (!noexec) { + if (pretty_print) + dump_results_pp(out, sql); + else + dump_results(out, sql, delimiter); } - if (pretty_print) - dump_results_pp(out, sql); - else - dump_results(out, sql, delimiter); + mdb_sql_reset(sql); } } @@ -281,8 +281,6 @@ dump_results(FILE *out, MdbSQL *sql, char *delimiter) if (footers) { print_rows_retrieved(out, row_count); } - - mdb_sql_reset(sql); } void @@ -343,8 +341,6 @@ dump_results_pp(FILE *out, MdbSQL *sql) for (j=0;jnum_columns;j++) { g_free(sql->bound_values[j]); } - - mdb_sql_reset(sql); } int From 0123d7e1c24244cb29b044a6daf88d16ccf416b8 Mon Sep 17 00:00:00 2001 From: William Rogers Date: Sun, 24 May 2015 17:12:29 -0500 Subject: [PATCH 4/7] Fixed memory leak - sql->bound_values Memory allocated by mdb_sql_bind_all for sql->bound_values was being leaked at each query execution. Memory is now freed in mdb_sql_reset --- src/sql/mdbsql.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sql/mdbsql.c b/src/sql/mdbsql.c index 0e04b73..96a19e4 100644 --- a/src/sql/mdbsql.c +++ b/src/sql/mdbsql.c @@ -473,6 +473,13 @@ void mdb_sql_reset(MdbSQL *sql) sql->cur_table = NULL; } + /* Reset bound values */ + unsigned int i; + for (i=0;inum_columns;i++) { + g_free(sql->bound_values[i]); + sql->bound_values[i] = NULL; + } + /* Reset columns */ mdb_sql_free_columns(sql->columns); sql->num_columns = 0; From 82e34364948995fcc69f50f5e987e76db858ef4d Mon Sep 17 00:00:00 2001 From: William Rogers Date: Sun, 24 May 2015 17:15:52 -0500 Subject: [PATCH 5/7] Corrected memory being improperly freed The memory for sql->bound_values is now freed by mdb_sql_reset, so these values no longer should be freed in dump_results_pp. Also, this fixes a memory leak that was occurring when results were not being pretty printed. --- src/util/mdb-sql.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/util/mdb-sql.c b/src/util/mdb-sql.c index 046caec..ea7a253 100644 --- a/src/util/mdb-sql.c +++ b/src/util/mdb-sql.c @@ -336,11 +336,6 @@ dump_results_pp(FILE *out, MdbSQL *sql) if (footers) { print_rows_retrieved(out, row_count); } - - /* clean up */ - for (j=0;jnum_columns;j++) { - g_free(sql->bound_values[j]); - } } int From d0472d96ba57fd5c8e0a4c648f8abc750c0119e3 Mon Sep 17 00:00:00 2001 From: William Rogers Date: Sun, 24 May 2015 17:38:50 -0500 Subject: [PATCH 6/7] Added proper SQL engine termination Since the SQL engine is initialized in _SQLAllocEnv, the engine should be also terminated in SQLFreeEnv. --- src/odbc/odbc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c index 469603e..8725023 100644 --- a/src/odbc/odbc.c +++ b/src/odbc/odbc.c @@ -1300,6 +1300,7 @@ static SQLRETURN SQL_API _SQLFreeEnv( return SQL_ERROR; } g_ptr_array_free(env->connections, TRUE); + mdb_sql_exit(env->sql); g_free(env); return SQL_SUCCESS; From 414851890661125cb6beed2fdfffa2dc8dad1aa1 Mon Sep 17 00:00:00 2001 From: William Rogers Date: Sun, 24 May 2015 18:04:14 -0500 Subject: [PATCH 7/7] Freed memory on SQL engine termination Modified mdb_sql_exit to free the memory allocated for the SQL engine in mdb_sql_init --- src/sql/mdbsql.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sql/mdbsql.c b/src/sql/mdbsql.c index 96a19e4..7f7d1a4 100644 --- a/src/sql/mdbsql.c +++ b/src/sql/mdbsql.c @@ -457,9 +457,18 @@ void mdb_sql_dump(MdbSQL *sql) } void mdb_sql_exit(MdbSQL *sql) { - mdb_sql_reset(sql); // Free memory + /* Free the memory associated with the SQL engine */ + mdb_sql_reset(sql); + + g_ptr_array_free(sql->columns, TRUE); + g_ptr_array_free(sql->tables, TRUE); + + /* If libmdb has been initialized, terminate it */ if (sql->mdb) mdb_close(sql->mdb); + + /* Cleanup the SQL engine object */ + g_free(sql); } void mdb_sql_reset(MdbSQL *sql) {