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:
@ -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;
|
||||
|
Reference in New Issue
Block a user