Thread: ODBC int2 parameters to pg function

ODBC int2 parameters to pg function

From
Gary Doades
Date:
I have discovered a problem with passing parameters to a pg function
using the ODBC driver.

I have delcared a pg function as:

function GENERATE_TIMESHEETS(timestamp,timestamp,smallint,smallint)
....

I have a .NET program that uses the following:
cmd.CommandText = "SELECT GENERATE_TIMESHEETS(?,?,?,?)";
cmd.Parameters.Add("DATE_FROM",OdbcType.DateTime,8);
cmd.Parameters.Add("DATE_TO",OdbcType.DateTime,8);
cmd.Parameters.Add("TIME_FROM",OdbcType.SmallInt,2);
cmd.Parameters.Add("TIME_TO",OdbcType.SmallInt,2);

I then assign the parameter values and execute the statement.

pg returns an error stating
GENERATE_TIMESHEETS(timestamp,timestamp,int4,int4) cannot be found

It appears that the ODBC driver is not typecasting the smallint (int2)
parameters correctly for the function call.

Can anyone shed any light on this?

Thanks
Gary.


Re: ODBC int2 parameters to pg function

From
Tom Lane
Date:
Gary Doades <gpd@cwcom.net> writes:
> I have delcared a pg function as:
> function GENERATE_TIMESHEETS(timestamp,timestamp,smallint,smallint)
> ....

You're probably best off to declare the inputs as integer not smallint.
Integer literals are assumed to be int4 by default, and since there's
no implicit downcast to int2 (anymore), writing a function this way will
require you to cast to smallint explicitly a lot.  It's seldom worth
that notational hassle.  You can cast inside the function if you really
need the values to be int2 inside it.

            regards, tom lane

Re: ODBC int2 parameters to pg function

From
"Gary Doades"
Date:
Tom,
Thanks for the reply.

I agree with your solution in principle, but I have nearly 100 databases
so far across several servers and many at customer sites. I am trying to
migrate some from and maintain compatibility with MS SQLServer.
These quantities have been smallint for quite some time. Changing the
underlying database types now would be a problem.

I can cast inside the function, this is my current solution. Given that
there is no implicit downcast wouldn't the best solution be to get the
ODBC driver do the cast on the function call?

Thanks,
Gary.

On 13 Mar 2004 at 19:40, Tom Lane wrote:

> Gary Doades <gpd@cwcom.net> writes:
> > I have delcared a pg function as:
> > function GENERATE_TIMESHEETS(timestamp,timestamp,smallint,smallint)
> > ....
>
> You're probably best off to declare the inputs as integer not smallint.
> Integer literals are assumed to be int4 by default, and since there's
> no implicit downcast to int2 (anymore), writing a function this way will
> require you to cast to smallint explicitly a lot.  It's seldom worth
> that notational hassle.  You can cast inside the function if you really
> need the values to be int2 inside it.
>
>             regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 7: don't forget to increase your free space map settings



Re: ODBC int2 parameters to pg function

From
Tom Lane
Date:
"Gary Doades" <gpd@gpdnet.co.uk> writes:
> I can cast inside the function, this is my current solution. Given that
> there is no implicit downcast wouldn't the best solution be to get the
> ODBC driver do the cast on the function call?

I think that would likely fix this example at the cost of breaking many
others.  Exactly what conditions would you have the ODBC driver cast to
int2 under?

            regards, tom lane

Re: ODBC int2 parameters to pg function

From
"Gary Doades"
Date:
I don't see how it would break anything. I the case where the driver is substituting
ODBC parameters it ought to substitute (bind) the datatype that you have asked for.

In the case of "Select a_func(?,?)". If the two parameters are timestamp and smallint,
then the ODBC bind function calls specify these datatypes. Currently the ODBC
driver calls the function with a timestamp and an int4 parameter, where it should call
it with a timestamp and an int2 parameter.

I have checked a few other datatypes and looked at the "mylog" output. It seems that
dates, timestamp, numeric, floats are all explicitly typecast by the ODBC driver to
make sure the pg function gets called correctly, but not int2.

I'm not suggesting that general SQL strings are scanned and typecasts inserted.
Where functions/statements are called with parameters and those parameters then
substitued (bound) at run-time then it should get the types right where it matters.
AFAICS it is only int2 types that are not typecast. All other datatypes (except string
and int4 which don't need it) are typecast explicitly by the driver before being passed
to the server.

Regards,
Gary.

On 14 Mar 2004 at 12:30, Tom Lane wrote:

> "Gary Doades" <gpd@gpdnet.co.uk> writes:
> > I can cast inside the function, this is my current solution. Given that
> > there is no implicit downcast wouldn't the best solution be to get the
> > ODBC driver do the cast on the function call?
>
> I think that would likely fix this example at the cost of breaking many
> others.  Exactly what conditions would you have the ODBC driver cast to
> int2 under?
>
>             regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
>                http://archives.postgresql.org



Re: ODBC int2 parameters to pg function

From
Tom Lane
Date:
"Gary Doades" <gpd@gpdnet.co.uk> writes:
> AFAICS it is only int2 types that are not typecast. All other
> datatypes (except string and int4 which don't need it) are typecast
> explicitly by the driver before being passed to the server.

I see.  AFAIR you hadn't mentioned that you were declaring the parameter
as smallint to ODBC.  I tend to agree that a cast should be added in
that case.  It's not my code though ...

            regards, tom lane

Re: ODBC int2 parameters to pg function

From
"Gary Doades"
Date:
Thanks Tom,

I did actually put the parameter binding examples in my original post,
but as they are in .NET speak it may not have been obvious.

I guess I should try to get this on the "things to do with the ODBC"
driver list. I should be able to look at the code myself, but I will have to
remember how to speak C.

Thanks again,
Gary.


On 14 Mar 2004 at 13:24, Tom Lane wrote:

> "Gary Doades" <gpd@gpdnet.co.uk> writes:
> > AFAICS it is only int2 types that are not typecast. All other
> > datatypes (except string and int4 which don't need it) are typecast
> > explicitly by the driver before being passed to the server.
>
> I see.  AFAIR you hadn't mentioned that you were declaring the parameter
> as smallint to ODBC.  I tend to agree that a cast should be added in
> that case.  It's not my code though ...
>
>             regards, tom lane