aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1998-02-10 16:44:17 +0000
committerMarc G. Fournier <scrappy@hub.org>1998-02-10 16:44:17 +0000
commit38201e21d0849a469e165085e4d12ac0969f5018 (patch)
treeb9e0e9db026ea6b3838f57025aebbca014f998f4
parenta8313f9671c621852dbdf16b6f47e19ceda489ea (diff)
downloadpostgresql-38201e21d0849a469e165085e4d12ac0969f5018.tar.gz
postgresql-38201e21d0849a469e165085e4d12ac0969f5018.zip
Erk, the whole directory structure changed on us here...
-rw-r--r--src/interfaces/ecpg/include/Makefile16
-rw-r--r--src/interfaces/ecpg/include/Makefile.in15
-rw-r--r--src/interfaces/ecpg/include/ecpglib.h (renamed from src/interfaces/ecpg/src/include/ecpglib.h)2
-rw-r--r--src/interfaces/ecpg/include/ecpgtype.h (renamed from src/interfaces/ecpg/src/include/ecpgtype.h)2
-rw-r--r--src/interfaces/ecpg/include/sqlca.h (renamed from src/interfaces/ecpg/src/include/sqlca.h)0
-rw-r--r--src/interfaces/ecpg/lib/Makefile (renamed from src/interfaces/ecpg/src/lib/Makefile)16
-rw-r--r--src/interfaces/ecpg/lib/Makefile.in (renamed from src/interfaces/ecpg/src/lib/Makefile.in)16
-rw-r--r--src/interfaces/ecpg/lib/ecpglib.c648
-rw-r--r--src/interfaces/ecpg/lib/typename.c (renamed from src/interfaces/ecpg/src/lib/typename.c)1
-rw-r--r--src/interfaces/ecpg/preproc/Makefile (renamed from src/interfaces/ecpg/src/preproc/Makefile)26
-rw-r--r--src/interfaces/ecpg/preproc/Makefile.in32
-rw-r--r--src/interfaces/ecpg/preproc/ecpg.c (renamed from src/interfaces/ecpg/src/preproc/ecpg.c)22
-rw-r--r--src/interfaces/ecpg/preproc/pgc.l (renamed from src/interfaces/ecpg/src/preproc/pgc.l)12
-rw-r--r--src/interfaces/ecpg/preproc/preproc.y (renamed from src/interfaces/ecpg/src/preproc/preproc.y)38
-rw-r--r--src/interfaces/ecpg/preproc/type.c (renamed from src/interfaces/ecpg/src/preproc/type.c)29
-rw-r--r--src/interfaces/ecpg/preproc/type.h (renamed from src/interfaces/ecpg/src/preproc/type.h)0
-rw-r--r--src/interfaces/ecpg/preproc/y.tab.h39
-rw-r--r--src/interfaces/ecpg/src/include/Makefile16
-rw-r--r--src/interfaces/ecpg/src/include/Makefile.in15
-rw-r--r--src/interfaces/ecpg/src/lib/ecpglib.c609
-rw-r--r--src/interfaces/ecpg/src/preproc/Makefile.in36
-rw-r--r--src/interfaces/ecpg/src/preproc/ecpg.in31
-rw-r--r--src/interfaces/ecpg/src/test/Makefile6
-rwxr-xr-xsrc/interfaces/ecpg/src/test/test2bin71167 -> 0 bytes
-rw-r--r--src/interfaces/ecpg/src/test/test2.c0
-rw-r--r--src/interfaces/ecpg/src/test/test2.qc0
-rw-r--r--src/interfaces/ecpg/test/Makefile14
-rw-r--r--src/interfaces/ecpg/test/Ptest1.c (renamed from src/interfaces/ecpg/src/test/Ptest1.c)0
-rw-r--r--src/interfaces/ecpg/test/perftest.pgc72
-rw-r--r--src/interfaces/ecpg/test/test1.c (renamed from src/interfaces/ecpg/src/test/test1.c)0
-rw-r--r--src/interfaces/ecpg/test/test2.pgc50
31 files changed, 985 insertions, 778 deletions
diff --git a/src/interfaces/ecpg/include/Makefile b/src/interfaces/ecpg/include/Makefile
new file mode 100644
index 00000000000..08bc9df7f2d
--- /dev/null
+++ b/src/interfaces/ecpg/include/Makefile
@@ -0,0 +1,16 @@
+# Generated automatically from Makefile.in by configure.
+SRCDIR= ../../..
+include $(SRCDIR)/Makefile.global
+
+all clean::
+ @echo Nothing to be done.
+
+install::
+ install ecpglib.h $(HEADERDIR)
+ install ecpgtype.h $(HEADERDIR)
+ install sqlca.h $(HEADERDIR)
+
+uninstall::
+ rm -f $(HEADERDIR)/ecpglib.h
+ rm -f $(HEADERDIR)/ecpgtype.h
+ rm -f $(HEADERDIR)/sqlca.h
diff --git a/src/interfaces/ecpg/include/Makefile.in b/src/interfaces/ecpg/include/Makefile.in
new file mode 100644
index 00000000000..2f5c63ab078
--- /dev/null
+++ b/src/interfaces/ecpg/include/Makefile.in
@@ -0,0 +1,15 @@
+SRCDIR= ../../..
+include $(SRCDIR)/Makefile.global
+
+all clean::
+ @echo Nothing to be done.
+
+install::
+ install ecpglib.h $(HEADERDIR)
+ install ecpgtype.h $(HEADERDIR)
+ install sqlca.h $(HEADERDIR)
+
+uninstall::
+ rm -f $(HEADERDIR)/ecpglib.h
+ rm -f $(HEADERDIR)/ecpgtype.h
+ rm -f $(HEADERDIR)/sqlca.h
diff --git a/src/interfaces/ecpg/src/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index b880182e0bd..1fb35f8dfee 100644
--- a/src/interfaces/ecpg/src/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -1,6 +1,6 @@
#include <c.h>
-void ECPGdebug(int);
+void ECPGdebug(int, FILE *);
bool ECPGconnect(const char * dbname);
bool ECPGdo(int, char *, ...);
bool ECPGcommit(int);
diff --git a/src/interfaces/ecpg/src/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h
index cc56b78cbb3..496c934f4f4 100644
--- a/src/interfaces/ecpg/src/include/ecpgtype.h
+++ b/src/interfaces/ecpg/include/ecpgtype.h
@@ -32,13 +32,13 @@
enum ECPGttype {
ECPGt_char = 1, ECPGt_unsigned_char, ECPGt_short, ECPGt_unsigned_short,
ECPGt_int, ECPGt_unsigned_int, ECPGt_long, ECPGt_unsigned_long,
+ ECPGt_bool,
ECPGt_float, ECPGt_double,
ECPGt_varchar, ECPGt_varchar2,
ECPGt_array,
ECPGt_record,
ECPGt_EOIT, /* End of insert types. */
ECPGt_EORT /* End of result types. */
-
};
#define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_varchar2)
diff --git a/src/interfaces/ecpg/src/include/sqlca.h b/src/interfaces/ecpg/include/sqlca.h
index 0e7126e7b36..0e7126e7b36 100644
--- a/src/interfaces/ecpg/src/include/sqlca.h
+++ b/src/interfaces/ecpg/include/sqlca.h
diff --git a/src/interfaces/ecpg/src/lib/Makefile b/src/interfaces/ecpg/lib/Makefile
index d227f6df364..e3722e8aec1 100644
--- a/src/interfaces/ecpg/src/lib/Makefile
+++ b/src/interfaces/ecpg/lib/Makefile
@@ -1,19 +1,21 @@
# Generated automatically from Makefile.in by configure.
-TOPDIR=/home/meskes/data/computer/databases/postgres/pgsql/src/interfaces/ecpg/../..
-PQ_INCLUDE=-I$(TOPDIR)/include -I$(TOPDIR)/interfaces/libpq
-POSTGRES_LIB=$(POSTGRESTOP)/lib
+SRCDIR= ../../..
+include $(SRCDIR)/Makefile.global
+
+PQ_INCLUDE=-I$(SRCDIR)/include -I$(SRCDIR)/interfaces/libpq
all: lib
lib: libecpg.a
-clean::
+clean:
rm -f *.o *.a core a.out *~
-install:: libecpg.a
- install -m644 libecpg.a $(POSTGRES_LIB)
+install: libecpg.a
+ install -m 644 libecpg.a $(LIBDIR)
+
uninstall::
- rm -f $(POSTGRES_LIB)/libecpg.a
+ rm -f $(LIBDIR)/libecpg.a
# Rules that do something
libecpg.a : libecpg.a(ecpglib.o) libecpg.a(typename.o)
diff --git a/src/interfaces/ecpg/src/lib/Makefile.in b/src/interfaces/ecpg/lib/Makefile.in
index 07d126bd5c6..7ed351ab7a9 100644
--- a/src/interfaces/ecpg/src/lib/Makefile.in
+++ b/src/interfaces/ecpg/lib/Makefile.in
@@ -1,18 +1,20 @@
-TOPDIR=@TOPSRC@
-PQ_INCLUDE=-I$(TOPDIR)/include -I$(TOPDIR)/interfaces/libpq
-POSTGRES_LIB=$(POSTGRESTOP)/lib
+SRCDIR= ../../..
+include $(SRCDIR)/Makefile.global
+
+PQ_INCLUDE=-I$(SRCDIR)/include -I$(SRCDIR)/interfaces/libpq
all: lib
lib: libecpg.a
-clean::
+clean:
rm -f *.o *.a core a.out *~
-install:: libecpg.a
- install -m644 libecpg.a $(POSTGRES_LIB)
+install: libecpg.a
+ install -m 644 libecpg.a $(LIBDIR)
+
uninstall::
- rm -f $(POSTGRES_LIB)/libecpg.a
+ rm -f $(LIBDIR)/libecpg.a
# Rules that do something
libecpg.a : libecpg.a(ecpglib.o) libecpg.a(typename.o)
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c
new file mode 100644
index 00000000000..80e9b0fd9c4
--- /dev/null
+++ b/src/interfaces/ecpg/lib/ecpglib.c
@@ -0,0 +1,648 @@
+/* Copyright comment */
+/*
+ * 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@debian.org>
+ on Feb. 5th, 1998 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <ecpgtype.h>
+#include <ecpglib.h>
+#include <sqlca.h>
+#include <libpq-fe.h>
+#include <libpq/pqcomm.h>
+
+static PGconn *simple_connection;
+static int simple_debug = 0;
+static FILE *debugstream = NULL;
+static int committed = true;
+
+static void
+register_error(int code, char *fmt,...)
+{
+ va_list args;
+
+ sqlca.sqlcode = code;
+ va_start(args, fmt);
+ vsprintf(sqlca.sqlerrm.sqlerrmc, fmt, args);
+ va_end(args);
+ sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
+}
+
+/* This function returns a newly malloced string that has the ' and \
+ in the argument quoted with \.
+ */
+static
+char *
+quote_postgres(char *arg)
+{
+ char *res = (char *) malloc(2 * strlen(arg) + 1);
+ int i,
+ ri;
+
+ for (i = 0, ri = 0; arg[i]; i++, ri++)
+ {
+ switch (arg[i])
+ {
+ case '\'':
+ case '\\':
+ res[ri++] = '\\';
+ default:
+ ;
+ }
+
+ res[ri] = arg[i];
+ }
+ res[ri] = '\0';
+
+ return res;
+}
+
+
+bool
+ECPGdo(int lineno, char *query,...)
+{
+ va_list ap;
+ bool status = false;
+ char *copiedquery;
+ PGresult *results;
+ PGnotify *notify;
+ enum ECPGttype type;
+
+ va_start(ap, query);
+
+ sqlca.sqlcode = 0;
+ copiedquery = strdup(query);
+
+ type = va_arg(ap, enum ECPGttype);
+
+ /*
+ * 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.
+ */
+ while (type != ECPGt_EOIT)
+ {
+ void *value = NULL;
+ short varcharsize;
+ short size;
+ short arrsize;
+
+ char *newcopy;
+ char *mallocedval = NULL;
+ char *tobeinserted = NULL;
+ char *p;
+ char buff[20];
+
+ /* Some special treatment is needed for records since we want their
+ contents to arrive in a comma-separated list on insert (I think). */
+
+ value = va_arg(ap, void *);
+ varcharsize = va_arg(ap, short);
+ size = va_arg(ap, short);
+ arrsize = va_arg(ap, short);
+
+ switch (type)
+ {
+ case ECPGt_char:
+ case ECPGt_short:
+ case ECPGt_int:
+ sprintf(buff, "%d", *(int *) value);
+ tobeinserted = buff;
+ break;
+
+ case ECPGt_unsigned_char:
+ case ECPGt_unsigned_short:
+ case ECPGt_unsigned_int:
+ sprintf(buff, "%d", *(unsigned int *) value);
+ tobeinserted = buff;
+ break;
+
+ case ECPGt_long:
+ sprintf(buff, "%ld", *(long *) value);
+ tobeinserted = buff;
+ break;
+
+ case ECPGt_unsigned_long:
+ sprintf(buff, "%ld", *(unsigned long *) value);
+ tobeinserted = buff;
+ break;
+
+ case ECPGt_float:
+ sprintf(buff, "%.14g", *(float *) value);
+ tobeinserted = buff;
+ break;
+
+ case ECPGt_double:
+ sprintf(buff, "%.14g", *(double *) value);
+ tobeinserted = buff;
+ break;
+
+ case ECPGt_bool:
+ sprintf(buff, "'%c'", (*(char *) value ? 't' : 'f'));
+ tobeinserted = buff;
+ break;
+
+ case ECPGt_varchar:
+ case ECPGt_varchar2:
+ {
+ struct ECPGgeneric_varchar *var =
+ (struct ECPGgeneric_varchar *) value;
+
+ newcopy = (char *) malloc(var->len + 1);
+ strncpy(newcopy, var->arr, var->len);
+ newcopy[var->len] = '\0';
+
+ mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
+ strcpy(mallocedval, "'");
+ strcat(mallocedval, quote_postgres(newcopy));
+ strcat(mallocedval, "'");
+
+ free(newcopy);
+
+ tobeinserted = mallocedval;
+ }
+ break;
+
+ default:
+ /* Not implemented yet */
+ register_error(-1, "Unsupported type %s on line %d.",
+ ECPGtype_name(type), lineno);
+ return false;
+ break;
+ }
+
+ /* Now tobeinserted points to an area that is to be inserted at
+ the first %s
+ */
+ newcopy = (char *) malloc(strlen(copiedquery)
+ + strlen(tobeinserted)
+ + 1);
+ strcpy(newcopy, copiedquery);
+ if ((p = strstr(newcopy, ";;")) == NULL)
+ {
+ /* We have an argument but we dont have the matched up string
+ in the string
+ */
+ register_error(-1, "Too many arguments line %d.", lineno);
+ return false;
+ }
+ else
+ {
+ strcpy(p, tobeinserted);
+ /* The strange thing in the second argument is the rest of the
+ string from the old string */
+ strcat(newcopy,
+ copiedquery
+ + (p - newcopy)
+ + 2 /* Length of ;; */ );
+ }
+
+ /* Now everything is safely copied to the newcopy. Lets free the
+ oldcopy and let the copiedquery get the value from the newcopy.
+ */
+ if (mallocedval != NULL)
+ {
+ free(mallocedval);
+ mallocedval = NULL;
+ }
+
+ free(copiedquery);
+ copiedquery = newcopy;
+
+ type = va_arg(ap, enum ECPGttype);
+ }
+
+ /* Check if there are unmatched things left. */
+ if (strstr(copiedquery, ";;") != NULL)
+ {
+ register_error(-1, "Too few arguments line %d.", lineno);
+ return false;
+ }
+
+ /* Now then request is built. */
+
+ if (committed)
+ {
+ if ((results = PQexec(simple_connection, "begin")) == NULL)
+ {
+ register_error(-1, "Error starting transaction line %d.", lineno);
+ return false;
+ }
+ PQclear(results);
+ committed = 0;
+ }
+
+ ECPGlog("ECPGdo line %d: QUERY: %s\n", lineno, copiedquery);
+ results = PQexec(simple_connection, copiedquery);
+ free(copiedquery);
+
+ if (results == NULL)
+ {
+ ECPGlog("ECPGdo line %d: error: %s", lineno,
+ PQerrorMessage(simple_connection));
+ register_error(-1, "Postgres error: %s line %d.",
+ PQerrorMessage(simple_connection), lineno);
+ }
+ else
+ switch (PQresultStatus(results))
+ {
+ int m,
+ n,
+ x;
+
+ case PGRES_TUPLES_OK:
+ /* XXX Cheap Hack. For now, we see only the last group
+ * of tuples. This is clearly not the right
+ * way to do things !!
+ */
+
+ m = PQnfields(results);
+ n = PQntuples(results);
+
+ if (n < 1)
+ {
+ ECPGlog("ECPGdo lineno %d: Incorrect number of matches: %d\n",
+ lineno, n);
+ register_error(1, "Data not found line %d.", lineno);
+ break;
+ }
+
+ if (n > 1)
+ {
+ ECPGlog("ECPGdo line %d: Incorrect number of matches: %d\n",
+ lineno, n);
+ register_error(-1, "To many matches line %d.", lineno);
+ break;
+ }
+
+ status = true;
+
+ for (x = 0; x < m && status; x++)
+ {
+ void *value = NULL;
+ short varcharsize;
+ short size;
+ short arrsize;
+
+ char *pval = PQgetvalue(results, 0, x);
+
+ /*long int * res_int;
+ char ** res_charstar;
+ char * res_char;
+ int res_len; */
+ char *scan_length;
+
+ ECPGlog("ECPGdo line %d: RESULT: %s\n", lineno, pval ? pval : "");
+
+ /* No the pval is a pointer to the value. */
+ /* We will have to decode the value */
+ type = va_arg(ap, enum ECPGttype);
+ value = va_arg(ap, void *);
+ varcharsize = va_arg(ap, short);
+ size = va_arg(ap, short);
+ arrsize = va_arg(ap, short);
+
+ switch (type)
+ {
+ long res;
+ unsigned long ures;
+ double dres;
+
+ case ECPGt_char:
+ case ECPGt_short:
+ case ECPGt_int:
+ case ECPGt_long:
+ if (pval)
+ {
+ res = strtol(pval, &scan_length, 10);
+ if (*scan_length != '\0') /* Garbage left */
+ {
+ register_error(-1, "Not correctly formatted int type: %s line %d.",
+ pval, lineno);
+ status = false;
+ res = 0L;
+ }
+ }
+ else
+ res = 0L;
+
+ /* Again?! Yes */
+ switch (type)
+ {
+ case ECPGt_char:
+ *(char *) value = (char) res;
+ break;
+ case ECPGt_short:
+ *(short *) value = (short) res;
+ break;
+ case ECPGt_int:
+ *(int *) value = (int) res;
+ break;
+ case ECPGt_long:
+ *(long *) value = res;
+ break;
+ default:
+ /* Cannot happen */
+ break;
+ }
+ break;
+
+ case ECPGt_unsigned_char:
+ case ECPGt_unsigned_short:
+ case ECPGt_unsigned_int:
+ case ECPGt_unsigned_long:
+ if (pval)
+ {
+ ures = strtoul(pval, &scan_length, 10);
+ if (*scan_length != '\0') /* Garbage left */
+ {
+ register_error(-1, "Not correctly formatted unsigned type: %s line %d.",
+ pval, lineno);
+ status = false;
+ ures = 0L;
+ }
+ }
+ else
+ ures = 0L;
+
+ /* Again?! Yes */
+ switch (type)
+ {
+ case ECPGt_unsigned_char:
+ *(unsigned char *) value = (unsigned char) ures;
+ break;
+ case ECPGt_unsigned_short:
+ *(unsigned short *) value = (unsigned short) ures;
+ break;
+ case ECPGt_unsigned_int:
+ *(unsigned int *) value = (unsigned int) ures;
+ break;
+ case ECPGt_unsigned_long:
+ *(unsigned long *) value = ures;
+ break;
+ default:
+ /* Cannot happen */
+ break;
+ }
+ break;
+
+
+ case ECPGt_float:
+ case ECPGt_double:
+ if (pval)
+ {
+ dres = strtod(pval, &scan_length);
+ if (*scan_length != '\0') /* Garbage left */
+ {
+ register_error(-1, "Not correctly formatted floating point type: %s line %d.",
+ pval, lineno);
+ status = false;
+ dres = 0.0;
+ }
+ }
+ else
+ dres = 0.0;
+
+ /* Again?! Yes */
+ switch (type)
+ {
+ case ECPGt_float:
+ *(float *) value = dres;
+ break;
+ case ECPGt_double:
+ *(double *) value = dres;
+ break;
+ default:
+ /* Cannot happen */
+ break;
+ }
+ break;
+
+ case ECPGt_bool:
+ if (pval)
+ {
+ if (pval[0] == 'f' && pval[1] == '\0')
+ {
+ *(char *) value = false;
+ break;
+ }
+ else if (pval[0] == 't' && pval[1] == '\0')
+ {
+ *(char *) value = true;
+ break;
+ }
+ }
+
+ register_error(-1, "Unable to convert %s to bool on line %d.",
+ (pval ? pval : "NULL"),
+ lineno);
+ return false;
+ break;
+
+ case ECPGt_varchar:
+ {
+ struct ECPGgeneric_varchar *var =
+ (struct ECPGgeneric_varchar *) value;
+
+ strncpy(var->arr, pval, varcharsize);
+ var->len = strlen(pval);
+ if (var->len > varcharsize)
+ var->len = varcharsize;
+ }
+ break;
+
+ case ECPGt_EORT:
+ ECPGlog("ECPGdo line %d: Too few arguments.\n", lineno);
+ register_error(-1, "Too few arguments line %d.", lineno);
+ status = false;
+ break;
+
+ default:
+ register_error(-1, "Unsupported type %s on line %d.",
+ ECPGtype_name(type), lineno);
+ return false;
+ break;
+ }
+ }
+
+ type = va_arg(ap, enum ECPGttype);
+
+ if (status && type != ECPGt_EORT)
+ {
+ register_error(-1, "Too many arguments line %d.", lineno);
+ return false;
+ }
+
+ PQclear(results);
+ break;
+ case PGRES_EMPTY_QUERY:
+ /* do nothing */
+ register_error(-1, "Empty query line %d.", lineno);
+ break;
+ case PGRES_COMMAND_OK:
+ status = true;
+ ECPGlog("ECPGdo line %d Ok: %s\n", lineno, PQcmdStatus(results));
+ break;
+ case PGRES_NONFATAL_ERROR:
+ case PGRES_FATAL_ERROR:
+ case PGRES_BAD_RESPONSE:
+ ECPGlog("ECPGdo line %d: Error: %s",
+ lineno, PQerrorMessage(simple_connection));
+ register_error(-1, "Error: %s line %d.",
+ PQerrorMessage(simple_connection), lineno);
+ break;
+ case PGRES_COPY_OUT:
+ ECPGlog("ECPGdo line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno);
+ PQendcopy(results->conn);
+ break;
+ case PGRES_COPY_IN:
+ ECPGlog("ECPGdo line %d: Got PGRES_COPY_IN ... tossing.\n", lineno);
+ PQendcopy(results->conn);
+ break;
+ default:
+ ECPGlog("ECPGdo line %d: Got something else, postgres error.\n",
+ lineno);
+ register_error(-1, "Postgres error line %d.", lineno);
+ break;
+ }
+
+ /* check for asynchronous returns */
+ notify = PQnotifies(simple_connection);
+ if (notify)
+ {
+ ECPGlog("ECPGdo line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
+ lineno, notify->relname, notify->be_pid);
+ free(notify);
+ }
+
+ va_end(ap);
+ return status;
+}
+
+
+bool
+ECPGcommit(int lineno)
+{
+ PGresult *res;
+
+ ECPGlog("ECPGcommit line %d\n", lineno);
+ if ((res = PQexec(simple_connection, "end")) == NULL)
+ {
+ register_error(-1, "Error committing line %d.", lineno);
+ return (FALSE);
+ }
+ PQclear(res);
+ committed = 1;
+ return (TRUE);
+}
+
+bool
+ECPGrollback(int lineno)
+{
+ PGresult *res;
+
+ ECPGlog("ECPGrollback line %d\n", lineno);
+ if ((res = PQexec(simple_connection, "abort")) == NULL)
+ {
+ register_error(-1, "Error rolling back line %d.", lineno);
+ return (FALSE);
+ }
+ PQclear(res);
+ committed = 1;
+ return (TRUE);
+}
+
+
+
+bool
+ECPGsetdb(PGconn *newcon)
+{
+ ECPGfinish();
+ simple_connection = newcon;
+ return true;
+}
+
+bool
+ECPGconnect(const char *dbname)
+{
+ char *name = strdup(dbname);
+
+ ECPGlog("ECPGconnect: opening database %s\n", name);
+
+ sqlca.sqlcode = 0;
+
+ ECPGsetdb(PQsetdb(NULL, NULL, NULL, NULL, name));
+
+ free(name);
+ name = NULL;
+
+ if (PQstatus(simple_connection) == CONNECTION_BAD)
+ {
+ ECPGfinish();
+ ECPGlog("ECPGconnect: could not open database %s\n", dbname);
+ register_error(-1, "ECPGconnect: could not open database %s.", dbname);
+ return false;
+ }
+ return true;
+}
+
+
+bool
+ECPGstatus()
+{
+ return PQstatus(simple_connection) != CONNECTION_BAD;
+}
+
+
+bool
+ECPGfinish()
+{
+ if (simple_connection != NULL)
+ {
+ ECPGlog("ECPGfinish: finishing.\n");
+ PQfinish(simple_connection);
+ }
+ else
+ ECPGlog("ECPGfinish: called an extra time.\n");
+ return true;
+}
+
+void
+ECPGdebug(int n, FILE *dbgs)
+{
+ simple_debug = n;
+ debugstream = dbgs;
+ ECPGlog("ECPGdebug: set to %d\n", simple_debug);
+}
+
+void
+ECPGlog(const char *format,...)
+{
+ va_list ap;
+
+ if (simple_debug)
+ {
+ char *f = (char *) malloc(strlen(format) + 100);
+
+ sprintf(f, "[%d]: %s", getpid(), format);
+
+ va_start(ap, format);
+ vfprintf(debugstream, f, ap);
+ va_end(ap);
+
+ free(f);
+ }
+}
diff --git a/src/interfaces/ecpg/src/lib/typename.c b/src/interfaces/ecpg/lib/typename.c
index c1789572057..55756037b30 100644
--- a/src/interfaces/ecpg/src/lib/typename.c
+++ b/src/interfaces/ecpg/lib/typename.c
@@ -17,6 +17,7 @@ ECPGtype_name(enum ECPGttype typ)
case ECPGt_unsigned_long: return "unsigned long";
case ECPGt_float: return "float";
case ECPGt_double: return "double";
+ case ECPGt_bool: return "bool";
default:
abort();
}
diff --git a/src/interfaces/ecpg/src/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index 9a53fb1b432..8cc8b7cb3aa 100644
--- a/src/interfaces/ecpg/src/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -1,36 +1,32 @@
# Generated automatically from Makefile.in by configure.
-POSTGRESTOP=@POSTGRESERVER@
-POSTGRES_BIN=$(POSTGRESTOP)/bin
-POSTGRES_LIB=$(POSTGRESTOP)/lib
+SRCDIR= ../../..
+include $(SRCDIR)/Makefile.global
CC=gcc
LEX=flex
LEXLIB=-lfl
-YACC=bison -y
-
+YACC=/usr/bin/bison
+YFLAGS=-y -d
CFLAGS=-I../include -O2 -g -Wall
all:: ecpg
-clean::
- rm -f *.o core a.out ecpg y.tab.h y.tab.c *~
+clean:
+ rm -f *.o core a.out ecpg preproc.tab.h y.tab.c *~
-install:: all
- install -c -d -m755 $(POSTGRES_LIB)/ecpg
- install -c -m555 preproc $(POSTGRES_LIB)/ecpg
- install -c -m555 ecpg $(POSTGRES_BIN)
+install: all
+ install -c -m 755 ecpg $(BINDIR)
-uninstall::
- rm -f $(POSTGRES_BIN)/ecpg
- rm -f $(POSTGRES_LIB)/ecpg/preproc
+uninstall:
+ rm -f $(BINDIR)/ecpg
# Rule that really do something.
ecpg: y.tab.o pgc.o type.o ecpg.o
$(CC) -g -O2 -Wall -o ecpg y.tab.o pgc.o type.o ecpg.o -L../lib -lecpg $(LEXLIB)
y.tab.h y.tab.c: preproc.y
- $(YACC) -d $<
+ $(YACC) $(YFLAGS) $<
y.tab.o : y.tab.h ../include/ecpgtype.h
type.o : ../include/ecpgtype.h
diff --git a/src/interfaces/ecpg/preproc/Makefile.in b/src/interfaces/ecpg/preproc/Makefile.in
new file mode 100644
index 00000000000..f3cb049e8c3
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/Makefile.in
@@ -0,0 +1,32 @@
+SRCDIR= ../../..
+include $(SRCDIR)/Makefile.global
+
+CC=@CC@
+LEX=@LEX@
+LEXLIB=@LEXLIB@
+YACC=@YACC@
+YFLAGS=@YFLAGS@
+
+CFLAGS=-I../include -O2 -g -Wall
+
+all:: ecpg
+
+clean:
+ rm -f *.o core a.out ecpg preproc.tab.h y.tab.c *~
+
+install: all
+ install -c -m 755 ecpg $(BINDIR)
+
+uninstall:
+ rm -f $(BINDIR)/ecpg
+
+# Rule that really do something.
+ecpg: y.tab.o pgc.o type.o ecpg.o
+ $(CC) -g -O2 -Wall -o ecpg y.tab.o pgc.o type.o ecpg.o -L../lib -lecpg $(LEXLIB)
+
+y.tab.h y.tab.c: preproc.y
+ $(YACC) $(YFLAGS) $<
+
+y.tab.o : y.tab.h ../include/ecpgtype.h
+type.o : ../include/ecpgtype.h
+pgc.o : ../include/ecpgtype.h
diff --git a/src/interfaces/ecpg/src/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index a7d96072af9..08f4a395250 100644
--- a/src/interfaces/ecpg/src/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -8,10 +8,9 @@
#include <strings.h>
extern void lex_init(void);
-extern FILE *yyin,
- *yyout;
-
-int yyparse(void);
+extern FILE *yyin, *yyout;
+extern char * input_filename;
+extern int yyparse(void);
static void
usage(char *progname)
@@ -22,7 +21,8 @@ usage(char *progname)
int
main(int argc, char *const argv[])
{
- char c, out_option = 0;
+ char c,
+ out_option = 0;
int fnr;
while ((c = getopt(argc, argv, "o:")) != EOF)
@@ -58,7 +58,8 @@ main(int argc, char *const argv[])
ptr2ext = strrchr(filename, '.');
/* no extension or extension not equal .pgc */
- if (ptr2ext == NULL || strcmp(ptr2ext, ".pgc") != 0) {
+ if (ptr2ext == NULL || strcmp(ptr2ext, ".pgc") != 0)
+ {
ptr2ext = filename + strlen(filename);
ptr2ext[0] = '.';
}
@@ -67,17 +68,18 @@ main(int argc, char *const argv[])
ptr2ext[1] = 'c';
ptr2ext[2] = '\0';
- if (out_option == 0) /* calculate the output name */
+ if (out_option == 0) /* calculate the output name */
{
yyout = fopen(filename, "w");
- if (yyout == NULL) {
+ if (yyout == NULL)
+ {
perror(filename);
free(filename);
continue;
}
}
- yyin = fopen(argv[fnr], "r");
+ yyin = fopen(input_filename = argv[fnr], "r");
if (yyin == NULL)
{
perror(argv[fnr]);
@@ -95,7 +97,7 @@ main(int argc, char *const argv[])
fclose(yyin);
if (out_option == 0)
- fclose (yyout);
+ fclose(yyout);
}
free(filename);
diff --git a/src/interfaces/ecpg/src/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index 857561df9c5..7ab3c5764f2 100644
--- a/src/interfaces/ecpg/src/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -3,8 +3,11 @@
#include "type.h"
#include "y.tab.h"
-#define dbg(arg) fprintf(stderr, "DEBUG: %s\n", #arg);
+extern int debugging;
+
+#define dbg(arg) if (debugging) fprintf(stderr, "DEBUG, %d: %s\n", yylineno, #arg);
%}
+%option yylineno
%s C SQL
ccomment \/\*([^*]|\*[^/]|\*\*[^/])*\*\/
ws ([ \t\n][ \t\n]*|{ccomment})*
@@ -53,7 +56,8 @@ int { dbg(S_INT); return S_INT; }
char { dbg(S_CHAR); return S_CHAR; }
float { dbg(S_FLOAT); return S_FLOAT; }
double { dbg(S_DOUBLE); return S_DOUBLE; }
-
+bool { dbg(S_BOOL); return S_BOOL; }
+
{string} { dbg(SQL_STRING); return SQL_STRING; }
<SQL>{ws} ;
{symbol} { dbg(S_SYMBOL); return S_SYMBOL; }
@@ -100,12 +104,12 @@ double { dbg(S_DOUBLE); return S_DOUBLE; }
. { dbg(.); return S_ANYTHING; }
%%
void
-lex_init()
+lex_init(void)
{
BEGIN C;
}
-int yywrap()
+int yywrap(void)
{
return 1;
}
diff --git a/src/interfaces/ecpg/src/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index f53c9a56133..b5a30c0d196 100644
--- a/src/interfaces/ecpg/src/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -8,9 +8,27 @@
void yyerror(char *);
extern FILE * yyout;
extern char * yytext;
+extern int yylineno;
extern int yyleng;
/*
+ * Variables containing simple states.
+ */
+int debugging = 0;
+
+/*
+ * Handle the filename and line numbering.
+ */
+char * input_filename = NULL;
+
+void
+output_line_number()
+{
+ if (input_filename)
+ fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename);
+}
+
+/*
* Handling of the variables.
*/
/* Since we don't want to keep track of where the functions end we just
@@ -144,7 +162,7 @@ dump_variables(struct arguments * list)
%token <tagname> S_VARCHAR S_VARCHAR2
%token <tagname> S_EXTERN S_STATIC
%token <tagname> S_UNSIGNED S_SIGNED
-%token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE
+%token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL
%token <tagname> '[' ']' ';' ','
%type <type> type type_detailed varchar_type simple_type array_type
@@ -175,10 +193,12 @@ sqldeclaration : sql_startdeclare
sql_enddeclare;
sql_startdeclare : SQL_START SQL_BEGIN SQL_DECLARE SQL_SECTION SQL_SEMI {
- printf("/* exec sql begin declare section */\n");
+ fprintf(yyout, "/* exec sql begin declare section */\n");
+ output_line_number();
};
sql_enddeclare : SQL_START SQL_END SQL_DECLARE SQL_SECTION SQL_SEMI {
- printf("/* exec sql end declare section */\n");
+ fprintf(yyout,"/* exec sql end declare section */\n");
+ output_line_number();
};
variable_declarations : /* empty */
@@ -235,7 +255,8 @@ simple_tag : S_CHAR { $<type_enum>$ = ECPGt_char; }
| S_LONG { $<type_enum>$ = ECPGt_long; }
| S_UNSIGNED S_LONG { $<type_enum>$ = ECPGt_unsigned_long; }
| S_FLOAT { $<type_enum>$ = ECPGt_float; }
- | S_DOUBLE { $<type_enum>$ = ECPGt_double; };
+ | S_DOUBLE { $<type_enum>$ = ECPGt_double; }
+ | S_BOOL { $<type_enum>$ = ECPGt_bool; };
maybe_storage_clause : S_EXTERN { fwrite(yytext, yyleng, 1, yyout); }
| S_STATIC { fwrite(yytext, yyleng, 1, yyout); }
@@ -248,17 +269,17 @@ index : '[' length ']' {
length : S_LENGTH { $<indexsize>$ = atoi(yytext); }
sqlinclude : SQL_START SQL_INCLUDE { fprintf(yyout, "#include \""); }
- filename SQL_SEMI { fprintf(yyout, ".h\""); };
+ filename SQL_SEMI { fprintf(yyout, ".h\""); output_line_number(); };
filename : cthing
| filename cthing;
sqlconnect : SQL_START SQL_CONNECT { fprintf(yyout, "ECPGconnect(\""); }
SQL_STRING { fwrite(yytext + 1, yyleng - 2, 1, yyout); }
- SQL_SEMI { fprintf(yyout, "\");"); };
+ SQL_SEMI { fprintf(yyout, "\");"); output_line_number(); };
/* Open is an open cursor. Removed. */
-sqlopen : SQL_START SQL_OPEN sqlgarbage SQL_SEMI { };
+sqlopen : SQL_START SQL_OPEN sqlgarbage SQL_SEMI { output_line_number(); };
sqlgarbage : /* Empty */
| sqlgarbage sqlanything;
@@ -266,9 +287,11 @@ sqlgarbage : /* Empty */
sqlcommit : SQL_START SQL_COMMIT SQL_SEMI {
fprintf(yyout, "ECPGcommit(__LINE__);");
+ output_line_number();
};
sqlrollback : SQL_START SQL_ROLLBACK SQL_SEMI {
fprintf(yyout, "ECPGrollback(__LINE__);");
+ output_line_number();
};
sqlstatement : SQL_START { /* Reset stack */
@@ -283,6 +306,7 @@ sqlstatement : SQL_START { /* Reset stack */
fprintf(yyout, "ECPGt_EOIT, ");
dump_variables(argsresult);
fprintf(yyout, "ECPGt_EORT );");
+ output_line_number();
};
sqlstatement_words : sqlstatement_word
diff --git a/src/interfaces/ecpg/src/preproc/type.c b/src/interfaces/ecpg/preproc/type.c
index a54cbd801db..e3ee2f003ab 100644
--- a/src/interfaces/ecpg/src/preproc/type.c
+++ b/src/interfaces/ecpg/preproc/type.c
@@ -1,6 +1,5 @@
#include <stdio.h>
#include <string.h>
-#include <stdlib.h>
#include "type.h"
@@ -134,55 +133,59 @@ ECPGdump_a_simple(FILE * o, const char * name, enum ECPGttype typ,
switch (typ)
{
case ECPGt_char:
- fprintf(o, "ECPGt_char,&%s,0,%d,%s, ", name, arrsiz,
+ fprintf(o, "\n\tECPGt_char,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
break;
case ECPGt_unsigned_char:
- fprintf(o, "ECPGt_unsigned_char,&%s,0,%d,%s, ", name, arrsiz,
+ fprintf(o, "\n\tECPGt_unsigned_char,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(unsigned char)" : siz);
break;
case ECPGt_short:
- fprintf(o, "ECPGt_short,&%s,0,%d,%s, ", name, arrsiz,
+ fprintf(o, "\n\tECPGt_short,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(short)" : siz);
break;
case ECPGt_unsigned_short:
fprintf(o,
- "ECPGt_unsigned_short,&%s,0,%d,%s, ", name, arrsiz,
+ "\n\tECPGt_unsigned_short,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(unsigned short)" : siz);
break;
case ECPGt_int:
- fprintf(o, "ECPGt_int,&%s,0,%d,%s, ", name, arrsiz,
+ fprintf(o, "\n\tECPGt_int,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(int)" : siz);
break;
case ECPGt_unsigned_int:
- fprintf(o, "ECPGt_unsigned_int,&%s,0,%d,%s, ", name, arrsiz,
+ fprintf(o, "\n\tECPGt_unsigned_int,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(unsigned int)" : siz);
break;
case ECPGt_long:
- fprintf(o, "ECPGt_long,&%s,0,%d,%s, ", name, arrsiz,
+ fprintf(o, "\n\tECPGt_long,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(long)" : siz);
break;
case ECPGt_unsigned_long:
- fprintf(o, "ECPGt_unsigned_int,&%s,0,%d,%s, ", name, arrsiz,
+ fprintf(o, "\n\tECPGt_unsigned_int,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(unsigned int)" : siz);
break;
case ECPGt_float:
- fprintf(o, "ECPGt_float,&%s,0,%d,%s, ", name, arrsiz,
+ fprintf(o, "\n\tECPGt_float,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(float)" : siz);
break;
case ECPGt_double:
- fprintf(o, "ECPGt_double,&%s,0,%d,%s, ", name, arrsiz,
+ fprintf(o, "\n\tECPGt_double,&%s,0,%d,%s, ", name, arrsiz,
siz == NULL ? "sizeof(double)" : siz);
break;
+ case ECPGt_bool:
+ fprintf(o, "\n\tECPGt_bool,&%s,0,%d,%s, ", name, arrsiz,
+ siz == NULL ? "sizeof(bool)" : siz);
+ break;
case ECPGt_varchar:
case ECPGt_varchar2:
if (siz == NULL)
- fprintf(o, "ECPGt_varchar,&%s,%d,%d,sizeof(struct varchar_%s), ",
+ fprintf(o, "\n\tECPGt_varchar,&%s,%d,%d,sizeof(struct varchar_%s), ",
name,
varcharsize,
arrsiz, name);
else
- fprintf(o, "ECPGt_varchar,&%s,%d,%d,%s, ",
+ fprintf(o, "\n\tECPGt_varchar,&%s,%d,%d,%s, ",
name,
varcharsize,
arrsiz, siz);
diff --git a/src/interfaces/ecpg/src/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index 6726683bd58..6726683bd58 100644
--- a/src/interfaces/ecpg/src/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
diff --git a/src/interfaces/ecpg/preproc/y.tab.h b/src/interfaces/ecpg/preproc/y.tab.h
new file mode 100644
index 00000000000..b2fadd683bf
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/y.tab.h
@@ -0,0 +1,39 @@
+typedef union {
+ int tagname;
+ struct ECPGtemp_type type;
+ char * symbolname;
+ int indexsize;
+ enum ECPGttype type_enum;
+} YYSTYPE;
+#define SQL_START 258
+#define SQL_SEMI 259
+#define SQL_STRING 260
+#define SQL_INTO 261
+#define SQL_BEGIN 262
+#define SQL_END 263
+#define SQL_DECLARE 264
+#define SQL_SECTION 265
+#define SQL_INCLUDE 266
+#define SQL_CONNECT 267
+#define SQL_OPEN 268
+#define SQL_COMMIT 269
+#define SQL_ROLLBACK 270
+#define S_SYMBOL 271
+#define S_LENGTH 272
+#define S_ANYTHING 273
+#define S_VARCHAR 274
+#define S_VARCHAR2 275
+#define S_EXTERN 276
+#define S_STATIC 277
+#define S_UNSIGNED 278
+#define S_SIGNED 279
+#define S_LONG 280
+#define S_SHORT 281
+#define S_INT 282
+#define S_CHAR 283
+#define S_FLOAT 284
+#define S_DOUBLE 285
+#define S_BOOL 286
+
+
+extern YYSTYPE yylval;
diff --git a/src/interfaces/ecpg/src/include/Makefile b/src/interfaces/ecpg/src/include/Makefile
deleted file mode 100644
index 3b001abaaf0..00000000000
--- a/src/interfaces/ecpg/src/include/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# Generated automatically from Makefile.in by configure.
-POSTGRESTOP=@POSTGRESERVER@
-POSTGRES_INCLUDE=$(POSTGRESTOP)/include
-
-all clean::
- @echo Nothing to be done.
-
-install::
- install ecpglib.h $(POSTGRES_INCLUDE)
- install ecpgtype.h $(POSTGRES_INCLUDE)
- install sqlca.h $(POSTGRES_INCLUDE)
-
-uninstall::
- rm -f $(POSTGRES_INCLUDE)/ecpglib.h
- rm -f $(POSTGRES_INCLUDE)/ecpgtype.h
- rm -f $(POSTGRES_INCLUDE)/sqlca.h
diff --git a/src/interfaces/ecpg/src/include/Makefile.in b/src/interfaces/ecpg/src/include/Makefile.in
deleted file mode 100644
index 80e0451e2b5..00000000000
--- a/src/interfaces/ecpg/src/include/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-POSTGRESTOP=@POSTGRESERVER@
-POSTGRES_INCLUDE=$(POSTGRESTOP)/include
-
-all clean::
- @echo Nothing to be done.
-
-install::
- install ecpglib.h $(POSTGRES_INCLUDE)
- install ecpgtype.h $(POSTGRES_INCLUDE)
- install sqlca.h $(POSTGRES_INCLUDE)
-
-uninstall::
- rm -f $(POSTGRES_INCLUDE)/ecpglib.h
- rm -f $(POSTGRES_INCLUDE)/ecpgtype.h
- rm -f $(POSTGRES_INCLUDE)/sqlca.h
diff --git a/src/interfaces/ecpg/src/lib/ecpglib.c b/src/interfaces/ecpg/src/lib/ecpglib.c
deleted file mode 100644
index d2c078e2d01..00000000000
--- a/src/interfaces/ecpg/src/lib/ecpglib.c
+++ /dev/null
@@ -1,609 +0,0 @@
-/* Copyright comment */
-/*
- * 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@debian.org>
- on Feb. 5th, 1998 */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include <ecpgtype.h>
-#include <ecpglib.h>
-#include <sqlca.h>
-#include <libpq-fe.h>
-#include <libpq/pqcomm.h>
-
-static PGconn * simple_connection;
-static int simple_debug = 0;
-static int committed = true;
-
-static void
-register_error(int code, char *fmt, ...)
-{
- va_list args;
-
- sqlca.sqlcode = code;
- va_start (args, fmt);
- vsprintf (sqlca.sqlerrm.sqlerrmc, fmt, args);
- va_end (args);
- sqlca.sqlerrm.sqlerrml = strlen (sqlca.sqlerrm.sqlerrmc);
-}
-
-/* This function returns a newly malloced string that has the ' and \
- in the argument quoted with \.
- */
-static
-char *
-quote_postgres(char * arg)
-{
- char * res = (char *)malloc(2 * strlen(arg) + 1);
- int i, ri;
-
- for (i = 0, ri = 0; arg[i]; i++, ri++)
- {
- switch (arg[i])
- {
- case '\'':
- case '\\':
- res[ri++] = '\\';
- default:
- ;
- }
-
- res[ri] = arg[i];
- }
- res[ri] = '\0';
-
- return res;
-}
-
-
-bool
-ECPGdo(int lineno, char * query, ...)
-{
- va_list ap;
- bool status = false;
- char * copiedquery;
- PGresult * results;
- PGnotify * notify;
- enum ECPGttype type;
-
- va_start(ap, query);
-
- sqlca.sqlcode = 0;
- copiedquery = strdup(query);
-
- type = va_arg(ap, enum ECPGttype);
-
- /*
- * 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.
- */
- while (type != ECPGt_EOIT)
- {
- void * value = NULL;
- short varcharsize;
- short size;
- short arrsize;
-
- char * newcopy;
- char * mallocedval = NULL;
- char * tobeinserted = NULL;
- char * p;
- char buff[20];
-
- /* Some special treatment is needed for records since we want their
- contents to arrive in a comma-separated list on insert (I think). */
-
- value = va_arg(ap, void *);
- varcharsize = va_arg(ap, short);
- size = va_arg(ap, short);
- arrsize = va_arg(ap, short);
-
- switch (type) {
- case ECPGt_char:
- case ECPGt_short:
- case ECPGt_int:
- sprintf(buff, "%d", *(int*)value);
- tobeinserted = buff;
- break;
-
- case ECPGt_unsigned_char:
- case ECPGt_unsigned_short:
- case ECPGt_unsigned_int:
- sprintf(buff, "%d", *(unsigned int*)value);
- tobeinserted = buff;
- break;
-
- case ECPGt_long:
- sprintf(buff, "%ld", *(long*)value);
- tobeinserted = buff;
- break;
-
- case ECPGt_unsigned_long:
- sprintf(buff, "%ld", *(unsigned long*)value);
- tobeinserted = buff;
- break;
-
- case ECPGt_float:
- sprintf(buff, "%.14g", *(float*)value);
- tobeinserted = buff;
- break;
-
- case ECPGt_double:
- sprintf(buff, "%.14g", *(double*)value);
- tobeinserted = buff;
- break;
-
- case ECPGt_varchar:
- case ECPGt_varchar2:
- {
- struct ECPGgeneric_varchar * var =
- (struct ECPGgeneric_varchar*)value;
-
- newcopy = (char *)malloc(var->len + 1);
- strncpy(newcopy, var->arr, var->len);
- newcopy[var->len] = '\0';
-
- mallocedval = (char *)malloc(2 * strlen(newcopy) + 3);
- strcpy(mallocedval, "'");
- strcat(mallocedval, quote_postgres(newcopy));
- strcat(mallocedval, "'");
-
- free(newcopy);
-
- tobeinserted = mallocedval;
- }
- break;
-
- default:
- /* Not implemented yet */
- register_error(-1, "Unsupported type %s on line %d.",
- ECPGtype_name(type), lineno);
- return false;
- break;
- }
-
- /* Now tobeinserted points to an area that is to be inserted at
- the first %s
- */
- newcopy = (char *)malloc(strlen(copiedquery)
- + strlen(tobeinserted)
- + 1);
- strcpy(newcopy, copiedquery);
- if ((p = strstr(newcopy, ";;")) == NULL)
- {
- /* We have an argument but we dont have the matched up string
- in the string
- */
- register_error(-1, "Too many arguments line %d.", lineno);
- return false;
- }
- else
- {
- strcpy(p, tobeinserted);
- /* The strange thing in the second argument is the rest of the
- string from the old string */
- strcat(newcopy,
- copiedquery
- + ( p - newcopy )
- + 2 /* Length of ;; */);
- }
-
- /* Now everything is safely copied to the newcopy. Lets free the
- oldcopy and let the copiedquery get the value from the newcopy.
- */
- if (mallocedval != NULL)
- {
- free(mallocedval);
- mallocedval = NULL;
- }
-
- free(copiedquery);
- copiedquery = newcopy;
-
- type = va_arg(ap, enum ECPGttype);
- }
-
- /* Check if there are unmatched things left. */
- if (strstr(copiedquery, ";;") != NULL)
- {
- register_error(-1, "Too few arguments line %d.", lineno);
- return false;
- }
-
- /* Now then request is built. */
-
- if (committed)
- {
- if ((results = PQexec (simple_connection, "begin")) == NULL) {
- register_error(-1, "Error starting transaction line %d.", lineno);
- return false;
- }
- PQclear (results);
- committed = 0;
- }
-
- ECPGlog("ECPGdo line %d: QUERY: %s\n", lineno, copiedquery);
- results = PQexec(simple_connection, copiedquery);
- free(copiedquery);
-
- if (results == NULL)
- {
- ECPGlog("ECPGdo line %d: error: %s", lineno,
- PQerrorMessage(simple_connection));
- register_error(-1, "Postgres error: %s line %d.",
- PQerrorMessage(simple_connection), lineno);
- }
- else switch(PQresultStatus(results))
- {
- int m,n,x;
-
- case PGRES_TUPLES_OK:
- /* XXX Cheap Hack. For now, we see only the last group
- * of tuples. This is clearly not the right
- * way to do things !!
- */
-
- m = PQnfields(results);
- n = PQntuples(results);
-
- if (n < 1)
- {
- ECPGlog("ECPGdo lineno %d: Incorrect number of matches: %d\n",
- lineno, n);
- register_error(1, "Data not found line %d.", lineno);
- break;
- }
-
- if (n > 1)
- {
- ECPGlog("ECPGdo line %d: Incorrect number of matches: %d\n",
- lineno, n);
- register_error(-1, "To many matches line %d.", lineno);
- break;
- }
-
- status = true;
-
- for (x = 0; x < m && status; x++)
- {
- void * value = NULL;
- short varcharsize;
- short size;
- short arrsize;
-
- char *pval = PQgetvalue(results,0,x);
- /*long int * res_int;
- char ** res_charstar;
- char * res_char;
- int res_len;*/
- char * scan_length;
-
- ECPGlog("ECPGdo line %d: RESULT: %s\n", lineno, pval ? pval : "");
-
- /* No the pval is a pointer to the value. */
- /* We will have to decode the value */
- type = va_arg(ap, enum ECPGttype);
- value = va_arg(ap, void *);
- varcharsize = va_arg(ap, short);
- size = va_arg(ap, short);
- arrsize = va_arg(ap, short);
-
- switch (type)
- {
- long res;
- unsigned long ures;
- double dres;
-
- case ECPGt_char:
- case ECPGt_short:
- case ECPGt_int:
- case ECPGt_long:
- if (pval)
- {
- res = strtol(pval, &scan_length, 10);
- if (*scan_length != '\0') /* Garbage left */
- {
- register_error(-1, "Not correctly formatted int type: %s line %d.",
- pval, lineno);
- status = false;
- res = 0L;
- }
- }
- else
- res = 0L;
-
- /* Again?! Yes */
- switch (type)
- {
- case ECPGt_char:
- *(char *)value = (char)res;
- break;
- case ECPGt_short:
- *(short *)value = (short)res;
- break;
- case ECPGt_int:
- *(int *)value = (int)res;
- break;
- case ECPGt_long:
- *(long *)value = res;
- break;
- default:
- /* Cannot happen */
- break;
- }
- break;
-
- case ECPGt_unsigned_char:
- case ECPGt_unsigned_short:
- case ECPGt_unsigned_int:
- case ECPGt_unsigned_long:
- if (pval)
- {
- ures = strtoul(pval, &scan_length, 10);
- if (*scan_length != '\0') /* Garbage left */
- {
- register_error(-1, "Not correctly formatted unsigned type: %s line %d.",
- pval, lineno);
- status = false;
- ures = 0L;
- }
- }
- else
- ures = 0L;
-
- /* Again?! Yes */
- switch (type)
- {
- case ECPGt_unsigned_char:
- *(unsigned char *)value = (unsigned char)ures;
- break;
- case ECPGt_unsigned_short:
- *(unsigned short *)value = (unsigned short)ures;
- break;
- case ECPGt_unsigned_int:
- *(unsigned int *)value = (unsigned int)ures;
- break;
- case ECPGt_unsigned_long:
- *(unsigned long *)value = ures;
- break;
- default:
- /* Cannot happen */
- break;
- }
- break;
-
-
- case ECPGt_float:
- case ECPGt_double:
- if (pval)
- {
- dres = strtod(pval, &scan_length);
- if (*scan_length != '\0') /* Garbage left */
- {
- register_error(-1, "Not correctly formatted floating point type: %s line %d.",
- pval, lineno);
- status = false;
- dres = 0.0;
- }
- }
- else
- dres = 0.0;
-
- /* Again?! Yes */
- switch (type)
- {
- case ECPGt_float:
- *(float *)value = (float)res;
- break;
- case ECPGt_double:
- *(double *)value = res;
- break;
- default:
- /* Cannot happen */
- break;
- }
- break;
-
-
- case ECPGt_varchar:
- {
- struct ECPGgeneric_varchar * var =
- (struct ECPGgeneric_varchar*)value;
-
- strncpy(var->arr, pval, varcharsize);
- var->len = strlen(pval);
- if (var->len > varcharsize)
- var->len = varcharsize;
- }
- break;
-
- case ECPGt_EORT:
- ECPGlog("ECPGdo line %d: Too few arguments.\n", lineno);
- register_error(-1, "Too few arguments line %d.", lineno);
- status = false;
- break;
-
- default:
- register_error(-1, "Unsupported type %s on line %d.",
- ECPGtype_name(type), lineno);
- return false;
- break;
- }
- }
-
- type = va_arg(ap, enum ECPGttype);
-
- if (status && type != ECPGt_EORT)
- {
- register_error(-1, "Too many arguments line %d.", lineno);
- return false;
- }
-
- PQclear(results);
- break;
- case PGRES_EMPTY_QUERY:
- /* do nothing */
- register_error(-1, "Empty query line %d.", lineno);
- break;
- case PGRES_COMMAND_OK:
- status = true;
- ECPGlog("ECPGdo line %d Ok: %s\n", lineno, PQcmdStatus(results));
- break;
- case PGRES_NONFATAL_ERROR:
- case PGRES_FATAL_ERROR:
- case PGRES_BAD_RESPONSE:
- ECPGlog("ECPGdo line %d: Error: %s",
- lineno, PQerrorMessage(simple_connection));
- register_error(-1, "Error: %s line %d.",
- PQerrorMessage(simple_connection), lineno);
- break;
- case PGRES_COPY_OUT:
- ECPGlog("ECPGdo line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno);
- PQendcopy(results->conn);
- break;
- case PGRES_COPY_IN:
- ECPGlog("ECPGdo line %d: Got PGRES_COPY_IN ... tossing.\n", lineno);
- PQendcopy(results->conn);
- break;
- default:
- ECPGlog("ECPGdo line %d: Got something else, postgres error.\n",
- lineno);
- register_error(-1, "Postgres error line %d.", lineno);
- break;
- }
-
- /* check for asynchronous returns */
- notify = PQnotifies(simple_connection);
- if (notify) {
- ECPGlog("ECPGdo line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
- lineno, notify->relname, notify->be_pid);
- free(notify);
- }
-
- va_end(ap);
- return status;
-}
-
-
-bool
-ECPGcommit(int lineno)
-{
- PGresult *res;
-
- ECPGlog("ECPGcommit line %d\n", lineno);
- if ((res = PQexec (simple_connection, "end")) == NULL) {
- register_error(-1, "Error committing line %d.", lineno);
- return (FALSE);
- }
- PQclear (res);
- committed = 1;
- return (TRUE);
-}
-
-bool
-ECPGrollback(int lineno)
-{
- PGresult *res;
-
- ECPGlog("ECPGrollback line %d\n", lineno);
- if ((res = PQexec (simple_connection, "abort")) == NULL) {
- register_error(-1, "Error rolling back line %d.", lineno);
- return (FALSE);
- }
- PQclear (res);
- committed = 1;
- return(TRUE);
-}
-
-
-
-bool
-ECPGsetdb(PGconn * newcon)
-{
- ECPGfinish();
- simple_connection = newcon;
- return true;
-}
-
-bool
-ECPGconnect(const char * dbname)
-{
- char * name = strdup(dbname);
- ECPGlog("ECPGconnect: opening database %s\n", name);
-
- sqlca.sqlcode = 0;
-
- ECPGsetdb(PQsetdb(NULL, NULL, NULL, NULL, name));
-
- free(name);
- name = NULL;
-
- if (PQstatus(simple_connection) == CONNECTION_BAD)
- {
- ECPGfinish();
- ECPGlog("ECPGconnect: could not open database %s\n", dbname);
- register_error(-1, "ECPGconnect: could not open database %s.", dbname);
- return false;
- }
- return true;
-}
-
-
-bool
-ECPGstatus()
-{
- return PQstatus(simple_connection) != CONNECTION_BAD;
-}
-
-
-bool
-ECPGfinish()
-{
- if (simple_connection != NULL)
- {
- ECPGlog("ECPGfinish: finishing.\n");
- PQfinish(simple_connection);
- }
- else
- ECPGlog("ECPGfinish: called an extra time.\n");
- return true;
-}
-
-void
-ECPGdebug(int n)
-{
- simple_debug = n;
- ECPGlog("ECPGdebug: set to %d\n", simple_debug);
-}
-
-void
-ECPGlog(const char * format, ...)
-{
- va_list ap;
- if (simple_debug)
- {
- char * f = (char *) malloc(strlen(format) + 100);
-
- sprintf(f, "[%d]: %s", getpid(), format);
-
- va_start(ap, format);
- vfprintf(stderr, f, ap);
- va_end(ap);
-
- free(f);
- }
-}
diff --git a/src/interfaces/ecpg/src/preproc/Makefile.in b/src/interfaces/ecpg/src/preproc/Makefile.in
deleted file mode 100644
index 2dca1341245..00000000000
--- a/src/interfaces/ecpg/src/preproc/Makefile.in
+++ /dev/null
@@ -1,36 +0,0 @@
-POSTGRESTOP=@POSTGRESERVER@
-POSTGRES_BIN=$(POSTGRESTOP)/bin
-POSTGRES_LIB=$(POSTGRESTOP)/lib
-
-CC=@CC@
-LEX=@LEX@
-LEXLIB=@LEXLIB@
-YACC=@YACC@
-
-
-CFLAGS=-I../include -O2 -g -Wall
-
-all:: ecpg
-
-clean::
- rm -f *.o core a.out ecpg y.tab.h y.tab.c *~
-
-install:: all
- install -c -d -m755 $(POSTGRES_LIB)/ecpg
- install -c -m555 preproc $(POSTGRES_LIB)/ecpg
- install -c -m555 ecpg $(POSTGRES_BIN)
-
-uninstall::
- rm -f $(POSTGRES_BIN)/ecpg
- rm -f $(POSTGRES_LIB)/ecpg/preproc
-
-# Rule that really do something.
-ecpg: y.tab.o pgc.o type.o ecpg.o
- $(CC) -g -O2 -Wall -o ecpg y.tab.o pgc.o type.o ecpg.o -L../lib -lecpg $(LEXLIB)
-
-y.tab.h y.tab.c: preproc.y
- $(YACC) -d $<
-
-y.tab.o : y.tab.h ../include/ecpgtype.h
-type.o : ../include/ecpgtype.h
-pgc.o : ../include/ecpgtype.h
diff --git a/src/interfaces/ecpg/src/preproc/ecpg.in b/src/interfaces/ecpg/src/preproc/ecpg.in
deleted file mode 100644
index b032cada7fd..00000000000
--- a/src/interfaces/ecpg/src/preproc/ecpg.in
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-
-INFILE=
-OUTFILE=
-
-for arg
-do
- case "$arg" in
- iname=*)
- INFILE=`expr substr $arg 7 1000`
- ;;
- oname=*)
- OUTFILE=`expr substr $arg 7 1000`
- ;;
- *)
- echo Wrong argument $arg
- exit 1;
- ;;
- esac
-done
-
-if [ -n "$INFILE" -a -n "$OUTFILE" ]
-then
- exec @POSTGRESERVER@/lib/ecpg/preproc < $INFILE > $OUTFILE
-else
- echo Missing arguments.
- echo usage: $0 iname=file oname=outfile
- exit 1;
-fi
-
-exit 0;
diff --git a/src/interfaces/ecpg/src/test/Makefile b/src/interfaces/ecpg/src/test/Makefile
deleted file mode 100644
index 219fb54e4f8..00000000000
--- a/src/interfaces/ecpg/src/test/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-test2: test2.c
- gcc -g -I ../include -I ../../../libpq -o test2 test2.c ../lib/libecpg.a ../../../libpq/libpq.a -lcrypt
-test2.c: test2.pgc
- ../preproc/ecpg test2.pgc
-clean:
- /bin/rm test2 test2.c
diff --git a/src/interfaces/ecpg/src/test/test2 b/src/interfaces/ecpg/src/test/test2
deleted file mode 100755
index 34b86808cd0..00000000000
--- a/src/interfaces/ecpg/src/test/test2
+++ /dev/null
Binary files differ
diff --git a/src/interfaces/ecpg/src/test/test2.c b/src/interfaces/ecpg/src/test/test2.c
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/src/interfaces/ecpg/src/test/test2.c
+++ /dev/null
diff --git a/src/interfaces/ecpg/src/test/test2.qc b/src/interfaces/ecpg/src/test/test2.qc
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/src/interfaces/ecpg/src/test/test2.qc
+++ /dev/null
diff --git a/src/interfaces/ecpg/test/Makefile b/src/interfaces/ecpg/test/Makefile
new file mode 100644
index 00000000000..0ec008964e5
--- /dev/null
+++ b/src/interfaces/ecpg/test/Makefile
@@ -0,0 +1,14 @@
+all: test2 perftest
+
+test2: test2.c
+ gcc -g -I ../include -I ../../../libpq -o test2 test2.c ../lib/libecpg.a ../../../libpq/libpq.a -lcrypt
+test2.c: test2.pgc
+ ../preproc/ecpg test2.pgc
+
+perftest: perftest.c
+ gcc -g -I ../include -I ../../../libpq -o perftest perftest.c ../lib/libecpg.a ../../../libpq/libpq.a -lcrypt
+perftest.c: perftest.pgc
+ ../preproc/ecpg perftest.pgc
+
+clean:
+ /bin/rm test2 test2.c perftest perftest.c
diff --git a/src/interfaces/ecpg/src/test/Ptest1.c b/src/interfaces/ecpg/test/Ptest1.c
index 5aee48e7d5c..5aee48e7d5c 100644
--- a/src/interfaces/ecpg/src/test/Ptest1.c
+++ b/src/interfaces/ecpg/test/Ptest1.c
diff --git a/src/interfaces/ecpg/test/perftest.pgc b/src/interfaces/ecpg/test/perftest.pgc
new file mode 100644
index 00000000000..9fb63fe6fad
--- /dev/null
+++ b/src/interfaces/ecpg/test/perftest.pgc
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+exec sql include sqlca;
+
+#define SQLCODE sqlca.sqlcode
+
+void
+db_error (char *msg)
+{
+ sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
+ printf ("%s: db error %s\n", msg, sqlca.sqlerrm.sqlerrmc);
+ exit (1);
+}
+
+int
+main ()
+{
+exec sql begin declare section;
+ long i;
+exec sql end declare section;
+ struct timeval tvs, tve;
+
+ gettimeofday(&tvs, NULL);
+
+ exec sql connect 'mm';
+ if (SQLCODE)
+ db_error ("connect");
+
+ exec sql create table perftest(number int4, ascii char16);
+ if (SQLCODE)
+ db_error ("create t");
+
+ exec sql create unique index number on perftest(number);
+ if (SQLCODE)
+ db_error ("create i");
+
+ for (i = 0;i < 1407; i++)
+ {
+ exec sql begin declare section;
+ char text[16];
+ exec sql end declare section;
+
+ sprintf(text, "%ld", i);
+ exec sql insert into perftest(number, ascii) values (:i, :text);
+ if (SQLCODE)
+ db_error ("insert");
+
+ exec sql commit;
+ if (SQLCODE)
+ db_error ("commit");
+ }
+
+ exec sql drop index number;
+ if (SQLCODE)
+ db_error ("drop i");
+
+ exec sql drop table perftest;
+ if (SQLCODE)
+ db_error ("drop t");
+
+ exec sql commit;
+ if (SQLCODE)
+ db_error ("commit");
+
+ gettimeofday(&tve, NULL);
+
+ printf("I needed %ld seconds and %ld microseconds for this test\n", tve.tv_sec - tvs.tv_sec, tve.tv_usec - tvs.tv_usec);
+
+ return (0);
+}
diff --git a/src/interfaces/ecpg/src/test/test1.c b/src/interfaces/ecpg/test/test1.c
index 68d9dd53981..68d9dd53981 100644
--- a/src/interfaces/ecpg/src/test/test1.c
+++ b/src/interfaces/ecpg/test/test1.c
diff --git a/src/interfaces/ecpg/test/test2.pgc b/src/interfaces/ecpg/test/test2.pgc
new file mode 100644
index 00000000000..5e944950876
--- /dev/null
+++ b/src/interfaces/ecpg/test/test2.pgc
@@ -0,0 +1,50 @@
+exec sql include sqlca;
+
+#define SQLCODE sqlca.sqlcode
+
+void
+db_error (char *msg)
+{
+ sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
+ printf ("%s: db error %s\n", msg, sqlca.sqlerrm.sqlerrmc);
+ exit (1);
+}
+
+int
+main ()
+{
+exec sql begin declare section;
+ varchar text[8];
+ int count;
+ double control;
+exec sql end declare section;
+
+ exec sql connect 'mm';
+ if (SQLCODE)
+ db_error ("connect");
+
+ exec sql declare cur cursor for
+ select text, control, count from test;
+ if (SQLCODE) db_error ("declare");
+
+ exec sql open cur;
+ if (SQLCODE)
+ db_error ("open");
+
+ while (1) {
+ exec sql fetch in cur into :text, :control, :count;
+ if (SQLCODE)
+ break;
+ printf ("%8.8s %d %f\n", text.arr, count, control);
+ }
+
+ if (SQLCODE < 0)
+ db_error ("fetch");
+
+ exec sql close cur;
+ if (SQLCODE) db_error ("close");
+ exec sql commit;
+ if (SQLCODE) db_error ("commit");
+
+ return (0);
+}