Skip to Content.
Sympa Menu

freetds - Re: [freetds] some ct_options / ct_diag questions

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "James K. Lowden" <jklowden AT freetds.org>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] some ct_options / ct_diag questions
  • Date: Sat, 13 Dec 2008 00:16:55 -0500

Greetings Tim,

> We are trying to get a CT-lib based driver between our software and a
> Sybase ASE backend to work with freetds as well,
> so it would be possible to transparently support SQL Server as a backend
>
> as well.

Ah. That is, you'd like you use ct-lib to connect to a Microsoft server.
And that naturally led you here. :-)

We get a patch now and then for ct-lib, but lately it hasn't gotten the
same time and attention the other libraries do. Mostly that's a function
of time and experience: no one actively working on the project ever used
ct-lib for much.

It does work, of course. sqsh and DBD::Sybase both use it. But the
feature set tends to be limited to what they need, because it's not too
often anyone else pipes up.

> ct_options(dbconn, CS_SET, CS_OPT_ANSIPERM, &cstrue, CS_UNUNSED,
> NULL)
>
> elicits the following server message
...
> text = "The datastream specifies a wrong option or commandl The
> datastream is 'TDS OPTION CMD'. This is an internal error"

We're not sure what to send to the server for that option. Here is the
code, from src/ctlib/ct.c:

switch (option) {
case CS_OPT_ANSIPERM:
case CS_OPT_STR_RTRUNC:
/* no documented tds option */
switch (*(CS_BOOL *) param) {
case CS_TRUE:
case CS_FALSE:
break; /* end valid choices */
default:
if (action == CS_SET)
return CS_FAIL;
}
break;

That results in an invalid command being sent, as the server reports. The
tds_submit_optioncmd() is not passed good data.

However, it might be easily fixed. Version 3.8 of Sybase's TDS 5.0
Functional Specification document says:


Name Value Description
TDS_OPT_ANSIPERM 36 Check permissions on search columns for update
clause.
TDS_OPT_STR_RTRUNC 37 ANSI string right trunc.

The include/tds.h definition of TDS_OPTION looks to be wrong, however.
I'm not sure where those values came from. The fix is straightforward but
a little tedious:

1. Bring TDS_OPTION into line with Sybase's definition, so that the
enumerated type can be passed directly into the datastream.

2. Adjust the TDS 7.0 part of tds_submit_optioncmd() to use the new
options.

3. Expand the list of CS_OPTIONS in cspublic.h. It's not clear to me why
that shouldn't also be an enumerated type or why the values can't be
identical to those used for TDS_OPTION.

4. Extend the boolean option map at the top of tds_submit_optioncmd().

That would satisfy your need AIUI.

> 2) I take it that support for the Open Client runtime configuration file
>
> does not work at all?

Yes, there's no support for that anywhere in the code.

> In the documentation it says that cs_config() is partially
> supported. In any case, the call cs_config(context, CS_SET,
> CS_APPNAME, (CS_VOID
> *)"my_app", CS_NULLTERM, NULL) simply fails.

Correct. It's not complicated add, though. See the code in
src/dblib/dblib.c::dbsetlname(). Call tds_set_app().

> 3) It looks like in-line message handling via ct_diag() is not supported
>
> in freetds, and a typedef for SQLCA is missing in the header file.

Looking at the code, that's supposed to work. It might be the victim of
bitrot, because error handling has seen a lot of work since that function
was written.

> For upsert we exploit the fact that the Sybase Open Client library
> automatically converts the client message that ASE generates
> for an update statement that affected no rows, into an SQLCA with an
> sqlcode of 100. So we can check for errors codes 100 and 2601 (with ASE)
> to decide whether or not to apply the alternate statement.

That sounds tricky to get right, no matter where it's done.

If I were you, I would consider extending FreeTDS in the direction you
need. Except for the last item, what you've pointed to is pretty
straight-ahead to fix. The underlying support is already in libtds and
the other APIs substantially implement the same features. I think getting
ct_diag repaired will likewise not be too bad, especially for someone who
knows what it's supposed to do.

Even fixing ct_diag to set the SQLCA correctly will be easier to correct
in ct-lib than in your application. Why? Because you'll either rip up
your application to route centralized message handling into your main
thread of control, or you'll do the same thing (more easily, say I) in
ct-lib itself, where it's already being done, thereby preserving your
application code and compatibility with Sybase's implementation.

Error message processing is inherently interrupt-driven (loosely speaking)
in TDS. The protocol guarantees errors arrive before any associated data.
Capturing the message and making it available via ct_diag() is quite
similar to what ODBC does, because ODBC has no callback-handler
functionality. (Inline is all there is.)

Mind, I don't get a commission, or even glory. *I* don't' myself use
ct-lib. I'm just offering my best technical advice. And, as a present,
an offer to guide you through the process if you get stuck. :-)

Thanks for your message. Hope the above helps.

--jkl




Archive powered by MHonArc 2.6.24.

Top of Page