aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/compatlib/informix.c
diff options
context:
space:
mode:
authorMichael Meskes <meskes@postgresql.org>2006-08-15 06:40:20 +0000
committerMichael Meskes <meskes@postgresql.org>2006-08-15 06:40:20 +0000
commitb30da7ba5f76b7411788dcce513761d79e6d137f (patch)
tree7c320269067bde66ca20a288216557c0a9910e9e /src/interfaces/ecpg/compatlib/informix.c
parent58538a0ffc7259419d1ee82feed93a9bef4bf726 (diff)
downloadpostgresql-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.c137
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;