- Fixed truncate bug.
authorMichael Meskes
Mon, 1 Oct 2001 12:02:28 +0000 (12:02 +0000)
committerMichael Meskes
Mon, 1 Oct 2001 12:02:28 +0000 (12:02 +0000)
        - Added patch by Christof Petig  to
clean up
ecpglib.

src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/lib/data.c
src/interfaces/ecpg/lib/execute.c
src/interfaces/ecpg/lib/extern.h
src/interfaces/ecpg/preproc/preproc.y

index 18708efae166d32cbba96febb61af4ede1bec74f..668bc986a8030ce4ae40d25218ff8615ad1e26f3 100644 (file)
@@ -1101,5 +1101,11 @@ Tue Sep 25 20:10:03 CEST 2001
 
    - Synced preproc.y with gram.y.
    - Changed locale handling.
+
+Mon Okt  1 13:49:40 CEST 2001
+
+   - Fixed truncate bug.
+   - Added patch by Christof Petig  to clean up
+     ecpglib.
    - Set ecpg version to 2.9.0.
         - Set library version to 3.3.0.
index 8bed8f711ed8a09aab8a620d60ca19c0f9e01e9c..5d5338131455df1d5f1539dced88438fb39b8118 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.15 2001/09/19 14:09:32 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.16 2001/10/01 12:02:28 meskes Exp $ */
 
 #include "postgres_fe.h"
 
@@ -12,7 +12,7 @@
 #include "sqlca.h"
 
 bool
-get_data(PGresult *results, int act_tuple, int act_field, int lineno,
+get_data(const 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,
         bool isarray)
index 87e690eaa8c2d57af64be82ab5dfca6a963b4dc0..c696afe54b6dcca38f4624528d2504fe958cd0c8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.25 2001/09/29 20:12:07 tgl Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.26 2001/10/01 12:02:28 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -370,40 +370,107 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia
    return isarray;
 }
 
-static bool
-ECPGexecute(struct statement * stmt)
-{
-   bool        status = false;
-   char       *copiedquery;
-   PGresult   *results;
-   PGnotify   *notify;
-   struct variable *var;
 
-   copiedquery = ecpg_strdup(stmt->command, stmt->lineno);
+bool
+ECPGstore_result(const PGresult *results, int act_field, 
+           const struct statement * stmt, struct variable *var)
+{  int     isarray,
+           act_tuple,
+           ntuples = PQntuples(results);
+   bool    status = true;
+               
+                   isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
 
-   /*
-    * Now, if the type is one of the fill in types then we take the
-    * argument and enter that in the string at the first %s position.
-    * Then if there are any more fill in types we fill in at the next and
-    * so on.
-    */
-   var = stmt->inlist;
-   while (var)
-   {
-       char       *newcopy;
+                   if (!isarray)
+                   {
+
+                       /*
+                        * if we don't have enough space, we cannot read
+                        * all tuples
+                        */
+                       if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
+                       {
+                           ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
+                                   stmt->lineno, ntuples, var->arrsize);
+                           ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL);
+                           return false;
+                       }
+                   }
+                   else
+                   {
+
+                       /*
+                        * since we read an array, the variable has to be
+                        * an array too
+                        */
+                       if (var->arrsize == 0)
+                       {
+                           ECPGlog("ECPGexecute line %d: variable is not an array\n");
+                           ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL);
+                           return false;
+                       }
+                   }
+
+                   /*
+                    * allocate memory for NULL pointers
+                    */
+                   if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)
+                   {
+                       int         len = 0;
+
+                       switch (var->type)
+                       {
+                           case ECPGt_char:
+                           case ECPGt_unsigned_char:
+                               var->varcharsize = 0;
+                               /* check strlen for each tuple */
+                               for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+                               {
+                                   int         len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
+
+                                   if (len > var->varcharsize)
+                                       var->varcharsize = len;
+                               }
+                               var->offset *= var->varcharsize;
+                               len = var->offset * ntuples;
+                               break;
+                           case ECPGt_varchar:
+                               len = ntuples * (var->varcharsize + sizeof(int));
+                               break;
+                           default:
+                               len = var->offset * ntuples;
+                               break;
+                       }
+                       var->value = (void *) ecpg_alloc(len, stmt->lineno);
+                       *((void **) var->pointer) = var->value;
+                       add_mem(var->value, stmt->lineno);
+                   }
+
+                   for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+                   {
+                       if (!get_data(results, act_tuple, act_field, stmt->lineno,
+                                   var->type, var->ind_type, var->value,
+                                     var->ind_value, var->varcharsize, var->offset, isarray))
+                           status = false;
+                   }
+   return status;
+}
+
+static bool
+ECPGstore_input(const struct statement * stmt, const struct variable *var,
+           const char **tobeinserted_p, bool *malloced_p)
+{
        char       *mallocedval = NULL;
-       char       *tobeinserted = NULL;
-       char       *p;
-       char        buff[20];
-       int         hostvarl = 0;
+       char       *newcopy = NULL;
 
        /*
         * Some special treatment is needed for records since we want
         * their contents to arrive in a comma-separated list on insert (I
         * think).
         */
-
-       buff[0] = '\0';
+       
+       *malloced_p=false;
+       *tobeinserted_p="";
 
        /* check for null value and set input buffer accordingly */
        switch (var->ind_type)
@@ -411,30 +478,30 @@ ECPGexecute(struct statement * stmt)
            case ECPGt_short:
            case ECPGt_unsigned_short:
                if (*(short *) var->ind_value < 0)
-                   strcpy(buff, "null");
+                   *tobeinserted_p="null";
                break;
            case ECPGt_int:
            case ECPGt_unsigned_int:
                if (*(int *) var->ind_value < 0)
-                   strcpy(buff, "null");
+                   *tobeinserted_p="null";
                break;
            case ECPGt_long:
            case ECPGt_unsigned_long:
                if (*(long *) var->ind_value < 0L)
-                   strcpy(buff, "null");
+                   *tobeinserted_p="null";
                break;
 #ifdef HAVE_LONG_LONG_INT_64
            case ECPGt_long_long:
            case ECPGt_unsigned_long_long:
                if (*(long long int *) var->ind_value < (long long) 0)
-                   strcpy(buff, "null");
+                   *tobeinserted_p="null";
                break;
 #endif  /* HAVE_LONG_LONG_INT_64 */
            default:
                break;
        }
 
-       if (*buff == '\0')
+       if (**tobeinserted_p == '\0')
        {
            switch (var->type)
            {
@@ -456,7 +523,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%hd", *((short *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 
                case ECPGt_int:
@@ -475,7 +543,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%d", *((int *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 
                case ECPGt_unsigned_short:
@@ -494,7 +563,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%hu", *((unsigned short *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 
                case ECPGt_unsigned_int:
@@ -513,7 +583,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%u", *((unsigned int *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 
                case ECPGt_long:
@@ -532,7 +603,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%ld", *((long *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 
                case ECPGt_unsigned_long:
@@ -551,7 +623,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%lu", *((unsigned long *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 #ifdef HAVE_LONG_LONG_INT_64
                case ECPGt_long_long:
@@ -570,7 +643,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%lld", *((long long *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 
                case ECPGt_unsigned_long_long:
@@ -589,7 +663,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%llu", *((unsigned long long *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 #endif  /* HAVE_LONG_LONG_INT_64 */
                case ECPGt_float:
@@ -608,7 +683,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%.14g", *((float *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 
                case ECPGt_double:
@@ -627,7 +703,8 @@ ECPGexecute(struct statement * stmt)
                    else
                        sprintf(mallocedval, "%.14g", *((double *) var->value));
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 
                case ECPGt_bool:
@@ -664,7 +741,8 @@ ECPGexecute(struct statement * stmt)
                            ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size");
                    }
 
-                   tobeinserted = mallocedval;
+                   *tobeinserted_p = mallocedval;
+                   *malloced_p = true;
                    break;
 
                case ECPGt_char:
@@ -685,7 +763,8 @@ ECPGexecute(struct statement * stmt)
 
                        free(newcopy);
 
-                       tobeinserted = mallocedval;
+                       *tobeinserted_p = mallocedval;
+                       *malloced_p = true;
                    }
                    break;
                case ECPGt_char_variable:
@@ -698,7 +777,8 @@ ECPGexecute(struct statement * stmt)
                        strncpy(mallocedval, (char *) var->value, slen);
                        mallocedval[slen] = '\0';
 
-                       tobeinserted = mallocedval;
+                       *tobeinserted_p = mallocedval;
+                       *malloced_p = true;
                    }
                    break;
                case ECPGt_varchar:
@@ -718,7 +798,8 @@ ECPGexecute(struct statement * stmt)
 
                        free(newcopy);
 
-                       tobeinserted = mallocedval;
+                       *tobeinserted_p = mallocedval;
+                       *malloced_p = true;
                    }
                    break;
 
@@ -729,9 +810,38 @@ ECPGexecute(struct statement * stmt)
                    break;
            }
        }
-       else
-           tobeinserted = buff;
+   return true;
+}
 
+static bool
+ECPGexecute(struct statement * stmt)
+{
+   bool        status = false;
+   char       *copiedquery;
+   PGresult   *results;
+   PGnotify   *notify;
+   struct variable *var;
+
+   copiedquery = ecpg_strdup(stmt->command, stmt->lineno);
+
+   /*
+    * Now, if the type is one of the fill in types then we take the
+    * argument and enter that in the string at the first %s position.
+    * Then if there are any more fill in types we fill in at the next and
+    * so on.
+    */
+   var = stmt->inlist;
+   while (var)
+   {
+       char       *newcopy = NULL;
+       const char *tobeinserted = NULL;
+       char       *p;
+       bool       malloced=FALSE;
+       int        hostvarl = 0;
+
+       if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
+           return false;
+           
        /*
         * Now tobeinserted points to an area that is to be inserted at
         * the first %s
@@ -770,10 +880,10 @@ ECPGexecute(struct statement * stmt)
         * oldcopy and let the copiedquery get the var->value from the
         * newcopy.
         */
-       if (mallocedval != NULL)
+       if (malloced)
        {
-           free(mallocedval);
-           mallocedval = NULL;
+           free((char*)tobeinserted);
+           tobeinserted = NULL;
        }
 
        free(copiedquery);
@@ -823,9 +933,7 @@ ECPGexecute(struct statement * stmt)
        {
                int         nfields,
                            ntuples,
-                           act_tuple,
-                           act_field,
-                           isarray;
+                           act_field;
 
            case PGRES_TUPLES_OK:
                nfields = PQnfields(results);
@@ -861,83 +969,9 @@ ECPGexecute(struct statement * stmt)
                        ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL);
                        return (false);
                    }
+                   
+                   status = ECPGstore_result(results, act_field, stmt, var);
 
-                   isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
-
-                   if (!isarray)
-                   {
-
-                       /*
-                        * if we don't have enough space, we cannot read
-                        * all tuples
-                        */
-                       if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
-                       {
-                           ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
-                                   stmt->lineno, ntuples, var->arrsize);
-                           ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL);
-                           status = false;
-                           break;
-                       }
-                   }
-                   else
-                   {
-
-                       /*
-                        * since we read an array, the variable has to be
-                        * an array too
-                        */
-                       if (var->arrsize == 0)
-                       {
-                           ECPGlog("ECPGexecute line %d: variable is not an array\n");
-                           ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL);
-                           status = false;
-                           break;
-                       }
-                   }
-
-                   /*
-                    * allocate memory for NULL pointers
-                    */
-                   if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)
-                   {
-                       int         len = 0;
-
-                       switch (var->type)
-                       {
-                           case ECPGt_char:
-                           case ECPGt_unsigned_char:
-                               var->varcharsize = 0;
-                               /* check strlen for each tuple */
-                               for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
-                               {
-                                   int         len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
-
-                                   if (len > var->varcharsize)
-                                       var->varcharsize = len;
-                               }
-                               var->offset *= var->varcharsize;
-                               len = var->offset * ntuples;
-                               break;
-                           case ECPGt_varchar:
-                               len = ntuples * (var->varcharsize + sizeof(int));
-                               break;
-                           default:
-                               len = var->offset * ntuples;
-                               break;
-                       }
-                       var->value = (void *) ecpg_alloc(len, stmt->lineno);
-                       *((void **) var->pointer) = var->value;
-                       add_mem(var->value, stmt->lineno);
-                   }
-
-                   for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
-                   {
-                       if (!get_data(results, act_tuple, act_field, stmt->lineno,
-                                   var->type, var->ind_type, var->value,
-                                     var->ind_value, var->varcharsize, var->offset, isarray))
-                           status = false;
-                   }
                    var = var->next;
                }
 
@@ -1006,26 +1040,23 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
    va_list     args;
    struct statement *stmt;
    struct connection *con = get_connection(connection_name);
-   bool        status;
-   char        *oldlocale;
+   bool        status = true;
+   char        *locale;
 
    /* Make sure we do NOT honor the locale for numeric input/output */
    /* since the database wants the standard decimal point */
-   oldlocale = strdup(setlocale(LC_NUMERIC, NULL));
-   setlocale(LC_NUMERIC, "C");
+   locale = setlocale(LC_NUMERIC, "C");
 
    if (!ecpg_init(con, connection_name, lineno))
    {
-       setlocale(LC_NUMERIC, oldlocale);
-       free(oldlocale);
+       setlocale(LC_NUMERIC, locale);
        return (false);
    }
 
    va_start(args, query);
    if (create_statement(lineno, con, &stmt, query, args) == false)
    {
-       setlocale(LC_NUMERIC, oldlocale);
-       free(oldlocale);
+       setlocale(LC_NUMERIC, locale);
        return (false);
    }
    va_end(args);
@@ -1036,8 +1067,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
        free_statement(stmt);
        ECPGlog("ECPGdo: not connected to %s\n", con->name);
        ECPGraise(lineno, ECPG_NOT_CONN, NULL);
-       setlocale(LC_NUMERIC, oldlocale);
-       free(oldlocale);
+       setlocale(LC_NUMERIC, locale);
        return false;
    }
 
@@ -1045,9 +1075,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
    free_statement(stmt);
 
    /* and reset locale value so our application is not affected */
-   setlocale(LC_NUMERIC, oldlocale);
-   free(oldlocale);
-
+   setlocale(LC_NUMERIC, locale);
    return (status);
 }
 
index 3186b5b11025130b0c7df6cbdacc9a0fe733237c..971924e708a6c8ab71e2108fb2f1a32e76265ef4 100644 (file)
@@ -4,7 +4,7 @@
 /* Here are some methods used by the lib. */
 /* Returns a pointer to a string containing a simple type name. */
 void       free_auto_mem(void);
-bool get_data(PGresult *, int, int, int, enum ECPGttype type,
+bool get_data(const PGresult *, int, int, int, enum ECPGttype type,
         enum ECPGttype, void *, void *, long, long, bool);
 struct connection *get_connection(const char *);
 void       init_sqlca(void);
@@ -14,6 +14,7 @@ char     *ecpg_strdup(const char *, int);
 const char *ECPGtype_name(enum ECPGttype);
 unsigned int ECPGDynamicType(Oid);
 
+
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
 {
@@ -63,3 +64,7 @@ struct descriptor
 
 PGresult **
 ECPGdescriptor_lvalue(int line, const char *descriptor);
+
+bool
+ECPGstore_result(const PGresult *results, int act_field, 
+           const struct statement * stmt, struct variable *var);
index 31a1cb42d4de9625ede555d262bbe6b2cb06c08f..e348f773c745e18630e38ab5d949768be11861bb 100644 (file)
@@ -1552,7 +1552,7 @@ drop_type:    TABLE       { $$ = make_str("table"); }
  *****************************************************************************/
 TruncateStmt:  TRUNCATE opt_table relation_name
                                {
-                   $$ = cat2_str(make_str("drop table"), $3);
+                   $$ = cat2_str(make_str("truncate table"), $3);
                                }
                        ;