]> granicus.if.org Git - postgresql/commitdiff
*** empty log message ***
authorMichael Meskes <meskes@postgresql.org>
Wed, 23 Feb 2000 19:26:05 +0000 (19:26 +0000)
committerMichael Meskes <meskes@postgresql.org>
Wed, 23 Feb 2000 19:26:05 +0000 (19:26 +0000)
16 files changed:
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/include/ecpgerrno.h
src/interfaces/ecpg/include/ecpglib.h
src/interfaces/ecpg/lib/Makefile.in
src/interfaces/ecpg/lib/data.c [new file with mode: 0644]
src/interfaces/ecpg/lib/descriptor.c
src/interfaces/ecpg/lib/dynamic.c [deleted file]
src/interfaces/ecpg/lib/ecpglib.c
src/interfaces/ecpg/lib/error.c [new file with mode: 0644]
src/interfaces/ecpg/lib/memory.c [new file with mode: 0644]
src/interfaces/ecpg/lib/prepare.c [new file with mode: 0644]
src/interfaces/ecpg/preproc/descriptor.c
src/interfaces/ecpg/test/Makefile
src/interfaces/ecpg/test/dyntest.pgc
src/interfaces/ecpg/test/stp.pgc [deleted file]
src/interfaces/ecpg/test/test5.pgc [deleted file]

index b9384070be735225099ca1d59ebe6c6599b3e05d..7a0a577be35b5b0c733b8659064113bd31f7a108 100644 (file)
@@ -824,5 +824,9 @@ Tue Feb 22 13:48:18 CET 2000
 
        - Synced preproc.y with gram.y.
        - Much more clean ups.
+
+Wed Feb 23 17:08:28 CET 2000
+
+       - Even more clean ups.
        - Set library version to 3.1.0.
        - Set ecpg version to 2.7.0.
index 2bc59f4b78521154dd4419f14b3867406577a25d..85b891688d64baabdaf46c895c97c9ff0aaad972 100644 (file)
@@ -34,6 +34,7 @@
 #define ECPG_INVALID_DESCRIPTOR_INDEX  -241
 #define ECPG_UNKNOWN_DESCRIPTOR_ITEM   -242
 #define ECPG_VAR_NOT_NUMERIC   -243
+#define ECPG_VAR_NOT_CHAR      -244
 
 /* finally the backend error messages, they start at 400 */
 #define ECPG_PGSQL             -400
index 0617412a1e90552092c11bc73de6097c41123375..14e06bf42dea7e5c2f8f97d9f23d03596569f6f5 100644 (file)
@@ -16,35 +16,28 @@ extern              "C"
        bool            ECPGdisconnect(int, const char *);
        bool            ECPGprepare(int, char *, char *);
        bool            ECPGdeallocate(int, char *);
+       bool            ECPGdeallocate_all(int);
        char            *ECPGprepared_statement(char *);
        
        void            ECPGlog(const char *format,...);
-
+       
+       /* print an error message */
+       void            sqlprint(void);
+       
 #ifdef LIBPQ_FE_H
        bool            ECPGsetdb(PGconn *);
-
 #endif
 
 /* Here are some methods used by the lib. */
 /* Returns a pointer to a string containing a simple type name. */
        const char *ECPGtype_name(enum ECPGttype);
+       bool get_data(PGresult *, int, int, int, enum ECPGttype type,
+                       enum ECPGttype, void *, void *, long, long);
+       char *ecpg_alloc(long, int);
+       char *ecpg_strdup(const char *, int);
 
-/* A generic varchar type. */
-       struct ECPGgeneric_varchar
-       {
-               int                     len;
-               char            arr[1];
-       };
-
-/* print an error message */
-       void            sqlprint(void);
-
-       struct cursor
-       {
-               const char *name;
-               char       *command;
-               struct cursor *next;
-       };
+/* and some vars */
+       extern struct auto_mem *auto_allocs;
 
 /* define this for simplicity as well as compatibility */
 
@@ -52,9 +45,6 @@ extern                "C"
 
 /* dynamic SQL */
 
-       unsigned int    ECPGDynamicType(Oid type);
-       unsigned int    ECPGDynamicType_DDT(Oid type);
-       PGresult *      ECPGresultByDescriptor(int line,const char *name);
        bool            ECPGdo_descriptor(int line,const char *connection,
                                                        const char *descriptor,const char *query);
        bool            ECPGdeallocate_desc(int line,const char *name);
index eee0d03ba44d48d163bbbbec28f772d53b3bbb66..7bd94259ab1ef80ffaaf861ab850ea02827e8393 100644 (file)
@@ -6,7 +6,7 @@
 # Copyright (c) 1994, Regents of the University of California
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.59 2000/02/22 19:57:05 meskes Exp $
+#    $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.60 2000/02/23 19:25:42 meskes Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -23,7 +23,7 @@ ifdef KRBVERS
 CFLAGS+= $(KRBFLAGS)
 endif
 
-OBJS= ecpglib.o typename.o descriptor.o
+OBJS= ecpglib.o typename.o descriptor.o data.o error.o prepare.o memory.o
 
 SHLIB_LINK= -L../../libpq -lpq
 
diff --git a/src/interfaces/ecpg/lib/data.c b/src/interfaces/ecpg/lib/data.c
new file mode 100644 (file)
index 0000000..5b30eb1
--- /dev/null
@@ -0,0 +1,252 @@
+#include <stdlib.h>
+
+#include <libpq/pqcomm.h>
+#include <ecpgtype.h>
+#include <ecpglib.h>
+#include <sqlca.h>
+
+bool
+get_data(PGresult *results, int act_tuple, int act_field, int lineno,
+        enum ECPGttype type, enum ECPGttype ind_type,
+        void *var, void *ind, long varcharsize, long offset)
+{
+       char *pval = (char *)PQgetvalue(results, act_tuple, act_field);
+
+       ECPGlog("get_data line %d: RESULT: %s\n", lineno, pval ? pval : "");
+
+       /* Now the pval is a pointer to the value. */
+       /* We will have to decode the value */
+
+       /*
+        * check for null value and set indicator
+        * accordingly
+        */
+       switch (ind_type)
+       {
+               case ECPGt_short:
+               case ECPGt_unsigned_short:
+                       ((short *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
+                       break;
+               case ECPGt_int:
+               case ECPGt_unsigned_int:
+                       ((int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
+                       break;
+               case ECPGt_long:
+               case ECPGt_unsigned_long:
+                       ((long *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
+                       break;
+               case ECPGt_NO_INDICATOR:
+                       if (PQgetisnull(results, act_tuple, act_field))
+                       {
+                               ECPGraise(lineno, ECPG_MISSING_INDICATOR, NULL);
+                               return (false);
+                       }
+                       break;
+               default:
+                       ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(ind_type));
+                       return (false);
+                       break;
+       }
+       
+       switch (type)
+       {
+               long            res;
+               unsigned long   ures;
+               double          dres;
+               char            *scan_length;
+
+               case ECPGt_short:
+               case ECPGt_int:
+               case ECPGt_long:
+                       if (pval)
+                       {
+                               res = strtol(pval, &scan_length, 10);
+                               if (*scan_length != '\0')       /* Garbage left */
+                               {
+                                       ECPGraise(lineno, ECPG_INT_FORMAT, pval);
+                                       return (false);
+                                       res = 0L;
+                               }
+                       }
+                       else
+                               res = 0L;
+
+                       switch (type)
+                       {
+                               case ECPGt_short:
+                                       ((short *) var)[act_tuple] = (short) res;
+                                       break;
+                               case ECPGt_int:
+                                       ((int *) var)[act_tuple] = (int) res;
+                                       break;
+                               case ECPGt_long:
+                                       ((long *) var)[act_tuple] = res;
+                                       break;
+                               default:
+                                       /* Cannot happen */
+                                       break;
+                       }
+                       break;
+
+               case ECPGt_unsigned_short:
+               case ECPGt_unsigned_int:
+               case ECPGt_unsigned_long:
+                       if (pval)
+                       {
+                               ures = strtoul(pval, &scan_length, 10);
+                               if (*scan_length != '\0')       /* Garbage left */
+                               {
+                                       ECPGraise(lineno, ECPG_UINT_FORMAT, pval);
+                                       return (false);
+                                       ures = 0L;
+                               }
+                       }
+                       else
+                               ures = 0L;
+
+                       switch (type)
+                       {
+                               case ECPGt_unsigned_short:
+                                       ((unsigned short *) var)[act_tuple] = (unsigned short) ures;
+                                       break;
+                               case ECPGt_unsigned_int:
+                                       ((unsigned int *) var)[act_tuple] = (unsigned int) ures;
+                                       break;
+                               case ECPGt_unsigned_long:
+                                       ((unsigned long *) var)[act_tuple] = ures;
+                                       break;
+                               default:
+                                       /* Cannot happen */
+                                       break;
+                       }
+                       break;
+
+
+               case ECPGt_float:
+               case ECPGt_double:
+                       if (pval)
+                       {
+                               dres = strtod(pval, &scan_length);
+                               if (*scan_length != '\0')       /* Garbage left */
+                               {
+                                       ECPGraise(lineno, ECPG_FLOAT_FORMAT, pval);
+                                       return (false);
+                                       dres = 0.0;
+                               }
+                       }
+                       else
+                               dres = 0.0;
+
+                       switch (type)
+                       {
+                               case ECPGt_float:
+                                       ((float *) var)[act_tuple] = dres;
+                                       break;
+                               case ECPGt_double:
+                                       ((double *) var)[act_tuple] = dres;
+                                       break;
+                               default:
+                                       /* Cannot happen */
+                                       break;
+                       }
+                       break;
+
+               case ECPGt_bool:
+                       if (pval)
+                       {
+                               if (pval[0] == 'f' && pval[1] == '\0')
+                               {
+                                       ((char *) var)[act_tuple] = false;
+                                       break;
+                               }
+                               else if (pval[0] == 't' && pval[1] == '\0')
+                               {
+                                       ((char *) var)[act_tuple] = true;
+                                       break;
+                               }
+                               else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
+                               {
+                                       // NULL is valid
+                                       break;
+                               }
+                       }
+
+                       ECPGraise(lineno, ECPG_CONVERT_BOOL, pval);
+                       return (false);
+                       break;
+
+               case ECPGt_char:
+               case ECPGt_unsigned_char:
+                       {
+                               strncpy((char *) ((long) var + offset * act_tuple), pval, varcharsize);
+                               if (varcharsize && varcharsize < strlen(pval))
+                               {
+                                       /* truncation */
+                                       switch (ind_type)
+                                       {
+                                               case ECPGt_short:
+                                               case ECPGt_unsigned_short:
+                                                       ((short *) ind)[act_tuple] = varcharsize;
+                                                       break;
+                                               case ECPGt_int:
+                                               case ECPGt_unsigned_int:
+                                                       ((int *) ind)[act_tuple] = varcharsize;
+                                                       break;
+                                               case ECPGt_long:
+                                               case ECPGt_unsigned_long:
+                                                       ((long *) ind)[act_tuple] = varcharsize;
+                                                       break;
+                                               default:
+                                                       break;
+                                       }
+                                       sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
+                               }
+                       }
+                       break;
+
+               case ECPGt_varchar:
+                       {
+                               struct ECPGgeneric_varchar *variable =
+                               (struct ECPGgeneric_varchar *) ((long) var + offset * act_tuple);
+
+                               if (varcharsize == 0)
+                                       strncpy(variable->arr, pval, strlen(pval));
+                               else
+                                       strncpy(variable->arr, pval, varcharsize);
+
+                               variable->len = strlen(pval);
+                               if (varcharsize > 0 && variable->len > varcharsize)
+                               {
+                                       /* truncation */
+                                       switch (ind_type)
+                                       {
+                                               case ECPGt_short:
+                                               case ECPGt_unsigned_short:
+                                                       ((short *) ind)[act_tuple] = varcharsize;
+                                                       break;
+                                               case ECPGt_int:
+                                               case ECPGt_unsigned_int:
+                                                       ((int *) ind)[act_tuple] = varcharsize;
+                                                       break;
+                                               case ECPGt_long:
+                                               case ECPGt_unsigned_long:
+                                                       ((long *) ind)[act_tuple] = varcharsize;
+                                                       break;
+                                               default:
+                                                       break;
+                                       }
+                                       sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
+
+                                       variable->len = varcharsize;
+                               }
+                       }
+                       break;
+
+               default:
+                       ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(type));
+                       return (false);
+                       break;
+       }
+       
+       return (true);
+}
index 8169f1d2f2b8376f662d8001db31092b0262d502..1b85340864cac284c2f1ed6d1fcc75067183aa44 100644 (file)
@@ -1,6 +1,68 @@
 #include <ecpgtype.h>
 #include <ecpglib.h>
 
+#include <sql3types.h>
+
+struct descriptor
+{
+        char *name;
+        PGresult *result;
+        struct descriptor *next;
+} *all_descriptors = NULL;
+                        
+static PGresult
+*ECPGresultByDescriptor(int line,const char *name)
+{
+       struct descriptor *i;
+       
+       for (i = all_descriptors; i != NULL; i = i->next)
+       {
+               if (!strcmp(name, i->name)) return i->result;
+       }
+       
+       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name);
+       
+       return NULL;
+} 
+
+static unsigned int
+ECPGDynamicType(Oid type)
+{
+       switch(type)
+       {
+               case 16:        return SQL3_BOOLEAN;    /* bool */
+               case 21:        return SQL3_SMALLINT;   /* int2 */
+               case 23:        return SQL3_INTEGER;    /* int4 */
+               case 25:        return SQL3_CHARACTER;  /* text */
+               case 700:       return SQL3_REAL;               /* float4 */
+               case 701:       return SQL3_DOUBLE_PRECISION;   /* float8 */
+               case 1042:      return SQL3_CHARACTER;  /* bpchar */
+               case 1043:      return SQL3_CHARACTER_VARYING;  /* varchar */
+               case 1082:      return SQL3_DATE_TIME_TIMESTAMP;        /* date */
+               case 1083:      return SQL3_DATE_TIME_TIMESTAMP;        /* time */
+               case 1184:      return SQL3_DATE_TIME_TIMESTAMP;        /* datetime */
+               case 1296:      return SQL3_DATE_TIME_TIMESTAMP;        /* timestamp */
+               case 1700:      return SQL3_NUMERIC;    /* numeric */
+               default:        return -type;
+       }
+}
+
+#if 0
+static unsigned int
+ECPGDynamicType_DDT(Oid type)
+{
+       switch(type)
+       {       
+               case 1082:      return SQL3_DDT_DATE;   /* date */
+               case 1083:      return SQL3_DDT_TIME;   /* time */
+               case 1184:      return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE;       /* datetime */
+               case 1296:      return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE;       /* timestamp */
+               default:
+                       return SQL3_DDT_ILLEGAL;
+       }
+}
+#endif
+
 bool
 ECPGget_desc_header(int lineno, char * desc_name, int *count)
 {
@@ -51,6 +113,38 @@ get_int_item(int lineno, void *var, enum ECPGdtype vartype, int value)
        return(true);
 }
 
+static bool
+get_char_item(int lineno, void *var, enum ECPGdtype vartype, char *value, int varcharsize)
+{
+       switch (vartype)
+       {
+                       case ECPGt_char:
+                       case ECPGt_unsigned_char:
+                               strncpy((char *) var, value, varcharsize);
+                               break;
+               case ECPGt_varchar:
+                       {
+                               struct ECPGgeneric_varchar *variable =
+                                                               (struct ECPGgeneric_varchar *) var;
+                                                               
+                               if (varcharsize == 0)
+                                       strncpy(variable->arr, value, strlen(value));
+                               else
+                                       strncpy(variable->arr, value, varcharsize);
+                               
+                               variable->len = strlen(value);
+                               if (varcharsize > 0 && variable->len > varcharsize)
+                                       variable->len = varcharsize;
+                       }
+                       break;
+               default:
+                       ECPGraise(lineno, ECPG_VAR_NOT_CHAR, NULL);
+                       return (false);
+       }
+       
+       return(true);
+}
+
 bool
 ECPGget_desc(int lineno, char *desc_name, int index, ...)
 {
@@ -100,53 +194,78 @@ ECPGget_desc(int lineno, char *desc_name, int index, ...)
                        case (ECPGd_indicator):
                                if (!get_int_item(lineno, var, vartype, -PQgetisnull(ECPGresult, 0, index)))
                                        return (false);
+                               
+                               ECPGlog("ECPGget_desc: INDICATOR = %d\n", -PQgetisnull(ECPGresult, 0, index));
                                break;
 
                        case ECPGd_name:
-                               strncpy((char *)var, PQfname(ECPGresult, index), varcharsize);
+                               if (!get_char_item(lineno, var, vartype, PQfname(ECPGresult, index), varcharsize))
+                                       return(false);
+                                       
+                               ECPGlog("ECPGget_desc: NAME = %s\n", PQfname(ECPGresult, index));
                                break;
                                
                        case ECPGd_nullable:
                                if (!get_int_item(lineno, var, vartype, 1))
                                        return (false);
-                               break;
+                                       
+                               break;
                                
                        case ECPGd_key_member:
                                if (!get_int_item(lineno, var, vartype, 0))
                                        return (false);
+                                       
                                break;
                         
                        case ECPGd_scale:
                                if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff))
                                        return (false);
+                                       
+                               ECPGlog("ECPGget_desc: SCALE = %d\n", (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff);
                                break;
                                 
                        case ECPGd_precision:
                                if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16))
                                        return (false);
+                                       
+                               ECPGlog("ECPGget_desc: PRECISION = %d\n", PQfmod(ECPGresult, index) >> 16);
                                break;
                                 
                        case ECPGd_ret_length:
                        case ECPGd_ret_octet:
                                if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, 0, index)))
                                        return (false);
+                                       
+                               ECPGlog("ECPGget_desc: RETURNED = %d\n", PQgetlength(ECPGresult, 0, index));
                                break;
                                
                        case ECPGd_octet:
                                if (!get_int_item(lineno, var, vartype, PQfsize(ECPGresult, index)))
                                        return (false);
+                                       
+                               ECPGlog("ECPGget_desc: OCTET_LENGTH = %d\n", PQfsize(ECPGresult, index));
                                break;
 
                        case ECPGd_length:
                                if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) - VARHDRSZ))
                                        return (false);
+                                       
+                               ECPGlog("ECPGget_desc: LENGTH = %d\n", PQfmod(ECPGresult, index) - VARHDRSZ);
                                break;
                                
                         case ECPGd_type:
                                if (!get_int_item(lineno, var, vartype, ECPGDynamicType(PQftype(ECPGresult, index))))
                                        return (false);
+                                       
+                               ECPGlog("ECPGget_desc: TYPE = %d\n", ECPGDynamicType(PQftype(ECPGresult, index)));
                                break;
-                               
+
+                       case ECPGd_data:
+                               if (!get_data(ECPGresult, 0, index, lineno, vartype, ECPGt_NO_INDICATOR, var, NULL, varcharsize, offset))
+                                       return (false);                         
+                                       
+                               break;
+                               
                         default:
                                snprintf(type_str, sizeof(type_str), "%d", type);
                                ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, type_str);
@@ -164,3 +283,37 @@ ECPGget_desc(int lineno, char *desc_name, int index, ...)
 
        return (true);                  
 }
+
+bool
+ECPGdeallocate_desc(int line, const char *name)
+{
+       struct descriptor *i;
+       struct descriptor **lastptr = &all_descriptors;
+       
+       for (i = all_descriptors; i; lastptr = &i->next, i = i->next)
+       {
+               if (!strcmp(name, i->name))
+               {
+                       *lastptr = i->next;
+                       free(i->name);
+                       PQclear(i->result);
+                       free(i);
+                       return true;
+               }
+       }
+       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name);
+       return false;
+} 
+
+bool
+ECPGallocate_desc(int line,const char *name)
+{
+       struct descriptor *new = (struct descriptor *)malloc(sizeof(struct descriptor));
+       
+       new->next = all_descriptors;
+       new->name = malloc(strlen(name)+1);
+       new->result = PQmakeEmptyPGresult(NULL, 0);
+       strcpy(new->name, name);
+       all_descriptors = new;
+       return true;
+}
diff --git a/src/interfaces/ecpg/lib/dynamic.c b/src/interfaces/ecpg/lib/dynamic.c
deleted file mode 100644 (file)
index 12aac32..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/* dynamic SQL support routines
- *
- * Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
- *
- * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/dynamic.c,v 1.5 2000/02/22 19:57:05 meskes Exp $
- */
-
-/* I borrowed the include files from ecpglib.c, maybe we don't need all of them */
-
-#include <sql3types.h>
-
-static struct descriptor
-{
-       char *name;
-       PGresult *result;
-       struct descriptor *next;
-} *all_descriptors=NULL;
-
-PGconn *ECPG_internal_get_connection(char *name);
-
-unsigned int ECPGDynamicType(Oid type)
-{
-       switch(type)
-       {       case 16:        return SQL3_BOOLEAN;    /* bool */
-               case 21:        return SQL3_SMALLINT;   /* int2 */
-               case 23:        return SQL3_INTEGER;    /* int4 */
-               case 25:        return SQL3_CHARACTER;  /* text */
-               case 700:       return SQL3_REAL;               /* float4 */
-               case 701:       return SQL3_DOUBLE_PRECISION;   /* float8 */
-               case 1042:      return SQL3_CHARACTER;  /* bpchar */
-               case 1043:      return SQL3_CHARACTER_VARYING;  /* varchar */
-               case 1082:      return SQL3_DATE_TIME_TIMESTAMP;        /* date */
-               case 1083:      return SQL3_DATE_TIME_TIMESTAMP;        /* time */
-               case 1184:      return SQL3_DATE_TIME_TIMESTAMP;        /* datetime */
-               case 1296:      return SQL3_DATE_TIME_TIMESTAMP;        /* timestamp */
-               case 1700:      return SQL3_NUMERIC;    /* numeric */
-               default:
-                       return -type;
-       }
-}
-
-unsigned int ECPGDynamicType_DDT(Oid type)
-{      switch(type)
-       {       
-               case 1082:      return SQL3_DDT_DATE;   /* date */
-               case 1083:      return SQL3_DDT_TIME;   /* time */
-               case 1184:      return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE;       /* datetime */
-               case 1296:      return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE;       /* timestamp */
-               default:
-                       return SQL3_DDT_ILLEGAL;
-       }
-}
-
-// like ECPGexecute
-static bool execute_descriptor(int lineno,const char *query
-                                                       ,struct connection *con,PGresult **resultptr)
-{
-       bool    status = false;
-       PGresult   *results;
-       PGnotify   *notify;
-       
-       /* Now the request is built. */
-
-       if (con->committed && !con->autocommit)
-       {
-               if ((results = PQexec(con->connection, "begin transaction")) == NULL)
-               {
-                       register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno);
-                       return false;
-               }
-               PQclear(results);
-               con->committed = false;
-       }
-
-       ECPGlog("execute_descriptor line %d: QUERY: %s on connection %s\n", lineno, query, con->name);
-       results = PQexec(con->connection, query);
-
-       if (results == NULL)
-       {
-               ECPGlog("ECPGexecute line %d: error: %s", lineno,
-                               PQerrorMessage(con->connection));
-               register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
-                        PQerrorMessage(con->connection), lineno);
-       }
-       else
-       {       *resultptr=results;
-               switch (PQresultStatus(results))
-               {       int ntuples;
-                       case PGRES_TUPLES_OK:
-                               status = true;
-                               sqlca.sqlerrd[2] = ntuples = PQntuples(results);
-                               if (ntuples < 1)
-                               {
-                                       ECPGlog("execute_descriptor line %d: Incorrect number of matches: %d\n",
-                                                       lineno, ntuples);
-                                       register_error(ECPG_NOT_FOUND, "No data found line %d.", lineno);
-                                       status = false;
-                                       break;
-                               }
-                               break;
-#if 1 /* strictly these are not needed (yet) */
-                       case PGRES_EMPTY_QUERY:
-                               /* do nothing */
-                               register_error(ECPG_EMPTY, "Empty query line %d.", lineno);
-                               break;
-                       case PGRES_COMMAND_OK:
-                               status = true;
-                               sqlca.sqlerrd[1] = atol(PQoidStatus(results));
-                               sqlca.sqlerrd[2] = atol(PQcmdTuples(results));
-                               ECPGlog("ECPGexecute line %d Ok: %s\n", lineno, PQcmdStatus(results));
-                               break;
-                       case PGRES_COPY_OUT:
-                               ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno);
-                               PQendcopy(con->connection);
-                               break;
-                       case PGRES_COPY_IN:
-                               ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", lineno);
-                               PQendcopy(con->connection);
-                               break;
-#else
-                       case PGRES_EMPTY_QUERY:
-                       case PGRES_COMMAND_OK:
-                       case PGRES_COPY_OUT:
-                       case PGRES_COPY_IN:
-                               break;
-#endif
-                       case PGRES_NONFATAL_ERROR:
-                       case PGRES_FATAL_ERROR:
-                       case PGRES_BAD_RESPONSE:
-                               ECPGlog("ECPGexecute line %d: Error: %s",
-                                               lineno, PQerrorMessage(con->connection));
-                               register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
-                                                          PQerrorMessage(con->connection), lineno);
-                               status = false;
-                               break;
-                       default:
-                               ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
-                                               lineno);
-                               register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
-                                                          PQerrorMessage(con->connection), lineno);
-                               status = false;
-                               break;
-               }
-       }
-
-       /* check for asynchronous returns */
-       notify = PQnotifies(con->connection);
-       if (notify)
-       {
-               ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
-                               lineno, notify->relname, notify->be_pid);
-               free(notify);
-       }
-       return status;
-}
-
-/* like ECPGdo */
-static bool do_descriptor2(int lineno,const char *connection_name,
-                                       PGresult **resultptr, const char *query)
-{
-       struct connection *con = get_connection(connection_name);
-       bool            status=true;
-       char *locale = setlocale(LC_NUMERIC, NULL);
-
-       /* Make sure we do NOT honor the locale for numeric input/output */
-       /* since the database wants teh standard decimal point */
-       setlocale(LC_NUMERIC, "C");
-
-       if (!ecpg_init(con, connection_name, lineno))
-       {       setlocale(LC_NUMERIC, locale);
-               return(false);
-       }
-
-       /* are we connected? */
-       if (con == NULL || con->connection == NULL)
-       {
-               ECPGlog("ECPGdo: not connected to %s\n", con->name);
-               register_error(ECPG_NOT_CONN, "Not connected in line %d.", lineno);
-               setlocale(LC_NUMERIC, locale);
-               return false;
-       }
-
-       status = execute_descriptor(lineno,query,con,resultptr);
-
-       /* and reset locale value so our application is not affected */
-       setlocale(LC_NUMERIC, locale);
-       return (status);
-}
-
-bool ECPGdo_descriptor(int line,const char *connection,
-                                                       const char *descriptor,const char *query)
-{
-       struct descriptor *i;
-       for (i=all_descriptors;i!=NULL;i=i->next)
-       {       if (!strcmp(descriptor,i->name)) 
-           {   
-                       bool status;
-
-                       /* free previous result */
-                       if (i->result) PQclear(i->result);
-                       i->result=NULL;
-               
-                       status=do_descriptor2(line,connection,&i->result,query);
-                       
-                       if (!i->result) PQmakeEmptyPGresult(NULL, 0);
-                       return (status);
-           }
-       }
-       
-       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, descriptor);
-       return false;
-}
-                                                       
-PGresult *ECPGresultByDescriptor(int line,const char *name)
-{
-       struct descriptor *i;
-       
-       for (i = all_descriptors; i != NULL; i = i->next)
-       {
-               if (!strcmp(name, i->name)) return i->result;
-       }
-       
-       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name);
-       
-       return NULL;
-} 
-
-
-bool ECPGdeallocate_desc(int line,const char *name)
-{
-       struct descriptor *i;
-       struct descriptor **lastptr=&all_descriptors;
-       for (i=all_descriptors;i;lastptr=&i->next,i=i->next)
-       {       if (!strcmp(name,i->name))
-               {       *lastptr=i->next;
-                       free(i->name);
-                       PQclear(i->result);
-                       free(i);
-                       return true;
-               }
-       }
-       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name);
-       return false;
-} 
-
-bool ECPGallocate_desc(int line,const char *name)
-{
-       struct descriptor *new=(struct descriptor *)malloc(sizeof(struct descriptor));
-       
-       new->next=all_descriptors;
-       new->name=malloc(strlen(name)+1);
-       new->result=PQmakeEmptyPGresult(NULL, 0);
-       strcpy(new->name,name);
-       all_descriptors=new;
-       return true;
-}
-
-void
-ECPGraise(int line, int code, const char *str)
-{
-       struct auto_mem *am;
-              
-       sqlca.sqlcode = code;
-       switch (code)
-       { 
-               case ECPG_NOT_FOUND: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "No data found line %d.", line);
-                       break;
-                       
-               case ECPG_OUT_OF_MEMORY: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "Out of memory in line %d.", line);
-                       break;
-                       
-               case ECPG_UNSUPPORTED: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "Unsupported type %s in line %d.", str, line);
-                       break;
-                       
-               case ECPG_TOO_MANY_ARGUMENTS: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "Too many arguments in line %d.", line);
-                       break;
-               
-               case ECPG_TOO_FEW_ARGUMENTS: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "Too few arguments in line %d.", line);
-                       break;
-                       
-               case ECPG_MISSING_INDICATOR: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "NULL value without indicator, line %d.", line);
-                       break;
-                       
-               case ECPG_UNKNOWN_DESCRIPTOR: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "descriptor %s not found, line %d.", str, line);
-                       break;
-                       
-               case ECPG_INVALID_DESCRIPTOR_INDEX: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "descriptor index out of range, line %d.", line);
-                       break;
-               
-               case ECPG_UNKNOWN_DESCRIPTOR_ITEM: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "unknown descriptor item %s, line %d.", str, line);
-                       break;
-               
-               case ECPG_VAR_NOT_NUMERIC: 
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "variable is not a numeric type, line %d.", line);
-                       break;
-                       
-               default:
-                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
-                               "SQL error #%d, line %d.",code, line);
-                       break;
-       }
-       
-        /* free all memory we have allocated for the user */
-        for (am = auto_allocs; am;)
-        {
-               struct auto_mem *act = am;
-               
-               am = am->next;
-               free(act->pointer);
-               free(act);
-       }
-
-        auto_allocs = NULL;
-}
index afdf93bda24eb75a9012ee795122b086a09a9808..2891eefe084ea795a954b7844863a5da192a28f9 100644 (file)
@@ -75,56 +75,11 @@ struct variable
        struct variable *next;
 };
 
-struct statement
-{
-       int                     lineno;
-       char       *command;
-       struct connection *connection;
-       struct variable *inlist;
-       struct variable *outlist;
-};
-
-static struct prepared_statement
-{
-       char       *name;
-       struct statement *stmt;
-       struct prepared_statement *next;
-}                 *prep_stmts = NULL;
-
-static struct auto_mem
-{
-       void       *pointer;
-       struct auto_mem *next;
-}                 *auto_allocs = NULL;
+struct auto_mem *auto_allocs;
 
 static int     simple_debug = 0;
 static FILE *debugstream = NULL;
 
-static void
-register_error(long code, char *fmt,...)
-{
-       va_list         args;
-       struct auto_mem *am;
-
-       sqlca.sqlcode = code;
-       va_start(args, fmt);
-       vsnprintf(sqlca.sqlerrm.sqlerrmc, SQLERRMC_LEN, fmt, args);
-       va_end(args);
-       sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
-
-       /* free all memory we have allocated for the user */
-       for (am = auto_allocs; am;)
-       {
-               struct auto_mem *act = am;
-
-               am = am->next;
-               free(act->pointer);
-               free(act);
-       }
-
-       auto_allocs = NULL;
-}
-
 static struct connection *
 get_connection(const char *connection_name)
 {
@@ -146,10 +101,12 @@ ecpg_init(const struct connection *con, const char * connection_name, const int
        memcpy((char *) &sqlca, (char *) &sqlca_init, sizeof(sqlca));
        if (con == NULL)
        {
-               register_error(ECPG_NO_CONN, "No such connection %s in line %d.", connection_name ? connection_name : "NULL", lineno);
+               ECPGraise(lineno, ECPG_NO_CONN, connection_name ? connection_name : "NULL");
                return (false);
        }
        
+       auto_allocs = NULL;
+       
        return (true);
 }
 
@@ -182,37 +139,6 @@ ecpg_finish(struct connection * act)
                ECPGlog("ecpg_finish: called an extra time.\n");
 }
 
-static char *
-ecpg_alloc(long size, int lineno)
-{
-       char       *new = (char *) calloc(1L, size);
-
-       if (!new)
-       {
-               ECPGlog("out of memory\n");
-               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
-               return NULL;
-       }
-
-       memset(new, '\0', size);
-       return (new);
-}
-
-static char *
-ecpg_strdup(const char *string, int lineno)
-{
-       char       *new = strdup(string);
-
-       if (!new)
-       {
-               ECPGlog("out of memory\n");
-               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
-               return NULL;
-       }
-
-       return (new);
-}
-
 static void
 add_mem(void *ptr, int lineno)
 {
@@ -313,7 +239,7 @@ create_statement(int lineno, struct connection * connection, struct statement **
                        if (var->pointer == NULL)
                        {
                                ECPGlog("create_statement: invalid statement name\n");
-                               register_error(ECPG_INVALID_STMT, "Invalid statement name in line %d.", lineno);
+                               ECPGraise(lineno, ECPG_INVALID_STMT, NULL);
                                free(var);
                                return false;
                        }
@@ -704,7 +630,7 @@ ECPGexecute(struct statement * stmt)
        {
                if ((results = PQexec(stmt->connection->connection, "begin transaction")) == NULL)
                {
-                       register_error(ECPG_TRANS, "Error in transaction processing line %d.", stmt->lineno);
+                       ECPGraise(stmt->lineno, ECPG_TRANS, NULL);
                        return false;
                }
                PQclear(results);
@@ -719,8 +645,7 @@ ECPGexecute(struct statement * stmt)
        {
                ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno,
                                PQerrorMessage(stmt->connection->connection));
-               register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
-                        PQerrorMessage(stmt->connection->connection), stmt->lineno);
+               ECPGraise(stmt->lineno, ECPG_PGSQL, PQerrorMessage(stmt->connection->connection));
        }
        else
        {
@@ -749,8 +674,6 @@ ECPGexecute(struct statement * stmt)
 
                                for (act_field = 0; act_field < nfields && status; act_field++)
                                {
-                                       char       *pval;
-                                       char       *scan_length;
                                        char       *array_query;
                                        
                                        if (var == NULL)
@@ -820,247 +743,10 @@ ECPGexecute(struct statement * stmt)
                                                                                
                                        for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
                                        {
-                                               pval = (char *)PQgetvalue(results, act_tuple, act_field);
-
-                                               ECPGlog("ECPGexecute line %d: RESULT: %s\n", stmt->lineno, pval ? pval : "");
-
-                                               /* Now the pval is a pointer to the value. */
-                                               /* We will have to decode the value */
-
-                                               /*
-                                                * check for null value and set indicator
-                                                * accordingly
-                                                */
-                                               switch (var->ind_type)
-                                               {
-                                                       case ECPGt_short:
-                                                       case ECPGt_unsigned_short:
-                                                               ((short *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
-                                                               break;
-                                                       case ECPGt_int:
-                                                       case ECPGt_unsigned_int:
-                                                               ((int *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
-                                                               break;
-                                                       case ECPGt_long:
-                                                       case ECPGt_unsigned_long:
-                                                               ((long *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
-                                                               break;
-                                                       case ECPGt_NO_INDICATOR:
-                                                               if (PQgetisnull(results, act_tuple, act_field))
-                                                               {
-                                                                       register_error(ECPG_MISSING_INDICATOR, "NULL value without indicator variable on line %d.", stmt->lineno);
-                                                                       status = false;
-                                                               }
-                                                               break;
-                                                       default:
-                                                               ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, ECPGtype_name(var->ind_type));
-                                                               status = false;
-                                                               break;
-                                               }
-                                               
-                                               switch (var->type)
-                                               {
-                                                               long            res;
-                                                               unsigned long ures;
-                                                               double          dres;
-
-                                                       case ECPGt_short:
-                                                       case ECPGt_int:
-                                                       case ECPGt_long:
-                                                               if (pval)
-                                                               {
-                                                                       res = strtol(pval, &scan_length, 10);
-                                                                       if (*scan_length != '\0')       /* Garbage left */
-                                                                       {
-                                                                               register_error(ECPG_INT_FORMAT, "Not correctly formatted int type: %s line %d.",
-                                                                                                        pval, stmt->lineno);
-                                                                               status = false;
-                                                                               res = 0L;
-                                                                       }
-                                                               }
-                                                               else
-                                                                       res = 0L;
-
-                                                               switch (var->type)
-                                                               {
-                                                                       case ECPGt_short:
-                                                                               ((short *) var->value)[act_tuple] = (short) res;
-                                                                               break;
-                                                                       case ECPGt_int:
-                                                                               ((int *) var->value)[act_tuple] = (int) res;
-                                                                               break;
-                                                                       case ECPGt_long:
-                                                                               ((long *) var->value)[act_tuple] = res;
-                                                                               break;
-                                                                       default:
-                                                                               /* Cannot happen */
-                                                                               break;
-                                                               }
-                                                               break;
-
-                                                       case ECPGt_unsigned_short:
-                                                       case ECPGt_unsigned_int:
-                                                       case ECPGt_unsigned_long:
-                                                               if (pval)
-                                                               {
-                                                                       ures = strtoul(pval, &scan_length, 10);
-                                                                       if (*scan_length != '\0')       /* Garbage left */
-                                                                       {
-                                                                               register_error(ECPG_UINT_FORMAT, "Not correctly formatted unsigned type: %s line %d.",
-                                                                                                        pval, stmt->lineno);
-                                                                               status = false;
-                                                                               ures = 0L;
-                                                                       }
-                                                               }
-                                                               else
-                                                                       ures = 0L;
-
-                                                               switch (var->type)
-                                                               {
-                                                                       case ECPGt_unsigned_short:
-                                                                               ((unsigned short *) var->value)[act_tuple] = (unsigned short) ures;
-                                                                               break;
-                                                                       case ECPGt_unsigned_int:
-                                                                               ((unsigned int *) var->value)[act_tuple] = (unsigned int) ures;
-                                                                               break;
-                                                                       case ECPGt_unsigned_long:
-                                                                               ((unsigned long *) var->value)[act_tuple] = ures;
-                                                                               break;
-                                                                       default:
-                                                                               /* Cannot happen */
-                                                                               break;
-                                                               }
-                                                               break;
-
-
-                                                       case ECPGt_float:
-                                                       case ECPGt_double:
-                                                               if (pval)
-                                                               {
-                                                                       dres = strtod(pval, &scan_length);
-                                                                       if (*scan_length != '\0')       /* Garbage left */
-                                                                       {
-                                                                               register_error(ECPG_FLOAT_FORMAT, "Not correctly formatted floating point type: %s line %d.",
-                                                                                                        pval, stmt->lineno);
-                                                                               status = false;
-                                                                               dres = 0.0;
-                                                                       }
-                                                               }
-                                                               else
-                                                                       dres = 0.0;
-
-                                                               switch (var->type)
-                                                               {
-                                                                       case ECPGt_float:
-                                                                               ((float *) var->value)[act_tuple] = dres;
-                                                                               break;
-                                                                       case ECPGt_double:
-                                                                               ((double *) var->value)[act_tuple] = dres;
-                                                                               break;
-                                                                       default:
-                                                                               /* Cannot happen */
-                                                                               break;
-                                                               }
-                                                               break;
-
-                                                       case ECPGt_bool:
-                                                               if (pval)
-                                                               {
-                                                                       if (pval[0] == 'f' && pval[1] == '\0')
-                                                                       {
-                                                                               ((char *) var->value)[act_tuple] = false;
-                                                                               break;
-                                                                       }
-                                                                       else if (pval[0] == 't' && pval[1] == '\0')
-                                                                       {
-                                                                               ((char *) var->value)[act_tuple] = true;
-                                                                               break;
-                                                                       }
-                                                                       else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
-                                                                       {
-                                                                               // NULL is valid
-                                                                               break;
-                                                                       }
-                                                               }
-
-                                                               register_error(ECPG_CONVERT_BOOL, "Unable to convert %s to bool on line %d.",
-                                                                                          (pval ? pval : "NULL"),
-                                                                                          stmt->lineno);
-                                                               status = false;
-                                                               break;
-
-                                                       case ECPGt_char:
-                                                       case ECPGt_unsigned_char:
-                                                               {
-                                                                       strncpy((char *) ((long) var->value + var->offset * act_tuple), pval, var->varcharsize);
-                                                                       if (var->varcharsize && var->varcharsize < strlen(pval))
-                                                                       {
-                                                                               /* truncation */
-                                                                               switch (var->ind_type)
-                                                                               {
-                                                                                       case ECPGt_short:
-                                                                                       case ECPGt_unsigned_short:
-                                                                                               ((short *) var->ind_value)[act_tuple] = var->varcharsize;
-                                                                                               break;
-                                                                                       case ECPGt_int:
-                                                                                       case ECPGt_unsigned_int:
-                                                                                               ((int *) var->ind_value)[act_tuple] = var->varcharsize;
-                                                                                               break;
-                                                                                       case ECPGt_long:
-                                                                                       case ECPGt_unsigned_long:
-                                                                                               ((long *) var->ind_value)[act_tuple] = var->varcharsize;
-                                                                                               break;
-                                                                                       default:
-                                                                                               break;
-                                                                               }
-                                                                               sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
-                                                                       }
-                                                               }
-                                                               break;
-
-                                                       case ECPGt_varchar:
-                                                               {
-                                                                       struct ECPGgeneric_varchar *variable =
-                                                                       (struct ECPGgeneric_varchar *) ((long) var->value + var->offset * act_tuple);
-
-                                                                       if (var->varcharsize == 0)
-                                                                               strncpy(variable->arr, pval, strlen(pval));
-                                                                       else
-                                                                               strncpy(variable->arr, pval, var->varcharsize);
-
-                                                                       variable->len = strlen(pval);
-                                                                       if (var->varcharsize > 0 && variable->len > var->varcharsize)
-                                                                       {
-                                                                               /* truncation */
-                                                                               switch (var->ind_type)
-                                                                               {
-                                                                                       case ECPGt_short:
-                                                                                       case ECPGt_unsigned_short:
-                                                                                               ((short *) var->ind_value)[act_tuple] = var->varcharsize;
-                                                                                               break;
-                                                                                       case ECPGt_int:
-                                                                                       case ECPGt_unsigned_int:
-                                                                                               ((int *) var->ind_value)[act_tuple] = var->varcharsize;
-                                                                                               break;
-                                                                                       case ECPGt_long:
-                                                                                       case ECPGt_unsigned_long:
-                                                                                               ((long *) var->ind_value)[act_tuple] = var->varcharsize;
-                                                                                               break;
-                                                                                       default:
-                                                                                               break;
-                                                                               }
-                                                                               sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
-
-                                                                               variable->len = var->varcharsize;
-                                                                       }
-                                                               }
-                                                               break;
-
-                                                       default:
-                                                               ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, ECPGtype_name(var->type));
-                                                               status = false;
-                                                               break;
-                                               }
+                                               if (!get_data(results, act_tuple, act_field, stmt->lineno,
+                                                        var->type, var->ind_type, var->value,
+                                                        var->ind_value, var->varcharsize, var->offset))
+                                                        status = false;
                                        }
                                        var = var->next;
                                }
@@ -1074,7 +760,7 @@ ECPGexecute(struct statement * stmt)
                                break;
                        case PGRES_EMPTY_QUERY:
                                /* do nothing */
-                               register_error(ECPG_EMPTY, "Empty query line %d.", stmt->lineno);
+                               ECPGraise(stmt->lineno, ECPG_EMPTY, NULL);
                                break;
                        case PGRES_COMMAND_OK:
                                status = true;
@@ -1087,8 +773,7 @@ ECPGexecute(struct statement * stmt)
                        case PGRES_BAD_RESPONSE:
                                ECPGlog("ECPGexecute line %d: Error: %s",
                                                stmt->lineno, PQerrorMessage(stmt->connection->connection));
-                               register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
-                                                          PQerrorMessage(stmt->connection->connection), stmt->lineno);
+                               ECPGraise(stmt->lineno, ECPG_PGSQL, PQerrorMessage(stmt->connection->connection));
                                status = false;
                                break;
                        case PGRES_COPY_OUT:
@@ -1102,8 +787,7 @@ ECPGexecute(struct statement * stmt)
                        default:
                                ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
                                                stmt->lineno);
-                               register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
-                                                          PQerrorMessage(stmt->connection->connection), stmt->lineno);
+                               ECPGraise(stmt->lineno, ECPG_PGSQL, PQerrorMessage(stmt->connection->connection));
                                status = false;
                                break;
                }
@@ -1154,7 +838,7 @@ ECPGdo(int lineno, const char *connection_name, char *query, ...)
        {
                free_statement(stmt);
                ECPGlog("ECPGdo: not connected to %s\n", con->name);
-               register_error(ECPG_NOT_CONN, "Not connected in line %d.", lineno);
+               ECPGraise(lineno, ECPG_NOT_CONN, NULL);
                setlocale(LC_NUMERIC, locale);
                return false;
        }
@@ -1179,7 +863,7 @@ ECPGstatus(int lineno, const char *connection_name)
        if (con->connection == NULL)
        {
                ECPGlog("ECPGdo: not connected to %s\n", con->name);
-               register_error(ECPG_NOT_CONN, "Not connected in line %d", lineno);
+               ECPGraise(lineno, ECPG_NOT_CONN, NULL);
                return false;
        }
 
@@ -1202,7 +886,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
        {
                if ((res = PQexec(con->connection, transaction)) == NULL)
                {
-                       register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno);
+                       ECPGraise(lineno, ECPG_TRANS, NULL);
                        return FALSE;
                }
                PQclear(res);
@@ -1213,13 +897,8 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
                con->committed = true;
 
                /* deallocate all prepared statements */
-               while(prep_stmts != NULL)
-               {
-                       bool            b = ECPGdeallocate(lineno, prep_stmts->name);
-
-                       if (!b)
+               if (!ECPGdeallocate_all(lineno))
                                return false;
-               }
        }
 
        return true;
@@ -1242,7 +921,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
                {
                        if ((results = PQexec(con->connection, "begin transaction")) == NULL)
                        {
-                               register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno);
+                               ECPGraise(lineno, ECPG_TRANS, NULL);
                                return false;
                        }
                        PQclear(results);
@@ -1256,7 +935,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
                {
                        if ((results = PQexec(con->connection, "commit")) == NULL)
                        {
-                               register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno);
+                               ECPGraise(lineno, ECPG_TRANS, NULL);
                                return false;
                        }
                        PQclear(results);
@@ -1315,7 +994,7 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
        {
                ecpg_finish(this);
                ECPGlog("connect: could not open database %s %s%s in line %d\n", dbname ? dbname : "<DEFAULT>", user ? "for user " : "", user ? user : "", lineno);
-               register_error(ECPG_CONNECT, "connect: could not open database %s.", dbname ? dbname : "<DEFAULT>");
+               ECPGraise(lineno, ECPG_CONNECT, dbname ? dbname : "<DEFAULT>");
                return false;
        }
 
@@ -1384,135 +1063,179 @@ ECPGlog(const char *format,...)
        }
 }
 
-/* print out an error message */
-void
-sqlprint(void)
-{
-       sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
-       fprintf(stderr, "sql error %s\n", sqlca.sqlerrm.sqlerrmc);
-}
-
-static bool
-isvarchar(unsigned char c)
-{
-       if (isalnum(c))
-               return true;
+/* dynamic SQL support routines
+ *
+ * Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
+ *
+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/ecpglib.c,v 1.60 2000/02/23 19:25:43 meskes Exp $
+ */
 
-       if (c == '_' || c == '>' || c == '-' || c == '.')
-               return true;
+/* I borrowed the include files from ecpglib.c, maybe we don't need all of them */
 
-       if (c >= 128)
-               return true;
+#include <sql3types.h>
 
-       return (false);
-}
+PGconn *ECPG_internal_get_connection(char *name);
 
-static void
-replace_variables(char *text)
+extern struct descriptor
 {
-       char       *ptr = text;
-       bool            string = false;
+   char *name;
+   PGresult *result;
+   struct descriptor *next;
+} *all_descriptors;
+
+// like ECPGexecute
+static bool execute_descriptor(int lineno,const char *query
+                                                       ,struct connection *con,PGresult **resultptr)
+{
+       bool    status = false;
+       PGresult   *results;
+       PGnotify   *notify;
+       
+       /* Now the request is built. */
 
-       for (; *ptr != '\0'; ptr++)
+       if (con->committed && !con->autocommit)
        {
-               if (*ptr == '\'')
-                       string = string ? false : true;
-
-               if (!string && *ptr == ':')
+               if ((results = PQexec(con->connection, "begin transaction")) == NULL)
                {
-                       *ptr = '?';
-                       for (++ptr; *ptr && isvarchar(*ptr); ptr++)
-                               *ptr = ' ';
+                       ECPGraise(lineno, ECPG_TRANS, NULL);
+                       return false;
                }
+               PQclear(results);
+               con->committed = false;
        }
-}
 
-/* handle the EXEC SQL PREPARE statement */
-bool
-ECPGprepare(int lineno, char *name, char *variable)
-{
-       struct statement *stmt;
-       struct prepared_statement *this;
+       ECPGlog("execute_descriptor line %d: QUERY: %s on connection %s\n", lineno, query, con->name);
+       results = PQexec(con->connection, query);
 
-       /* check if we already have prepared this statement */
-       for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
-       if (this)
+       if (results == NULL)
        {
-               bool            b = ECPGdeallocate(lineno, name);
-
-               if (!b)
-                       return false;
+               ECPGlog("ECPGexecute line %d: error: %s", lineno,
+                               PQerrorMessage(con->connection));
+               ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection));
+       }
+       else
+       {       *resultptr=results;
+               switch (PQresultStatus(results))
+               {       int ntuples;
+                       case PGRES_TUPLES_OK:
+                               status = true;
+                               sqlca.sqlerrd[2] = ntuples = PQntuples(results);
+                               if (ntuples < 1)
+                               {
+                                       ECPGlog("execute_descriptor line %d: Incorrect number of matches: %d\n",
+                                                       lineno, ntuples);
+                                       ECPGraise(lineno, ECPG_NOT_FOUND, NULL);
+                                       status = false;
+                                       break;
+                               }
+                               break;
+#if 1 /* strictly these are not needed (yet) */
+                       case PGRES_EMPTY_QUERY:
+                               /* do nothing */
+                               ECPGraise(lineno, ECPG_EMPTY, NULL);
+                               break;
+                       case PGRES_COMMAND_OK:
+                               status = true;
+                               sqlca.sqlerrd[1] = atol(PQoidStatus(results));
+                               sqlca.sqlerrd[2] = atol(PQcmdTuples(results));
+                               ECPGlog("ECPGexecute line %d Ok: %s\n", lineno, PQcmdStatus(results));
+                               break;
+                       case PGRES_COPY_OUT:
+                               ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno);
+                               PQendcopy(con->connection);
+                               break;
+                       case PGRES_COPY_IN:
+                               ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", lineno);
+                               PQendcopy(con->connection);
+                               break;
+#else
+                       case PGRES_EMPTY_QUERY:
+                       case PGRES_COMMAND_OK:
+                       case PGRES_COPY_OUT:
+                       case PGRES_COPY_IN:
+                               break;
+#endif
+                       case PGRES_NONFATAL_ERROR:
+                       case PGRES_FATAL_ERROR:
+                       case PGRES_BAD_RESPONSE:
+                               ECPGlog("ECPGexecute line %d: Error: %s",
+                                               lineno, PQerrorMessage(con->connection));
+                               ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection));
+                               status = false;
+                               break;
+                       default:
+                               ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
+                                               lineno);
+                               ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection));
+                               status = false;
+                               break;
+               }
        }
 
-       this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
-       if (!this)
-               return false;
-
-       stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno);
-       if (!stmt)
+       /* check for asynchronous returns */
+       notify = PQnotifies(con->connection);
+       if (notify)
        {
-               free(this);
-               return false;
+               ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
+                               lineno, notify->relname, notify->be_pid);
+               free(notify);
        }
+       return status;
+}
 
-       /* create statement */
-       stmt->lineno = lineno;
-       stmt->connection = NULL;
-       stmt->command = ecpg_strdup(variable, lineno);
-       stmt->inlist = stmt->outlist = NULL;
+/* like ECPGdo */
+static bool do_descriptor2(int lineno,const char *connection_name,
+                                       PGresult **resultptr, const char *query)
+{
+       struct connection *con = get_connection(connection_name);
+       bool            status=true;
+       char *locale = setlocale(LC_NUMERIC, NULL);
+
+       /* Make sure we do NOT honor the locale for numeric input/output */
+       /* since the database wants teh standard decimal point */
+       setlocale(LC_NUMERIC, "C");
 
-       /* if we have C variables in our statment replace them with '?' */
-       replace_variables(stmt->command);
+       if (!ecpg_init(con, connection_name, lineno))
+       {       setlocale(LC_NUMERIC, locale);
+               return(false);
+       }
 
-       /* add prepared statement to our list */
-       this->name = ecpg_strdup(name, lineno);
-       this->stmt = stmt;
+       /* are we connected? */
+       if (con == NULL || con->connection == NULL)
+       {
+               ECPGlog("do_descriptor2: not connected to %s\n", con->name);
+               ECPGraise(lineno, ECPG_NOT_CONN, NULL);
+               setlocale(LC_NUMERIC, locale);
+               return false;
+       }
 
-       if (prep_stmts == NULL)
-               this->next = NULL;
-       else
-               this->next = prep_stmts;
+       status = execute_descriptor(lineno,query,con,resultptr);
 
-       prep_stmts = this;
-       return true;
+       /* and reset locale value so our application is not affected */
+       setlocale(LC_NUMERIC, locale);
+       return (status);
 }
 
-/* handle the EXEC SQL DEALLOCATE PREPARE statement */
-bool
-ECPGdeallocate(int lineno, char *name)
+bool ECPGdo_descriptor(int line,const char *connection,
+                                                       const char *descriptor,const char *query)
 {
-       struct prepared_statement *this,
-                          *prev;
-
-       /* check if we really have prepared this statement */
-       for (this = prep_stmts, prev = NULL; this != NULL && strcmp(this->name, name) != 0; prev = this, this = this->next);
-       if (this)
-       {
-               /* okay, free all the resources */
-               free(this->name);
-               free(this->stmt->command);
-               free(this->stmt);
-               if (prev != NULL)
-                       prev->next = this->next;
-               else
-                       prep_stmts = this->next;
-               
-               free(this);
-               return true;
+       struct descriptor *i;
+       for (i=all_descriptors;i!=NULL;i=i->next)
+       {       if (!strcmp(descriptor,i->name)) 
+           {   
+                       bool status;
+
+                       /* free previous result */
+                       if (i->result) PQclear(i->result);
+                       i->result=NULL;
+               
+                       status=do_descriptor2(line,connection,&i->result,query);
+                       
+                       if (!i->result) PQmakeEmptyPGresult(NULL, 0);
+                       return (status);
+           }
        }
-       ECPGlog("deallocate_prepare: invalid statement name %s\n", name);
-       register_error(ECPG_INVALID_STMT, "Invalid statement name %s in line %d", name, lineno);
+       
+       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, descriptor);
        return false;
 }
-
-/* return the prepared statement */
-char *
-ECPGprepared_statement(char *name)
-{
-       struct prepared_statement *this;
-
-       for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
-       return (this) ? this->stmt->command : NULL;
-}
-
-#include "dynamic.c"
diff --git a/src/interfaces/ecpg/lib/error.c b/src/interfaces/ecpg/lib/error.c
new file mode 100644 (file)
index 0000000..aa63fe9
--- /dev/null
@@ -0,0 +1,151 @@
+#include <stdio.h>
+
+#include <ecpgerrno.h>
+#include <ecpgtype.h>
+#include <ecpglib.h>
+#include <sqlca.h>
+
+void
+ECPGraise(int line, int code, const char *str)
+{
+       struct auto_mem *am;
+              
+       sqlca.sqlcode = code;
+       switch (code)
+       { 
+               case ECPG_NOT_FOUND: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "No data found in line %d.", line);
+                       break;
+                       
+               case ECPG_OUT_OF_MEMORY: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Out of memory in line %d.", line);
+                       break;
+                       
+               case ECPG_UNSUPPORTED: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Unsupported type %s in line %d.", str, line);
+                       break;
+                       
+               case ECPG_TOO_MANY_ARGUMENTS: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Too many arguments in line %d.", line);
+                       break;
+               
+               case ECPG_TOO_FEW_ARGUMENTS: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Too few arguments in line %d.", line);
+                       break;
+               
+               case ECPG_INT_FORMAT: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Not correctly formatted int type: %s line %d.", str, line);
+                       break;
+                       
+               case ECPG_UINT_FORMAT: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Not correctly formatted unsigned type: %s in line %d.", str, line);
+                       break;
+                               
+               case ECPG_FLOAT_FORMAT: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Not correctly formatted floating point type: %s in line %d.", str, line);
+                       break;
+
+               case ECPG_CONVERT_BOOL: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Unable to convert %s to bool on line %d.", str, line);
+                       break;
+
+               case ECPG_EMPTY: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Empty query in line %d.", line);
+                       break;
+
+               case ECPG_MISSING_INDICATOR: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "NULL value without indicator in line %d.", line);
+                       break;
+                       
+               case ECPG_NO_CONN: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "No such connection %s in line %d.", str, line);
+                       break;
+                       
+               case ECPG_NOT_CONN: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Not connected in line %d.", line);
+                       break;
+
+               case ECPG_INVALID_STMT: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Invalid statement name in line %d.", line);
+                       break;
+                       
+               case ECPG_UNKNOWN_DESCRIPTOR: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Sescriptor %s not found in line %d.", str, line);
+                       break;
+                       
+               case ECPG_INVALID_DESCRIPTOR_INDEX: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Sescriptor index out of range in line %d.", line);
+                       break;
+               
+               case ECPG_UNKNOWN_DESCRIPTOR_ITEM: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Unknown descriptor item %s in line %d.", str, line);
+                       break;
+               
+               case ECPG_VAR_NOT_NUMERIC: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Variable is not a numeric type in line %d.", line);
+                       break;
+               
+               case ECPG_VAR_NOT_CHAR: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Variable is not a character type in line %d.", line);
+                       break;
+                       
+               case ECPG_PGSQL: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Postgres error '%s' in line %d.", str, line);
+                       break;
+                       
+               case ECPG_TRANS: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Error in transaction processing in line %d.", line);
+                       break;
+                       
+               case ECPG_CONNECT: 
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "Could not connect to database %s in line %d.", str, line);
+                       break;
+                       
+               default:
+                       snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+                               "SQL error #%d in line %d.",code, line);
+                       break;
+       }
+       
+       sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
+       
+        /* free all memory we have allocated for the user */
+        for (am = auto_allocs; am;)
+        {
+               struct auto_mem *act = am;
+               
+               am = am->next;
+               free(act->pointer);
+               free(act);
+       }
+}
+
+/* print out an error message */
+void
+sqlprint(void)
+{
+       sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
+       fprintf(stderr, "sql error %s\n", sqlca.sqlerrm.sqlerrmc);
+}
diff --git a/src/interfaces/ecpg/lib/memory.c b/src/interfaces/ecpg/lib/memory.c
new file mode 100644 (file)
index 0000000..61c5d29
--- /dev/null
@@ -0,0 +1,33 @@
+#include <ecpgtype.h>
+#include <ecpglib.h>
+
+char *
+ecpg_alloc(long size, int lineno)
+{
+       char       *new = (char *) calloc(1L, size);
+
+       if (!new)
+       {
+               ECPGlog("out of memory\n");
+               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
+               return NULL;
+       }
+
+       memset(new, '\0', size);
+       return (new);
+}
+
+char *
+ecpg_strdup(const char *string, int lineno)
+{
+       char       *new = strdup(string);
+
+       if (!new)
+       {
+               ECPGlog("out of memory\n");
+               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
+               return NULL;
+       }
+
+       return (new);
+}
diff --git a/src/interfaces/ecpg/lib/prepare.c b/src/interfaces/ecpg/lib/prepare.c
new file mode 100644 (file)
index 0000000..409d289
--- /dev/null
@@ -0,0 +1,149 @@
+#include <ctype.h>
+
+#include <ecpgtype.h>
+#include <ecpglib.h>
+#include <sqlca.h>
+
+static struct prepared_statement
+{
+        char       *name;
+        struct statement *stmt;
+        struct prepared_statement *next;
+}                  *prep_stmts = NULL;
+
+static bool
+isvarchar(unsigned char c)
+{
+       if (isalnum(c))
+               return true;
+
+       if (c == '_' || c == '>' || c == '-' || c == '.')
+               return true;
+
+       if (c >= 128)
+               return true;
+
+       return (false);
+}
+
+static void
+replace_variables(char *text)
+{
+       char       *ptr = text;
+       bool            string = false;
+
+       for (; *ptr != '\0'; ptr++)
+       {
+               if (*ptr == '\'')
+                       string = string ? false : true;
+
+               if (!string && *ptr == ':')
+               {
+                       *ptr = '?';
+                       for (++ptr; *ptr && isvarchar(*ptr); ptr++)
+                               *ptr = ' ';
+               }
+       }
+}
+                        
+/* handle the EXEC SQL PREPARE statement */
+bool
+ECPGprepare(int lineno, char *name, char *variable)
+{
+       struct statement *stmt;
+       struct prepared_statement *this;
+
+       /* check if we already have prepared this statement */
+       for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
+       if (this)
+       {
+               bool            b = ECPGdeallocate(lineno, name);
+
+               if (!b)
+                       return false;
+       }
+
+       this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
+       if (!this)
+               return false;
+
+       stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno);
+       if (!stmt)
+       {
+               free(this);
+               return false;
+       }
+
+       /* create statement */
+       stmt->lineno = lineno;
+       stmt->connection = NULL;
+       stmt->command = ecpg_strdup(variable, lineno);
+       stmt->inlist = stmt->outlist = NULL;
+
+       /* if we have C variables in our statment replace them with '?' */
+       replace_variables(stmt->command);
+
+       /* add prepared statement to our list */
+       this->name = ecpg_strdup(name, lineno);
+       this->stmt = stmt;
+
+       if (prep_stmts == NULL)
+               this->next = NULL;
+       else
+               this->next = prep_stmts;
+
+       prep_stmts = this;
+       return true;
+}
+
+/* handle the EXEC SQL DEALLOCATE PREPARE statement */
+bool
+ECPGdeallocate(int lineno, char *name)
+{
+       struct prepared_statement *this,
+                          *prev;
+
+       /* check if we really have prepared this statement */
+       for (this = prep_stmts, prev = NULL; this != NULL && strcmp(this->name, name) != 0; prev = this, this = this->next);
+       if (this)
+       {
+               /* okay, free all the resources */
+               free(this->name);
+               free(this->stmt->command);
+               free(this->stmt);
+               if (prev != NULL)
+                       prev->next = this->next;
+               else
+                       prep_stmts = this->next;
+               
+               free(this);
+               return true;
+       }
+       ECPGlog("deallocate_prepare: invalid statement name %s\n", name);
+       ECPGraise(lineno, ECPG_INVALID_STMT, name);
+       return false;
+}
+
+bool
+ECPGdeallocate_all(int lineno)
+{
+       /* deallocate all prepared statements */
+        while(prep_stmts != NULL)
+        {
+               bool b = ECPGdeallocate(lineno, prep_stmts->name);
+               
+               if (!b)
+                       return false;
+         }
+                                                                                                                        
+}
+
+/* return the prepared statement */
+char *
+ECPGprepared_statement(char *name)
+{
+       struct prepared_statement *this;
+
+       for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
+       return (this) ? this->stmt->command : NULL;
+}
index 845a70c0aa872bd76383faed8dbae7030220d8c4..e55aa886cf807fff3350df97be07bd346925e1d4 100644 (file)
@@ -57,116 +57,6 @@ static void ECPGnumeric_lvalue(FILE *f,char *name)
        }        
 }
 
-static void ECPGstring_buffer(FILE *f, char *name)
-{ 
-       const struct variable *v = find_variable(name);
-
-       switch(v->type->typ)
-       {
-               case ECPGt_varchar:
-                       fprintf(yyout,"%s.arr",name);
-                       break;
-                       
-               case ECPGt_char:
-               case ECPGt_unsigned_char:
-                       fputs(name,yyout);
-                       break;
-                       
-               default:
-                       snprintf(errortext,sizeof errortext,"variable %s: character type needed"
-                                       ,name);
-                       mmerror(ET_ERROR,errortext);
-                       break;
-       }
-}
-
-static void ECPGstring_length(FILE *f,char *name)
-{
-       const struct variable *v=find_variable(name);
-       
-       switch(v->type->typ)
-       {       case ECPGt_varchar:
-               case ECPGt_char:
-               case ECPGt_unsigned_char:
-                   if (!v->type->size) 
-                   {   snprintf(errortext,sizeof errortext,"zero length char variable %s for assignment",
-                                                                                       v->name);
-                       mmerror(ET_ERROR,errortext);
-                   }
-                       fprintf(yyout,"%ld",v->type->size);
-                       break;
-               default:
-                       snprintf(errortext,sizeof errortext,"variable %s: character type needed"
-                                       ,name);
-                       mmerror(ET_ERROR,errortext);
-                       break;
-       }
-}
-
-static void ECPGdata_assignment(char *variable,char *index_plus_1)
-{
-       const struct variable *v=find_variable(variable);
-
-       fprintf(yyout,"\t\t\tif (!PQgetisnull(ECPGresult,0,(%s)-1))\n",index_plus_1);
-       switch(v->type->typ)
-       {
-               case ECPGt_short:
-               case ECPGt_int: /* use the same conversion as ecpglib does */
-               case ECPGt_long:
-                       fprintf(yyout,"\t\t\t\t%s=strtol(PQgetvalue(ECPGresult,0,(%s)-1),NULL,10);\n"
-                                                                                       ,variable,index_plus_1);
-                       break;
-               case ECPGt_unsigned_short:
-               case ECPGt_unsigned_int:
-               case ECPGt_unsigned_long:
-                       fprintf(yyout,"\t\t\t\t%s=strtoul(PQgetvalue(ECPGresult,0,(%s)-1),NULL,10);\n"
-                                                                                       ,variable,index_plus_1);
-                       break;
-               case ECPGt_float:
-               case ECPGt_double:
-                       fprintf(yyout,"\t\t\t\t%s=strtod(PQgetvalue(ECPGresult,0,(%s)-1),NULL);\n"
-                                                                                       ,variable,index_plus_1);
-                       break;
-                       
-               case ECPGt_bool:
-                       fprintf(yyout,"\t\t\t\t%s=PQgetvalue(ECPGresult,0,(%s)-1)[0]=='t';\n"
-                                                                                       ,variable,index_plus_1);
-                       break;
-               
-               case ECPGt_varchar:
-                       fprintf(yyout,"\t\t\t{\tstrncpy(%s.arr,PQgetvalue(ECPGresult,0,(%s)-1),%ld);\n"
-                                                                                       ,variable,index_plus_1,v->type->size);
-                       fprintf(yyout,"\t\t\t\t%s.len=strlen(PQgetvalue(ECPGresult,0,(%s)-1)\n"
-                                                                                       ,variable,index_plus_1);
-                       fprintf(yyout,"\t\t\t\tif (%s.len>%ld) { %s.len=%ld; sqlca.sqlwarn[0]=sqlca.sqlwarn[1]='W'; }\n"
-                                                                                       ,variable,v->type->size,variable,v->type->size);
-                       fputs("\t\t\t}\n",yyout);                                                                                       
-                       break;
-                       
-               case ECPGt_char:
-               case ECPGt_unsigned_char:
-                   if (!v->type->size) 
-                   {
-                       snprintf(errortext,sizeof errortext,"zero length char variable %s for DATA assignment",
-                                                                                       v->name);
-                       mmerror(ET_ERROR,errortext);
-                   }
-                       fprintf(yyout,"\t\t\t{\tstrncpy(%s,PQgetvalue(ECPGresult,0,(%s)-1),%ld);\n"
-                                                                                       ,variable,index_plus_1,v->type->size);
-                       fprintf(yyout,"\t\t\t\tif (strlen(PQgetvalue(ECPGresult,0,(%s)-1))>=%ld)\n"
-                               "\t\t\t\t{ %s[%ld]=0; sqlca.sqlwarn[0]=sqlca.sqlwarn[1]='W'; }\n"
-                                                                                       ,index_plus_1,v->type->size,variable,v->type->size-1);
-                       fputs("\t\t\t}\n",yyout);                                                                                       
-                       break;
-                       
-               default:
-                       snprintf(errortext,sizeof errortext,"unknown variable type %d for DATA assignment"
-                                       ,v->type->typ);
-                       mmerror(ET_ERROR,errortext);
-                       break;
-       }
-}
-
 /*
  * descriptor name lookup
  */
index 50217b52aea6b766edf483f8f45f2ef96f8f0959..a4238fcc3839e2f5cda8628893e62bb8dec6f458 100644 (file)
@@ -1,4 +1,4 @@
-all: stp.so test1 test2 test3 test4 test5 perftest dyntest
+all: test1 test2 test3 test4 perftest dyntest
 
 #LDFLAGS=-g -I /usr/local/pgsql/include -L/usr/local/pgsql/lib -lecpg -lpq -lcrypt
 LDFLAGS=-g -I../include -I/usr/include/postgresql  -L/usr/lib/postgresql -L../lib -lecpg -lpq -lcrypt
@@ -14,17 +14,11 @@ test1: test1.c
 test2: test2.c
 test3: test3.c
 test4: test4.c
-test5: test5.c
 perftest: perftest.c
 dyntest: dyntest.c
 
 .pgc.c:
        $(ECPG) $? 
 
-stp.so: stp.c
-       cc -fPIC -I../include -I/usr/include/postgresql -c -o stp.o stp.c
-       ld -Bdynamic -shared -soname stp.so -o stp.so stp.o -lpq -lecpg -lc
-
-
 clean:
-       -/bin/rm test1 test2 test3 test4 test5 perftest *.c log stp.o stp.so dyntest
+       -/bin/rm test1 test2 test3 test4 perftest *.c log dyntest
index 3698cf685f5680d77b5f470d8b221c4b3f035f9b..f7c9ee4798b8ffa4c2cbc19fe7354903cb6b78ec 100644 (file)
@@ -2,7 +2,7 @@
  *
  * Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
  *
- * $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Attic/dyntest.pgc,v 1.3 2000/02/22 19:57:12 meskes Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Attic/dyntest.pgc,v 1.4 2000/02/23 19:26:04 meskes Exp $
  */
 
 #include <stdio.h>
@@ -11,14 +11,16 @@ exec sql include sql3types;
 exec sql include sqlca;
 
 void error()
-{  printf("#%d:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+{
+   printf("\n#%d:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
    exit(1);
 }
 
 int main(int argc,char **argv)
-{ exec sql begin declare section;
+{
+exec sql begin declare section;
   int COUNT;
-  int INTVAR;
+  int INTVAR, BOOLVAR;
   int INDEX;
   int INDICATOR;
   int TYPE,LENGTH,OCTET_LENGTH,PRECISION,SCALE,NULLABLE,RETURNED_OCTET_LENGTH;
@@ -28,10 +30,12 @@ int main(int argc,char **argv)
   float FLOATVAR;
   double DOUBLEVAR;
   char QUERY[1024];
-  exec sql end declare section;
+exec sql end declare section;
   int done=0;
   FILE *dbgs;
 
+  exec sql var BOOLVAR is bool;
+
   if ((dbgs = fopen("log", "w")) != NULL)
        ECPGdebug(1, dbgs);
   
@@ -67,14 +71,16 @@ int main(int argc,char **argv)
                :PRECISION = precision, :SCALE=scale,
                :NULLABLE=nullable, :NAME=name,
                :INDICATOR=indicator;
-       printf("%2d %s %d(%d)(%d,%d) %d,%d %d = "
+       printf("%2d\t%s (type: %d length: %d precision: %d scale: %d
+               \toctet_length: %d returned_octet_length: %d nullable: %d)\n\t= "
                        ,INDEX,NAME,TYPE,LENGTH,PRECISION,SCALE
                        ,OCTET_LENGTH,RETURNED_OCTET_LENGTH,NULLABLE);
        if (INDICATOR==-1) printf("NULL\n");
         else switch (TYPE)
-       {  case SQL3_BOOLEAN: 
-               exec sql get descriptor MYDESC value :INDEX :INTVAR=data;
-               printf("%s\n",INTVAR?"true":"false");
+       {
+         case SQL3_BOOLEAN: 
+               exec sql get descriptor MYDESC value :INDEX :BOOLVAR=data;
+               printf("%s\n",BOOLVAR ? "true":"false");
                break;
           case SQL3_NUMERIC:
           case SQL3_DECIMAL:
diff --git a/src/interfaces/ecpg/test/stp.pgc b/src/interfaces/ecpg/test/stp.pgc
deleted file mode 100644 (file)
index ac80b88..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-EXEC SQL INCLUDE sqlca;
-
-int my_fun (void)
-       {
-       EXEC SQL BEGIN DECLARE SECTION;
-       int                     sql_index = 0;
-       EXEC SQL END DECLARE SECTION;   
-       FILE *dbgs;
-
-       if ((dbgs = fopen("log", "w")) != NULL)
-                ECPGdebug(1, dbgs);
-
-       EXEC SQL WHENEVER SQLERROR GOTO Error;
-
-       EXEC SQL CONNECT TO 'mm';
-       EXEC SQL SELECT MIN(index) INTO :sql_index FROM tab;
-       EXEC SQL DISCONNECT;
-
-       if (dbgs != NULL)
-                fclose(dbgs);  
-
-       return (sql_index);
-
-Error:
-       return (sqlca.sqlcode); 
-       }
diff --git a/src/interfaces/ecpg/test/test5.pgc b/src/interfaces/ecpg/test/test5.pgc
deleted file mode 100644 (file)
index 1c9289a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-EXEC SQL INCLUDE sqlca;
-
-static void ErrorExit (void);
-
-int main (void)
-       {
-       EXEC SQL BEGIN DECLARE SECTION;
-       int                     result;
-       int                     values[2], i;
-       EXEC SQL END DECLARE SECTION;
-       FILE *dbgs;
-       
-        if ((dbgs = fopen("log", "w")) != NULL)
-                ECPGdebug(1, dbgs);
-
-       EXEC SQL WHENEVER SQLERROR DO ErrorExit();
-       EXEC SQL CONNECT TO 'mm';
-       EXEC SQL CREATE TABLE tab (index int);
-       EXEC SQL INSERT INTO tab(index) values(14);
-       EXEC SQL INSERT INTO tab(index) values(7);
-       EXEC SQL COMMIT;
-
-       EXEC SQL CREATE FUNCTION my_fun () RETURNS int AS
-               '/home/postgres/pgsql/src/interfaces/ecpg.mm/test/stp.so' LANGUAGE 'C';
-       EXEC SQL COMMIT;
-
-       EXEC SQL SELECT index INTO :values FROM tab;
-       for (i = 0; i < 2; i++)
-               printf("tab[%d] = %d\n", i, values[i]);
-
-       EXEC SQL SELECT my_fun () INTO :result;
-       printf ("result = %d\n", result);
-       
-       EXEC SQL DROP TABLE tab;
-       EXEC SQL DROP FUNCTION my_fun ();
-       EXEC SQL COMMIT;
-       EXEC SQL DISCONNECT;
-
-       if (dbgs != NULL)
-                fclose(dbgs);
-       exit (0);
-       }
-
-       
-static void ErrorExit (void)
-       {
-       EXEC SQL WHENEVER SQLERROR CONTINUE;
-       
-       sqlprint();
-
-       EXEC SQL ROLLBACK;
-
-       EXEC SQL DROP TABLE tab;
-       EXEC SQL DROP FUNCTION my_fun ();
-       EXEC SQL COMMIT;
-
-       EXEC SQL DISCONNECT;
-       exit (-1);
-       }