[erlang-patches] [PATCH] ODBC server segfaults on 64-bit platform
Ingela Anderton Andin
ingela@REDACTED
Mon May 5 10:16:39 CEST 2008
Thank you for your patch. I have included it in our daily build.
Hopefully it is just what we where wishing for :)
We just currently tested odbc on a 64-bit platform and noticed problems
related to SQLINTEGER, but as we have no
actual demand for odbc on 64-bits form our financiers, this has very
low priority. If all goes
well it will be included in the next OTP-release.
Regards Ingela - OTP team
willi wrote:
> Hi,
>
> Please, consider this patch for inclusion. I've replaced SQLINTEGER with SQLLEN where it is mandated by ODBC specification.
> Without this modifications, ODBC driver segfaults on functions with SQLLEN type parameters on 64bit platforms.
> Tested on linux (both AMD64 and 32-bit).
>
> ---
> lib/odbc/c_src/odbcserver.c | 60 ++++++++++--------------------------------
> lib/odbc/c_src/odbcserver.h | 6 ++--
> 2 files changed, 18 insertions(+), 48 deletions(-)
>
> diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
> index a5d10ab..168f09f 100644
> --- a/lib/odbc/c_src/odbcserver.c
> +++ b/lib/odbc/c_src/odbcserver.c
> @@ -154,8 +154,6 @@ static db_result_msg encode_value_list_scroll(SQLSMALLINT num_of_columns,
> db_state *state);
> static db_result_msg encode_row_count(SQLINTEGER num_of_rows,
> db_state *state);
> -static int encode_column(byte *buffer, int index, db_column column,
> - int column_nr, db_state *state);
> static void encode_column_dyn(db_column column, int column_nr,
> db_state *state);
> static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size,
> @@ -590,7 +588,7 @@ static db_result_msg db_query(byte *sql, db_state *state)
> static db_result_msg db_select_count(byte *sql, db_state *state)
> {
> SQLSMALLINT num_of_columns, intresult;
> - SQLINTEGER num_of_rows;
> + SQLLEN num_of_rows;
> SQLRETURN result;
> diagnos diagnos;
> db_result_msg msg;
> @@ -760,6 +758,7 @@ static db_result_msg db_param_query(byte *buffer, db_state *state)
> switch (param_status.param_status_array[i]) {
> case SQL_PARAM_SUCCESS:
> case SQL_PARAM_SUCCESS_WITH_INFO:
> + case SQL_PARAM_DIAG_UNAVAILABLE:
> break;
> default:
> diagnos =
> @@ -812,7 +811,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state)
> SQLSMALLINT num_of_columns;
> SQLCHAR name[MAX_NAME];
> SQLSMALLINT name_len, sql_type, dec_digits, nullable;
> - SQLINTEGER size;
> + SQLLEN size;
> diagnos diagnos;
> int i;
>
> @@ -851,7 +850,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state)
> for (i = 0; i < num_of_columns; ++i) {
>
> if(!sql_success(SQLDescribeCol(statement_handle(state),
> - (SQLSMALLINT)(i+1),
> + (SQLUSMALLINT)(i+1),
> name, sizeof(name), &name_len,
> &sql_type, &size, &dec_digits,
> &nullable)))
> @@ -938,7 +937,8 @@ static db_result_msg encode_atom_message(char* atom)
> static db_result_msg encode_result(db_state *state)
> {
> SQLSMALLINT num_of_columns = 0;
> - SQLINTEGER RowCountPtr = 0, paramBatch = 0;
> + SQLLEN RowCountPtr = 0;
> + SQLINTEGER paramBatch = 0;
> db_result_msg msg;
> int elements, update, num_of_rows = 0;
> char *atom;
> @@ -1039,7 +1039,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns,
> db_result_msg msg;
> SQLCHAR name[MAX_NAME];
> SQLSMALLINT name_len, sql_type, dec_digits, nullable;
> - SQLUINTEGER size;
> + SQLLEN size;
> SQLRETURN result;
>
> msg = encode_empty_message();
> @@ -1224,48 +1224,11 @@ static db_result_msg encode_row_count(SQLINTEGER num_of_rows,
> return msg;
> }
>
> -/* Description: Encodes a column value into the buffer <buffer>.*/
> -static int encode_column(byte *buffer, int index, db_column column,
> - int column_nr, db_state *state)
> -{
> - if(column.type.len == 0 ||
> - column.type.strlen_or_indptr == SQL_NULL_DATA)
> - ei_encode_atom((char *)buffer, &index, "null");
> - else {
> - switch(column.type.c) {
> - case SQL_C_CHAR:
> - ei_encode_string((char *)buffer, &index, column.buffer);
> - break;
> - case SQL_C_DOUBLE:
> - ei_encode_double((char *)buffer, &index, *(double *)column.buffer);
> - break;
> - case SQL_C_SLONG:
> - ei_encode_long((char *)buffer, &index, *(long *)column.buffer);
> - break;
> - case SQL_C_BIT:
> - ei_encode_atom((char *)buffer, &index,
> - column.buffer[0]?"true":"false");
> - break;
> - case SQL_C_BINARY:
> - if (buffer == NULL) {
> - column = retrive_binary_data(column, column_nr, state);
> - }
> - ei_encode_string((char *)buffer, &index, (void *)column.buffer);
> - break;
> - default:
> - ei_encode_atom((char *)buffer, &index, "error");
> - break;
> - }
> - }
> - return index;
> -}
> -
> /* Description: Encodes the a column value into the "ei_x" - dynamic_buffer
> held by the state variable */
> static void encode_column_dyn(db_column column, int column_nr,
> db_state *state)
> {
> -
> if (column.type.len == 0 ||
> column.type.strlen_or_indptr == SQL_NULL_DATA) {
> ei_x_encode_atom(&dynamic_buffer(state), "null");
> @@ -1930,7 +1893,7 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
> params->type.c = SQL_C_CHAR;
> params->type.col_size = (SQLUINTEGER)length;
> params->type.strlen_or_indptr_array =
> - (SQLUINTEGER*)safe_malloc(num_param_values
> + (SQLLEN*)safe_malloc(num_param_values
> * sizeof(SQL_NTS));
> params->values.string =
> (byte *)safe_malloc((num_param_values + 1) *
> @@ -1977,8 +1940,15 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
> static void init_param_statement(int cols, int num_param_values,
> db_state *state, param_status *status)
> {
> + int i;
> +
> status -> param_status_array =
> (SQLUSMALLINT *)safe_malloc(num_param_values * sizeof(SQLUSMALLINT));
> +
> + for(i=0; i<num_param_values; i++) {
> + status -> param_status_array[i] = SQL_PARAM_PROCEED;
> + }
> +
> status -> params_processed = 0;
>
> if(!sql_success(SQLAllocHandle(SQL_HANDLE_STMT,
> diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h
> index 2e6146a..fb74bf8 100644
> --- a/lib/odbc/c_src/odbcserver.h
> +++ b/lib/odbc/c_src/odbcserver.h
> @@ -118,9 +118,9 @@ typedef struct {
> SQLSMALLINT sql;
> SQLUINTEGER col_size;
> SQLSMALLINT decimal_digits;
> - SQLUINTEGER len;
> - SQLINTEGER strlen_or_indptr;
> - SQLINTEGER *strlen_or_indptr_array;
> + SQLLEN len;
> + SQLLEN strlen_or_indptr;
> + SQLLEN *strlen_or_indptr_array;
> } col_type;
>
> typedef struct {
>
More information about the erlang-patches
mailing list