diff options
author | Michael Meskes <meskes@postgresql.org> | 2006-08-15 06:40:20 +0000 |
---|---|---|
committer | Michael Meskes <meskes@postgresql.org> | 2006-08-15 06:40:20 +0000 |
commit | b30da7ba5f76b7411788dcce513761d79e6d137f (patch) | |
tree | 7c320269067bde66ca20a288216557c0a9910e9e /src/interfaces/ecpg/compatlib/informix.c | |
parent | 58538a0ffc7259419d1ee82feed93a9bef4bf726 (diff) | |
download | postgresql-b30da7ba5f76b7411788dcce513761d79e6d137f.tar.gz postgresql-b30da7ba5f76b7411788dcce513761d79e6d137f.zip |
Added lots of SoC stuff made by Joachim.
Fixed broken newline on Windows.
Fixed a nasty buffer underrun that only occured when using Informix
no_indicator NULL setting on timestamps and intervals.
Diffstat (limited to 'src/interfaces/ecpg/compatlib/informix.c')
-rw-r--r-- | src/interfaces/ecpg/compatlib/informix.c | 137 |
1 files changed, 59 insertions, 78 deletions
diff --git a/src/interfaces/ecpg/compatlib/informix.c b/src/interfaces/ecpg/compatlib/informix.c index 65da37dcdee..a8a95f4e437 100644 --- a/src/interfaces/ecpg/compatlib/informix.c +++ b/src/interfaces/ecpg/compatlib/informix.c @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/compatlib/informix.c,v 1.46 2006/06/26 09:20:09 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/compatlib/informix.c,v 1.47 2006/08/15 06:40:19 meskes Exp $ */ #include <stdlib.h> #include <string.h> @@ -122,12 +122,15 @@ deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, n int decadd(decimal *arg1, decimal *arg2, decimal *sum) { + errno = 0; deccall3(arg1, arg2, sum, PGTYPESnumeric_add); if (errno == PGTYPES_NUM_OVERFLOW) return ECPG_INFORMIX_NUM_OVERFLOW; - else if (errno != 0) + else if (errno == PGTYPES_NUM_UNDERFLOW) return ECPG_INFORMIX_NUM_UNDERFLOW; + else if (errno != 0) + return -1; else return 0; } @@ -179,6 +182,7 @@ deccvasc(char *cp, int len, decimal *np) ret = ECPG_INFORMIX_NUM_UNDERFLOW; else { + errno = 0; result = PGTYPESnumeric_from_asc(str, NULL); if (!result) { @@ -280,6 +284,7 @@ decdiv(decimal *n1, decimal *n2, decimal *result) int i; + errno = 0; i = deccall3(n1, n2, result, PGTYPESnumeric_div); if (i != 0) @@ -304,6 +309,7 @@ decmul(decimal *n1, decimal *n2, decimal *result) { int i; + errno = 0; i = deccall3(n1, n2, result, PGTYPESnumeric_mul); if (i != 0) @@ -325,6 +331,7 @@ decsub(decimal *n1, decimal *n2, decimal *result) { int i; + errno = 0; i = deccall3(n1, n2, result, PGTYPESnumeric_sub); if (i != 0) @@ -371,13 +378,25 @@ dectoasc(decimal *np, char *cp, int len, int right) return -1; /* - * TODO: have to take care of len here and create exponatial notion if - * necessary + * TODO: have to take care of len here and create exponential notation + * if necessary */ - strncpy(cp, str, len); - free(str); - - return 0; + if ((int) (strlen(str) + 1) > len) + { + if (len > 1) + { + cp[0] = '*'; + cp[1] = '\0'; + } + free(str); + return -1; + } + else + { + strcpy(cp, str); + free(str); + return 0; + } } int @@ -474,59 +493,7 @@ rdatestr(date d, char *str) int rstrdate(char *str, date * d) { - date dat; - char strbuf[10]; - int i, - j; - - rsetnull(CDATETYPE, (char *) &dat); - - /* - * we have to flip the year month date around for postgres expects - * yyyymmdd - * - */ - - for (i = 0, j = 0; i < 10; i++) - { - /* ignore non-digits */ - if (isdigit((unsigned char) str[i])) - { - - /* j only increments if it is a digit */ - switch (j) - { - /* stick the month into the 4th, 5th position */ - case 0: - case 1: - strbuf[j + 4] = str[i]; - break; - /* stick the day into the 6th, and 7th position */ - case 2: - case 3: - strbuf[j + 4] = str[i]; - break; - - /* stick the year into the first 4 positions */ - case 4: - case 5: - case 6: - case 7: - strbuf[j - 4] = str[i]; - break; - - } - j++; - } - } - strbuf[8] = '\0'; - dat = PGTYPESdate_from_asc(strbuf, NULL); - - if (errno && errno != PGTYPES_DATE_BAD_DATE) - return ECPG_INFORMIX_BAD_DATE; - - *d = dat; - return 0; + return rdefmtdate(d, "mm/dd/yyyy", str); } void @@ -554,6 +521,7 @@ rdefmtdate(date * d, char *fmt, char *str) /* TODO: take care of DBCENTURY environment variable */ /* PGSQL functions allow all centuries */ + errno = 0; if (PGTYPESdate_defmt_asc(d, fmt, str) == 0) return 0; @@ -576,6 +544,7 @@ rdefmtdate(date * d, char *fmt, char *str) int rfmtdate(date d, char *fmt, char *str) { + errno = 0; if (PGTYPESdate_fmt_asc(d, fmt, str) == 0) return 0; @@ -618,15 +587,18 @@ dtcvasc(char *str, timestamp * ts) int i; char **endptr = &str; + errno = 0; ts_tmp = PGTYPEStimestamp_from_asc(str, endptr); i = errno; if (i) + /* TODO: rewrite to Informix error codes */ return i; if (**endptr) { /* extra characters exist at the end */ return ECPG_INFORMIX_EXTRA_CHARS; } + /* TODO: other Informix error codes missing */ /* everything went fine */ *ts = ts_tmp; @@ -635,6 +607,12 @@ dtcvasc(char *str, timestamp * ts) } int +dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue) +{ + return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue); +} + +int dtsub(timestamp * ts1, timestamp * ts2, interval * iv) { return PGTYPEStimestamp_sub(ts1, ts2, iv); @@ -659,6 +637,7 @@ dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr) int intoasc(interval * i, char *str) { + errno = 0; str = PGTYPESinterval_to_asc(i); if (!str) @@ -797,17 +776,21 @@ rfmtlong(long lng_val, char *fmt, char *outbuf) /* qualify, where we are in the value_string */ if (k < 0) { - if (leftalign) - { - /* can't use strncat(,,0) here, Solaris would freek out */ - temp[j] = '\0'; - break; - } blank = 1; if (k == -2) entity = 1; else if (k == -1) sign = 1; + if (leftalign) + { + /* can't use strncat(,,0) here, Solaris would freek out */ + if (sign) + if (signdone) + { + temp[j] = '\0'; + break; + } + } } /* if we're right side of the right-most dot, print '0' */ if (dotpos >= 0 && dotpos <= i) @@ -829,6 +812,9 @@ rfmtlong(long lng_val, char *fmt, char *outbuf) fmtchar = lastfmt; else fmtchar = fmt[i]; + /* waiting for the sign */ + if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-') + continue; /* analyse this format-char */ switch (fmtchar) { @@ -854,9 +840,6 @@ rfmtlong(long lng_val, char *fmt, char *outbuf) else tmp[0] = value.val_string[k]; break; - case '<': - tmp[0] = value.val_string[k]; - break; case '-': if (sign && value.sign == '-' && !signdone) { @@ -904,6 +887,9 @@ rfmtlong(long lng_val, char *fmt, char *outbuf) else tmp[0] = value.val_string[k]; break; + case '<': + tmp[0] = value.val_string[k]; + break; default: tmp[0] = fmt[i]; } @@ -950,8 +936,9 @@ byleng(char *str, int len) void ldchar(char *src, int len, char *dest) { - memmove(dest, src, len); - dest[len] = 0; + int dlen = byleng(src, len); + memmove(dest, src, dlen); + dest[dlen] = '\0'; } int @@ -978,12 +965,6 @@ rtypwidth(int sqltype, int sqllen) return 0; } -int -dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue) -{ - return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue); -} - static struct var_list { int number; |