From 38201e21d0849a469e165085e4d12ac0969f5018 Mon Sep 17 00:00:00 2001 From: "Marc G. Fournier" Date: Tue, 10 Feb 1998 16:44:17 +0000 Subject: [PATCH] Erk, the whole directory structure changed on us here... --- src/interfaces/ecpg/include/Makefile | 16 + src/interfaces/ecpg/include/Makefile.in | 15 + .../ecpg/{src => }/include/ecpglib.h | 2 +- .../ecpg/{src => }/include/ecpgtype.h | 2 +- src/interfaces/ecpg/{src => }/include/sqlca.h | 0 src/interfaces/ecpg/{src => }/lib/Makefile | 16 +- src/interfaces/ecpg/{src => }/lib/Makefile.in | 16 +- src/interfaces/ecpg/lib/ecpglib.c | 648 ++++++++++++++++++ src/interfaces/ecpg/{src => }/lib/typename.c | 1 + .../ecpg/{src => }/preproc/Makefile | 26 +- src/interfaces/ecpg/preproc/Makefile.in | 32 + src/interfaces/ecpg/{src => }/preproc/ecpg.c | 22 +- src/interfaces/ecpg/{src => }/preproc/pgc.l | 12 +- .../ecpg/{src => }/preproc/preproc.y | 38 +- src/interfaces/ecpg/{src => }/preproc/type.c | 29 +- src/interfaces/ecpg/{src => }/preproc/type.h | 0 src/interfaces/ecpg/preproc/y.tab.h | 39 ++ src/interfaces/ecpg/src/include/Makefile | 16 - src/interfaces/ecpg/src/include/Makefile.in | 15 - src/interfaces/ecpg/src/lib/ecpglib.c | 609 ---------------- src/interfaces/ecpg/src/preproc/Makefile.in | 36 - src/interfaces/ecpg/src/preproc/ecpg.in | 31 - src/interfaces/ecpg/src/test/Makefile | 6 - src/interfaces/ecpg/src/test/test2 | Bin 71167 -> 0 bytes src/interfaces/ecpg/src/test/test2.c | 0 src/interfaces/ecpg/src/test/test2.qc | 0 src/interfaces/ecpg/test/Makefile | 14 + src/interfaces/ecpg/{src => }/test/Ptest1.c | 0 src/interfaces/ecpg/test/perftest.pgc | 72 ++ src/interfaces/ecpg/{src => }/test/test1.c | 0 src/interfaces/ecpg/test/test2.pgc | 50 ++ 31 files changed, 985 insertions(+), 778 deletions(-) create mode 100644 src/interfaces/ecpg/include/Makefile create mode 100644 src/interfaces/ecpg/include/Makefile.in rename src/interfaces/ecpg/{src => }/include/ecpglib.h (94%) rename src/interfaces/ecpg/{src => }/include/ecpgtype.h (98%) rename src/interfaces/ecpg/{src => }/include/sqlca.h (100%) rename src/interfaces/ecpg/{src => }/lib/Makefile (61%) rename src/interfaces/ecpg/{src => }/lib/Makefile.in (64%) create mode 100644 src/interfaces/ecpg/lib/ecpglib.c rename src/interfaces/ecpg/{src => }/lib/typename.c (94%) rename src/interfaces/ecpg/{src => }/preproc/Makefile (51%) create mode 100644 src/interfaces/ecpg/preproc/Makefile.in rename src/interfaces/ecpg/{src => }/preproc/ecpg.c (84%) rename src/interfaces/ecpg/{src => }/preproc/pgc.l (94%) rename src/interfaces/ecpg/{src => }/preproc/preproc.y (90%) rename src/interfaces/ecpg/{src => }/preproc/type.c (87%) rename src/interfaces/ecpg/{src => }/preproc/type.h (100%) create mode 100644 src/interfaces/ecpg/preproc/y.tab.h delete mode 100644 src/interfaces/ecpg/src/include/Makefile delete mode 100644 src/interfaces/ecpg/src/include/Makefile.in delete mode 100644 src/interfaces/ecpg/src/lib/ecpglib.c delete mode 100644 src/interfaces/ecpg/src/preproc/Makefile.in delete mode 100644 src/interfaces/ecpg/src/preproc/ecpg.in delete mode 100644 src/interfaces/ecpg/src/test/Makefile delete mode 100755 src/interfaces/ecpg/src/test/test2 delete mode 100644 src/interfaces/ecpg/src/test/test2.c delete mode 100644 src/interfaces/ecpg/src/test/test2.qc create mode 100644 src/interfaces/ecpg/test/Makefile rename src/interfaces/ecpg/{src => }/test/Ptest1.c (100%) create mode 100644 src/interfaces/ecpg/test/perftest.pgc rename src/interfaces/ecpg/{src => }/test/test1.c (100%) create mode 100644 src/interfaces/ecpg/test/test2.pgc 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 similarity index 94% rename from src/interfaces/ecpg/src/include/ecpglib.h rename to 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 -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 similarity index 98% rename from src/interfaces/ecpg/src/include/ecpgtype.h rename to 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 similarity index 100% rename from src/interfaces/ecpg/src/include/sqlca.h rename to src/interfaces/ecpg/include/sqlca.h diff --git a/src/interfaces/ecpg/src/lib/Makefile b/src/interfaces/ecpg/lib/Makefile similarity index 61% rename from src/interfaces/ecpg/src/lib/Makefile rename to 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 similarity index 64% rename from src/interfaces/ecpg/src/lib/Makefile.in rename to 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 + on Feb. 5th, 1998 */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +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 similarity index 94% rename from src/interfaces/ecpg/src/lib/typename.c rename to 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 similarity index 51% rename from src/interfaces/ecpg/src/preproc/Makefile rename to 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 similarity index 84% rename from src/interfaces/ecpg/src/preproc/ecpg.c rename to 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 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 similarity index 94% rename from src/interfaces/ecpg/src/preproc/pgc.l rename to 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; } {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 similarity index 90% rename from src/interfaces/ecpg/src/preproc/preproc.y rename to 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,8 +8,26 @@ 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. */ @@ -144,7 +162,7 @@ dump_variables(struct arguments * list) %token S_VARCHAR S_VARCHAR2 %token S_EXTERN S_STATIC %token S_UNSIGNED S_SIGNED -%token S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE +%token S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL %token '[' ']' ';' ',' %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 { $$ = ECPGt_char; } | S_LONG { $$ = ECPGt_long; } | S_UNSIGNED S_LONG { $$ = ECPGt_unsigned_long; } | S_FLOAT { $$ = ECPGt_float; } - | S_DOUBLE { $$ = ECPGt_double; }; + | S_DOUBLE { $$ = ECPGt_double; } + | S_BOOL { $$ = 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 { $$ = 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 similarity index 87% rename from src/interfaces/ecpg/src/preproc/type.c rename to 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 #include -#include #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 similarity index 100% rename from src/interfaces/ecpg/src/preproc/type.h rename to 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 - on Feb. 5th, 1998 */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -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 34b86808cd05b730a8ddb891f02891ac9a37d383..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 71167 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 T +#include +#include + +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 similarity index 100% rename from src/interfaces/ecpg/src/test/test1.c rename to 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); +} -- 2.39.5