[erlang-patches] [PATCH] ODBC server segfaults on 64-bit platform

Ingela Anderton Andin <>
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