Skip to Content.
Sympa Menu

freetds - Re: Help Freetds 0.53 - removing messages printed to STDERR

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Michael Horowitz" <michael.horowitz AT storagenetworks.com>
  • To: freetds AT franklin.oit.unc.edu
  • Subject: Re: Help Freetds 0.53 - removing messages printed to STDERR
  • Date: Wed, 2 Jan 2002 21:33:45 -0500


I tried out my fix and it works!!!
You should probably check it out to make sure that removing that second
swap doesn't break something else, since I am not positive that it is
completely unnecessary.
It is a simple change, but I'll paste a "diff -c" bellow so you can patch.

***************
*** 1135,1143 ****
/* message number */
/* swap bytes on bigendian systems (mlilback, 11/7/01) */
rc = tds_get_int(tds);
! #ifdef WORDS_BIGENDIAN
! tds_swap_bytes(&rc, 4);
! #endif
tds->msg_info->msg_number = rc;

/* msg state */
--- 1135,1141 ----
/* message number */
/* swap bytes on bigendian systems (mlilback, 11/7/01) */
rc = tds_get_int(tds);
!
tds->msg_info->msg_number = rc;

/* msg state */

Thanks for all your help. Please get back to me if it turns out that this
change is wrong.

--Mike

> Hello again,
>
> I am not really familiar with the code, but I used some the hints you gave
> me and took a quick look through the code. I think I have spotted the
> problem.
>
> In tds/token.c line 1139, you swap the bytes, but I think they are already
> swapped.
> Here is a section of the code:
> /* message number */
> /* swap bytes on bigendian systems (mlilback, 11/7/01) */
> rc = tds_get_int(tds);
> #ifdef WORDS_BIGENDIAN
> tds_swap_bytes(&rc, 4);
> #endif
> tds->msg_info->msg_number = rc;
>
> I looked at tds_get_int, and it already swaps the bytes:
> /*
> ** Get an int32 from the server.
> */
> TDS_INT tds_get_int(TDSSOCKET *tds)
> {
> unsigned char bytes[4];
>
> tds_get_n(tds, bytes, 4);
> #if WORDS_BIGENDIAN
> if (tds->emul_little_endian) {
> return TDS_BYTE_SWAP32(*(TDS_INT *)bytes);
> }
> #endif
> return *(TDS_INT *)bytes;
> }
>
> And, "tds->msg_info->msg_number" is a TDS_SMALLINT:
>
> typedef struct tds_msg_info {
> TDS_SMALLINT priv_msg_type;
> TDS_SMALLINT line_number;
> TDS_SMALLINT msg_number;
> TDS_SMALLINT msg_state;
> TDS_SMALLINT msg_level;
> TDS_CHAR *server;
> TDS_CHAR *message;
> TDS_CHAR *proc_name;
> TDS_CHAR *sql_state;
> } TDSMSGINFO;
>
> And, a TDS_SMALLINT is a short, which is 2 bytes:
> typedef short TDS_SMALLINT; /* 16 bit int */
>
> So, if the bytes are double swapped for "rc" and the 2 least significant
> bytes end up as 0, then when it is assigned to
> "tds->msg_info->msg_number", "tds->msg_info->msg_number" ends up as zero.
>
> I took a look in the "servermsg_cb()" like you suggested, and if the
> message nubmer is false(zero), then it calls "warn" with just the text of
> the message:
> if(srvmsg->msgnumber) {
> PerlIO_printf(DBILOGFP, "Server message: number=%ld
> severity=%ld ",
> srvmsg->msgnumber, srvmsg->severity);
> PerlIO_printf(DBILOGFP, "state=%ld line=%ld ",
> srvmsg->state, srvmsg->line);
> if (srvmsg->svrnlen > 0) {
> PerlIO_printf(DBILOGFP, "server=%s ", srvmsg->svrname);
> }
> if (srvmsg->proclen > 0) {
> PerlIO_printf(DBILOGFP, "procedure=%s ", srvmsg->proc);
> }
> PerlIO_printf(DBILOGFP, "text=%s\n", srvmsg->text);
> } else {
> warn("%s\n", srvmsg->text);
> }
>
> I modified my perl program to have a warn handler, and that was exactly
> it. The message is being printed as a warn message since it has no
> message number.
>
> So you seem to be correct. I am not familiar with the code, so maybe
> there is a reason for the double swapping... Tell me if I am wrong.
> I am going to remove the second swapping of bytes and see if it works.
>
> --Mike
>
> > Michael Horowitz writes:
> > > Hello again,
> > >
> > > I added an insert statement that violated a primary key constraint, and
> > > this is what I get:
> >
> > > Violation of PRIMARY KEY constraint 'PK_names'. Cannot insert duplicate
> > > key in object 'names'.
> > > The statement has been terminated.
> >
> > Right - this really looks like a bug in FreeTDS.
> >
> > If I run a similar script with the Sybase libraries I get:
> >
> > -> prepare for DBD::Sybase::db (DBI::db=HASH(0x81c5ac8)~0x81c5a68
> > 'insert dups values(1, 'testing too')')
> > New DBI::st (for DBD::Sybase::st, parent=DBI::db=HASH(0x81c5a68), id=)
> > dbih_setup_handle(DBI::st=HASH(0x81c5ae0)=>DBI::st=HASH(0x80f8930),
> > DBD::Sybase::st, 81c5af8, Null!)
> > dbih_make_com(DBI::db=HASH(0x81c5a68), DBD::Sybase::st, 396)
> > <- prepare= DBI::st=HASH(0x81c5ae0) at dups.pl line 8
> > -> execute for DBD::Sybase::st (DBI::st=HASH(0x81c5ae0)~0x80f8930)
> > syb_st_execute() -> ct_command() OK
> > syb_st_execute() -> ct_send() OK
> > st_next_result() -> ct_results(4048) == 1
> > st_next_result() -> ct_results(4046) == 1
> > ct_results() final retcode = -205
> > st_next_result() -> lasterr = 2601, lastsev = 14
> > st_next_result() -> restype is not data result, force failFlag
> > syb_st_execute() -> got CS_CMD_DONE: resetting ACTIVE, moreResults,
> > dyn_execed
> > !! ERROR: 2601 'Server message number=2601 severity=14 state=3 line=1
> > text=Attempt to insert duplicate key row in object 'dups' with unique
> > index 'dups_i_16960090731'
> > Server message number=3621 severity=10 state=0 line=1 text=Command has
> > been aborted.
> > '
> > <- execute= undef at dups.pl line 9
> > DBD::Sybase::st execute failed: Server message number=2601 severity=14
> > state=3 line=1 text=Attempt to insert duplicate key row in object 'dups'
> > with unique index 'dups_i_16960090731'
> > Server message number=3621 severity=10 state=0 line=1 text=Command has
> > been aborted.
> > <> DESTROY ignored for outer handle DBI::st=HASH(0x81c5ae0) (inner
> > DBI::st=HASH(0x80f8930))
> > -> DESTROY for DBD::Sybase::st (DBI::st=HASH(0x80f8930)~INNER)
> >
> >
> > In your case the servermsg_cb() function in dbdimp.c gets an error
> > message structure that does not have the error number set, possibly
> > because of the endian fiddling.
> >
> > I don't know how to get this fixed - I suspect that we'll have to wait
> > for Brian to get back...
> >
> > Michael
> > --
> > Michael Peppler - Data Migrations Inc. - http://www.mbay.net/~mpeppler
> > mpeppler AT peppler.org - mpeppler AT mbay.net
> > International Sybase User Group - http://www.isug.com




Archive powered by MHonArc 2.6.24.

Top of Page