Thread: ecpg long int problem on alpha + fix
Hi, we had a problem on Alpha that in interfaces/ecpg/lib/typename.c we have HAVE_LONG_INT_64 defined, but not HAVE_LONG_LONG_INT_64. Consequently no code is included for long ints and typename calls *abort*. I put in a few lines that check for HAVE_LONG_INT_64 and seem to generate the right code. I've got a new version of typename.c attached. It would be good if Michael could review and get this into 7.1. Cheers, Adriaan#include "config.h" #include <stdlib.h> #include "ecpgtype.h" #include "ecpglib.h" #include "extern.h" #include "sql3types.h" #include "pg_type.h" /* * This function is used to generate the correct type names. */ const char * ECPGtype_name(enum ECPGttype typ) { switch (typ) { case ECPGt_char: return "char"; case ECPGt_unsigned_char: return "unsigned char"; case ECPGt_short: return "short"; case ECPGt_unsigned_short: return "unsigned short"; case ECPGt_int: return "int"; case ECPGt_unsigned_int: return "unsigned int"; case ECPGt_long: return "long"; case ECPGt_unsigned_long: return "unsigned long"; #if defined(HAVE_LONG_LONG_INT_64) case ECPGt_long_long: return "long long"; case ECPGt_unsigned_long_long: return "unsigned long long"; #elif defined(HAVE_LONG_INT_64) case ECPGt_long_long: return "long int"; case ECPGt_unsigned_long_long: return "unsigned long int"; #endif /* HAVE_LONG_LONG_INT_64 */ case ECPGt_float: return "float"; case ECPGt_double: return "double"; case ECPGt_bool: return "bool"; case ECPGt_varchar: return "varchar"; case ECPGt_char_variable: return "char"; default: abort(); } return NULL; } unsigned int ECPGDynamicType(Oid type) { switch (type) { case BOOLOID:return SQL3_BOOLEAN; /* bool */ case INT2OID: return SQL3_SMALLINT; /* int2 */ case INT4OID: return SQL3_INTEGER;/* int4 */ case TEXTOID: return SQL3_CHARACTER; /* text */ case FLOAT4OID: return SQL3_REAL; /* float4 */ case FLOAT8OID: return SQL3_DOUBLE_PRECISION; /* float8 */ case BPCHAROID: return SQL3_CHARACTER; /* bpchar */ case VARCHAROID: return SQL3_CHARACTER_VARYING; /* varchar */ case DATEOID: return SQL3_DATE_TIME_TIMESTAMP; /* date */ case TIMEOID: return SQL3_DATE_TIME_TIMESTAMP; /* time */ case TIMESTAMPOID: return SQL3_DATE_TIME_TIMESTAMP; /* datetime */ case NUMERICOID: return SQL3_NUMERIC;/* numeric */ default: return -type; } }
On Tue, Apr 03, 2001 at 06:32:25PM +0300, Adriaan Joubert wrote: > we had a problem on Alpha that in interfaces/ecpg/lib/typename.c we > have > HAVE_LONG_INT_64 defined, but not HAVE_LONG_LONG_INT_64. Consequently no Sure since that means your long int and not your long long int is 64 bits. > code is included for long ints and typename calls *abort*. I put in a > few lines that check for HAVE_LONG_INT_64 and seem to generate the right Why is this needed? What you do is use "long long" as variable type for 64 bits integer. But on the alpha you do not need "long long", just use "long int" instead. Or did I misunderstand something? Michael -- Michael Meskes Michael@Fam-Meskes.De Go SF 49ers! Go Rhein Fire! Use Debian GNU/Linux! Use PostgreSQL!
On Wed, Apr 04, 2001 at 03:35:34PM +0300, Adriaan Joubert wrote: > OK, I see. Problem is that without the fix ecpg aborts when writing to a > table with an int8 column using valid code. Sorry, I still don't seem to understand that. Data between ecpg and the backend is tranfered in ascii only. What exactly happens? > all exist on alpha and are all 64 bits, but HAVE_LONG_LONG_INT_64 is not > defined, so ecpg cannot handle ECPGt_long_long types. It is not clear to I see. I was under the impression that HAVE_LONG_LONG_INT_64 should be defined if long long int is 64 bit integer which of course it is on the alpha. > me what the best thing is to fix here -- possibly configure needs to set > HAVE_LONG_LONG_INT_64 (which solves the problem on alpha as well), but I > do not know what the consequences of that are. I would think that this is the correct solution. After all there is a #ifdef HAVE_LONG_LONG_INT_64 in the backend as well. Anyone else with more knowledge about HAVE_LONG_LONG_INT_64 dare to comment? Michael -- Michael Meskes Michael@Fam-Meskes.De Go SF 49ers! Go Rhein Fire! Use Debian GNU/Linux! Use PostgreSQL!
Michael Meskes <meskes@postgresql.org> writes: >> all exist on alpha and are all 64 bits, but HAVE_LONG_LONG_INT_64 is not >> defined, so ecpg cannot handle ECPGt_long_long types. It is not clear to > I see. I was under the impression that HAVE_LONG_LONG_INT_64 should be > defined if long long int is 64 bit integer which of course it is on the > alpha. No! Look at the configure test! It doesn't bother to investigate long long int if it finds that long int will serve. At most one of the two symbols will be defined. I believe that that is the correct way, at least for the backend's purposes, since we only want to compile one set of int64-related code. regards, tom lane
Michael Meskes wrote: > > On Wed, Apr 04, 2001 at 03:35:34PM +0300, Adriaan Joubert wrote: > > OK, I see. Problem is that without the fix ecpg aborts when writing to a > > table with an int8 column using valid code. > > Sorry, I still don't seem to understand that. Data between ecpg and the > backend is tranfered in ascii only. What exactly happens? This has nothing to do with the backend. ecpg itself core-dumps after calling abort() at the end of the switch statement in typename.c, when processing a .pgc file. As people complained to me about ecpg core-dumping I tried to find out why and then found that it called the abort() at the end of this switch ;-) I have not looked at ecpg in any detail, but I expect that the types in typename.c are derived from the host variables in some way. If we have an int8 column in a table, we need to use a 64 bit type, i.e. a 'long long', and as HAVE_LONG_LONG_INT_64 is not true, no such type is compiled into the switch. As HAVE_LONG_INT_64 is defined on alpha, my fix fixes this for alpha, and any other platform where HAVE_LONG_INT_64 is defined but not HAVE_LONG_LONG_INT_64. From Tom's mail I gather that it is not an option to define HAVE_LONG_LONG_INT_64 on alpha, so I think this patch, or something similar, is necessary. Apologies for not being clear enough initially. Cheers, Adriaan
On Wed, Apr 04, 2001 at 05:47:50PM +0300, Adriaan Joubert wrote: > This has nothing to do with the backend. ecpg itself core-dumps after > calling abort() at the end of the switch statement in typename.c, when > processing a .pgc file. As people complained to me about ecpg Yes, I did understand that. What I do not understand is the problem with long long int. On an alpha the normal long int should be sufficient for storing int8. > core-dumping I tried to find out why and then found that it called the > abort() at the end of this switch ;-) This abort() is used to make sure ecpg stops if a type id is found that does not exist. Normally this must not happen. Ah, now I understand, the parser accepts long long but typename.c does not like that. It should be sufficient to just remove the #ifdef in typename.c since nothing serious is happening there. The reason for this precompiler define is to make sure that no long long code is generated that the C compiler cannot cope with. But in typename.c there is no code generated other than the creation of a string. Could you please try to just remove the cpp flag? Also I wonder why you are using "long long int" instead of just "long int" in your C program. Well that is the people who complained to you. > an int8 column in a table, we need to use a 64 bit type, i.e. a 'long > long', and as HAVE_LONG_LONG_INT_64 is not true, no such type is I thought "long int" is 64 bits too, so that should be sufficient. > From Tom's mail I gather that it is not an option to define > HAVE_LONG_LONG_INT_64 on alpha, so I think this patch, or something > similar, is necessary. Thanks to Tom btw for setting this straight. > Apologies for not being clear enough initially. I think you were pretty clear from teh get go, but I simply misunderstood you. Michael -- Michael Meskes Michael@Fam-Meskes.De Go SF 49ers! Go Rhein Fire! Use Debian GNU/Linux! Use PostgreSQL!
> Could you please try to just remove the cpp flag? Also I wonder why you are > using "long long int" instead of just "long int" in your C program. Well > that is the people who complained to you. Yes, dropping the CPP flags solves the problem for us. I assume all platforms have long long now? We used long long as this seems to be pretty consistently 64 bits on different platforms, and our code runs on Tru64, PC linux and openBSD. It also agrees with the CORBA type naming for 64 bit ints, so it makes the type naming more consistent. Thanks, Adriaan
Adriaan Joubert <a.joubert@albourne.com> writes: > Yes, dropping the CPP flags solves the problem for us. I assume all > platforms have long long now? Surely you jest. regards, tom lane
Tom Lane wrote: > > Adriaan Joubert <a.joubert@albourne.com> writes: > > Yes, dropping the CPP flags solves the problem for us. I assume all > > platforms have long long now? > > Surely you jest. Yep, it was a rhetorical question. I think we probably do need the CPP defines from my patch in there, so that it really doesn't work on platforms that do not have int8. But I do not know the ins-and-outs of the ecpg code, so that's Michael's call. As long as it works on my shiny alpha-boxes at the end of it all I'm happy ;-) Adriaan
On Thu, Apr 05, 2001 at 09:13:49AM +0300, Adriaan Joubert wrote: > I think we probably do need the CPP defines from my patch in there, so Not exactly. The test in typename.c does not make sense at all. It will be removed. But there are other places where it is needed. Or can I safely assume that if HAVE_LONG_INT_64 is defined then HAVE_LONG_LONG_INT_64 also is true, although not defined? Hmm, thinking about it, how about using long instead of long long if HAVE_LONG_LONG_INT_64 is undefined? Michael -- Michael Meskes Michael@Fam-Meskes.De Go SF 49ers! Go Rhein Fire! Use Debian GNU/Linux! Use PostgreSQL!
Michael Meskes wrote: > > On Tue, Apr 03, 2001 at 06:32:25PM +0300, Adriaan Joubert wrote: > > we had a problem on Alpha that in interfaces/ecpg/lib/typename.c we > > have > > HAVE_LONG_INT_64 defined, but not HAVE_LONG_LONG_INT_64. Consequently no > > Sure since that means your long int and not your long long int is 64 bits. > > > code is included for long ints and typename calls *abort*. I put in a > > few lines that check for HAVE_LONG_INT_64 and seem to generate the right > > Why is this needed? What you do is use "long long" as variable type for 64 > bits integer. But on the alpha you do not need "long long", just use "long > int" instead. > > Or did I misunderstand something? OK, I see. Problem is that without the fix ecpg aborts when writing to a table with an int8 column using valid code. long int long long long long int all exist on alpha and are all 64 bits, but HAVE_LONG_LONG_INT_64 is not defined, so ecpg cannot handle ECPGt_long_long types. It is not clear to me what the best thing is to fix here -- possibly configure needs to set HAVE_LONG_LONG_INT_64 (which solves the problem on alpha as well), but I do not know what the consequences of that are. Cheers, Adriaan