aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/lib/execute.c
diff options
context:
space:
mode:
authorMichael Meskes <meskes@postgresql.org>2003-03-16 10:49:51 +0000
committerMichael Meskes <meskes@postgresql.org>2003-03-16 10:49:51 +0000
commitbb3730893b475bbf84fbde79918ddda9f31dc550 (patch)
treeb74b752bed83ee1245d7315ac4559ccb0373836e /src/interfaces/ecpg/lib/execute.c
parenta4f25b6a9c2dbf5f38e498922e3761cb3bf46ba0 (diff)
downloadpostgresql-bb3730893b475bbf84fbde79918ddda9f31dc550.tar.gz
postgresql-bb3730893b475bbf84fbde79918ddda9f31dc550.zip
Forgot some files...
Diffstat (limited to 'src/interfaces/ecpg/lib/execute.c')
-rw-r--r--src/interfaces/ecpg/lib/execute.c1143
1 files changed, 0 insertions, 1143 deletions
diff --git a/src/interfaces/ecpg/lib/execute.c b/src/interfaces/ecpg/lib/execute.c
deleted file mode 100644
index 10f0d8404bd..00000000000
--- a/src/interfaces/ecpg/lib/execute.c
+++ /dev/null
@@ -1,1143 +0,0 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.41 2003/02/13 13:11:52 meskes Exp $ */
-
-/*
- * The aim is to get a simpler inteface to the database routines.
- * All the tidieous messing around with tuples is supposed to be hidden
- * by this function.
- */
-/* Author: Linus Tolke
- (actually most if the code is "borrowed" from the distribution and just
- slightly modified)
- */
-
-/* Taken over as part of PostgreSQL by Michael Meskes <meskes@postgresql.org>
- on Feb. 5th, 1998 */
-
-#include "postgres_fe.h"
-
-#include <stdio.h>
-#include <locale.h>
-
-#include "pg_type.h"
-
-#include "ecpgtype.h"
-#include "ecpglib.h"
-#include "ecpgerrno.h"
-#include "extern.h"
-#include "sqlca.h"
-#include "sql3types.h"
-
-/* variables visible to the programs */
-struct sqlca sqlca =
-{
- {
- 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
- },
- sizeof(struct sqlca),
- 0,
- {
- 0,
- {
- 0
- }
- },
- {
- 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
- },
- {
- 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0
- }
-};
-
-/* This function returns a newly malloced string that has the \
- in the argument quoted with \ and the ' quoted with ' as SQL92 says.
- */
-static
-char *
-quote_postgres(char *arg, int lineno)
-{
- char *res = (char *) ECPGalloc(2 * strlen(arg) + 3, lineno);
- int i,
- ri = 0;
-
- if (!res)
- return (res);
-
- res[ri++] = '\'';
-
- for (i = 0; arg[i]; i++, ri++)
- {
- switch (arg[i])
- {
- case '\'':
- res[ri++] = '\'';
- break;
- case '\\':
- res[ri++] = '\\';
- break;
- default:
- ;
- }
- res[ri] = arg[i];
- }
-
- res[ri++] = '\'';
- res[ri] = '\0';
-
- return res;
-}
-
-/*
- * create a list of variables
- * The variables are listed with input variables preceding outputvariables
- * The end of each group is marked by an end marker.
- * per variable we list:
- * type - as defined in ecpgtype.h
- * value - where to store the data
- * varcharsize - length of string in case we have a stringvariable, else 0
- * arraysize - 0 for pointer (we don't know the size of the array),
- * 1 for simple variable, size for arrays
- * offset - offset between ith and (i+1)th entry in an array,
- * normally that means sizeof(type)
- * ind_type - type of indicator variable
- * ind_value - pointer to indicator variable
- * ind_varcharsize - empty
- * ind_arraysize - arraysize of indicator array
- * ind_offset - indicator offset
- */
-static bool
-create_statement(int lineno, struct connection * connection, struct statement ** stmt, char *query, va_list ap)
-{
- struct variable **list = &((*stmt)->inlist);
- enum ECPGttype type;
-
- if (!(*stmt = (struct statement *) ECPGalloc(sizeof(struct statement), lineno)))
- return false;
-
- (*stmt)->command = query;
- (*stmt)->connection = connection;
- (*stmt)->lineno = lineno;
-
- list = &((*stmt)->inlist);
-
- type = va_arg(ap, enum ECPGttype);
-
- while (type != ECPGt_EORT)
- {
- if (type == ECPGt_EOIT)
- list = &((*stmt)->outlist);
- else
- {
- struct variable *var,
- *ptr;
-
- if (!(var = (struct variable *) ECPGalloc(sizeof(struct variable), lineno)))
- return false;
-
- var->type = type;
- var->pointer = va_arg(ap, char *);
-
- /* if variable is NULL, the statement hasn't been prepared */
- if (var->pointer == NULL)
- {
- ECPGraise(lineno, ECPG_INVALID_STMT, NULL);
- ECPGfree(var);
- return false;
- }
-
- var->varcharsize = va_arg(ap, long);
- var->arrsize = va_arg(ap, long);
- var->offset = va_arg(ap, long);
-
- if (var->arrsize == 0 || var->varcharsize == 0)
- var->value = *((char **) (var->pointer));
- else
- var->value = var->pointer;
-
- var->ind_type = va_arg(ap, enum ECPGttype);
- var->ind_pointer = va_arg(ap, char *);
- var->ind_varcharsize = va_arg(ap, long);
- var->ind_arrsize = va_arg(ap, long);
- var->ind_offset = va_arg(ap, long);
- var->next = NULL;
-
- if (var->ind_type != ECPGt_NO_INDICATOR
- && (var->ind_arrsize == 0 || var->ind_varcharsize == 0))
- var->ind_value = *((char **) (var->ind_pointer));
- else
- var->ind_value = var->ind_pointer;
-
- for (ptr = *list; ptr && ptr->next; ptr = ptr->next);
-
- if (ptr == NULL)
- *list = var;
- else
- ptr->next = var;
- }
-
- type = va_arg(ap, enum ECPGttype);
- }
-
- return (true);
-}
-
-static void
-free_variable(struct variable * var)
-{
- struct variable *var_next;
-
- if (var == (struct variable *) NULL)
- return;
- var_next = var->next;
- ECPGfree(var);
-
- while (var_next)
- {
- var = var_next;
- var_next = var->next;
- ECPGfree(var);
- }
-}
-
-static void
-free_statement(struct statement * stmt)
-{
- if (stmt == (struct statement *) NULL)
- return;
- free_variable(stmt->inlist);
- free_variable(stmt->outlist);
- ECPGfree(stmt);
-}
-
-static char *
-next_insert(char *text)
-{
- char *ptr = text;
- bool string = false;
-
- for (; *ptr != '\0' && (*ptr != '?' || string); ptr++)
- {
- if (*ptr == '\\') /* escape character */
- ptr++;
- else if (*ptr == '\'')
- string = string ? false : true;
- }
-
- return (*ptr == '\0') ? NULL : ptr;
-}
-
-/*
- * push a value on the cache
- */
-
-static void
-ECPGtypeinfocache_push(struct ECPGtype_information_cache ** cache, int oid, bool isarray, int lineno)
-{
- struct ECPGtype_information_cache *new_entry
- = (struct ECPGtype_information_cache *) ECPGalloc(sizeof(struct ECPGtype_information_cache), lineno);
-
- new_entry->oid = oid;
- new_entry->isarray = isarray;
- new_entry->next = *cache;
- *cache = new_entry;
-}
-
-static bool
-ECPGis_type_an_array(int type, const struct statement * stmt, const struct variable * var)
-{
- char *array_query;
- int isarray = 0;
- PGresult *query;
- struct ECPGtype_information_cache *cache_entry;
-
- if ((stmt->connection->cache_head) == NULL)
- {
- /*
- * Text like types are not an array for ecpg, but postgres counts
- * them as an array. This define reminds you to not 'correct'
- * these values.
- */
-#define not_an_array_in_ecpg false
-
- /* populate cache with well known types to speed things up */
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), BOOLOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), BYTEAOID, not_an_array_in_ecpg, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), CHAROID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), NAMEOID, not_an_array_in_ecpg, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), INT8OID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), INT2OID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), INT2VECTOROID, true, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), INT4OID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), REGPROCOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), TEXTOID, not_an_array_in_ecpg, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), OIDOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), TIDOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), XIDOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), CIDOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), OIDVECTOROID, true, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), POINTOID, true, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), LSEGOID, true, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), PATHOID, not_an_array_in_ecpg, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), BOXOID, true, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), POLYGONOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), LINEOID, true, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), FLOAT4OID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), FLOAT8OID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), ABSTIMEOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), RELTIMEOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), TINTERVALOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), UNKNOWNOID, not_an_array_in_ecpg, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), CIRCLEOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), CASHOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), INETOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), CIDROID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), BPCHAROID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), VARCHAROID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), DATEOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), TIMEOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), TIMESTAMPOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), TIMESTAMPTZOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), INTERVALOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), TIMETZOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), ZPBITOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), VARBITOID, false, stmt->lineno);
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), NUMERICOID, false, stmt->lineno);
- }
-
- for (cache_entry = (stmt->connection->cache_head); cache_entry != NULL; cache_entry = cache_entry->next)
- {
- if (cache_entry->oid == type)
- return cache_entry->isarray;
- }
-
- array_query = (char *) ECPGalloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno);
- sprintf(array_query, "select typelem from pg_type where oid=%d", type);
- query = PQexec(stmt->connection->connection, array_query);
- ECPGfree(array_query);
- if (PQresultStatus(query) == PGRES_TUPLES_OK)
- {
- isarray = atol((char *) PQgetvalue(query, 0, 0));
- if (ECPGDynamicType(type) == SQL3_CHARACTER ||
- ECPGDynamicType(type) == SQL3_CHARACTER_VARYING)
- {
- /*
- * arrays of character strings are not yet implemented
- */
- isarray = false;
- }
- ECPGlog("ECPGexecute line %d: TYPE database: %d C: %d array: %s\n", stmt->lineno, type, var->type, isarray ? "yes" : "no");
- ECPGtypeinfocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno);
- }
- PQclear(query);
- return isarray;
-}
-
-
-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);
-
- 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)
- {
- 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:
- if (!var->varcharsize && !var->arrsize)
- {
- /* special mode for handling char**foo=0 */
- for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
- len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
- len *= var->offset; /* should be 1, but YMNK */
- len += (ntuples + 1) * sizeof(char *);
-
- ECPGlog("ECPGstore_result: line %d: allocating %d bytes for %d tuples (char**=0)",
- stmt->lineno, len, ntuples);
- }
- else
- {
- 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 = (char *) ECPGalloc(len, stmt->lineno);
- *((char **) var->pointer) = var->value;
- ECPGadd_mem(var->value, stmt->lineno);
- }
-
- /* allocate indicator variable if needed */
- if ((var->ind_arrsize == 0 || var->ind_varcharsize == 0) && var->ind_value == NULL && var->ind_pointer != NULL)
- {
- int len = var->ind_offset * ntuples;
-
- var->ind_value = (char *) ECPGalloc(len, stmt->lineno);
- *((char **) var->ind_pointer) = var->ind_value;
- ECPGadd_mem(var->ind_value, stmt->lineno);
- }
-
- /* fill the variable with the tuple(s) */
- if (!var->varcharsize && !var->arrsize &&
- (var->type == ECPGt_char || var->type == ECPGt_unsigned_char))
- {
- /* special mode for handling char**foo=0 */
-
- /* filling the array of (char*)s */
- char **current_string = (char **) var->value;
-
- /* storing the data (after the last array element) */
- char *current_data_location = (char *) &current_string[ntuples + 1];
-
- for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
- {
- int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
-
- if (!ECPGget_data(results, act_tuple, act_field, stmt->lineno,
- var->type, var->ind_type, current_data_location,
- var->ind_value, len, 0, 0, isarray))
- status = false;
- else
- {
- *current_string = current_data_location;
- current_data_location += len;
- current_string++;
- }
- }
-
- /* terminate the list */
- *current_string = NULL;
- }
- else
- {
- for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
- {
- if (!ECPGget_data(results, act_tuple, act_field, stmt->lineno,
- var->type, var->ind_type, var->value,
- var->ind_value, var->varcharsize, var->offset, var->ind_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 *newcopy = NULL;
-
- /*
- * arrays are not possible unless the attribute is an array too FIXME:
- * we do not know if the attribute is an array here
- */
-
-/* if (var->arrsize > 1 && ...)
- {
- ECPGraise(stmt->lineno, ECPG_ARRAY_INSERT, NULL);
- return false;
- }*/
-
- /*
- * Some special treatment is needed for records since we want their
- * contents to arrive in a comma-separated list on insert (I think).
- */
-
- *malloced_p = false;
- *tobeinserted_p = "";
-
- /* check for null value and set input buffer accordingly */
- switch (var->ind_type)
- {
- case ECPGt_short:
- case ECPGt_unsigned_short:
- if (*(short *) var->ind_value < 0)
- *tobeinserted_p = "null";
- break;
- case ECPGt_int:
- case ECPGt_unsigned_int:
- if (*(int *) var->ind_value < 0)
- *tobeinserted_p = "null";
- break;
- case ECPGt_long:
- case ECPGt_unsigned_long:
- if (*(long *) var->ind_value < 0L)
- *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)
- *tobeinserted_p = "null";
- break;
-#endif /* HAVE_LONG_LONG_INT_64 */
- default:
- break;
- }
-
- if (**tobeinserted_p == '\0')
- {
- switch (var->type)
- {
- int element;
-
- case ECPGt_short:
- if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%hd,", ((short *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%hd", *((short *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-
- case ECPGt_int:
- if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%d,", ((int *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%d", *((int *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-
- case ECPGt_unsigned_short:
- if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%hu,", ((unsigned short *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%hu", *((unsigned short *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-
- case ECPGt_unsigned_int:
- if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%u,", ((unsigned int *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%u", *((unsigned int *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-
- case ECPGt_long:
- if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%ld,", ((long *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%ld", *((long *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-
- case ECPGt_unsigned_long:
- if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%lu,", ((unsigned long *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%lu", *((unsigned long *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-#ifdef HAVE_LONG_LONG_INT_64
- case ECPGt_long_long:
- if (!(mallocedval = ECPGalloc(var->arrsize * 25, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%lld,", ((long long *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%lld", *((long long *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-
- case ECPGt_unsigned_long_long:
- if (!(mallocedval = ECPGalloc(var->arrsize * 25, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%llu,", ((unsigned long long *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%llu", *((unsigned long long *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-#endif /* HAVE_LONG_LONG_INT_64 */
- case ECPGt_float:
- if (!(mallocedval = ECPGalloc(var->arrsize * 21, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%.14g,", ((float *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%.14g", *((float *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-
- case ECPGt_double:
- if (!(mallocedval = ECPGalloc(var->arrsize * 21, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%.14g,", ((double *) var->value)[element]);
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- sprintf(mallocedval, "%.14g", *((double *) var->value));
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-
- case ECPGt_bool:
- if (!(mallocedval = ECPGalloc(var->arrsize * 2, stmt->lineno)))
- return false;
-
- if (var->arrsize > 1)
- {
- strncpy(mallocedval, "'{", sizeof("'{"));
-
- if (var->offset == sizeof(char))
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%c,", (((char *) var->value)[element]) ? 't' : 'f');
-
- /*
- * this is necessary since sizeof(C++'s
- * bool)==sizeof(int)
- */
- else if (var->offset == sizeof(int))
- for (element = 0; element < var->arrsize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%c,", (((int *) var->value)[element]) ? 't' : 'f');
- else
- ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size");
-
- strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
- }
- else
- {
- if (var->offset == sizeof(char))
- sprintf(mallocedval, "'%c'", (*((char *) var->value)) ? 't' : 'f');
- else if (var->offset == sizeof(int))
- sprintf(mallocedval, "'%c'", (*((int *) var->value)) ? 't' : 'f');
- else
- ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size");
- }
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- break;
-
- case ECPGt_char:
- case ECPGt_unsigned_char:
- {
- /* set slen to string length if type is char * */
- int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize;
-
- if (!(newcopy = ECPGalloc(slen + 1, stmt->lineno)))
- return false;
-
- strncpy(newcopy, (char *) var->value, slen);
- newcopy[slen] = '\0';
-
- mallocedval = quote_postgres(newcopy, stmt->lineno);
- if (!mallocedval)
- return false;
-
- ECPGfree(newcopy);
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- }
- break;
- case ECPGt_char_variable:
- {
- int slen = strlen((char *) var->value);
-
- if (!(mallocedval = ECPGalloc(slen + 1, stmt->lineno)))
- return false;
-
- strncpy(mallocedval, (char *) var->value, slen);
- mallocedval[slen] = '\0';
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- }
- break;
- case ECPGt_varchar:
- {
- struct ECPGgeneric_varchar *variable =
- (struct ECPGgeneric_varchar *) (var->value);
-
- if (!(newcopy = (char *) ECPGalloc(variable->len + 1, stmt->lineno)))
- return false;
-
- strncpy(newcopy, variable->arr, variable->len);
- newcopy[variable->len] = '\0';
-
- mallocedval = quote_postgres(newcopy, stmt->lineno);
- if (!mallocedval)
- return false;
-
- ECPGfree(newcopy);
-
- *tobeinserted_p = mallocedval;
- *malloced_p = true;
- }
- break;
-
- default:
- /* Not implemented yet */
- ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, (char *) ECPGtype_name(var->type));
- return false;
- break;
- }
- }
- return true;
-}
-
-static bool
-ECPGexecute(struct statement * stmt)
-{
- bool status = false;
- char *copiedquery;
- char *errmsg, *cmdstat;
- PGresult *results;
- PGnotify *notify;
- struct variable *var;
-
- copiedquery = ECPGstrdup(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
- */
- if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
- return false;
-
- strcpy(newcopy, copiedquery);
- if ((p = next_insert(newcopy + hostvarl)) == NULL)
- {
- /*
- * We have an argument but we dont have the matched up string
- * in the string
- */
- ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, NULL);
- return false;
- }
- else
- {
- strcpy(p, tobeinserted);
- hostvarl = strlen(newcopy);
-
- /*
- * The strange thing in the second argument is the rest of the
- * string from the old string
- */
- strcat(newcopy,
- copiedquery
- + (p - newcopy)
- + sizeof("?") - 1 /* don't count the '\0' */ );
- }
-
- /*
- * Now everything is safely copied to the newcopy. Lets free the
- * oldcopy and let the copiedquery get the var->value from the
- * newcopy.
- */
- if (malloced)
- {
- ECPGfree((char *) tobeinserted);
- tobeinserted = NULL;
- }
-
- ECPGfree(copiedquery);
- copiedquery = newcopy;
-
- var = var->next;
- }
-
- /* Check if there are unmatched things left. */
- if (next_insert(copiedquery) != NULL)
- {
- ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL);
- return false;
- }
-
- /* Now the request is built. */
-
- if (stmt->connection->committed && !stmt->connection->autocommit)
- {
- if ((results = PQexec(stmt->connection->connection, "begin transaction")) == NULL)
- {
- ECPGraise(stmt->lineno, ECPG_TRANS, NULL);
- return false;
- }
- PQclear(results);
- stmt->connection->committed = false;
- }
-
- ECPGlog("ECPGexecute line %d: QUERY: %s on connection %s\n", stmt->lineno, copiedquery, stmt->connection->name);
- results = PQexec(stmt->connection->connection, copiedquery);
- ECPGfree(copiedquery);
-
- if (results == NULL)
- {
- errmsg = PQerrorMessage(stmt->connection->connection);
- ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno, errmsg);
- ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg);
- set_backend_err(errmsg, stmt->lineno);
- }
- else
-
- /*
- * note: since some of the following code is duplicated in
- * descriptor.c it should go into a separate function
- */
- {
- bool clear_result = TRUE;
- errmsg = PQresultErrorMessage(results);
- set_backend_err(errmsg, stmt->lineno);
-
- var = stmt->outlist;
- switch (PQresultStatus(results))
- {
- int nfields,
- ntuples,
- act_field;
-
- case PGRES_TUPLES_OK:
- nfields = PQnfields(results);
- sqlca.sqlerrd[2] = ntuples = PQntuples(results);
- status = true;
-
- if (ntuples < 1)
- {
- if (ntuples)
- ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d\n",
- stmt->lineno, ntuples);
- ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL);
- status = false;
- break;
- }
-
- if (var != NULL && var->type == ECPGt_descriptor)
- {
- PGresult **resultpp = ECPGdescriptor_lvalue(stmt->lineno, (const char *) var->pointer);
-
- if (resultpp == NULL)
- status = false;
- else
- {
- if (*resultpp)
- PQclear(*resultpp);
- *resultpp = results;
- clear_result = FALSE;
- ECPGlog("ECPGexecute putting result (%d tuples) into descriptor '%s'\n", PQntuples(results), (const char *) var->pointer);
- }
- var = var->next;
- }
- else
- for (act_field = 0; act_field < nfields && status; act_field++)
- {
- if (var == NULL)
- {
- ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL);
- return (false);
- }
-
- status = ECPGstore_result(results, act_field, stmt, var);
-
- var = var->next;
- }
-
- if (status && var != NULL)
- {
- ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, NULL);
- status = false;
- }
-
- break;
- case PGRES_EMPTY_QUERY:
- /* do nothing */
- ECPGraise(stmt->lineno, ECPG_EMPTY, NULL);
- break;
- case PGRES_COMMAND_OK:
- status = true;
- cmdstat = PQcmdStatus(results);
- sqlca.sqlerrd[1] = PQoidValue(results);
- sqlca.sqlerrd[2] = atol(PQcmdTuples(results));
- ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, cmdstat);
- if (!sqlca.sqlerrd[2] && ( !strncmp(cmdstat, "UPDATE", 6)
- || !strncmp(cmdstat, "INSERT", 6)
- || !strncmp(cmdstat, "DELETE", 6)))
- ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL);
- break;
- case PGRES_NONFATAL_ERROR:
- case PGRES_FATAL_ERROR:
- case PGRES_BAD_RESPONSE:
- ECPGlog("ECPGexecute line %d: Error: %s", stmt->lineno, errmsg);
- ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg);
- status = false;
- break;
- case PGRES_COPY_OUT:
- ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", stmt->lineno);
- PQendcopy(stmt->connection->connection);
- break;
- case PGRES_COPY_IN:
- ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", stmt->lineno);
- PQendcopy(stmt->connection->connection);
- break;
- default:
- ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
- stmt->lineno);
- ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg);
- status = false;
- break;
- }
- if (clear_result)
- PQclear(results);
- }
-
- /* check for asynchronous returns */
- notify = PQnotifies(stmt->connection->connection);
- if (notify)
- {
- ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
- stmt->lineno, notify->relname, notify->be_pid);
- ECPGfree(notify);
- }
-
- return status;
-}
-
-bool
-ECPGdo(int lineno, const char *connection_name, char *query,...)
-{
- va_list args;
- struct statement *stmt;
- struct connection *con = ECPGget_connection(connection_name);
- bool status;
- char *oldlocale;
-
- /* 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");
-
- if (!ECPGinit(con, connection_name, lineno))
- {
- setlocale(LC_NUMERIC, oldlocale);
- ECPGfree(oldlocale);
- return (false);
- }
-
- /* construct statement in our own structure */
- va_start(args, query);
- if (create_statement(lineno, con, &stmt, query, args) == false)
- {
- setlocale(LC_NUMERIC, oldlocale);
- ECPGfree(oldlocale);
- return (false);
- }
- va_end(args);
-
- /* are we connected? */
- if (con == NULL || con->connection == NULL)
- {
- free_statement(stmt);
- ECPGraise(lineno, ECPG_NOT_CONN, (con) ? con->name : "<empty>");
- setlocale(LC_NUMERIC, oldlocale);
- ECPGfree(oldlocale);
- return false;
- }
-
- /* initialize auto_mem struct */
- ECPGclear_auto_mem();
-
- status = ECPGexecute(stmt);
- free_statement(stmt);
-
- /* and reset locale value so our application is not affected */
- setlocale(LC_NUMERIC, oldlocale);
- ECPGfree(oldlocale);
-
- return (status);
-}
-
-/* old descriptor interface */
-bool
-ECPGdo_descriptor(int line, const char *connection,
- const char *descriptor, const char *query)
-{
- return ECPGdo(line, connection, (char *) query, ECPGt_EOIT,
- ECPGt_descriptor, descriptor, 0L, 0L, 0L,
- ECPGt_NO_INDICATOR, NULL, 0L, 0L, 0L, ECPGt_EORT);
-}