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 0000000000..08bc9df7f2 --- /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 0000000000..2f5c63ab07 --- /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 b880182e0b..1fb35f8dfe 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 cc56b78cbb..496c934f4f 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 d227f6df36..e3722e8aec 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 07d126bd5c..7ed351ab7a 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 0000000000..80e9b0fd9c --- /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 c178957205..55756037b3 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 9a53fb1b43..8cc8b7cb3a 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 0000000000..f3cb049e8c --- /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 a7d96072af..08f4a39525 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 857561df9c..7ab3c5764f 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 f53c9a5613..b5a30c0d19 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 a54cbd801d..e3ee2f003a 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 0000000000..b2fadd683b --- /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 3b001abaaf..0000000000 --- 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 80e0451e2b..0000000000 --- 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 d2c078e2d0..0000000000 --- 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 2dca134124..0000000000 --- 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 b032cada7f..0000000000 --- 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 219fb54e4f..0000000000 --- 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 HcmV?d00001 literal 71167 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 G{Qm<6Q&;W) diff --git a/src/interfaces/ecpg/src/test/test2.c b/src/interfaces/ecpg/src/test/test2.c deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/interfaces/ecpg/src/test/test2.qc b/src/interfaces/ecpg/src/test/test2.qc deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/interfaces/ecpg/test/Makefile b/src/interfaces/ecpg/test/Makefile new file mode 100644 index 0000000000..0ec008964e --- /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 similarity index 100% rename from src/interfaces/ecpg/src/test/Ptest1.c rename to 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 0000000000..9fb63fe6fa --- /dev/null +++ b/src/interfaces/ecpg/test/perftest.pgc @@ -0,0 +1,72 @@ +#include +#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 0000000000..5e94495087 --- /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); +}