From f0212ced68990b004cf10d6577eedc6bbdf67c78 Mon Sep 17 00:00:00 2001 From: Michael Meskes Date: Wed, 19 Sep 2001 14:09:32 +0000 Subject: [PATCH] - Synced preproc.y with gram.y. - Synced pgc.l with scan.l. - Synced keyword.c. - Include the remaining patches by Christof Petig . --- src/interfaces/ecpg/ChangeLog | 11 +- src/interfaces/ecpg/include/ecpgtype.h | 5 +- src/interfaces/ecpg/include/sql3types.h | 2 +- src/interfaces/ecpg/lib/Makefile | 2 +- src/interfaces/ecpg/lib/connect.c | 2 +- src/interfaces/ecpg/lib/data.c | 2 +- src/interfaces/ecpg/lib/descriptor.c | 40 +++--- src/interfaces/ecpg/lib/error.c | 2 +- src/interfaces/ecpg/lib/execute.c | 201 +++----------------------- src/interfaces/ecpg/lib/extern.h | 11 ++ src/interfaces/ecpg/lib/memory.c | 2 +- src/interfaces/ecpg/lib/misc.c | 2 +- src/interfaces/ecpg/lib/prepare.c | 2 +- src/interfaces/ecpg/lib/typename.c | 2 +- src/interfaces/ecpg/preproc/Makefile | 2 +- src/interfaces/ecpg/preproc/descriptor.c | 21 +++ src/interfaces/ecpg/preproc/ecpg.c | 2 +- src/interfaces/ecpg/preproc/ecpg_keywords.c | 2 +- src/interfaces/ecpg/preproc/extern.h | 3 +- src/interfaces/ecpg/preproc/keywords.c | 4 +- src/interfaces/ecpg/preproc/output.c | 31 ++-- src/interfaces/ecpg/preproc/pgc.l | 2 +- src/interfaces/ecpg/preproc/preproc.y | 216 +++++++++++++--------------- src/interfaces/ecpg/preproc/type.c | 10 ++ 24 files changed, 223 insertions(+), 356 deletions(-) diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 236b28b10b..f6055beb28 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -1084,10 +1084,17 @@ Wed Jun 13 14:39:12 CEST 2001 - Synced preproc.y with gram.y. - Applied bug fix by John Summerfield. - - Set ecpg version to 2.9.0. - - Set library version to 3.3.0. Son Aug 19 11:04:39 CEST 2001 - Synced preproc.y with gram.y. - Include some patches by Christof Petig . + +Wed Sep 19 15:57:49 CEST 2001 + + - Synced preproc.y with gram.y. + - Synced pgc.l with scan.l. + - Synced keyword.c. + - Include the remaining patches by Christof Petig . + - Set ecpg version to 2.9.0. + - Set library version to 3.3.0. diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h index aec2baf52e..c8410352dd 100644 --- a/src/interfaces/ecpg/include/ecpgtype.h +++ b/src/interfaces/ecpg/include/ecpgtype.h @@ -46,7 +46,8 @@ extern "C" ECPGt_EOIT, /* End of insert types. */ ECPGt_EORT, /* End of result types. */ ECPGt_NO_INDICATOR, /* no indicator */ - ECPGt_long_long, ECPGt_unsigned_long_long + ECPGt_long_long, ECPGt_unsigned_long_long, + ECPGt_descriptor /* sql descriptor, no C variable */ }; /* descriptor items */ @@ -71,7 +72,7 @@ extern "C" ECPGd_EODT /* End of descriptor types. */ }; -#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_varchar2) || (type)>=ECPGt_long_long) +#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_varchar2) || ((type)>=ECPGt_long_long && (type) <= ECPGt_unsigned_long_long)) #ifdef __cplusplus } diff --git a/src/interfaces/ecpg/include/sql3types.h b/src/interfaces/ecpg/include/sql3types.h index e7e153f34c..17fe493c11 100644 --- a/src/interfaces/ecpg/include/sql3types.h +++ b/src/interfaces/ecpg/include/sql3types.h @@ -2,7 +2,7 @@ * * Copyright (c) 2000, Christof Petig * - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/include/sql3types.h,v 1.4 2000/04/12 17:17:01 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/include/sql3types.h,v 1.5 2001/09/19 14:09:32 meskes Exp $ */ /* chapter 13.1 table 2: Codes used for SQL data types in Dynamic SQL */ diff --git a/src/interfaces/ecpg/lib/Makefile b/src/interfaces/ecpg/lib/Makefile index 7b413af49d..d69b0215e4 100644 --- a/src/interfaces/ecpg/lib/Makefile +++ b/src/interfaces/ecpg/lib/Makefile @@ -4,7 +4,7 @@ # # Copyright (c) 1994, Regents of the University of California # -# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.12 2001/05/11 01:46:33 momjian Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.13 2001/09/19 14:09:32 meskes Exp $ # #------------------------------------------------------------------------- diff --git a/src/interfaces/ecpg/lib/connect.c b/src/interfaces/ecpg/lib/connect.c index e70299dc5f..9da651a020 100644 --- a/src/interfaces/ecpg/lib/connect.c +++ b/src/interfaces/ecpg/lib/connect.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.11 2001/08/24 14:07:49 petere Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.12 2001/09/19 14:09:32 meskes Exp $ */ #include "postgres_fe.h" diff --git a/src/interfaces/ecpg/lib/data.c b/src/interfaces/ecpg/lib/data.c index 1f6a86f16c..8bed8f711e 100644 --- a/src/interfaces/ecpg/lib/data.c +++ b/src/interfaces/ecpg/lib/data.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.14 2001/08/24 14:07:49 petere Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.15 2001/09/19 14:09:32 meskes Exp $ */ #include "postgres_fe.h" diff --git a/src/interfaces/ecpg/lib/descriptor.c b/src/interfaces/ecpg/lib/descriptor.c index 1312b22e47..ba11f5af5e 100644 --- a/src/interfaces/ecpg/lib/descriptor.c +++ b/src/interfaces/ecpg/lib/descriptor.c @@ -1,4 +1,7 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/descriptor.c,v 1.15 2001/08/24 14:07:49 petere Exp $ */ +/* dynamic SQL support routines + * + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/descriptor.c,v 1.16 2001/09/19 14:09:32 meskes Exp $ + */ #include "postgres_fe.h" @@ -8,27 +11,15 @@ #include "extern.h" #include "sql3types.h" -struct descriptor -{ - char *name; - PGresult *result; - struct descriptor *next; -} *all_descriptors = NULL; +struct descriptor *all_descriptors = NULL; +/* old internal convenience function that might go away later */ static PGresult * ECPGresultByDescriptor(int line, const char *name) { - struct descriptor *i; - - for (i = all_descriptors; i != NULL; i = i->next) - { - if (!strcmp(name, i->name)) - return i->result; - } - - ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name); - + PGresult **resultpp = ECPGdescriptor_lvalue ( line, name ); + if (resultpp) return *resultpp; return NULL; } @@ -373,3 +364,18 @@ ECPGallocate_desc(int line, const char *name) all_descriptors = new; return true; } + +PGresult ** +ECPGdescriptor_lvalue(int line, const char *descriptor) +{ + struct descriptor *i; + + for (i = all_descriptors; i != NULL; i = i->next) + { + if (!strcmp(descriptor, i->name)) + return &i->result; + } + + ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, (char *) descriptor); + return NULL; +} diff --git a/src/interfaces/ecpg/lib/error.c b/src/interfaces/ecpg/lib/error.c index c16fb8395a..8ea4d5775e 100644 --- a/src/interfaces/ecpg/lib/error.c +++ b/src/interfaces/ecpg/lib/error.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.9 2001/08/24 14:07:49 petere Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.10 2001/09/19 14:09:32 meskes Exp $ */ #include "postgres_fe.h" diff --git a/src/interfaces/ecpg/lib/execute.c b/src/interfaces/ecpg/lib/execute.c index 3238fd59bb..30d6645c51 100644 --- a/src/interfaces/ecpg/lib/execute.c +++ b/src/interfaces/ecpg/lib/execute.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.22 2001/08/24 14:07:49 petere Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.23 2001/09/19 14:09:32 meskes Exp $ */ /* * The aim is to get a simpler inteface to the database routines. @@ -817,6 +817,7 @@ ECPGexecute(struct statement * stmt) * it should go into a separate function */ { + bool clear_result = TRUE; var = stmt->outlist; switch (PQresultStatus(results)) { @@ -840,7 +841,19 @@ ECPGexecute(struct statement * stmt) break; } - for (act_field = 0; act_field < nfields && status; act_field++) + if (var != NULL && var->type==ECPGt_descriptor) + { PGresult **resultpp = ECPGdescriptor_lvalue(stmt->lineno, (const char*)var->pointer); + if (resultpp == NULL) status = false; + else + { if (*resultpp) + PQclear(*resultpp); + *resultpp=results; + clear_result = FALSE; + ECPGlog("ECPGexecute putting result into descriptor '%s'\n", (const char*)var->pointer); + } + var = var->next; + } + else for (act_field = 0; act_field < nfields && status; act_field++) { if (var == NULL) { @@ -972,7 +985,7 @@ ECPGexecute(struct statement * stmt) status = false; break; } - PQclear(results); + if (clear_result) PQclear(results); } /* check for asynchronous returns */ @@ -1032,186 +1045,12 @@ ECPGdo(int lineno, const char *connection_name, char *query,...) return (status); } -/* dynamic SQL support routines - * - * Copyright (c) 2000, Christof Petig - * - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.22 2001/08/24 14:07:49 petere Exp $ - */ - -PGconn *ECPG_internal_get_connection(char *name); - -extern struct descriptor -{ - char *name; - PGresult *result; - struct descriptor *next; -} *all_descriptors; - -/* like ECPGexecute */ -static bool -execute_descriptor(int lineno, const char *query - ,struct connection * con, PGresult **resultptr) -{ - bool status = false; - PGresult *results; - PGnotify *notify; - - /* Now the request is built. */ - - if (con->committed && !con->autocommit) - { - if ((results = PQexec(con->connection, "begin transaction")) == NULL) - { - ECPGraise(lineno, ECPG_TRANS, NULL); - return false; - } - PQclear(results); - con->committed = false; - } - - ECPGlog("execute_descriptor line %d: QUERY: %s on connection %s\n", lineno, query, con->name); - results = PQexec(con->connection, query); - - if (results == NULL) - { - ECPGlog("ECPGexecute line %d: error: %s", lineno, - PQerrorMessage(con->connection)); - ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection)); - } - else - { - *resultptr = results; - switch (PQresultStatus(results)) - { - int ntuples; - - case PGRES_TUPLES_OK: - status = true; - sqlca.sqlerrd[2] = ntuples = PQntuples(results); - if (ntuples < 1) - { - ECPGlog("execute_descriptor line %d: Incorrect number of matches: %d\n", - lineno, ntuples); - ECPGraise(lineno, ECPG_NOT_FOUND, NULL); - status = false; - break; - } - break; -#if 1 /* strictly these are not needed (yet) */ - case PGRES_EMPTY_QUERY: - /* do nothing */ - ECPGraise(lineno, ECPG_EMPTY, NULL); - break; - case PGRES_COMMAND_OK: - status = true; - sqlca.sqlerrd[1] = PQoidValue(results); - sqlca.sqlerrd[2] = atol(PQcmdTuples(results)); - ECPGlog("ECPGexecute line %d Ok: %s\n", lineno, PQcmdStatus(results)); - break; - case PGRES_COPY_OUT: - ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno); - PQendcopy(con->connection); - break; - case PGRES_COPY_IN: - ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", lineno); - PQendcopy(con->connection); - break; -#else - case PGRES_EMPTY_QUERY: - case PGRES_COMMAND_OK: - case PGRES_COPY_OUT: - case PGRES_COPY_IN: - break; -#endif - case PGRES_NONFATAL_ERROR: - case PGRES_FATAL_ERROR: - case PGRES_BAD_RESPONSE: - ECPGlog("ECPGexecute line %d: Error: %s", - lineno, PQerrorMessage(con->connection)); - ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection)); - status = false; - break; - default: - ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n", - lineno); - ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection)); - status = false; - break; - } - } - - /* check for asynchronous returns */ - notify = PQnotifies(con->connection); - if (notify) - { - ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n", - lineno, notify->relname, notify->be_pid); - free(notify); - } - return status; -} - -/* like ECPGdo */ -static bool -do_descriptor2(int lineno, const char *connection_name, - PGresult **resultptr, const char *query) -{ - struct connection *con = get_connection(connection_name); - bool status = true; - char *locale = setlocale(LC_NUMERIC, NULL); - - /* Make sure we do NOT honor the locale for numeric input/output */ - /* since the database wants teh standard decimal point */ - setlocale(LC_NUMERIC, "C"); - - if (!ecpg_init(con, connection_name, lineno)) - { - setlocale(LC_NUMERIC, locale); - return (false); - } - - /* are we connected? */ - if (con == NULL || con->connection == NULL) - { - ECPGlog("do_descriptor2: not connected to %s\n", con->name); - ECPGraise(lineno, ECPG_NOT_CONN, NULL); - setlocale(LC_NUMERIC, locale); - return false; - } - - status = execute_descriptor(lineno, query, con, resultptr); - - /* and reset locale value so our application is not affected */ - setlocale(LC_NUMERIC, locale); - return (status); -} - +/* old descriptor interface */ bool ECPGdo_descriptor(int line, const char *connection, const char *descriptor, const char *query) { - struct descriptor *i; - - for (i = all_descriptors; i != NULL; i = i->next) - { - if (!strcmp(descriptor, i->name)) - { - bool status; - - /* free previous result */ - if (i->result) - PQclear(i->result); - i->result = NULL; - - status = do_descriptor2(line, connection, &i->result, query); - - if (!i->result) - PQmakeEmptyPGresult(NULL, 0); - return (status); - } - } - - ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, (char *) descriptor); - return false; + return ECPGdo(line, connection, (char *)query, ECPGt_EOIT, + ECPGt_descriptor, descriptor, 0L, 0L, 0L, + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); } diff --git a/src/interfaces/ecpg/lib/extern.h b/src/interfaces/ecpg/lib/extern.h index b9318d05c9..3186b5b110 100644 --- a/src/interfaces/ecpg/lib/extern.h +++ b/src/interfaces/ecpg/lib/extern.h @@ -52,3 +52,14 @@ struct connection struct ECPGtype_information_cache *cache_head; struct connection *next; }; + +/* structure to store descriptors */ +struct descriptor +{ + char *name; + PGresult *result; + struct descriptor *next; +}; + +PGresult ** +ECPGdescriptor_lvalue(int line, const char *descriptor); diff --git a/src/interfaces/ecpg/lib/memory.c b/src/interfaces/ecpg/lib/memory.c index d7ff879963..c971e61192 100644 --- a/src/interfaces/ecpg/lib/memory.c +++ b/src/interfaces/ecpg/lib/memory.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/memory.c,v 1.4 2001/08/24 14:07:49 petere Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/memory.c,v 1.5 2001/09/19 14:09:32 meskes Exp $ */ #include "postgres_fe.h" diff --git a/src/interfaces/ecpg/lib/misc.c b/src/interfaces/ecpg/lib/misc.c index 4a93be4b90..bb6d4b423b 100644 --- a/src/interfaces/ecpg/lib/misc.c +++ b/src/interfaces/ecpg/lib/misc.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/misc.c,v 1.4 2001/08/24 14:07:49 petere Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/misc.c,v 1.5 2001/09/19 14:09:32 meskes Exp $ */ #include "postgres_fe.h" diff --git a/src/interfaces/ecpg/lib/prepare.c b/src/interfaces/ecpg/lib/prepare.c index f1c164c7f4..92a03a9670 100644 --- a/src/interfaces/ecpg/lib/prepare.c +++ b/src/interfaces/ecpg/lib/prepare.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/prepare.c,v 1.6 2001/08/24 14:07:49 petere Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/prepare.c,v 1.7 2001/09/19 14:09:32 meskes Exp $ */ #include "postgres_fe.h" diff --git a/src/interfaces/ecpg/lib/typename.c b/src/interfaces/ecpg/lib/typename.c index d41ca58390..345a5f36f1 100644 --- a/src/interfaces/ecpg/lib/typename.c +++ b/src/interfaces/ecpg/lib/typename.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/typename.c,v 1.18 2001/08/24 14:07:49 petere Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/typename.c,v 1.19 2001/09/19 14:09:32 meskes Exp $ */ #include "postgres_fe.h" diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile index e869987a2d..7841a8d501 100644 --- a/src/interfaces/ecpg/preproc/Makefile +++ b/src/interfaces/ecpg/preproc/Makefile @@ -1,4 +1,4 @@ -# $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.76 2001/05/12 19:49:48 petere Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.77 2001/09/19 14:09:32 meskes Exp $ subdir = src/interfaces/ecpg/preproc top_builddir = ../../../.. diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c index 405f97a60f..6542888dd7 100644 --- a/src/interfaces/ecpg/preproc/descriptor.c +++ b/src/interfaces/ecpg/preproc/descriptor.c @@ -196,3 +196,24 @@ output_get_descr(char *desc_name, char *index) whenever_action(2 | 1); } + +/* I consider dynamic allocation overkill since at most two descriptor + variables are possible per statement. (input and output descriptor) + And descriptors are no normal variables, so they don't belong into + the variable list. +*/ + +#define MAX_DESCRIPTOR_NAMELEN 128 +struct variable *descriptor_variable(const char *name,int input) +{ static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN]; + static const struct ECPGtype descriptor_type = + { ECPGt_descriptor, 0 }; + static const struct variable varspace[2] = + {{ descriptor_names[0], (struct ECPGtype*)&descriptor_type, 0, NULL }, + { descriptor_names[1], (struct ECPGtype*)&descriptor_type, 0, NULL } + }; + + strncpy(descriptor_names[input],name,MAX_DESCRIPTOR_NAMELEN); + descriptor_names[input][MAX_DESCRIPTOR_NAMELEN-1]=0; + return (struct variable*)&varspace[input]; +} diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c index 2cdcaa999e..4897f77393 100644 --- a/src/interfaces/ecpg/preproc/ecpg.c +++ b/src/interfaces/ecpg/preproc/ecpg.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.48 2001/08/28 02:47:18 tgl Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.49 2001/09/19 14:09:32 meskes Exp $ */ /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */ /* (C) Michael Meskes Feb 5th, 1998 */ diff --git a/src/interfaces/ecpg/preproc/ecpg_keywords.c b/src/interfaces/ecpg/preproc/ecpg_keywords.c index 5967c338fa..9ddd1e2e4e 100644 --- a/src/interfaces/ecpg/preproc/ecpg_keywords.c +++ b/src/interfaces/ecpg/preproc/ecpg_keywords.c @@ -4,7 +4,7 @@ * lexical token lookup for reserved words in postgres embedded SQL * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.24 2001/08/19 09:21:44 meskes Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.25 2001/09/19 14:09:32 meskes Exp $ * *------------------------------------------------------------------------- */ diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h index 43cfd086c5..b393fd3ad7 100644 --- a/src/interfaces/ecpg/preproc/extern.h +++ b/src/interfaces/ecpg/preproc/extern.h @@ -48,7 +48,7 @@ extern const char *get_dtype(enum ECPGdtype); extern void lex_init(void); extern char *make_str(const char *); extern void output_line_number(void); -extern void output_statement(char *, int, char *, char *); +extern void output_statement(char *, int, char *); extern void output_simple_statement(char *); extern char *hashline_number(void); extern int yyparse(void); @@ -67,6 +67,7 @@ extern void whenever_action(int); extern void add_descriptor(char *, char *); extern void drop_descriptor(char *, char *); extern struct descriptor *lookup_descriptor(char *, char *); +extern struct variable *descriptor_variable(const char *name,int input); extern void add_variable(struct arguments **, struct variable *, struct variable *); extern void append_variable(struct arguments **, struct variable *, struct variable *); extern void dump_variables(struct arguments *, int); diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c index 0a5ba188de..2c6f29165d 100644 --- a/src/interfaces/ecpg/preproc/keywords.c +++ b/src/interfaces/ecpg/preproc/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.43 2001/08/16 20:38:55 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.44 2001/09/19 14:09:32 meskes Exp $ * *------------------------------------------------------------------------- */ @@ -102,6 +102,7 @@ static ScanKeyword ScanKeywords[] = { {"each", EACH}, {"else", ELSE}, {"encoding", ENCODING}, + {"encrypted", ENCRYPTED}, {"end", END_TRANS}, {"escape", ESCAPE}, {"except", EXCEPT}, @@ -261,6 +262,7 @@ static ScanKeyword ScanKeywords[] = { {"truncate", TRUNCATE}, {"trusted", TRUSTED}, {"type", TYPE_P}, + {"unencrypted", UNENCRYPTED}, {"union", UNION}, {"unique", UNIQUE}, {"unknown", UNKNOWN}, diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c index 3146901171..690ed861a3 100644 --- a/src/interfaces/ecpg/preproc/output.c +++ b/src/interfaces/ecpg/preproc/output.c @@ -103,16 +103,12 @@ hashline_number(void) } void -output_statement(char *stmt, int mode, char *descriptor, char *con) +output_statement(char *stmt, int mode, char *con) { int i, j = strlen(stmt); - if (descriptor == NULL) - fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"", con ? con : "NULL"); - else - fprintf(yyout, "{ ECPGdo_descriptor(__LINE__, %s, %s, \"", - con ? con : "NULL", descriptor); + fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"", con ? con : "NULL"); /* do this char by char as we have to filter '\"' */ for (i = 0; i < j; i++) @@ -123,25 +119,18 @@ output_statement(char *stmt, int mode, char *descriptor, char *con) fputs("\\\"", yyout); } - if (descriptor == NULL) - { - fputs("\", ", yyout); - - /* dump variables to C file */ - dump_variables(argsinsert, 1); - fputs("ECPGt_EOIT, ", yyout); - dump_variables(argsresult, 1); - fputs("ECPGt_EORT);", yyout); - reset_variables(); - } - else - fputs("\");", yyout); + fputs("\", ", yyout); + + /* dump variables to C file */ + dump_variables(argsinsert, 1); + fputs("ECPGt_EOIT, ", yyout); + dump_variables(argsresult, 1); + fputs("ECPGt_EORT);", yyout); + reset_variables(); mode |= 2; whenever_action(mode); free(stmt); - if (descriptor != NULL) - free(descriptor); if (connection != NULL) free(connection); } diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index d6d99adcee..7b5a2eb392 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -12,7 +12,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.80 2001/09/07 23:17:14 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.81 2001/09/19 14:09:32 meskes Exp $ * *------------------------------------------------------------------------- */ diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 454c29711c..b4939adabf 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -217,8 +217,8 @@ make_name(void) %token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYSE, ANALYZE, BACKWARD, BEFORE, BINARY, BIT, CACHE, CHECKPOINT, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, DATABASE, - DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND, - FORCE, FORWARD, FUNCTION, HANDLER, INCREMENT, + DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN, + FORCE, FORWARD, FREEZE, FUNCTION, HANDLER, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL, LANCOMPILER, LIMIT, LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE, MINVALUE, MODE, MOVE, NEW, NOCREATEDB, NOCREATEUSER, @@ -303,7 +303,7 @@ make_name(void) %type copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary %type opt_with_copy FetchStmt direction fetch_how_many from_in %type ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose -%type opt_full func_arg OptWithOids +%type opt_full func_arg OptWithOids opt_freeze opt_ecpg_into %type analyze_keyword opt_name_list ExplainStmt index_params %type index_list func_index index_elem opt_class access_method_clause %type index_opt_unique IndexStmt func_return ConstInterval @@ -342,7 +342,7 @@ make_name(void) %type select_limit opt_for_update_clause CheckPointStmt %type ECPGWhenever ECPGConnect connection_target ECPGOpen -%type indicator ECPGExecute ECPGPrepare ecpg_using +%type indicator ECPGExecute ECPGPrepare ecpg_using ecpg_into %type storage_clause opt_initializer c_anything blockstart %type blockend variable_list variable c_thing c_term %type opt_pointer ECPGDisconnect dis_name storage_modifier @@ -360,7 +360,7 @@ make_name(void) %type ECPGGetDescriptorHeader ECPGColLabel ECPGTypeName %type ECPGLabelTypeName ECPGColId variablelist cvariable -%type ECPGFetchDescStmt ECPGGetDescriptor +%type ECPGGetDescriptor %type simple_type signed_type unsigned_type varchar_type @@ -392,68 +392,68 @@ statement: ecpgstart opt_at stmt ';' { connection = NULL; } opt_at: AT connection_target { connection = $2; }; -stmt: AlterSchemaStmt { output_statement($1, 0, NULL, connection); } - | AlterTableStmt { output_statement($1, 0, NULL, connection); } - | AlterGroupStmt { output_statement($1, 0, NULL, connection); } - | AlterUserStmt { output_statement($1, 0, NULL, connection); } - | ClosePortalStmt { output_statement($1, 0, NULL, connection); } - | CommentStmt { output_statement($1, 0, NULL, connection); } - | CopyStmt { output_statement($1, 0, NULL, connection); } - | CreateStmt { output_statement($1, 0, NULL, connection); } - | CreateAsStmt { output_statement($1, 0, NULL, connection); } - | CreateSchemaStmt { output_statement($1, 0, NULL, connection); } - | CreateGroupStmt { output_statement($1, 0, NULL, connection); } - | CreateSeqStmt { output_statement($1, 0, NULL, connection); } - | CreatePLangStmt { output_statement($1, 0, NULL, connection); } - | CreateTrigStmt { output_statement($1, 0, NULL, connection); } - | CreateUserStmt { output_statement($1, 0, NULL, connection); } - | ClusterStmt { output_statement($1, 0, NULL, connection); } - | DefineStmt { output_statement($1, 0, NULL, connection); } - | DropStmt { output_statement($1, 0, NULL, connection); } - | DropSchemaStmt { output_statement($1, 0, NULL, connection); } - | TruncateStmt { output_statement($1, 0, NULL, connection); } - | DropGroupStmt { output_statement($1, 0, NULL, connection); } - | DropPLangStmt { output_statement($1, 0, NULL, connection); } - | DropTrigStmt { output_statement($1, 0, NULL, connection); } - | DropUserStmt { output_statement($1, 0, NULL, connection); } - | ExplainStmt { output_statement($1, 0, NULL, connection); } - | FetchStmt { output_statement($1, 1, NULL, connection); } - | GrantStmt { output_statement($1, 0, NULL, connection); } - | IndexStmt { output_statement($1, 0, NULL, connection); } - | ListenStmt { output_statement($1, 0, NULL, connection); } - | UnlistenStmt { output_statement($1, 0, NULL, connection); } - | LockStmt { output_statement($1, 0, NULL, connection); } - | NotifyStmt { output_statement($1, 0, NULL, connection); } - | ProcedureStmt { output_statement($1, 0, NULL, connection); } - | ReindexStmt { output_statement($1, 0, NULL, connection); } - | RemoveAggrStmt { output_statement($1, 0, NULL, connection); } - | RemoveOperStmt { output_statement($1, 0, NULL, connection); } - | RemoveFuncStmt { output_statement($1, 0, NULL, connection); } - | RenameStmt { output_statement($1, 0, NULL, connection); } - | RevokeStmt { output_statement($1, 0, NULL, connection); } +stmt: AlterSchemaStmt { output_statement($1, 0, connection); } + | AlterTableStmt { output_statement($1, 0, connection); } + | AlterGroupStmt { output_statement($1, 0, connection); } + | AlterUserStmt { output_statement($1, 0, connection); } + | ClosePortalStmt { output_statement($1, 0, connection); } + | CommentStmt { output_statement($1, 0, connection); } + | CopyStmt { output_statement($1, 0, connection); } + | CreateStmt { output_statement($1, 0, connection); } + | CreateAsStmt { output_statement($1, 0, connection); } + | CreateSchemaStmt { output_statement($1, 0, connection); } + | CreateGroupStmt { output_statement($1, 0, connection); } + | CreateSeqStmt { output_statement($1, 0, connection); } + | CreatePLangStmt { output_statement($1, 0, connection); } + | CreateTrigStmt { output_statement($1, 0, connection); } + | CreateUserStmt { output_statement($1, 0, connection); } + | ClusterStmt { output_statement($1, 0, connection); } + | DefineStmt { output_statement($1, 0, connection); } + | DropStmt { output_statement($1, 0, connection); } + | DropSchemaStmt { output_statement($1, 0, connection); } + | TruncateStmt { output_statement($1, 0, connection); } + | DropGroupStmt { output_statement($1, 0, connection); } + | DropPLangStmt { output_statement($1, 0, connection); } + | DropTrigStmt { output_statement($1, 0, connection); } + | DropUserStmt { output_statement($1, 0, connection); } + | ExplainStmt { output_statement($1, 0, connection); } + | FetchStmt { output_statement($1, 1, connection); } + | GrantStmt { output_statement($1, 0, connection); } + | IndexStmt { output_statement($1, 0, connection); } + | ListenStmt { output_statement($1, 0, connection); } + | UnlistenStmt { output_statement($1, 0, connection); } + | LockStmt { output_statement($1, 0, connection); } + | NotifyStmt { output_statement($1, 0, connection); } + | ProcedureStmt { output_statement($1, 0, connection); } + | ReindexStmt { output_statement($1, 0, connection); } + | RemoveAggrStmt { output_statement($1, 0, connection); } + | RemoveOperStmt { output_statement($1, 0, connection); } + | RemoveFuncStmt { output_statement($1, 0, connection); } + | RenameStmt { output_statement($1, 0, connection); } + | RevokeStmt { output_statement($1, 0, connection); } | OptimizableStmt { if (strncmp($1, "/* " , sizeof("/* ")-1) == 0) output_simple_statement($1); else - output_statement($1, 1, NULL, connection); + output_statement($1, 1, connection); } - | RuleStmt { output_statement($1, 0, NULL, connection); } + | RuleStmt { output_statement($1, 0, connection); } | TransactionStmt { fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1); whenever_action(2); free($1); } - | ViewStmt { output_statement($1, 0, NULL, connection); } - | LoadStmt { output_statement($1, 0, NULL, connection); } - | CreatedbStmt { output_statement($1, 0, NULL, connection); } - | DropdbStmt { output_statement($1, 0, NULL, connection); } - | VacuumStmt { output_statement($1, 0, NULL, connection); } - | AnalyzeStmt { output_statement($1, 0, NULL, connection); } - | VariableSetStmt { output_statement($1, 0, NULL, connection); } - | VariableShowStmt { output_statement($1, 0, NULL, connection); } - | VariableResetStmt { output_statement($1, 0, NULL, connection); } - | ConstraintsSetStmt { output_statement($1, 0, NULL, connection); } - | CheckPointStmt { output_statement($1, 0, NULL, connection); } + | ViewStmt { output_statement($1, 0, connection); } + | LoadStmt { output_statement($1, 0, connection); } + | CreatedbStmt { output_statement($1, 0, connection); } + | DropdbStmt { output_statement($1, 0, connection); } + | VacuumStmt { output_statement($1, 0, connection); } + | AnalyzeStmt { output_statement($1, 0, connection); } + | VariableSetStmt { output_statement($1, 0, connection); } + | VariableShowStmt { output_statement($1, 0, connection); } + | VariableResetStmt { output_statement($1, 0, connection); } + | ConstraintsSetStmt { output_statement($1, 0, connection); } + | CheckPointStmt { output_statement($1, 0, connection); } | ECPGAllocateDescr { fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1); whenever_action(0); free($1); @@ -496,8 +496,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, NULL, connection); } whenever_action(2); free($1); } - | ECPGExecute { output_statement($1, 0, NULL, connection); } - | ECPGFetchDescStmt { output_statement($1.str, 1, $1.name, connection); } + | ECPGExecute { output_statement($1, 0, connection); } | ECPGFree { fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1); @@ -538,7 +537,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, NULL, connection); } for (p = ptr->argsresult; p; p = p->next) add_variable(&argsresult, p->variable, p->indicator); - output_statement(mm_strdup(ptr->command), 0, NULL, ptr->connection ? mm_strdup(ptr->connection) : NULL); + output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL); } | ECPGPrepare { if (connection) @@ -1566,26 +1565,26 @@ TruncateStmt: TRUNCATE opt_table relation_name * *****************************************************************************/ -FetchStmt: FETCH direction fetch_how_many from_in name INTO into_list +FetchStmt: FETCH direction fetch_how_many from_in name ecpg_into { if (strcmp($2, "relative") == 0 && atol($3) == 0L) mmerror(ET_ERROR, "FETCH/RELATIVE at current position is not supported"); $$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5); } - | FETCH fetch_how_many from_in name INTO into_list + | FETCH fetch_how_many from_in name ecpg_into { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); } - | FETCH direction from_in name INTO into_list + | FETCH direction from_in name ecpg_into { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); } - | FETCH from_in name INTO into_list + | FETCH from_in name ecpg_into { $$ = cat_str(3, make_str("fetch"), $2, $3); } - | FETCH name INTO into_list + | FETCH name ecpg_into { $$ = cat2_str(make_str("fetch"), $2); } @@ -1804,15 +1803,14 @@ RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee_list * QUERY: * create index on * [ using ] "(" ( with )+ ")" - * [ with ] * [ where ] * *****************************************************************************/ IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name - access_method_clause '(' index_params ')' opt_with where_clause + access_method_clause '(' index_params ')' where_clause { - $$ = cat_str(12, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11, $12); + $$ = cat_str(11, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11); } ; @@ -2279,17 +2277,17 @@ ClusterStmt: CLUSTER index_name ON relation_name * *****************************************************************************/ -VacuumStmt: VACUUM opt_full opt_verbose +VacuumStmt: VACUUM opt_full opt_freeze opt_verbose { - $$ = cat_str(3, make_str("vacuum"), $2, $3); + $$ = cat_str(4, make_str("vacuum"), $2, $3, $4); } - | VACUUM opt_full opt_verbose relation_name + | VACUUM opt_full opt_freeze opt_verbose relation_name { - $$ = cat_str(4, make_str("vacuum"), $2, $3, $4); + $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); } - | VACUUM opt_full opt_verbose AnalyzeStmt + | VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt { - $$ = cat_str(4, make_str("vacuum"), $2, $3, $4); + $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); } ; @@ -2315,6 +2313,10 @@ opt_full: FULL { $$ = make_str("full"); } | /*EMPTY*/ { $$ = EMPTY; } ; +opt_freeze: FREEZE { $$ = make_str("freeze"); } + | /*EMPTY*/ { $$ = EMPTY; } + ; + opt_name_list: '(' name_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); } | /*EMPTY*/ { $$ = EMPTY; } ; @@ -2580,8 +2582,8 @@ into_clause: INTO OptTempTableName { FoundInto = 1; $$= cat2_str(make_str("into"), $2); } - | INTO into_list { $$ = EMPTY; } - | /*EMPTY*/ { $$ = EMPTY; } + | ecpg_into { $$ = EMPTY; } + | /*EMPTY*/ { $$ = EMPTY; } ; /* @@ -4494,7 +4496,7 @@ ECPGExecute : EXECUTE IMMEDIATE execstring sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2); add_variable(&argsinsert, thisquery, &no_indicator); - } ecpg_using + } ecpg_using opt_ecpg_into { $$ = make_str("?"); } @@ -4522,6 +4524,22 @@ ecpg_using: /* empty */ { $$ = EMPTY; } } ; +opt_sql: /* empty */ | SQL_SQL; + +ecpg_into: INTO into_list { + $$ = EMPTY; + } + | INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar + { + add_variable(&argsresult, descriptor_variable($4,0), &no_indicator); + $$ = EMPTY; + } + ; + +opt_ecpg_into: /* empty */ { $$ = EMPTY; } + | ecpg_into { $$ = $1; } + ; + variable: civarind | civar variablelist: variable | variable ',' variablelist; @@ -4601,45 +4619,6 @@ ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE cvari { $$.str = $5; $$.name = $3; } ; -/***************************************************************************** - * - * QUERY: - * fetch [forward | backward] [ # | all ] [ in ] - * fetch [ forward | backward | absolute | relative ] - * [ # | all | next | prior ] [ [ in | from ] ] - * - * Have to seperate the descriptor version since we have to - * call a different output function - * - *****************************************************************************/ - -ECPGFetchDescStmt: FETCH direction fetch_how_many from_in name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar - { - $$.str = cat_str(5, make_str("fetch"), $2, $3, $4, $5); - $$.name=$9; - } - | FETCH fetch_how_many from_in name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar - { - $$.str = cat_str(4, make_str("fetch"), $2, $3, $4); - $$.name=$8; - } - | FETCH direction from_in name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar - { - $$.str = cat_str(4, make_str("fetch"), $2, $3, $4); - $$.name=$8; - } - | FETCH from_in name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar - { - $$.str = cat_str(3, make_str("fetch"), $2, $3); - $$.name=$7; - } - | FETCH name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar - { - $$.str = cat2_str(make_str("fetch"), $2); - $$.name=$6; - } - ; - /* * for compatibility with ORACLE we will also allow the keyword RELEASE * after a transaction statement to disconnect from the database. @@ -5010,6 +4989,7 @@ TokenId: ABSOLUTE { $$ = make_str("absolute"); } | DROP { $$ = make_str("drop"); } | EACH { $$ = make_str("each"); } | ENCODING { $$ = make_str("encoding"); } + | ENCRYPTED { $$ = make_str("encrypted"); } | ESCAPE { $$ = make_str("escape"); } | EXCLUSIVE { $$ = make_str("exclusive"); } | EXECUTE { $$ = make_str("execute"); } @@ -5087,6 +5067,7 @@ TokenId: ABSOLUTE { $$ = make_str("absolute"); } | TRIGGER { $$ = make_str("trigger"); } | TRUNCATE { $$ = make_str("truncate"); } | TRUSTED { $$ = make_str("trusted"); } + | UNENCRYPTED { $$ = make_str("unencrypted"); } | UNLISTEN { $$ = make_str("unlisten"); } | UNTIL { $$ = make_str("until"); } | UPDATE { $$ = make_str("update"); } @@ -5148,7 +5129,6 @@ ECPGColLabel: ECPGColId { $$ = $1; } | DISTINCT { $$ = make_str("distinct"); } | DO { $$ = make_str("do"); } | ELSE { $$ = make_str("else"); } - | ENCRYPTED { $$ = make_str("encrypted"); } | END_TRANS { $$ = make_str("end"); } | EXCEPT { $$ = make_str("except"); } | EXISTS { $$ = make_str("exists"); } @@ -5157,6 +5137,7 @@ ECPGColLabel: ECPGColId { $$ = $1; } | FALSE_P { $$ = make_str("false"); } | FOR { $$ = make_str("for"); } | FOREIGN { $$ = make_str("foreign"); } + | FREEZE { $$ = make_str("freeze"); } | FROM { $$ = make_str("from"); } | FULL { $$ = make_str("full"); } | IN { $$ = make_str("in"); } @@ -5216,7 +5197,6 @@ ECPGColLabel: ECPGColId { $$ = $1; } | TRANSACTION { $$ = make_str("transaction"); } | TRIM { $$ = make_str("trim"); } | TRUE_P { $$ = make_str("true"); } - | UNENCRYPTED { $$ = make_str("unencrypted"); } | UNIQUE { $$ = make_str("unique"); } | UNKNOWN { $$ = make_str("unknown"); } | USER { $$ = make_str("user"); } diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c index 5201badbc2..be688ab63e 100644 --- a/src/interfaces/ecpg/preproc/type.c +++ b/src/interfaces/ecpg/preproc/type.c @@ -169,6 +169,9 @@ get_type(enum ECPGttype typ) * quoted */ return ("ECPGt_char_variable"); break; + case ECPGt_descriptor: + return ("ECPGt_descriptor"); + break; default: sprintf(errortext, "illegal variable type %d\n", typ); yyerror(errortext); @@ -252,6 +255,10 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in ECPGdump_a_simple(o, name, typ->typ, 1, 1, NULL, prefix); ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); break; + case ECPGt_descriptor: + ECPGdump_a_simple(o, name, typ->typ, 0, -1, NULL, prefix); + ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); + break; default: ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix); if (ind_typ != NULL) @@ -273,6 +280,9 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ, { if (typ == ECPGt_NO_INDICATOR) fprintf(o, "\n\tECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, "); + else if (typ == ECPGt_descriptor) + /* remember that name here already contains quotes (if needed) */ + fprintf(o, "\n\tECPGt_descriptor, %s, 0L, 0L, 0L, ", name); else { char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4); -- 2.11.0