1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

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.
This commit is contained in:
Michael Meskes
2006-08-15 06:40:20 +00:00
parent 58538a0ffc
commit b30da7ba5f
15 changed files with 1531 additions and 377 deletions

View File

@ -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;
@ -634,6 +606,12 @@ dtcvasc(char *str, timestamp * ts)
return 0;
}
int
dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue)
{
return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue);
}
int
dtsub(timestamp * ts1, timestamp * ts2, interval * 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;