aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Meskes <meskes@postgresql.org>2003-07-01 12:40:52 +0000
committerMichael Meskes <meskes@postgresql.org>2003-07-01 12:40:52 +0000
commit2bdd2e5dcff20e4cf5987c901a71b794808d582b (patch)
treee158aaeb7ac2ab4db9e2e738e6be2aefa9cf4a50 /src
parentf973b74583c24e28ff8977d0fdd455474705604a (diff)
downloadpostgresql-2bdd2e5dcff20e4cf5987c901a71b794808d582b.tar.gz
postgresql-2bdd2e5dcff20e4cf5987c901a71b794808d582b.zip
Use ISO dates in pgtypeslib by default.
Applied patch by Philip Yarra to fix some thread issues. Added a new data type "decimal" which is mostly the same as our "numeric" but uses a fixed length array to store the digits. This is for compatibility with Informix and maybe others.
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/ecpg/ChangeLog8
-rw-r--r--src/interfaces/ecpg/compatlib/informix.c285
-rw-r--r--src/interfaces/ecpg/ecpglib/connect.c28
-rw-r--r--src/interfaces/ecpg/ecpglib/data.c8
-rw-r--r--src/interfaces/ecpg/ecpglib/execute.c21
-rw-r--r--src/interfaces/ecpg/ecpglib/misc.c14
-rw-r--r--src/interfaces/ecpg/ecpglib/typename.c4
-rw-r--r--src/interfaces/ecpg/include/decimal.h2
-rw-r--r--src/interfaces/ecpg/include/ecpgtype.h4
-rw-r--r--src/interfaces/ecpg/include/pgtypes_numeric.h16
-rw-r--r--src/interfaces/ecpg/include/sqltypes.h2
-rw-r--r--src/interfaces/ecpg/pgtypeslib/numeric.c44
-rw-r--r--src/interfaces/ecpg/pgtypeslib/timestamp.c2
-rw-r--r--src/interfaces/ecpg/preproc/preproc.y35
-rw-r--r--src/interfaces/ecpg/preproc/type.c3
-rw-r--r--src/interfaces/ecpg/test/Makefile4
-rw-r--r--src/interfaces/ecpg/test/num_test.pgc6
-rw-r--r--src/interfaces/ecpg/test/test_informix.pgc7
18 files changed, 349 insertions, 144 deletions
diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 32cb6f40ec8..ad428b5da01 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -1533,6 +1533,14 @@ Sun Jun 29 11:22:48 CEST 2003
around. PostgreSQL numeric type remains the same.
- In INFORMIX_SE mode with autcommit set, make all cursors be "with
hold". Is this really they way SE behaves?
+
+Tue Jul 1 11:57:56 CEST 2003
+
+ - Use ISO dates in pgtypeslib by default.
+ - Applied patch by Philip Yarra to fix some thread issues.
+ - Added a new data type "decimal" which is mostly the same as our
+ "numeric" but uses a fixed length array to store the digits. This is
+ for compatibility with Informix and maybe others.
- Set ecpg version to 3.0.0
- Set ecpg library to 4.0.0
- Set pgtypes library to 1.0.0
diff --git a/src/interfaces/ecpg/compatlib/informix.c b/src/interfaces/ecpg/compatlib/informix.c
index 71f914d0369..3bdbce693e0 100644
--- a/src/interfaces/ecpg/compatlib/informix.c
+++ b/src/interfaces/ecpg/compatlib/informix.c
@@ -11,50 +11,115 @@
char * ECPGalloc(long, int);
-/* we start with the numeric functions */
-int
-decadd(Numeric *arg1, Numeric *arg2, Numeric *sum)
+static int
+deccall2(Decimal *arg1, Decimal *arg2, int (*ptr)(Numeric *, Numeric *))
{
- Numeric *temp_sum = malloc(sizeof(Numeric)) ;
+ Numeric *a1, *a2;
int i;
+
+ if ((a1 = PGTYPESnumeric_new()) == NULL)
+ return -1211;
- if (temp_sum == NULL)
+ if ((a2 = PGTYPESnumeric_new()) == NULL)
+ {
+ PGTYPESnumeric_free(a1);
return -1211;
+ }
+
+ if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
+ {
+ PGTYPESnumeric_free(a1);
+ PGTYPESnumeric_free(a2);
+ return -1211;
+ }
- i = PGTYPESnumeric_add(arg1, arg2, temp_sum);
+ if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
+ {
+ PGTYPESnumeric_free(a1);
+ PGTYPESnumeric_free(a2);
+ return -1211;
+ }
+
+ i = (*ptr)(a1, a2);
+
+ PGTYPESnumeric_free(a1);
+ PGTYPESnumeric_free(a2);
+
+ return (i);
+}
- if (i == 0) /* No error */
+static int
+deccall3(Decimal *arg1, Decimal *arg2, Decimal *result, int (*ptr)(Numeric *, Numeric *, Numeric *))
+{
+ Numeric *a1, *a2, *nres;
+ int i;
+
+ if ((a1 = PGTYPESnumeric_new()) == NULL)
+ return -1211;
+
+ if ((a2 = PGTYPESnumeric_new()) == NULL)
{
+ PGTYPESnumeric_free(a1);
+ return -1211;
+ }
- if (PGTYPESnumeric_copy(temp_sum, sum) !=0)
- return -1211;
+ if ((nres = PGTYPESnumeric_new()) == NULL)
+ {
+ PGTYPESnumeric_free(a1);
+ PGTYPESnumeric_free(a2);
+ return -1211;
+ }
- free(temp_sum);
- return 0;
+ if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
+ {
+ PGTYPESnumeric_free(a1);
+ PGTYPESnumeric_free(a2);
+ PGTYPESnumeric_free(nres);
+ return -1211;
}
- else
+
+ if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
{
- free(temp_sum);
-
- if (errno == PGTYPES_NUM_OVERFLOW)
- return -1200;
+ PGTYPESnumeric_free(a1);
+ PGTYPESnumeric_free(a2);
+ PGTYPESnumeric_free(nres);
+ return -1211;
}
+
+ i = (*ptr)(a1, a2, nres);
+
+ if (i == 0) /* No error */
+ PGTYPESnumeric_to_decimal(nres, result);
+
+ PGTYPESnumeric_free(nres);
+ PGTYPESnumeric_free(a1);
+ PGTYPESnumeric_free(a2);
+
+ return (i);
+}
+/* we start with the numeric functions */
+int
+decadd(Decimal *arg1, Decimal *arg2, Decimal *sum)
+{
+ deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
- return -1201;
+ if (errno == PGTYPES_NUM_OVERFLOW)
+ return -1200;
+ else if (errno != 0)
+ return -1201;
+ else return 0;
}
int
-deccmp(Numeric *arg1, Numeric *arg2)
+deccmp(Decimal *arg1, Decimal *arg2)
{
- int i = PGTYPESnumeric_cmp(arg1, arg2);
-
- return (i);
+ return(deccall2(arg1, arg2, PGTYPESnumeric_cmp));
}
void
-deccopy(Numeric *src, Numeric *target)
+deccopy(Decimal *src, Decimal *target)
{
- PGTYPESnumeric_copy(src, target);
+ memcpy(target, src, sizeof(Decimal));
}
static char *
@@ -77,12 +142,13 @@ strndup(const char *str, size_t len)
}
int
-deccvasc(char *cp, int len, Numeric *np)
+deccvasc(char *cp, int len, Decimal *np)
{
- char *str = strndup(cp, len); /* Numeric_in always converts the complete string */
+ char *str = strndup(cp, len); /* Decimal_in always converts the complete string */
int ret = 0;
Numeric *result;
+
if (!str)
ret = -1201;
else
@@ -102,129 +168,136 @@ deccvasc(char *cp, int len, Numeric *np)
}
else
{
- if (PGTYPESnumeric_copy(result, np) !=0)
- ret = -1211;
+ if (PGTYPESnumeric_to_decimal(result, np) !=0)
+ ret = -1200;
free(result);
}
}
+ free(str);
return ret;
}
int
-deccvdbl(double dbl, Numeric *np)
+deccvdbl(double dbl, Decimal *np)
{
- return(PGTYPESnumeric_from_double(dbl, np));
+ Numeric *nres = PGTYPESnumeric_new();
+ int result = 1;
+
+ if (nres == NULL)
+ return -1211;
+
+ result = PGTYPESnumeric_from_double(dbl, nres);
+ if (result == 0)
+ result = PGTYPESnumeric_to_decimal(nres, np);
+
+ PGTYPESnumeric_free(nres);
+ return(result);
}
int
-deccvint(int in, Numeric *np)
+deccvint(int in, Decimal *np)
{
- return(PGTYPESnumeric_from_int(in, np));
+ Numeric *nres = PGTYPESnumeric_new();
+ int result = 1;
+
+ if (nres == NULL)
+ return -1211;
+
+ result = PGTYPESnumeric_from_int(in, nres);
+ if (result == 0)
+ result = PGTYPESnumeric_to_decimal(nres, np);
+
+ PGTYPESnumeric_free(nres);
+ return(result);
}
int
-deccvlong(long lng, Numeric *np)
+deccvlong(long lng, Decimal *np)
{
- return(PGTYPESnumeric_from_long(lng, np));
+ Numeric *nres = PGTYPESnumeric_new();
+ int result = 1;
+
+ if (nres == NULL)
+ return -1211;
+
+ result = PGTYPESnumeric_from_long(lng, nres);
+ if (result == 0)
+ result = PGTYPESnumeric_to_decimal(nres, np);
+
+ PGTYPESnumeric_free(nres);
+ return(result);
}
int
-decdiv(Numeric *n1, Numeric *n2, Numeric *n3)
+decdiv(Decimal *n1, Decimal *n2, Decimal *n3)
{
- Numeric *temp = malloc(sizeof(Numeric));
- int i, ret = 0;
-
- if (temp == NULL)
- return -1211;
-
- i = PGTYPESnumeric_div(n1, n2, temp);
+ int i = deccall3(n1, n2, n3, PGTYPESnumeric_div);
if (i != 0)
switch (errno)
{
- case PGTYPES_NUM_DIVIDE_ZERO: ret = -1202;
+ case PGTYPES_NUM_DIVIDE_ZERO: return -1202;
break;
- case PGTYPES_NUM_OVERFLOW: ret = -1200;
+ case PGTYPES_NUM_OVERFLOW: return -1200;
break;
- default: ret = -1201;
+ default: return -1201;
break;
}
- else
- if (PGTYPESnumeric_copy(temp, n3) !=0)
- ret = -1211;
-
- free(temp);
- return ret;
+
+ return 0;
}
int
-decmul(Numeric *n1, Numeric *n2, Numeric *n3)
+decmul(Decimal *n1, Decimal *n2, Decimal *n3)
{
- Numeric *temp = malloc(sizeof(Numeric));
- int i, ret = 0;
-
- if (temp == NULL)
- return -1211;
+ int i = deccall3(n1, n2, n3, PGTYPESnumeric_mul);
- i = PGTYPESnumeric_mul(n1, n2, temp);
-
if (i != 0)
switch (errno)
{
- case PGTYPES_NUM_OVERFLOW: ret = -1200;
+ case PGTYPES_NUM_OVERFLOW: return -1200;
break;
- default: ret = -1201;
+ default: return -1201;
break;
}
- else
- if (PGTYPESnumeric_copy(temp, n3) !=0)
- ret = -1211;
-
- free(temp);
- return ret;
+ return 0;
}
int
-decsub(Numeric *n1, Numeric *n2, Numeric *n3)
+decsub(Decimal *n1, Decimal *n2, Decimal *n3)
{
- Numeric *temp = malloc(sizeof(Numeric));
- int i, ret = 0;
-
- if (temp == NULL)
- return -1211;
-
- i = PGTYPESnumeric_sub(n1, n2, temp);
+ int i = deccall3(n1, n2, n3, PGTYPESnumeric_sub);
if (i != 0)
switch (errno)
{
- case PGTYPES_NUM_OVERFLOW: ret = -1200;
+ case PGTYPES_NUM_OVERFLOW: return -1200;
break;
- default: ret = -1201;
+ default: return -1201;
break;
}
- else
- if (PGTYPESnumeric_copy(temp, n3) !=0)
- ret = -1211;
-
- free(temp);
- return ret;
+ return 0;
}
int
-dectoasc(Numeric *np, char *cp, int len, int right)
+dectoasc(Decimal *np, char *cp, int len, int right)
{
char *str;
+ Numeric *nres;
+
+ if (PGTYPESnumeric_from_decimal(np, nres) != 0)
+ return -1211;
if (right >= 0)
- str = PGTYPESnumeric_to_asc(np, right);
+ str = PGTYPESnumeric_to_asc(nres, right);
else
- str = PGTYPESnumeric_to_asc(np, 0);
+ str = PGTYPESnumeric_to_asc(nres, 0);
+ PGTYPESnumeric_free(nres);
if (!str)
return -1;
@@ -236,15 +309,36 @@ dectoasc(Numeric *np, char *cp, int len, int right)
}
int
-dectodbl(Numeric *np, double *dblp)
+dectodbl(Decimal *np, double *dblp)
{
- return(PGTYPESnumeric_to_double(np, dblp));
+ Numeric *nres = PGTYPESnumeric_new();;
+ int i;
+
+ if (nres == NULL)
+ return -1211;
+
+ if (PGTYPESnumeric_from_decimal(np, nres) != 0)
+ return -1211;
+
+ i = PGTYPESnumeric_to_double(nres, dblp);
+ PGTYPESnumeric_free(nres);
+
+ return i;
}
int
-dectoint(Numeric *np, int *ip)
+dectoint(Decimal *np, int *ip)
{
- int ret = PGTYPESnumeric_to_int(np, ip);
+ int ret;
+ Numeric *nres = PGTYPESnumeric_new();
+
+ if (nres == NULL)
+ return -1211;
+
+ if (PGTYPESnumeric_from_decimal(np, nres) != 0)
+ return -1211;
+
+ ret = PGTYPESnumeric_to_int(nres, ip);
if (ret == PGTYPES_NUM_OVERFLOW)
ret = -1200;
@@ -253,9 +347,18 @@ dectoint(Numeric *np, int *ip)
}
int
-dectolong(Numeric *np, long *lngp)
+dectolong(Decimal *np, long *lngp)
{
- int ret = PGTYPESnumeric_to_long(np, lngp);
+ int ret;
+ Numeric *nres = PGTYPESnumeric_new();;
+
+ if (nres == NULL)
+ return -1211;
+
+ if (PGTYPESnumeric_from_decimal(np, nres) != 0)
+ return -1211;
+
+ ret = PGTYPESnumeric_to_long(nres, lngp);
if (ret == PGTYPES_NUM_OVERFLOW)
ret = -1200;
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index 77505f1184a..d7c721acd33 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.9 2003/06/26 11:37:05 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.10 2003/07/01 12:40:51 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
@@ -18,15 +18,11 @@ static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct connection *all_connections = NULL;
static struct connection *actual_connection = NULL;
-struct connection *
-ECPGget_connection(const char *connection_name)
+static struct connection *
+ecpg_get_connection_nr(const char *connection_name)
{
struct connection *ret = NULL;
-#ifdef USE_THREADS
- pthread_mutex_lock(&connections_mutex);
-#endif
-
if( (connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0) )
{
ret = actual_connection;
@@ -43,11 +39,25 @@ ECPGget_connection(const char *connection_name)
ret = con;
}
+ return( ret );
+}
+
+struct connection *
+ECPGget_connection(const char *connection_name)
+{
+ struct connection *ret = NULL;
+#ifdef USE_THREADS
+ pthread_mutex_lock(&connections_mutex);
+#endif
+
+ ret = ecpg_get_connection_nr(connection_name);
+
#ifdef USE_THREADS
pthread_mutex_unlock(&connections_mutex);
#endif
- return( ret );
+ return (ret);
+
}
static void
@@ -546,7 +556,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
}
else
{
- con = ECPGget_connection(connection_name);
+ con = ecpg_get_connection_nr(connection_name);
if (!ECPGinit(con, connection_name, lineno))
{
diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index 77f35e639e0..c9da13794df 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.9 2003/06/26 11:37:05 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.10 2003/07/01 12:40:51 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
@@ -398,6 +398,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
}
break;
+ case ECPGt_decimal:
case ECPGt_numeric:
if (pval)
{
@@ -419,7 +420,10 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
else
nres = PGTYPESnumeric_from_asc("0.0", &scan_length);
- PGTYPESnumeric_copy(nres, (Numeric *)(var + offset * act_tuple));
+ if (type == ECPGt_numeric)
+ PGTYPESnumeric_copy(nres, (Numeric *)(var + offset * act_tuple));
+ else
+ PGTYPESnumeric_to_decimal(nres, (Decimal *)(var + offset * act_tuple));
break;
case ECPGt_interval:
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index ad5ab5d1f02..bc945a442c1 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.13 2003/06/26 11:37:05 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.14 2003/07/01 12:40:51 meskes Exp $ */
/*
* The aim is to get a simpler inteface to the database routines.
@@ -820,16 +820,24 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
}
break;
+ case ECPGt_decimal:
case ECPGt_numeric:
{
char *str = NULL;
int slen;
+ Numeric *nval = PGTYPESnumeric_new();
if (var->arrsize > 1)
{
for (element = 0; element < var->arrsize; element++)
{
- str = PGTYPESnumeric_to_asc((Numeric *)((var + var->offset * element)->value), 0);
+ if (var->type == ECPGt_numeric)
+ PGTYPESnumeric_copy((Numeric *)((var + var->offset * element)->value), nval);
+ else
+ PGTYPESnumeric_from_decimal((Decimal *)((var + var->offset * element)->value), nval);
+
+ str = PGTYPESnumeric_to_asc(nval, 0);
+ PGTYPESnumeric_free(nval);
slen = strlen (str);
if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + 5, stmt->lineno)))
@@ -845,7 +853,14 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
}
else
{
- str = PGTYPESnumeric_to_asc((Numeric *)(var->value), 0);
+ if (var->type == ECPGt_numeric)
+ PGTYPESnumeric_copy((Numeric *)(var->value), nval);
+ else
+ PGTYPESnumeric_from_decimal((Decimal *)(var->value), nval);
+
+ str = PGTYPESnumeric_to_asc(nval, 0);
+
+ PGTYPESnumeric_free(nval);
slen = strlen (str);
if (!(mallocedval = ECPGalloc(slen + 1, stmt->lineno)))
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 33091e7d8c0..6c9bd208c7b 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.8 2003/06/26 01:45:04 momjian Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.9 2003/07/01 12:40:51 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
@@ -85,6 +85,7 @@ static struct sqlca_t sqlca =
#ifdef USE_THREADS
static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
static int simple_debug = 0;
static FILE *debugstream = NULL;
@@ -204,7 +205,7 @@ void
ECPGdebug(int n, FILE *dbgs)
{
#ifdef USE_THREADS
- pthread_mutex_lock(&debug_mutex);
+ pthread_mutex_lock(&debug_init_mutex);
#endif
simple_debug = n;
@@ -212,7 +213,7 @@ ECPGdebug(int n, FILE *dbgs)
ECPGlog("ECPGdebug: set to %d\n", simple_debug);
#ifdef USE_THREADS
- pthread_mutex_unlock(&debug_mutex);
+ pthread_mutex_unlock(&debug_init_mutex);
#endif
}
@@ -241,6 +242,7 @@ ECPGlog(const char *format,...)
va_start(ap, format);
vfprintf(debugstream, f, ap);
va_end(ap);
+ fflush(debugstream);
ECPGfree(f);
}
@@ -287,6 +289,9 @@ ECPGset_informix_null(enum ECPGttype type, void *ptr)
case ECPGt_varchar:
*(((struct ECPGgeneric_varchar *) ptr)->arr) = 0x00;
break;
+ case ECPGt_decimal:
+ ((Decimal *) ptr)->sign = NUMERIC_NAN;
+ break;
case ECPGt_numeric:
((Numeric *) ptr)->sign = NUMERIC_NAN;
break;
@@ -345,6 +350,9 @@ ECPGis_informix_null(enum ECPGttype type, void *ptr)
case ECPGt_varchar:
if (*(((struct ECPGgeneric_varchar *) ptr)->arr) == 0x00) return true;
break;
+ case ECPGt_decimal:
+ if (((Decimal *) ptr)->sign == NUMERIC_NAN) return true;
+ break;
case ECPGt_numeric:
if (((Numeric *) ptr)->sign == NUMERIC_NAN) return true;
break;
diff --git a/src/interfaces/ecpg/ecpglib/typename.c b/src/interfaces/ecpg/ecpglib/typename.c
index f8eb793ba37..752b4f6063e 100644
--- a/src/interfaces/ecpg/ecpglib/typename.c
+++ b/src/interfaces/ecpg/ecpglib/typename.c
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/typename.c,v 1.7 2003/06/20 12:01:46 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/typename.c,v 1.8 2003/07/01 12:40:51 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
@@ -48,6 +48,8 @@ ECPGtype_name(enum ECPGttype typ)
return "varchar";
case ECPGt_char_variable:
return "char";
+ case ECPGt_decimal:
+ return "Decimal";
case ECPGt_numeric:
return "Numeric";
case ECPGt_date:
diff --git a/src/interfaces/ecpg/include/decimal.h b/src/interfaces/ecpg/include/decimal.h
index acbb758814a..e0cb06bd5c8 100644
--- a/src/interfaces/ecpg/include/decimal.h
+++ b/src/interfaces/ecpg/include/decimal.h
@@ -1,7 +1,7 @@
#include <pgtypes_numeric.h>
#ifndef dec_t
-#define dec_t Numeric
+#define dec_t Decimal
#endif /* dec_t */
int decadd(dec_t *, dec_t *, dec_t *);
diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h
index 94899413da5..7a299d0be89 100644
--- a/src/interfaces/ecpg/include/ecpgtype.h
+++ b/src/interfaces/ecpg/include/ecpgtype.h
@@ -44,8 +44,8 @@ enum ECPGttype
ECPGt_bool,
ECPGt_float, ECPGt_double,
ECPGt_varchar, ECPGt_varchar2,
- ECPGt_numeric,
- ECPGt_decimal, /* only used internally */
+ ECPGt_numeric, /* this is a decimal that stores its digits in a malloced array */
+ ECPGt_decimal, /* this is a decimal that stores its digits in a fixed array */
ECPGt_date,
ECPGt_timestamp,
ECPGt_interval,
diff --git a/src/interfaces/ecpg/include/pgtypes_numeric.h b/src/interfaces/ecpg/include/pgtypes_numeric.h
index cd7552db384..28b902f290d 100644
--- a/src/interfaces/ecpg/include/pgtypes_numeric.h
+++ b/src/interfaces/ecpg/include/pgtypes_numeric.h
@@ -9,6 +9,8 @@
#define NUMERIC_MIN_DISPLAY_SCALE 0
#define NUMERIC_MIN_SIG_DIGITS 16
+#define DECSIZE 30
+
typedef unsigned char NumericDigit;
typedef struct
{
@@ -21,7 +23,17 @@ typedef struct
NumericDigit *digits; /* decimal digits */
} Numeric;
-Numeric *PGTYPESnew(void);
+typedef struct
+{
+ int ndigits; /* number of digits in digits[] - can be 0! */
+ int weight; /* weight of first digit */
+ int rscale; /* result scale */
+ int dscale; /* display scale */
+ int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */
+ NumericDigit digits[DECSIZE]; /* decimal digits */
+} Decimal;
+
+Numeric *PGTYPESnumeric_new(void);
void PGTYPESnumeric_free(Numeric *);
Numeric *PGTYPESnumeric_from_asc(char *, char **);
char *PGTYPESnumeric_to_asc(Numeric *, int);
@@ -37,5 +49,7 @@ int PGTYPESnumeric_from_double(double, Numeric *);
int PGTYPESnumeric_to_double(Numeric *, double *);
int PGTYPESnumeric_to_int(Numeric *, int *);
int PGTYPESnumeric_to_long(Numeric *, long *);
+int PGTYPESnumeric_to_decimal(Numeric *, Decimal *);
+int PGTYPESnumeric_from_decimal(Decimal *, Numeric *);
#endif /* PGTYPES_NUMERIC */
diff --git a/src/interfaces/ecpg/include/sqltypes.h b/src/interfaces/ecpg/include/sqltypes.h
index e6a96bcf48d..c50bf54314b 100644
--- a/src/interfaces/ecpg/include/sqltypes.h
+++ b/src/interfaces/ecpg/include/sqltypes.h
@@ -4,7 +4,7 @@
#define CLONGTYPE ECPGt_long
#define CFLOATTYPE ECPGt_float
#define CDOUBLETYPE ECPGt_double
-#define CDECIMALTYPE ECPGt_numeric
+#define CDECIMALTYPE ECPGt_decimal
#define CFIXCHARTYPE 108
#define CSTRINGTYPE ECPGt_char
#define CDATETYPE ECPGt_date
diff --git a/src/interfaces/ecpg/pgtypeslib/numeric.c b/src/interfaces/ecpg/pgtypeslib/numeric.c
index a3f96339848..b2b1e9e6124 100644
--- a/src/interfaces/ecpg/pgtypeslib/numeric.c
+++ b/src/interfaces/ecpg/pgtypeslib/numeric.c
@@ -126,7 +126,7 @@ alloc_var(Numeric *var, int ndigits)
}
Numeric *
-PGTYPESnew(void)
+PGTYPESnumeric_new(void)
{
Numeric *var;
@@ -1489,3 +1489,45 @@ PGTYPESnumeric_to_long(Numeric* nv, long* lp) {
return 0;
}
+int
+PGTYPESnumeric_to_decimal(Numeric *src, Decimal *dst) {
+ int i;
+
+ if (src->ndigits > DECSIZE) {
+ errno = PGTYPES_NUM_OVERFLOW;
+ return -1;
+ }
+
+ dst->weight = src->weight;
+ dst->rscale = src->rscale;
+ dst->dscale = src->dscale;
+ dst->sign = src->sign;
+ dst->ndigits = src->ndigits;
+
+ for (i = 0; i < src->ndigits; i++) {
+ dst->digits[i] = src->digits[i];
+ }
+
+ return 0;
+}
+
+int
+PGTYPESnumeric_from_decimal(Decimal *src, Numeric *dst) {
+ int i;
+
+ zero_var(dst);
+
+ dst->weight = src->weight;
+ dst->rscale = src->rscale;
+ dst->dscale = src->dscale;
+ dst->sign = src->sign;
+
+ if (alloc_var(dst, src->ndigits) != 0)
+ return -1;
+
+ for (i = 0; i < src->ndigits; i++) {
+ dst->digits[i] = src->digits[i];
+ }
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.c
index e65929b0d26..08d5db19e9f 100644
--- a/src/interfaces/ecpg/pgtypeslib/timestamp.c
+++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c
@@ -341,7 +341,7 @@ PGTYPEStimestamp_to_asc(Timestamp tstamp)
char buf[MAXDATELEN + 1];
char *tzn = NULL;
fsec_t fsec;
- int DateStyle = 0;
+ int DateStyle = 1; /* this defaults to ISO_DATES, shall we make it an option? */
if (TIMESTAMP_NOT_FINITE(tstamp))
EncodeSpecialTimestamp(tstamp, buf);
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index b82adfa7325..a4aa18e50ce 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.243 2003/06/29 16:52:58 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.244 2003/07/01 12:40:51 meskes Exp $ */
/* Copyright comment */
%{
@@ -4453,7 +4453,7 @@ single_vt_type: common_type
else if (strcmp($1, "decimal") == 0)
{
$$.type_enum = ECPGt_decimal;
- $$.type_str = make_str("Numeric");
+ $$.type_str = make_str("Decimal");
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
@@ -4751,11 +4751,19 @@ common_type: simple_type
}
| ECPGColLabelCommon '(' precision opt_scale ')'
{
- if (strcmp($1, "numeric") != 0 && strcmp($1, "decimal") != 0)
+ if (strcmp($1, "numeric") == 0)
+ {
+ $$.type_enum = ECPGt_numeric;
+ $$.type_str = make_str("Numeric");
+ }
+ else if (strcmp($1, "decimal") == 0)
+ {
+ $$.type_enum = ECPGt_decimal;
+ $$.type_str = make_str("Decimal");
+ }
+ else
mmerror(PARSE_ERROR, ET_ERROR, "Only numeric/decimal have precision/scale argument");
- $$.type_enum = (strcmp($1, "numeric") != 0) ? ECPGt_decimal : ECPGt_numeric;
- $$.type_str = make_str("Numeric");
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
@@ -4807,7 +4815,7 @@ var_type: common_type
else if (strcmp($1, "decimal") == 0)
{
$$.type_enum = ECPGt_decimal;
- $$.type_str = make_str("Numeric");
+ $$.type_str = make_str("Deciaml");
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
@@ -5076,21 +5084,6 @@ variable: opt_pointer ECPGColLabelCommon opt_array_bounds opt_initializer
$$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
break;
- case ECPGt_decimal: /* this is used by informix and need to be initialized */
- if (atoi(dimension) < 0)
- type = ECPGmake_simple_type(ECPGt_numeric, make_str("1"));
- else
- type = ECPGmake_array_type(ECPGmake_simple_type(ECPGt_numeric, make_str("1")), dimension);
-
- if (strlen($4) == 0)
- {
- $4 = mm_alloc(sizeof(" = {0, 0, 0, 0, 0, NULL, NULL}"));
- strcpy($4, " = {0, 0, 0, 0, 0, NULL, NULL}");
- }
-
- $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
-
- break;
default:
if (atoi(dimension) < 0)
type = ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"));
diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c
index 80406bbccc5..58ef58af985 100644
--- a/src/interfaces/ecpg/preproc/type.c
+++ b/src/interfaces/ecpg/preproc/type.c
@@ -172,6 +172,9 @@ get_type(enum ECPGttype type)
case ECPGt_const: /* constant string quoted */
return ("ECPGt_const");
break;
+ case ECPGt_decimal:
+ return ("ECPGt_decimal");
+ break;
case ECPGt_numeric:
return ("ECPGt_numeric");
break;
diff --git a/src/interfaces/ecpg/test/Makefile b/src/interfaces/ecpg/test/Makefile
index 78bbcbe286a..7e7f1fee07d 100644
--- a/src/interfaces/ecpg/test/Makefile
+++ b/src/interfaces/ecpg/test/Makefile
@@ -1,4 +1,4 @@
-# $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Makefile,v 1.37 2003/06/25 10:44:21 meskes Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Makefile,v 1.38 2003/07/01 12:40:52 meskes Exp $
subdir = src/interfaces/ecpg/test
top_builddir = ../../../..
@@ -22,7 +22,7 @@ test_informix: test_informix.o
$(ECPG) $<
test_informix.c: test_informix.pgc
- $(ECPG) -C INFORMIX $<
+ $(ECPG) -C INFORMIX -r no_indicator $<
clean:
rm -f $(TESTS) $(TESTS:%=%.o) $(TESTS:%=%.c) log
diff --git a/src/interfaces/ecpg/test/num_test.pgc b/src/interfaces/ecpg/test/num_test.pgc
index 5b83af5bd07..7cf687c220a 100644
--- a/src/interfaces/ecpg/test/num_test.pgc
+++ b/src/interfaces/ecpg/test/num_test.pgc
@@ -18,16 +18,16 @@ main()
exec sql whenever sqlerror do sqlprint();
exec sql connect to mm;
- exec sql create table test (text char(5), num decimal(14,7));
+ exec sql create table test (text char(5), num numeric(14,7));
- value1 = PGTYPESnew();
+ value1 = PGTYPESnumeric_new();
PGTYPESnumeric_from_int(1407, value1);
text = PGTYPESnumeric_to_asc(value1, 0);
printf("long = %s\n", text);
value1 = PGTYPESnumeric_from_asc("2369.7", NULL);
value2 = PGTYPESnumeric_from_asc("10.0", NULL);
- res = PGTYPESnew();
+ res = PGTYPESnumeric_new();
PGTYPESnumeric_add(value1, value2, res);
text = PGTYPESnumeric_to_asc(res, 0);
printf("add = %s\n", text);
diff --git a/src/interfaces/ecpg/test/test_informix.pgc b/src/interfaces/ecpg/test/test_informix.pgc
index 0ca4c0647fc..fa0de6eb6ef 100644
--- a/src/interfaces/ecpg/test/test_informix.pgc
+++ b/src/interfaces/ecpg/test/test_informix.pgc
@@ -5,7 +5,7 @@ void openit(void);
int main()
{
$int i = 14;
- $decimal j;
+ $decimal j, m, n;
FILE *dbgs;
if ((dbgs = fopen("log", "w")) != NULL)
@@ -41,7 +41,10 @@ int main()
}
}
- $delete from test where i=87;
+ deccvint(7, &j);
+ deccvint(14, &m);
+ decadd(&j, &m, &n);
+ $delete from test where i=:n;
printf("delete: %ld\n", sqlca.sqlcode);
$commit;