- Fixed several bugs concerning indicators and added error messages
instead of segfaults.
+
+Thu Dec 20 14:15:56 CET 2001
+
+ - Removed space_or_nl and line_end from pgc.l.
+
+Sun Dec 23 13:08:36 CET 2001
+
+ - Fixed several bugs concerning arrays of structs including a memory
+ allocation bug.
- Set ecpg version to 2.9.0.
- Set library version to 3.3.0.
#define ECPG_MISSING_INDICATOR -209
#define ECPG_NO_ARRAY -210
#define ECPG_DATA_NOT_ARRAY -211
+#define ECPG_ARRAY_INSERT -212
#define ECPG_NO_CONN -220
#define ECPG_NOT_CONN -221
#
# Copyright (c) 1994, Regents of the University of California
#
-# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.13 2001/09/19 14:09:32 meskes Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.14 2001/12/23 12:17:41 meskes Exp $
#
#-------------------------------------------------------------------------
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
+CFLAGS=-g
+
NAME= ecpg
SO_MAJOR_VERSION= 3
SO_MINOR_VERSION= 3.0
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.16 2001/12/05 15:32:06 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.17 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h"
if (actual_connection == act)
actual_connection = all_connections;
- for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, free(ptr));
- free(act->name);
- free(act);
+ for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, ECPGfree(ptr));
+ ECPGfree(act->name);
+ ECPGfree(act);
}
else
ECPGlog("ecpg_finish: called an extra time.\n");
ECPGlog("connect: socketname %s given for TCP connection in line %d\n", host, lineno);
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
if (host)
- free(host);
+ ECPGfree(host);
if (port)
- free(port);
+ ECPGfree(port);
if (options)
- free(options);
+ ECPGfree(options);
if (realname)
- free(realname);
+ ECPGfree(realname);
if (dbname)
- free(dbname);
+ ECPGfree(dbname);
return false;
}
}
ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno);
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
if (host)
- free(host);
+ ECPGfree(host);
if (port)
- free(port);
+ ECPGfree(port);
if (options)
- free(options);
+ ECPGfree(options);
if (realname)
- free(realname);
+ ECPGfree(realname);
if (dbname)
- free(dbname);
+ ECPGfree(dbname);
return false;
}
}
lineno);
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
if (host)
- free(host);
+ ECPGfree(host);
if (port)
- free(port);
+ ECPGfree(port);
if (options)
- free(options);
+ ECPGfree(options);
if (realname)
- free(realname);
+ ECPGfree(realname);
if (dbname)
- free(dbname);
+ ECPGfree(dbname);
return false;
}
if (host)
- free(host);
+ ECPGfree(host);
if (port)
- free(port);
+ ECPGfree(port);
if (options)
- free(options);
+ ECPGfree(options);
if (realname)
- free(realname);
+ ECPGfree(realname);
if (dbname)
- free(dbname);
+ ECPGfree(dbname);
this->committed = true;
this->autocommit = autocommit;
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.20 2001/12/05 15:32:06 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.21 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h"
ECPGget_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)
+ long ind_offset, bool isarray)
{
char *pval = (char *) PQgetvalue(results, act_tuple, act_field);
- ECPGlog("ECPGget_data line %d: RESULT: %s\n", lineno, pval ? pval : "");
+ ECPGlog("ECPGget_data line %d: RESULT: %s offset: %ld\n", lineno, pval ? pval : "", offset);
/* pval is a pointer to the value */
/* let's check is it really is an array if it should be one */
{
case ECPGt_short:
case ECPGt_unsigned_short:
- ((short *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
+/* ((short *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);*/
+ *((short *) (ind + ind_offset*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);
+/* ((int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);*/
+ *((int *) (ind + ind_offset*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);
+/* ((long *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);*/
+ *((long *) (ind + ind_offset*act_tuple)) = -PQgetisnull(results, act_tuple, act_field);
break;
#ifdef HAVE_LONG_LONG_INT_64
case ECPGt_long_long:
- ((long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
- break;
case ECPGt_unsigned_long_long:
- ((unsigned long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
+/* ((long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);*/
+ *((long long int *) (ind + ind_offset*act_tuple)) = -PQgetisnull(results, act_tuple, act_field);
break;
+/* case ECPGt_unsigned_long_long:
+ ((unsigned long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
+ break;*/
#endif /* HAVE_LONG_LONG_INT_64 */
case ECPGt_NO_INDICATOR:
if (PQgetisnull(results, act_tuple, act_field))
switch (type)
{
case ECPGt_short:
- ((short *) var)[act_tuple] = (short) res;
+/* ((short *) var)[act_tuple] = (short) res;*/
+ *((short *) (var + offset*act_tuple)) = (short) res;
break;
case ECPGt_int:
- ((int *) var)[act_tuple] = (int) res;
+/* ((int *) var)[act_tuple] = (int) res;*/
+ *((int *) (var + offset*act_tuple)) = (int) res;
break;
case ECPGt_long:
- ((long *) var)[act_tuple] = res;
+/* ((long *) var)[act_tuple] = res;*/
+ *((long *) (var + offset*act_tuple)) = (long) res;
break;
default:
/* Cannot happen */
switch (type)
{
case ECPGt_unsigned_short:
- ((unsigned short *) var)[act_tuple] = (unsigned short) ures;
+/* ((unsigned short *) var)[act_tuple] = (unsigned short) ures;*/
+ *((unsigned short *) (var + offset*act_tuple)) = (unsigned short) res;
break;
case ECPGt_unsigned_int:
- ((unsigned int *) var)[act_tuple] = (unsigned int) ures;
+/* ((unsigned int *) var)[act_tuple] = (unsigned int) ures;*/
+ *((unsigned int *) (var + offset*act_tuple)) = (unsigned int) res;
break;
case ECPGt_unsigned_long:
- ((unsigned long *) var)[act_tuple] = ures;
+/* ((unsigned long *) var)[act_tuple] = ures;*/
+ *((unsigned long *) (var + offset*act_tuple)) = (unsigned long) res;
break;
default:
/* Cannot happen */
case ECPGt_long_long:
if (pval)
{
- ((long long int *) var)[act_tuple] = strtoll(pval, &scan_length, 10);
+/* ((long long int *) var)[act_tuple] = strtoll(pval, &scan_length, 10);*/
+ *((long long int *) (var + offset*act_tuple)) = strtoll(pval, &scan_length, 10);
if ((isarray && *scan_length != ',' && *scan_length != '}')
|| (!isarray && *scan_length != '\0')) /* Garbage left */
{
}
}
else
- ((long long int *) var)[act_tuple] = (long long) 0;
+/* ((long long int *) var)[act_tuple] = (long long) 0;*/
+ *((long long int *) (var + offset*act_tuple)) = (long long) 0;
break;
#endif /* HAVE_STRTOLL */
case ECPGt_unsigned_long_long:
if (pval)
{
- ((unsigned long long int *) var)[act_tuple] = strtoull(pval, &scan_length, 10);
+/* ((unsigned long long int *) var)[act_tuple] = strtoull(pval, &scan_length, 10);*/
+ *((unsigned long long int *) (var + offset*act_tuple)) = strtoull(pval, &scan_length, 10);
if ((isarray && *scan_length != ',' && *scan_length != '}')
|| (!isarray && *scan_length != '\0')) /* Garbage left */
{
}
}
else
- ((unsigned long long int *) var)[act_tuple] = (long long) 0;
+/* ((unsigned long long int *) var)[act_tuple] = (long long) 0;*/
+ *((unsigned long long int *) (var + offset*act_tuple)) = (long long) 0;
break;
#endif /* HAVE_STRTOULL */
switch (type)
{
case ECPGt_float:
- ((float *) var)[act_tuple] = dres;
+/* ((float *) var)[act_tuple] = dres;*/
+ *((float *) (var + offset*act_tuple)) = dres;
break;
case ECPGt_double:
- ((double *) var)[act_tuple] = dres;
+/* ((double *) var)[act_tuple] = dres;*/
+ *((double *) (var + offset*act_tuple)) = dres;
break;
default:
/* Cannot happen */
if (pval[0] == 'f' && pval[1] == '\0')
{
if (offset == sizeof(char))
- ((char *) var)[act_tuple] = false;
+/* ((char *) var)[act_tuple] = false;*/
+ *((char *) (var + offset*act_tuple)) = false;
else if (offset == sizeof(int))
- ((int *) var)[act_tuple] = false;
+/* ((int *) var)[act_tuple] = false;*/
+ *((int *) (var + offset*act_tuple)) = false;
else
ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
break;
else if (pval[0] == 't' && pval[1] == '\0')
{
if (offset == sizeof(char))
- ((char *) var)[act_tuple] = true;
+/* ((char *) var)[act_tuple] = true;*/
+ *((char *) (var + offset*act_tuple)) = true;
else if (offset == sizeof(int))
- ((int *) var)[act_tuple] = true;
+/* ((int *) var)[act_tuple] = true;*/
+ *((int *) (var + offset*act_tuple)) = true;
else
ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
break;
{
case ECPGt_short:
case ECPGt_unsigned_short:
- ((short *) ind)[act_tuple] = strlen(pval);
+/* ((short *) ind)[act_tuple] = strlen(pval);*/
+ *((short *) (ind + ind_offset*act_tuple)) = strlen(pval);
break;
case ECPGt_int:
case ECPGt_unsigned_int:
- ((int *) ind)[act_tuple] = strlen(pval);
+/* ((int *) ind)[act_tuple] = strlen(pval);*/
+ *((int *) (ind + ind_offset*act_tuple)) = strlen(pval);
break;
case ECPGt_long:
case ECPGt_unsigned_long:
- ((long *) ind)[act_tuple] = strlen(pval);
+/* ((long *) ind)[act_tuple] = strlen(pval);*/
+ *((long *) (ind + ind_offset*act_tuple)) = strlen(pval);
+ break;
+#ifdef HAVE_LONG_LONG_INT_64
+ case ECPGt_long_long:
+ case ECPGt_unsigned_long_long:
+ *((long long int *) (ind + ind_offset*act_tuple)) = strlen(pval);
break;
+#endif /* HAVE_LONG_LONG_INT_64 */
default:
break;
}
{
case ECPGt_short:
case ECPGt_unsigned_short:
- ((short *) ind)[act_tuple] = variable->len;
+/* ((short *) ind)[act_tuple] = variable->len;*/
+ *((short *) (ind + offset*act_tuple)) = variable->len;
break;
case ECPGt_int:
case ECPGt_unsigned_int:
- ((int *) ind)[act_tuple] = variable->len;
+/* ((int *) ind)[act_tuple] = variable->len;*/
+ *((int *) (ind + offset*act_tuple)) = variable->len;
break;
case ECPGt_long:
case ECPGt_unsigned_long:
- ((long *) ind)[act_tuple] = variable->len;
+/* ((long *) ind)[act_tuple] = variable->len;*/
+ *((long *) (ind + offset*act_tuple)) = variable->len;
+ break;
+#ifdef HAVE_LONG_LONG_INT_64
+ case ECPGt_long_long:
+ case ECPGt_unsigned_long_long:
+ *((long long int *) (ind + ind_offset*act_tuple)) = variable->len;
break;
+#endif /* HAVE_LONG_LONG_INT_64 */
default:
break;
}
/* dynamic SQL support routines
*
- * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/descriptor.c,v 1.19 2001/11/14 11:11:49 meskes Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/descriptor.c,v 1.20 2001/12/23 12:17:41 meskes Exp $
*/
#include "postgres_fe.h"
if (!strcmp(name, i->name))
{
*lastptr = i->next;
- free(i->name);
+ ECPGfree(i->name);
PQclear(i->result);
- free(i);
+ ECPGfree(i);
return true;
}
}
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.13 2001/11/14 11:11:49 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.14 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h"
"Data read from backend is not an array in line %d.", line);
break;
+ case ECPG_ARRAY_INSERT:
+ snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
+ "Trying to insert an array of variables 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);
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.33 2001/11/21 22:57:01 tgl Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.34 2001/12/23 12:17:41 meskes Exp $ */
/*
* The aim is to get a simpler inteface to the database routines.
}
};
-/* keep a list of memory we allocated for the user */
-static struct auto_mem
-{
- void *pointer;
- struct auto_mem *next;
-} *auto_allocs = NULL;
-
-void
-ECPGadd_mem(void *ptr, int lineno)
-{
- struct auto_mem *am = (struct auto_mem *) ECPGalloc(sizeof(struct auto_mem), lineno);
- am->pointer = ptr;
- am->next = auto_allocs;
- auto_allocs = am;
-}
-
-void
-ECPGfree_auto_mem(void)
-{
- struct auto_mem *am;
-
- /* 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;
-}
-
/* This function returns a newly malloced string that has the \
in the argument quoted with \ and the ' quote with ' as SQL92 says.
*/
if (var->pointer == NULL)
{
ECPGraise(lineno, ECPG_INVALID_STMT, NULL);
- free(var);
+ ECPGfree(var);
return false;
}
var->ind_offset = va_arg(ap, long);
var->next = NULL;
- if (var->ind_type!=ECPGt_NO_INDICATOR
+ if (var->ind_type != ECPGt_NO_INDICATOR
&& (var->ind_arrsize == 0 || var->ind_varcharsize == 0))
var->ind_value = *((void **) (var->ind_pointer));
else
if (var == (struct variable *) NULL)
return;
var_next = var->next;
- free(var);
+ ECPGfree(var);
while (var_next)
{
var = var_next;
var_next = var->next;
- free(var);
+ ECPGfree(var);
}
}
return;
free_variable(stmt->inlist);
free_variable(stmt->outlist);
- free(stmt);
+ ECPGfree(stmt);
}
static char *
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);
- free(array_query);
+ ECPGfree(array_query);
if (PQresultStatus(query) == PGRES_TUPLES_OK)
{
isarray = atol((char *) PQgetvalue(query, 0, 0));
*((void **) 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)
{
}
/* fill the variable with the tuple(s) */
-
if (!var->varcharsize && !var->arrsize &&
(var->type==ECPGt_char || var->type==ECPGt_unsigned_char))
{
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, isarray))
+ var->ind_value, len, 0, 0, isarray))
status = false;
else
{
{
if (!ECPGget_data(results, act_tuple, act_field, stmt->lineno,
var->type, var->ind_type, var->value,
- var->ind_value, var->varcharsize, var->offset, isarray))
+ var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray))
status = false;
}
}
char *mallocedval = NULL;
char *newcopy = NULL;
+ /*
+ * arrays are not possible
+ */
+
+ 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).
if (!mallocedval)
return false;
- free(newcopy);
+ ECPGfree(newcopy);
*tobeinserted_p = mallocedval;
*malloced_p = true;
if (!mallocedval)
return false;
- free(newcopy);
+ ECPGfree(newcopy);
*tobeinserted_p = mallocedval;
*malloced_p = true;
*/
if (malloced)
{
- free((char *) tobeinserted);
+ ECPGfree((char *) tobeinserted);
tobeinserted = NULL;
}
- free(copiedquery);
+ ECPGfree(copiedquery);
copiedquery = newcopy;
var = var->next;
ECPGlog("ECPGexecute line %d: QUERY: %s on connection %s\n", stmt->lineno, copiedquery, stmt->connection->name);
results = PQexec(stmt->connection->connection, copiedquery);
- free(copiedquery);
+ ECPGfree(copiedquery);
if (results == NULL)
{
{
ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
stmt->lineno, notify->relname, notify->be_pid);
- free(notify);
+ ECPGfree(notify);
}
return status;
if (!ECPGinit(con, connection_name, lineno))
{
setlocale(LC_NUMERIC, oldlocale);
- free(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);
- free(oldlocale);
+ ECPGfree(oldlocale);
return (false);
}
va_end(args);
free_statement(stmt);
ECPGraise(lineno, ECPG_NOT_CONN, (con) ? con->name : "<empty>");
setlocale(LC_NUMERIC, oldlocale);
- free(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);
- free(oldlocale);
+ ECPGfree(oldlocale);
return (status);
}
void ECPGadd_mem(void *ptr, int lineno);
bool ECPGget_data(const PGresult *, int, int, int, enum ECPGttype type,
- enum ECPGttype, void *, void *, long, long, bool);
+ enum ECPGttype, void *, void *, long, long, long, bool);
struct connection *ECPGget_connection(const char *);
void ECPGinit_sqlca(void);
char *ECPGalloc(long, int);
+void ECPGfree(void *);
bool ECPGinit(const struct connection *, const char *, const int);
char *ECPGstrdup(const char *, int);
const char *ECPGtype_name(enum ECPGttype);
unsigned int ECPGDynamicType(Oid);
-
+void ECPGfree_auto_mem(void);
+void ECPGclear_auto_mem(void);
/* A generic varchar type. */
struct ECPGgeneric_varchar
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/memory.c,v 1.7 2001/11/14 11:11:49 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/memory.c,v 1.8 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h"
#include "ecpgerrno.h"
#include "extern.h"
+void
+ECPGfree(void *ptr)
+{
+ free(ptr);
+}
+
char *
ECPGalloc(long size, int lineno)
{
return (new);
}
+
+/* keep a list of memory we allocated for the user */
+static struct auto_mem
+{
+ void *pointer;
+ struct auto_mem *next;
+} *auto_allocs = NULL;
+
+void
+ECPGadd_mem(void *ptr, int lineno)
+{
+ struct auto_mem *am = (struct auto_mem *) ECPGalloc(sizeof(struct auto_mem), lineno);
+ am->pointer = ptr;
+ am->next = auto_allocs;
+ auto_allocs = am;
+}
+
+void
+ECPGfree_auto_mem(void)
+{
+ struct auto_mem *am;
+
+ /* free all memory we have allocated for the user */
+ for (am = auto_allocs; am;)
+ {
+ struct auto_mem *act = am;
+
+ am = am->next;
+ ECPGfree(act->pointer);
+ ECPGfree(act);
+ }
+
+ auto_allocs = NULL;
+}
+
+void
+ECPGclear_auto_mem(void)
+{
+ struct auto_mem *am;
+
+ /* free just our own structure */
+ for (am = auto_allocs; am;)
+ {
+ struct auto_mem *act = am;
+
+ am = am->next;
+ ECPGfree(act);
+ }
+
+ auto_allocs = NULL;
+}
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/misc.c,v 1.10 2001/11/14 11:11:49 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/misc.c,v 1.11 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h"
vfprintf(debugstream, f, ap);
va_end(ap);
- free(f);
+ ECPGfree(f);
}
}
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/prepare.c,v 1.11 2001/11/14 11:11:49 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/prepare.c,v 1.12 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h"
stmt = (struct statement *) ECPGalloc(sizeof(struct statement), lineno);
if (!stmt)
{
- free(this);
+ ECPGfree(this);
return false;
}
if (this)
{
/* okay, free all the resources */
- free(this->name);
- free(this->stmt->command);
- free(this->stmt);
+ ECPGfree(this->name);
+ ECPGfree(this->stmt->command);
+ ECPGfree(this->stmt);
if (prev != NULL)
prev->next = this->next;
else
prep_stmts = this->next;
- free(this);
+ ECPGfree(this);
return true;
}
ECPGraise(lineno, ECPG_INVALID_STMT, name);
-# $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.78 2001/11/16 16:32:33 petere Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.79 2001/12/23 12:17:41 meskes Exp $
subdir = src/interfaces/ecpg/preproc
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
+CFLAGS+=-g
+
MAJOR_VERSION=2
MINOR_VERSION=9
PATCHLEVEL=0
{
const struct variable *v = find_variable(name);
- switch (v->type->typ)
+ switch (v->type->type)
{
case ECPGt_short:
case ECPGt_int:
break;
}
fprintf(yyout, "%s,", get_dtype(results->value));
- ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL);
+ ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, 0L, NULL, NULL);
}
drop_assignments();
fputs("ECPGd_EODT);\n", yyout);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.82 2001/12/09 15:27:49 meskes Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.83 2001/12/23 12:17:41 meskes Exp $
*
*-------------------------------------------------------------------------
*/
ccomment "//".*\n
-space [ \t\r\f]
-space_or_nl [ \t\r\f\n]
-line_end {space}*\n
+space [ \t\n\r\f]
horiz_space [ \t\f]
newline [\n\r]
non_newline [^\n\r]
elif [eE][lL][iI][fF]
endif [eE][nN][dD][iI][fF]
-exec_sql {exec}{space_or_nl}*{sql}{space_or_nl}*
+exec_sql {exec}{space}*{sql}{space}*
ipdigit ({digit}|{digit}{digit}|{digit}{digit}{digit})
ip {ipdigit}\.{ipdigit}\.{ipdigit}\.{ipdigit}
/* Take care of cpp continuation lines */
-cppline {space}*#(.*\\{line_end})*.*
+cppline {space}*#(.*\\{space})*.*
/* DO NOT PUT ANY COMMENTS IN THE FOLLOWING SECTION.
* AT&T lex does not properly handle C-style comments in this second lex block.
<C>"-" { return('-'); }
<C>"(" { return('('); }
<C>")" { return(')'); }
-<C>{space_or_nl} { ECHO; }
+<C>{space} { ECHO; }
<C>\{ { return('{'); }
<C>\} { return('}'); }
<C>\[ { return('['); }
<C>".*" { return(S_DOTPOINT); }
<C>{other} { return S_ANYTHING; }
-<C>{exec_sql}{define}{space_or_nl}* { BEGIN(def_ident); }
-<C>{exec_sql}{include}{space_or_nl}* { BEGIN(incl); }
+<C>{exec_sql}{define}{space}* { BEGIN(def_ident); }
+<C>{exec_sql}{include}{space}* { BEGIN(incl); }
-<C,xskip>{exec_sql}{ifdef}{space_or_nl}* { ifcond = TRUE; BEGIN(xcond); }
-<C,xskip>{exec_sql}{ifndef}{space_or_nl}* { ifcond = FALSE; BEGIN(xcond); }
+<C,xskip>{exec_sql}{ifdef}{space}* { ifcond = TRUE; BEGIN(xcond); }
+<C,xskip>{exec_sql}{ifndef}{space}* { ifcond = FALSE; BEGIN(xcond); }
-<C,xskip>{exec_sql}{elif}{space_or_nl}* { /* pop stack */
+<C,xskip>{exec_sql}{elif}{space}* { /* pop stack */
if ( preproc_tos == 0 ) {
mmerror(PARSE_ERROR, ET_FATAL, "Missing matching 'EXEC SQL IFDEF / EXEC SQL IFNDEF'");
}
ifcond = TRUE; BEGIN(xcond);
}
-<C,xskip>{exec_sql}{else}{space_or_nl}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */
+<C,xskip>{exec_sql}{else}{space}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */
if ( stacked_if_value[preproc_tos].else_branch ) {
mmerror(PARSE_ERROR, ET_FATAL, "Duplicated 'EXEC SQL ELSE;'");
}
}
}
}
-<C,xskip>{exec_sql}{endif}{space_or_nl}*";" {
+<C,xskip>{exec_sql}{endif}{space}*";" {
if ( preproc_tos == 0 ) {
mmerror(PARSE_ERROR, ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'");
}
<xskip>{other} { /* ignore */ }
-<xcond>{identifier}{space_or_nl}*";" {
+<xcond>{identifier}{space}*";" {
if ( preproc_tos >= MAX_NESTED_IF-1 ) {
mmerror(PARSE_ERROR, ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions");
}
BEGIN(def);
startlit();
}
-<def>{space_or_nl}*";" {
+<def>{space}*";" {
struct _defines *ptr, *this;
for (ptr = defines; ptr != NULL; ptr = ptr->next)
/* temporarily store struct members while creating the data structure */
struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
-struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}};
+/* also store struct type so we can do a sizeof() later */
+static char *ECPGstruct_sizeof = NULL;
+
+struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, NULL, {NULL}};
struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
-struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}};
+struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, NULL, {NULL}};
/*
* Handle parsing errors and warnings
$$ = $1;
else if (strcmp($1, "?") == 0) /* variable */
{
- enum ECPGttype typ = argsinsert->variable->type->typ;
+ enum ECPGttype type = argsinsert->variable->type->type;
/* if array see what's inside */
- if (typ == ECPGt_array)
- typ = argsinsert->variable->type->u.element->typ;
+ if (type == ECPGt_array)
+ type = argsinsert->variable->type->u.element->type;
/* handle varchars */
- if (typ == ECPGt_varchar)
+ if (type == ECPGt_varchar)
$$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
else
$$ = mm_strdup(argsinsert->variable->name);
$$ = $1;
else if (strcmp($1, "?") == 0) /* variable */
{
- enum ECPGttype typ = argsinsert->variable->type->typ;
+ enum ECPGttype type = argsinsert->variable->type->type;
/* if array see what's inside */
- if (typ == ECPGt_array)
- typ = argsinsert->variable->type->u.element->typ;
+ if (type == ECPGt_array)
+ type = argsinsert->variable->type->u.element->type;
/* handle varchars */
- if (typ == ECPGt_varchar)
+ if (type == ECPGt_varchar)
$$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
else
$$ = mm_strdup(argsinsert->variable->name);
char_variable: cvariable
{ /* check if we have a char variable */
struct variable *p = find_variable($1);
- enum ECPGttype typ = p->type->typ;
+ enum ECPGttype type = p->type->type;
/* if array see what's inside */
- if (typ == ECPGt_array)
- typ = p->type->u.element->typ;
+ if (type == ECPGt_array)
+ type = p->type->u.element->type;
- switch (typ)
+ switch (type)
{
case ECPGt_char:
case ECPGt_unsigned_char:
s_struct: SQL_STRUCT opt_symbol
{
struct_member_list[struct_level++] = NULL;
+ $$ = cat2_str(make_str("struct"), $2);
+ ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), strdup($$), make_str(")"));
if (struct_level >= STRUCT_DEPTH)
mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
-
- $$ = cat2_str(make_str("struct"), $2);
};
s_union: UNION opt_symbol
case ECPGt_struct:
case ECPGt_union:
if (dimension < 0)
- type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum);
+ type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, ECPGstruct_sizeof);
else
- type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension);
+ type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, ECPGstruct_sizeof), dimension);
$$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
break;
case ECPGt_struct:
case ECPGt_union:
if (dimension < 0)
- type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum);
+ type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, ECPGstruct_sizeof);
else
- type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum), dimension);
+ type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, ECPGstruct_sizeof), dimension);
break;
case ECPGt_varchar:
if (dimension == -1)
civarind: cvariable indicator
{
- if ($2 != NULL && (find_variable($2))->type->typ == ECPGt_array)
+ if ($2 != NULL && (find_variable($2))->type->type == ECPGt_array)
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
#include "extern.h"
-#define indicator_set ind_typ != NULL && ind_typ->typ != ECPGt_NO_INDICATOR
+#define indicator_set ind_type != NULL && ind_type->type != ECPGt_NO_INDICATOR
struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL};
{
struct ECPGtype *type;
- switch (rm->typ->typ)
+ switch (rm->type->type)
{
case ECPGt_struct:
case ECPGt_union:
- type = ECPGmake_struct_type(rm->typ->u.members, rm->typ->typ);
+ type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->struct_sizeof);
break;
case ECPGt_array:
- type = ECPGmake_array_type(ECPGmake_simple_type(rm->typ->u.element->typ, rm->typ->u.element->size), rm->typ->size);
+ type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size), rm->type->size);
break;
default:
- type = ECPGmake_simple_type(rm->typ->typ, rm->typ->size);
+ type = ECPGmake_simple_type(rm->type->type, rm->type->size);
break;
}
(struct ECPGstruct_member *) mm_alloc(sizeof(struct ECPGstruct_member));
ne->name = strdup(name);
- ne->typ = type;
+ ne->type = type;
ne->next = NULL;
for (ptr = *start; ptr && ptr->next; ptr = ptr->next);
}
struct ECPGtype *
-ECPGmake_simple_type(enum ECPGttype typ, long siz)
+ECPGmake_simple_type(enum ECPGttype type, long size)
{
struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
- ne->typ = typ;
- ne->size = siz;
+ ne->type = type;
+ ne->size = size;
ne->u.element = 0;
+ ne->struct_sizeof = NULL;
return ne;
}
struct ECPGtype *
-ECPGmake_array_type(struct ECPGtype * typ, long siz)
+ECPGmake_array_type(struct ECPGtype * type, long size)
{
- struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, siz);
+ struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, size);
- ne->u.element = typ;
+ ne->u.element = type;
return ne;
}
struct ECPGtype *
-ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type)
+ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type, char *struct_sizeof)
{
struct ECPGtype *ne = ECPGmake_simple_type(type, 1);
ne->u.members = ECPGstruct_member_dup(rm);
+ ne->struct_sizeof = struct_sizeof;
return ne;
}
static const char *
-get_type(enum ECPGttype typ)
+get_type(enum ECPGttype type)
{
- switch (typ)
+ switch (type)
{
case ECPGt_char:
return ("ECPGt_char");
return ("ECPGt_descriptor");
break;
default:
- sprintf(errortext, "illegal variable type %d\n", typ);
+ sprintf(errortext, "illegal variable type %d\n", type);
yyerror(errortext);
}
size is the maxsize in case it is a varchar. Otherwise it is the size of
the variable (required to do array fetches of structs).
*/
-static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
+static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
long varcharsize,
long arrsiz, const char *siz, const char *prefix);
static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, long arrsiz,
- struct ECPGtype * typ, struct ECPGtype * ind_typ, const char *offset, const char *prefix, const char *ind_prefix);
+ struct ECPGtype * type, struct ECPGtype * ind_type, const char *offset, const char *prefix, const char *ind_prefix);
void
-ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *ind_name, struct ECPGtype * ind_typ, const char *prefix, const char *ind_prefix)
+ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type, const char *ind_name, struct ECPGtype * ind_type, const char *prefix, const char *ind_prefix, const long arr_str_siz, const char *struct_sizeof, const char *ind_struct_sizeof)
{
- switch (typ->typ)
+ switch (type->type)
{
case ECPGt_array:
- if (indicator_set && ind_typ->typ != ECPGt_array)
+ if (indicator_set && ind_type->type != ECPGt_array)
mmerror(INDICATOR_NOT_ARRAY, ET_FATAL, "Indicator for array/pointer has to be array/pointer.\n");
- switch (typ->u.element->typ)
+ switch (type->u.element->type)
{
case ECPGt_array:
mmerror(PARSE_ERROR, ET_ERROR, "No nested arrays allowed (except strings)"); /* array of array */
break;
case ECPGt_struct:
case ECPGt_union:
- ECPGdump_a_struct(o, name, ind_name, typ->size, typ->u.element, ind_typ->u.element, NULL, prefix, ind_prefix);
+ ECPGdump_a_struct(o, name, ind_name, type->size, type->u.element, (ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element, NULL, prefix, ind_prefix);
break;
default:
- if (!IS_SIMPLE_TYPE(typ->u.element->typ))
+ if (!IS_SIMPLE_TYPE(type->u.element->type))
yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org");
- ECPGdump_a_simple(o, name, typ->u.element->typ,
- typ->u.element->size, typ->size, NULL, prefix);
- if (ind_typ != NULL)
+ ECPGdump_a_simple(o, name, type->u.element->type,
+ type->u.element->size, type->size, NULL, prefix);
+ if (ind_type != NULL)
{
- if (ind_typ->typ == ECPGt_NO_INDICATOR)
- ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
+ if (ind_type->type == ECPGt_NO_INDICATOR)
+ ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, -1, NULL, ind_prefix);
else
- ECPGdump_a_simple(o, ind_name, ind_typ->u.element->typ,
- ind_typ->u.element->size, ind_typ->size, NULL, prefix);
+ ECPGdump_a_simple(o, ind_name, ind_type->u.element->type,
+ ind_type->u.element->size, ind_type->size, NULL, prefix);
}
}
break;
case ECPGt_struct:
- if (indicator_set && ind_typ->typ != ECPGt_struct)
+ if (indicator_set && ind_type->type != ECPGt_struct)
mmerror(INDICATOR_NOT_STRUCT, ET_FATAL, "Indicator for struct has to be struct.\n");
- ECPGdump_a_struct(o, name, ind_name, 1, typ, ind_typ, NULL, prefix, ind_prefix);
+ ECPGdump_a_struct(o, name, ind_name, 1, type, ind_type, NULL, prefix, ind_prefix);
break;
case ECPGt_union: /* cannot dump a complete union */
yyerror("Type of union has to be specified");
break;
case ECPGt_char_variable:
- if (indicator_set && (ind_typ->typ == ECPGt_struct || ind_typ->typ == ECPGt_array))
+ if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
- ECPGdump_a_simple(o, name, typ->typ, 1, 1, NULL, prefix);
- ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
+ ECPGdump_a_simple(o, name, type->type, 1, arr_str_siz ? arr_str_siz : 1, struct_sizeof, prefix);
+ ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, arr_str_siz ? arr_str_siz : -1, ind_struct_sizeof, ind_prefix);
break;
case ECPGt_descriptor:
- if (indicator_set && (ind_typ->typ == ECPGt_struct || ind_typ->typ == ECPGt_array))
+ if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
- ECPGdump_a_simple(o, name, typ->typ, 0, -1, NULL, prefix);
- ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
+ ECPGdump_a_simple(o, name, type->type, 0, -1, NULL, prefix);
+ ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, -1, NULL, ind_prefix);
break;
default:
- if (indicator_set && (ind_typ->typ == ECPGt_struct || ind_typ->typ == ECPGt_array))
+ if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
- ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix);
- if (ind_typ != NULL)
- ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
+ ECPGdump_a_simple(o, name, type->type, type->size, arr_str_siz ? arr_str_siz : -1, struct_sizeof, prefix);
+ if (ind_type != NULL)
+ ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, arr_str_siz ? arr_str_siz : -1, ind_struct_sizeof, ind_prefix);
break;
}
}
/* If siz is NULL, then the offset is 0, if not use siz as a
string, it represents the offset needed if we are in an array of structs. */
static void
-ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
+ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
long varcharsize,
long arrsize,
const char *siz,
const char *prefix
)
{
- if (typ == ECPGt_NO_INDICATOR)
+ if (type == ECPGt_NO_INDICATOR)
fprintf(o, "\n\tECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ");
- else if (typ == ECPGt_descriptor)
+ else if (type == ECPGt_descriptor)
/* remember that name here already contains quotes (if needed) */
fprintf(o, "\n\tECPGt_descriptor, %s, 0L, 0L, 0L, ", name);
else
char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
char *offset = (char *) mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1);
- switch (typ)
+ switch (type)
{
case ECPGt_varchar:
* we have to use the pointer except for arrays with given
* bounds
*/
- if (arrsize > 0)
+ if (arrsize > 0 && siz == NULL)
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
else
sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
* we have to use the pointer except for arrays with given
* bounds
*/
- if (varcharsize > 1 || arrsize > 0)
+ if ((varcharsize > 1 || arrsize > 0) && siz == NULL)
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
else
sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
* we have to use the pointer except for arrays with given
* bounds
*/
- if (arrsize > 0)
+ if (arrsize > 0 && siz== NULL)
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
else
sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
- sprintf(offset, "sizeof(%s)", ECPGtype_name(typ));
+ sprintf(offset, "sizeof(%s)", ECPGtype_name(type));
break;
}
if (arrsize < 0)
arrsize = 1;
- if (siz == NULL)
- fprintf(o, "\n\t%s,%s,%ldL,%ldL,%s, ", get_type(typ), variable, varcharsize, arrsize, offset);
+ if (siz == NULL || arrsize <= 1)
+ fprintf(o, "\n\t%s,%s,%ldL,%ldL,%s, ", get_type(type), variable, varcharsize, arrsize, offset);
else
- fprintf(o, "\n\t%s,%s,%ldL,%ldL,%s, ", get_type(typ), variable, varcharsize, arrsize, siz);
+ fprintf(o, "\n\t%s,%s,%ldL,%ldL,%s, ", get_type(type), variable, varcharsize, arrsize, siz);
free(variable);
free(offset);
/* Penetrate a struct and dump the contents. */
static void
-ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, long arrsiz, struct ECPGtype * typ, struct ECPGtype * ind_typ, const char *offsetarg, const char *prefix, const char *ind_prefix)
+ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, long arrsiz, struct ECPGtype * type, struct ECPGtype * ind_type, const char *offsetarg, const char *prefix, const char *ind_prefix)
{
/*
* If offset is NULL, then this is the first recursive level. If not
else
offset = offsetarg;
- if (arrsiz != 0)
+ if (arrsiz == 1)
sprintf(pbuf, "%s%s.", prefix ? prefix : "", name);
else
sprintf(pbuf, "%s%s->", prefix ? prefix : "", name);
prefix = pbuf;
- if (ind_typ == &ecpg_no_indicator)
+ if (ind_type == &ecpg_no_indicator)
{
ind_p = &struct_no_indicator;
}
- else if (ind_typ != NULL)
+ else if (ind_type != NULL)
{
- if (arrsiz != 0)
+ if (arrsiz == 1)
sprintf(ind_pbuf, "%s%s.", ind_prefix ? ind_prefix : "", ind_name);
else
sprintf(ind_pbuf, "%s%s->", ind_prefix ? ind_prefix : "", ind_name);
ind_prefix = ind_pbuf;
- ind_p = ind_typ->u.members;
+ ind_p = ind_type->u.members;
}
- for (p = typ->u.members; p; p = p->next)
+ for (p = type->u.members; p; p = p->next)
{
- ECPGdump_a_type(o, p->name, p->typ, (ind_p != NULL) ? ind_p->name : NULL, (ind_p != NULL) ? ind_p->typ : NULL, prefix, ind_prefix);
+ ECPGdump_a_type(o, p->name, p->type, (ind_p != NULL) ? ind_p->name : NULL, (ind_p != NULL) ? ind_p->type : NULL, prefix, ind_prefix, arrsiz, type->struct_sizeof, (ind_p != NULL) ? ind_type->struct_sizeof : NULL);
if (ind_p != NULL && ind_p != &struct_no_indicator)
ind_p = ind_p->next;
}
rm = rm->next;
free(p->name);
- free(p->typ);
+ free(p->type);
free(p);
}
}
void
-ECPGfree_type(struct ECPGtype * typ)
+ECPGfree_type(struct ECPGtype * type)
{
- if (!IS_SIMPLE_TYPE(typ->typ))
+ if (!IS_SIMPLE_TYPE(type->type))
{
- switch (typ->typ)
+ switch (type->type)
{
case ECPGt_array:
- switch (typ->u.element->typ)
+ switch (type->u.element->type)
{
case ECPGt_array:
yyerror("internal error, found multi-dimensional array\n");
case ECPGt_struct:
case ECPGt_union:
/* Array of structs. */
- ECPGfree_struct_member(typ->u.element->u.members);
- free(typ->u.element);
+ ECPGfree_struct_member(type->u.element->u.members);
+ free(type->u.element);
break;
default:
- if (!IS_SIMPLE_TYPE(typ->u.element->typ))
+ if (!IS_SIMPLE_TYPE(type->u.element->type))
yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org");
- free(typ->u.element);
+ free(type->u.element);
}
break;
case ECPGt_struct:
case ECPGt_union:
- ECPGfree_struct_member(typ->u.members);
+ ECPGfree_struct_member(type->u.members);
break;
default:
- sprintf(errortext, "illegal variable type %d\n", typ->typ);
+ sprintf(errortext, "illegal variable type %d\n", type->type);
yyerror(errortext);
break;
}
}
- free(typ);
+ free(type);
}
const char *
-get_dtype(enum ECPGdtype typ)
+get_dtype(enum ECPGdtype type)
{
- switch (typ)
+ switch (type)
{
case ECPGd_count:
return ("ECPGd_countr");
case ECPGd_cardinality:
return ("ECPGd_cardinality");
default:
- sprintf(errortext, "illegal descriptor item %d\n", typ);
+ sprintf(errortext, "illegal descriptor item %d\n", type);
yyerror(errortext);
}
struct ECPGstruct_member
{
char *name;
- struct ECPGtype *typ;
+ struct ECPGtype *type;
struct ECPGstruct_member *next;
};
struct ECPGtype
{
- enum ECPGttype typ;
+ enum ECPGttype type;
long size; /* For array it is the number of elements.
* For varchar it is the maxsize of the
* area. */
+ char *struct_sizeof; /* For a struct this is the sizeof() type as string */
union
{
struct ECPGtype *element; /* For an array this is the type
struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, long);
struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long);
struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, long);
-struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype type);
+struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype, char *);
struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member *);
/* Frees a type. */
size is the maxsize in case it is a varchar. Otherwise it is the size of
the variable (required to do array fetches of structs).
*/
-void ECPGdump_a_type(FILE *, const char *, struct ECPGtype *, const char *, struct ECPGtype *, const char *, const char *);
+void ECPGdump_a_type(FILE *, const char *, struct ECPGtype *, const char *, struct ECPGtype *, const char *, const char *, const long, const char *, const char *);
/* A simple struct to keep a variable and its type. */
struct ECPGtemp_type
{
- struct ECPGtype *typ;
+ struct ECPGtype *type;
const char *name;
};
-extern const char *ECPGtype_name(enum ECPGttype typ);
+extern const char *ECPGtype_name(enum ECPGttype type);
/* some stuff for whenever statements */
enum WHEN_TYPE
if (c == '\0')
{
/* found the end */
- switch (members->typ->typ)
+ switch (members->type->type)
{
case ECPGt_array:
- return (new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
+ return (new_variable(name, ECPGmake_array_type(members->type->u.element, members->type->size)));
case ECPGt_struct:
case ECPGt_union:
- return (new_variable(name, ECPGmake_struct_type(members->typ->u.members, members->typ->typ)));
+ return (new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->struct_sizeof)));
default:
- return (new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
+ return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size)));
}
}
else
if (c == '-')
{
next++;
- return (find_struct_member(name, next, members->typ->u.element->u.members));
+ return (find_struct_member(name, next, members->type->u.element->u.members));
}
else
- return (find_struct_member(name, next, members->typ->u.members));
+ return (find_struct_member(name, next, members->type->u.members));
}
}
}
if (c == '-')
{
- if (p->type->typ != ECPGt_array)
+ if (p->type->type != ECPGt_array)
{
sprintf(errortext, "variable %s is not a pointer", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
- if (p->type->u.element->typ != ECPGt_struct && p->type->u.element->typ != ECPGt_union)
+ if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
{
sprintf(errortext, "variable %s is not a pointer to a structure or a union", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
else
{
- if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
+ if (p->type->type != ECPGt_struct && p->type->type != ECPGt_union)
{
sprintf(errortext, "variable %s is neither a structure nor a union", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
/* Then the current element and its indicator */
ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
- list->indicator->name, list->indicator->type, NULL, NULL);
+ list->indicator->name, list->indicator->type, NULL, NULL, 0, NULL, NULL);
/* Then release the list element. */
if (mode != 0)
check_indicator(struct ECPGtype * var)
{
/* make sure this is a valid indicator variable */
- switch (var->typ)
+ switch (var->type)
{
struct ECPGstruct_member *p;
case ECPGt_struct:
case ECPGt_union:
for (p = var->u.members; p; p = p->next)
- check_indicator(p->typ);
+ check_indicator(p->type);
break;
case ECPGt_array:
-# $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Makefile,v 1.32 2001/11/14 11:11:49 meskes Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Makefile,v 1.33 2001/12/23 12:17:41 meskes Exp $
subdir = src/interfaces/ecpg/test
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
-override CPPFLAGS := -I$(srcdir)/../include $(CPPFLAGS)
+override CPPFLAGS := -I$(srcdir)/../include $(CPPFLAGS) -g
ECPG = ../preproc/ecpg -I$(srcdir)/../include
-#include <stdlib.h>
+
#include <string.h>
exec sql include sqlca;
int increment=100;
char name[AMOUNT][8];
char letter[AMOUNT][1];
+ struct name_letter_struct
+ {
+ char name[8];
+ int amount;
+ char letter;
+ } name_letter[AMOUNT];
+ struct ind_struct
+ {
+ short a;
+ short b;
+ short c;
+ } ind[AMOUNT];
char command[128];
char *connection="pm";
exec sql end declare section;
exec sql at pm insert into "Test" (name, amount, letter) values (:n, :a, :l);
}
+ strcpy(msg, "commit");
+ exec sql at pm commit;
+
strcpy(msg, "select");
exec sql at :connection select name, amount, letter into :name, :amount, :letter from "Test";
- printf("Database: pm\n");
+ printf("Database: %s\n", connection);
for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, name[i], i, amount[i],i, letter[i][0]);
-
+
+ strcpy(msg, "select");
+ exec sql at pm select name, amount, letter into :name_letter from "Test";
+
strcpy(msg, "commit");
exec sql commit;
- exec sql at pm commit;
+
+ strcpy(msg, "select");
+ exec sql at pm select name, amount, letter into :name_letter:ind from "Test";
+
+ printf("Database: pm\n");
+ for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
+ printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, name_letter[i].name, i, name_letter[i].amount,i, name_letter[i].letter);
/* Start automatic transactioning for connection main. */
exec sql set autocommit to on;
strcpy(msg, "fetch");
exec sql fetch cur into :p:i, :married:ind_married, :children.integer:ind_children.smallint;
printf("%8.8s", personal.name.arr);
- if (ind_personal.ind_birth.born >= 0)
+ if (i->ind_birth.born >= 0)
printf(", born %ld", personal.birth.born);
- if (ind_personal.ind_birth.age >= 0)
+ if (i->ind_birth.age >= 0)
printf(", age = %d", personal.birth.age);
if ((long)ind_married >= 0)
printf(", married %s", married);