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:58:16 -0500


Hey, sorry for the mistake, but I just realized you write the DBD::Sybase
module, not the freetds stuff. So, when I say "you" I mean whoever it is
that develops the freetds libs, which I guess is the "Brian" you mentioned
;).

--Mike

> 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