[freetds] Problems when using odbc : SQLPutData, SQLExecDirect, Decimals

ZIGLIO, Frediano, VF-IT Frediano.Ziglio at vodafone.com
Mon May 15 11:16:49 EDT 2006


> 
> 
> Using freetds (freetds-0.63 version) to access SqlServer from 
> Linux Redhat
> using ODBC.
> Encountered a couple of problems.  Diff files attached for changes --
> sources were for 0.63 version).
> 
> -----------------------------------------------------
> 
> Using SQLPutData with a RemoteProcedureCall results in error return.
> The code in SQLPutData needs to check if the statment is a RPC call.
> 
> odbc.c
> *** 4850,4856 ****
>   {
>   	INIT_HSTMT;
> 
> ! 	if (stmt->prepared_query || stmt->prepared_query_is_rpc) {
>   		/* TODO do some more tests before setting this flag */
>   		stmt->param_data_called = 1;
>   		ODBC_RETURN(stmt, 
> continue_parse_prepared_query(stmt, rgbValue,
> cbValue));
> --- 4849,4855 ----
>   {
>   	INIT_HSTMT;
> 
> ! 	if (stmt->prepared_query) {
>   		/* TODO do some more tests before setting this flag */
>   		stmt->param_data_called = 1;
>   		ODBC_RETURN(stmt, 
> continue_parse_prepared_query(stmt, rgbValue,
> cbValue));
> 
> ----------------------------------------------------------------------
> 
> If using SQLExecDirect (instead of SQLExecute) and calling 
> SQLParamData, the
> second set of calls to SQLParamData returns an error.
> The code in SQLExecDirect needs to clear the 
> param_data_called flag (as
> SQLExecute does).
> 
> odbc.c
> *** 2529,2535 ****
>   	/* count placeholders */
>   	/* note: szSqlStr can be no-null terminated, so first 
> we set query and
> then count placeholders */
>   	stmt->param_count = tds_count_placeholders(stmt->query);
> - 	stmt->param_data_called = 0;
> 
>   	if (SQL_SUCCESS != prepare_call(stmt)) {
>   		/* TODO return another better error, 
> prepare_call should set error ?? */
> --- 2529,2534 ----
> 

Very fine. Applied to 0.63, 0.64 and CVS HEAD !!!
Can you provide a small test ??

> 
> Passing a SQL_DECIMAL parameter where the src_type is 
> Character and the
> dest_type is SQL_DECIMAL -- i.e. the program passes the value 
> in as string
> but type is SQL_DECIMAL  The sql2tds routine needs to set up 
> the precision
> and scale for tds_convert based on the dest_type (otherwise 
> the conversion
> fails).    Using curcol values seemed to work for me.
> 
> sql2tds.c
> *** 262,277 ****
>   		/* TODO intervals */
>   	}
> 
> - 	switch (dest_type)
> - 	{
> - 	case SYBDECIMAL:
> - 	case SYBNUMERIC:
> - 		/* set output */
> - 		/* TODO use descriptors informations ?? */
> - 		ores.n.precision = curcol->column_prec;
> - 		ores.n.scale = curcol->column_scale;
> - 	}
> -
>   	res = tds_convert(dbc->env->tds_ctx, src_type, src, 
> len, dest_type,
> &ores);
>   	if (res < 0)
>   		return SQL_ERROR;
> --- 262,267 ----
> 
> --------------------------------------------------------------
> --------------
> -----------------
> 
> Passing a decimal value fails (I can't remember now exactly how).  The
> problem was that in the tds_convert routine, the 
> curcol->column_size was 0.
> So the res value (length) returned from tds_convert (which 
> was correct) was
> reset to 0 in the code below.  This resulted in 0 bytes being 
> memcpy'd.
> This had to do with the fact that column_varint_size was 1 
> and the code to
> deal with that.
> 
> The "fix" I put in for my case (below) was to not reset res 
> if column_size
> was 0.  But I'm not sure that this would be the correct fix 
> in all cases
> (not having taken the time to understand what 
> column_varint_size is all
> about).
> 
> *** 279,285 ****
> 
>   	/* truncate ?? */
>   	/* TODO what happen for blobs ?? */
> ! 	if ((curcol->column_size != 0) && (res > curcol->column_size))
>   		res = curcol->column_size;
>   	curcol->column_cur_size = res;
> 
> --- 269,275 ----
> 
>   	/* truncate ?? */
>   	/* TODO what happen for blobs ?? */
> ! 	if (res > curcol->column_size)
>   		res = curcol->column_size;
>   	curcol->column_cur_size = res;
> 
> ---------------------------------------------------------------
> 
> Charlene Herring
> 
> 

For sql2tds.c these fixes was just present in 0.64 (with a test too) so
I backported fixes. You can find cumulative patch at
http://freetds.sf.net

bye
  freddy77




More information about the FreeTDS mailing list