Skip to Content.
Sympa Menu

freetds - RE: More on using FreeTDS on a server (was Re: [freetds] Server dumpscore...)

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "ZIGLIO, Frediano, VF-IT" <Frediano.Ziglio AT vodafone.com>
  • To: "FreeTDS Development Group" <freetds AT lists.ibiblio.org>
  • Subject: RE: More on using FreeTDS on a server (was Re: [freetds] Server dumpscore...)
  • Date: Mon, 19 Apr 2004 14:06:39 +0200

>
> Here's the latest on my efforts to use FreeTDS for
> server-side networking.
>
> First the bad news: Microsoft's ODBC driver for SQL Server
> still refuses
> to talk to my little server. All I get is a generic
> "Protocol error in
> TDS stream". I suspect I'm failing to send some critical token in the
> login response, but it's hard to be sure with an error
> message that vague.
>

I don't know too... never tried.

> Now a little the good news: I can now use the tsql program to submit
> queries, and get tables back. The tables don't look quite right --
> strings come across okay, but numbers are mangled. But I'm definitely
> making progress.
>
> And the real purpose of this message: Questions!
>
> * Can anybody recommend an alternative ODBC/TDS driver for
> Windows? One
> that, maybe, would give better error messages? Or it would
> also be okay
> if it simply worked, I suppose.
>

As James said ODBC compile under windows. Also you can enable logging.

> * I have a log, produced by FreeTDS, of the network traffic
> in my failed
> attempts to access my little SQL server via Microsoft's ODBC driver.
> Does anybody out there have a similar dump of a *successful* login?
> Nothing fancy, just a TDS4.2 login such as the "test connection"
> button in the ODBC Microsoft SQL Server Setup dialog.
>

It would be useful if you zip&mail the log..

> * What should I do about queries that don't result in tables?
> For example,
> tsql sends a "set textsize 64512" request. My server currently just
> sends token #253 (Result Set Done). Is that proper?
>

Yes and not. Any query end with a DONE token however if you issue a
batch of 3 select you get 3 done, if you issue a batch with 3 "set
textsize" you get only one DONE.

> * Are there any common "gotchas" when sending numbers? It
> kind of looks
> like tsql is printing the addresses of the numbers, instead of the
> numbers themselves -- the values are all similar, but never
> identical.
> I don't think it's an endian thing.
>

If similar they can't be a endian problem...

> * Can anybody spot any obvious problems with my table-sending
> function,
> below? The XXXX_t names are all types; their purpose
> should be pretty
> obvious, except that rows are represented as an array of
> value_t values.
> value_t is a union of all supported data types. For
> strings, it is a
> (char *) and the actual text of the string is appended to
> each row's
> value_t array; that way, when the row is freed so are all
> of its strings.
> Column types, names, etc. are stored in the table->col
> array. By looking
> at the log file, I have verified that my little SQL server is indeed
> sending garbage for integers; this isn't a bug in tsql.
>
> /* send a table to the client */
> void tdsprinttable(table)
> table_t table; /* the table to send */
> {
> TDSRESULTINFO *resinfo;/* FreeTDS library version of table */
> int r, c; /* row & column counters */
> int rowsize;/* maximum row memory needed */
> int offset; /* offset of field within row */
>
> /* allocate a FreeTDS table */
> resinfo = tds_alloc_results(table->ncols);
>
> /* fill in the column info for all columns */
> rowsize = 0;
> for (c = 0; c < table->ncols; c++)
> {
> /* fill in this column's info */
> switch (table->col[c].type)
> {
> case OP_STRING:
> resinfo->columns[c]->column_type = SYBCHAR;
> resinfo->columns[c]->column_size =
> table->col[c].width;
> break;
>

you should use tds_set_column_type

> case OP_INTEGER:
> resinfo->columns[c]->column_type = SYBINT4;
> resinfo->columns[c]->column_size = sizeof(long);
> break;
>
> case OP_NUMERIC:
> resinfo->columns[c]->column_type = SYBFLT8;
> resinfo->columns[c]->column_size =
> sizeof(double);
> break;
>
> case OP_BOOLEAN:
> resinfo->columns[c]->column_type = SYBBIT;
> resinfo->columns[c]->column_size = 1;
> break;
> }
> strcpy(resinfo->columns[c]->column_name,
> textnametext(table->col[c].name));
> resinfo->columns[c]->column_namelen =
>
> strlen(resinfo->columns[c]->column_name);
>
> /* for non-string data, the data offsets don't change so
> * we might as well set them here.
> */
> resinfo->columns[c]->column_offset = c *
> sizeof(value_t);
>
> /* add this column's row data size to rowmax */
> rowsize += resinfo->columns[c]->column_size;

see tds_add_row_column_size and tds_process_col_fmt in token.c

> }
>
> /* start the result, and send column info */
> tds_send_result(tds, resinfo);
> tds_send_174_token(tds, table->ncols);
>
> /* for each row... */
> for (r = 0; r < table->nrows; r++)
> {
> /* tell FreeTDS where the data is */
> resinfo->current_row = (unsigned char *)&table->row[r];
>
> /* convert the row */
> for (c = 0; c < table->ncols; c++)
> {
> /* most fields' offsets don't change, but we do
> * need to worry about strings.
> */
> if (table->col[c].type == OP_STRING)
> {
> resinfo->columns[c]->column_offset =
> (unsigned char
> *)table->row[r][c].string
> - resinfo->current_row;
> }
> }
>
> /* send the row */
> tds_send_row(tds, resinfo);

quite strange code... if I understand you don't use our row buffer but
rewrite column_offset and current_row...

> }
> resinfo->current_row = NULL;
>
> /* end the table */
> tds_send_253_token(tds, 16, table->nrows);
> tds_flush_packet(tds);
>
> /* clean up */
> tds_free_results(resinfo);
> didresult = 1;
> }
>

Why don't you join to FreeTDS group to improve our (rudimental and not
working) server ??

freddy77




Archive powered by MHonArc 2.6.24.

Top of Page