From ab0c8c691e6f377f59d439076701ec7d3943748e Mon Sep 17 00:00:00 2001 From: Michael Meskes Date: Fri, 18 Feb 2000 14:34:12 +0000 Subject: [PATCH] *** empty log message *** --- src/interfaces/ecpg/ChangeLog | 5 + src/interfaces/ecpg/TODO | 2 + src/interfaces/ecpg/include/ecpglib.h | 16 +- src/interfaces/ecpg/lib/descriptor.c | 15 ++ src/interfaces/ecpg/lib/dynamic.c | 22 +- src/interfaces/ecpg/preproc/Makefile | 2 +- src/interfaces/ecpg/preproc/descriptor.c | 211 ++++++++----------- src/interfaces/ecpg/preproc/extern.h | 19 +- src/interfaces/ecpg/preproc/output.c | 126 +++++++++++ src/interfaces/ecpg/preproc/preproc.y | 257 ++++++----------------- src/interfaces/ecpg/preproc/type.h | 6 + 11 files changed, 346 insertions(+), 335 deletions(-) create mode 100644 src/interfaces/ecpg/lib/descriptor.c create mode 100644 src/interfaces/ecpg/preproc/output.c diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 157f219a30..d733e9e0df 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -814,5 +814,10 @@ Wed Feb 16 17:04:41 CET 2000 - Apply patch by Christof Petig that adds descriptors. + +Thu Feb 17 19:37:44 CET 2000 + + - Synced preproc.y with gram.y. + - Started to clean up preproc.y. - Set library version to 3.1.0. - Set ecpg version to 2.7.0. diff --git a/src/interfaces/ecpg/TODO b/src/interfaces/ecpg/TODO index 8be5f3f5fb..d7546c7925 100644 --- a/src/interfaces/ecpg/TODO +++ b/src/interfaces/ecpg/TODO @@ -26,6 +26,8 @@ Add a semantic check level, e.g. check if a table really exists. It would be nice if there was a alternative library using SPI functions instead of libpq so we can write backend functions using ecpg. +make ECPGnumeric_lvalue more accurate by using something like ECPGdump_a_* + Missing statements: - exec sql ifdef - SQLSTATE diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h index f50a2bb09d..b3105e943a 100644 --- a/src/interfaces/ecpg/include/ecpglib.h +++ b/src/interfaces/ecpg/include/ecpglib.h @@ -16,8 +16,8 @@ extern "C" bool ECPGdisconnect(int, const char *); bool ECPGprepare(int, char *, char *); bool ECPGdeallocate(int, char *); - char *ECPGprepared_statement(char *); - + char *ECPGprepared_statement(char *); + void ECPGlog(const char *format,...); #ifdef LIBPQ_FE_H @@ -54,12 +54,14 @@ extern "C" unsigned int ECPGDynamicType(Oid type); unsigned int ECPGDynamicType_DDT(Oid type); - PGresult * ECPGresultByDescriptor(int line,const char *name); - bool ECPGdo_descriptor(int line,const char *connection, + PGresult * ECPGresultByDescriptor(int line,const char *name); + bool ECPGdo_descriptor(int line,const char *connection, const char *descriptor,const char *query); - bool ECPGdeallocate_desc(int line,const char *name); - bool ECPGallocate_desc(int line,const char *name); - void ECPGraise(int line,int code); + bool ECPGdeallocate_desc(int line,const char *name); + bool ECPGallocate_desc(int line,const char *name); + void ECPGraise(int line,int code); + bool ECPGget_desc_header(int, char *, int *); + #ifdef __cplusplus } diff --git a/src/interfaces/ecpg/lib/descriptor.c b/src/interfaces/ecpg/lib/descriptor.c new file mode 100644 index 0000000000..09815b2d10 --- /dev/null +++ b/src/interfaces/ecpg/lib/descriptor.c @@ -0,0 +1,15 @@ +#include +#include + +bool +ECPGget_desc_header(int lineno, char * desc_name, int *count) +{ + PGresult *ECPGresult = ECPGresultByDescriptor(lineno, desc_name); + + if (!ECPGresult) + return false; + + *count = PQnfields(ECPGresult); + ECPGlog("ECPGget-desc_header: found %d sttributes.\n", *count); + return true; +} diff --git a/src/interfaces/ecpg/lib/dynamic.c b/src/interfaces/ecpg/lib/dynamic.c index 752c02cfc0..b66883b934 100644 --- a/src/interfaces/ecpg/lib/dynamic.c +++ b/src/interfaces/ecpg/lib/dynamic.c @@ -2,7 +2,7 @@ * * Copyright (c) 2000, Christof Petig * - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/dynamic.c,v 1.2 2000/02/17 19:48:41 meskes Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/dynamic.c,v 1.3 2000/02/18 14:34:05 meskes Exp $ */ /* I borrowed the include files from ecpglib.c, maybe we don't need all of them */ @@ -211,11 +211,15 @@ bool ECPGdo_descriptor(int line,const char *connection, 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; + + for (i = all_descriptors; i != NULL; i = i->next) + { + if (!strcmp(name, i->name)) return i->result; } + ECPGraise(line,ECPG_UNKNOWN_DESCRIPTOR); - return 0; + + return NULL; } @@ -248,10 +252,12 @@ bool ECPGallocate_desc(int line,const char *name) return true; } -void ECPGraise(int line,int code) -{ sqlca.sqlcode=code; +void ECPGraise(int line, int code) +{ + sqlca.sqlcode=code; switch (code) - { case ECPG_NOT_FOUND: + { + case ECPG_NOT_FOUND: snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc), "No data found line %d.",line); break; @@ -268,7 +274,7 @@ void ECPGraise(int line,int code) "descriptor index out of range, line %d.",line); break; default: - snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc), + snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc), "SQL error #%d, line %d.",code,line); break; } diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile index 72240e2efc..3fa7307de2 100644 --- a/src/interfaces/ecpg/preproc/Makefile +++ b/src/interfaces/ecpg/preproc/Makefile @@ -9,7 +9,7 @@ CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \ -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \ -DINCLUDE_PATH=\"$(HEADERDIR)\" -g -OBJ=preproc.o pgc.o type.o ecpg.o ecpg_keywords.o \ +OBJ=preproc.o pgc.o type.o ecpg.o ecpg_keywords.o output.o\ keywords.o c_keywords.o ../lib/typename.o descriptor.o variable.o all:: ecpg diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c index c2b09fa076..247e48f234 100644 --- a/src/interfaces/ecpg/preproc/descriptor.c +++ b/src/interfaces/ecpg/preproc/descriptor.c @@ -11,33 +11,35 @@ struct assignment *assignments; -void push_assignment(char *var,char *value) +void push_assignment(char *var, char *value) { - struct assignment *new=(struct assignment *)mm_alloc(sizeof(struct assignment)); + struct assignment *new = (struct assignment *)mm_alloc(sizeof(struct assignment)); - new->next=assignments; - new->variable=mm_alloc(strlen(var)+1); + new->next = assignments; + new->variable = mm_alloc(strlen(var)+1); strcpy(new->variable,var); - new->value=mm_alloc(strlen(value)+1); + new->value = mm_alloc(strlen(value)+1); strcpy(new->value,value); - assignments=new; + assignments = new; } static void drop_assignments(void) -{ while (assignments) - { struct assignment *old_head=assignments; +{ + while (assignments) + { + struct assignment *old_head = assignments; - assignments=old_head->next; + assignments = old_head->next; free(old_head->variable); free(old_head->value); free(old_head); } } -/* XXX: these should be more accurate (consider ECPGdump_a_* ) */ static void ECPGnumeric_lvalue(FILE *f,char *name) -{ const struct variable *v=find_variable(name); +{ + const struct variable *v=find_variable(name); switch(v->type->typ) { @@ -54,10 +56,10 @@ static void ECPGnumeric_lvalue(FILE *f,char *name) ,name); mmerror(ET_ERROR,errortext); break; - } + } } -static void ECPGstring_buffer(FILE *f,char *name) +static void ECPGstring_buffer(FILE *f, char *name) { const struct variable *v=find_variable(name); @@ -167,30 +169,94 @@ static void ECPGdata_assignment(char *variable,char *index_plus_1) } } +/* + * descriptor name lookup + */ + +static struct descriptor *descriptors; + +void add_descriptor(char *name,char *connection) +{ + struct descriptor *new=(struct descriptor *)mm_alloc(sizeof(struct descriptor)); + + new->next=descriptors; + new->name=mm_alloc(strlen(name)+1); + strcpy(new->name,name); + if (connection) + { new->connection=mm_alloc(strlen(connection)+1); + strcpy(new->connection,connection); + } + else new->connection=connection; + descriptors=new; +} + +void +drop_descriptor(char *name,char *connection) +{ + struct descriptor *i; + struct descriptor **lastptr=&descriptors; + + for (i=descriptors;i;lastptr=&i->next,i=i->next) + { + if (!strcmp(name,i->name)) + { + if ((!connection && !i->connection) + || (connection && i->connection + && !strcmp(connection,i->connection))) + { + *lastptr=i->next; + if (i->connection) free(i->connection); + free(i->name); + free(i); + return; + } + } + } + snprintf(errortext,sizeof errortext,"unknown descriptor %s",name); + mmerror(ET_WARN,errortext); +} + +struct descriptor +*lookup_descriptor(char *name,char *connection) +{ + struct descriptor *i; + + for (i=descriptors;i;i=i->next) + { + if (!strcmp(name,i->name)) + { + if ((!connection && !i->connection) + || (connection && i->connection + && !strcmp(connection,i->connection))) + { + return i; + } + } + } + snprintf(errortext,sizeof errortext,"unknown descriptor %s",name); + mmerror(ET_WARN,errortext); + return NULL; +} + void output_get_descr_header(char *desc_name) { struct assignment *results; - fprintf(yyout,"{\tPGresult *ECPGresult=ECPGresultByDescriptor(%d, \"%s\");\n" ,yylineno,desc_name); - fputs("\tif (ECPGresult)\n\t{",yyout); - for (results=assignments;results!=NULL;results=results->next) + fprintf(yyout, "{ ECPGget_desc_header(%d, \"%s\", &(", yylineno, desc_name); + for (results = assignments; results != NULL; results = results->next) { - if (!strcasecmp(results->value,"count")) - { - fputs("\t\t",yyout); + if (!strcasecmp(results->value, "count")) ECPGnumeric_lvalue(yyout,results->variable); - fputs("=PQnfields(ECPGresult);\n",yyout); - } else - { snprintf(errortext,sizeof errortext,"unknown descriptor header item '%s'",results->value); - mmerror(ET_WARN,errortext); + { snprintf(errortext, sizeof errortext, "unknown descriptor header item '%s'", results->value); + mmerror(ET_WARN, errortext); } } - drop_assignments(); - fputs("}",yyout); - whenever_action(2|1); + drop_assignments(); + fprintf(yyout, "));\n"); + whenever_action(3); } void @@ -305,96 +371,3 @@ output_get_descr(char *desc_name) whenever_action(2|1); } - -/* - * descriptor name lookup - */ - -static struct descriptor *descriptors; - -void add_descriptor(char *name,char *connection) -{ - struct descriptor *new=(struct descriptor *)mm_alloc(sizeof(struct descriptor)); - - new->next=descriptors; - new->name=mm_alloc(strlen(name)+1); - strcpy(new->name,name); - if (connection) - { new->connection=mm_alloc(strlen(connection)+1); - strcpy(new->connection,connection); - } - else new->connection=connection; - descriptors=new; -} - -void drop_descriptor(char *name,char *connection) -{ - struct descriptor *i; - struct descriptor **lastptr=&descriptors; - - for (i=descriptors;i;lastptr=&i->next,i=i->next) - { - if (!strcmp(name,i->name)) - { - if ((!connection && !i->connection) - || (connection && i->connection - && !strcmp(connection,i->connection))) - { - *lastptr=i->next; - if (i->connection) free(i->connection); - free(i->name); - free(i); - return; - } - } - } - snprintf(errortext,sizeof errortext,"unknown descriptor %s",name); - mmerror(ET_WARN,errortext); -} - -struct descriptor *lookup_descriptor(char *name,char *connection) -{ - struct descriptor *i; - - for (i=descriptors;i;i=i->next) - { - if (!strcmp(name,i->name)) - { - if ((!connection && !i->connection) - || (connection && i->connection - && !strcmp(connection,i->connection))) - { - return i; - } - } - } - snprintf(errortext,sizeof errortext,"unknown descriptor %s",name); - mmerror(ET_WARN,errortext); - return NULL; -} - -void -output_statement_desc(char * stmt, int mode) -{ - int i, j=strlen(stmt); - - fprintf(yyout, "{ ECPGdo_descriptor(__LINE__, %s, \"%s\", \"", - connection ? connection : "NULL", descriptor_name); - - /* do this char by char as we have to filter '\"' */ - for (i = 0;i < j; i++) { - if (stmt[i] != '\"') - fputc(stmt[i], yyout); - else - fputs("\\\"", yyout); - } - - fputs("\");", yyout); - - mode |= 2; - whenever_action(mode); - free(stmt); - if (connection != NULL) - free(connection); - free(descriptor_name); -} diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h index cbee29e0a5..3ec8a596b1 100644 --- a/src/interfaces/ecpg/preproc/extern.h +++ b/src/interfaces/ecpg/preproc/extern.h @@ -5,6 +5,7 @@ /* defines */ #define STRUCT_DEPTH 128 +#define EMPTY make_str("") /* variables */ @@ -12,15 +13,13 @@ extern int braces_open, autocommit, ret_value, struct_level; -extern char *yytext, - errortext[128]; -extern int yylineno, - yyleng; -extern FILE *yyin, - *yyout; extern char *descriptor_index; extern char *descriptor_name; extern char *connection; +extern char *input_filename;; +extern char *yytext, errortext[128]; +extern int yylineno, yyleng; +extern FILE *yyin, *yyout; extern struct _include_path *include_paths; extern struct cursor *cur; @@ -36,9 +35,12 @@ extern struct descriptor *descriptors; /* functions */ -extern void output_line_number(void); extern void lex_init(void); -extern char *input_filename; +extern char *make_str(const char *); +extern void output_line_number(void); +extern void output_statement(char *, int, char *); +extern void output_simple_statement(char *); +extern char *hashline_number(void); extern int yyparse(void); extern int yylex(void); extern void yyerror(char *); @@ -55,7 +57,6 @@ 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 void output_statement_desc(char *, int); extern void add_variable(struct arguments ** , struct variable * , struct variable *); extern void dump_variables(struct arguments *, int); extern struct typedefs *get_typedef(char *); diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c new file mode 100644 index 0000000000..c60adf8f40 --- /dev/null +++ b/src/interfaces/ecpg/preproc/output.c @@ -0,0 +1,126 @@ +#include + +#include "postgres.h" +#include "extern.h" + +void +output_line_number() +{ + if (input_filename) + fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename); +} + +void +output_simple_statement(char *cmd) +{ + fputs(cmd, yyout); + output_line_number(); + free(cmd); +} + +/* + * store the whenever action here + */ +struct when when_error, when_nf, when_warn; + +static void +print_action(struct when *w) +{ + switch (w->code) + { + case W_SQLPRINT: fprintf(yyout, "sqlprint();"); + break; + case W_GOTO: fprintf(yyout, "goto %s;", w->command); + break; + case W_DO: fprintf(yyout, "%s;", w->command); + break; + case W_STOP: fprintf(yyout, "exit (1);"); + break; + case W_BREAK: fprintf(yyout, "break;"); + break; + default: fprintf(yyout, "{/* %d not implemented yet */}", w->code); + break; + } +} + +void +whenever_action(int mode) +{ + if ((mode&1) == 1 && when_nf.code != W_NOTHING) + { + output_line_number(); + fprintf(yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) "); + print_action(&when_nf); + } + if (when_warn.code != W_NOTHING) + { + output_line_number(); + fprintf(yyout, "\nif (sqlca.sqlwarn[0] == 'W') "); + print_action(&when_warn); + } + if (when_error.code != W_NOTHING) + { + output_line_number(); + fprintf(yyout, "\nif (sqlca.sqlcode < 0) "); + print_action(&when_error); + } + + if ((mode&2) == 2) + fputc('}', yyout); + + output_line_number(); +} + +char * +hashline_number(void) +{ + if (input_filename) + { + char* line = mm_alloc(strlen("\n#line %d \"%s\"\n") + 21 + strlen(input_filename)); + sprintf(line, "\n#line %d \"%s\"\n", yylineno, input_filename); + + return line; + } + + return EMPTY; +} + +void +output_statement(char * stmt, int mode, char *descriptor) +{ + int i, j=strlen(stmt); + + if (descriptor == NULL) + fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"", connection ? connection : "NULL"); + else + fprintf(yyout, "{ ECPGdo_descriptor(__LINE__, %s, \"%s\", \"", + connection ? connection : "NULL", descriptor); + + /* do this char by char as we have to filter '\"' */ + for (i = 0;i < j; i++) { + if (stmt[i] != '\"') + fputc(stmt[i], yyout); + else + 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); + } + else + fputs("\");", yyout); + + mode |= 2; + whenever_action(mode); + free(stmt); + if (connection != NULL) + free(connection); +} + diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 41354d8712..2b1f1c304a 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -15,16 +15,15 @@ #include "mb/pg_wchar.h" #endif -#define EMPTY make_str("") - /* * Variables containing simple states. */ int struct_level = 0; +int braces_open; /* brace level counter */ char errortext[128]; char *descriptor_index= NULL; char *connection = NULL; -char *descriptor_name = NULL; +char *input_filename = NULL; static int QueryIsRule = 0, ForUpdateNotAllowed = 0, FoundInto = 0; static int FoundSort = 0; @@ -47,7 +46,6 @@ struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}}; void mmerror(enum errortype type, char * error) { - switch(type) { case ET_WARN: @@ -63,86 +61,6 @@ mmerror(enum errortype type, char * error) } } -/* - * 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); -} - -static void -output_simple_statement(char *cmd) -{ - fputs(cmd, yyout); - output_line_number(); - free(cmd); -} - -/* - * store the whenever action here - */ -struct when when_error, when_nf, when_warn; - -static void -print_action(struct when *w) -{ - switch (w->code) - { - case W_SQLPRINT: fprintf(yyout, "sqlprint();"); - break; - case W_GOTO: fprintf(yyout, "goto %s;", w->command); - break; - case W_DO: fprintf(yyout, "%s;", w->command); - break; - case W_STOP: fprintf(yyout, "exit (1);"); - break; - case W_BREAK: fprintf(yyout, "break;"); - break; - default: fprintf(yyout, "{/* %d not implemented yet */}", w->code); - break; - } -} - -void -whenever_action(int mode) -{ - if ((mode&1) == 1 && when_nf.code != W_NOTHING) - { - output_line_number(); - fprintf(yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) "); - print_action(&when_nf); - } - if (when_warn.code != W_NOTHING) - { - output_line_number(); - fprintf(yyout, "\nif (sqlca.sqlwarn[0] == 'W') "); - print_action(&when_warn); - } - if (when_error.code != W_NOTHING) - { - output_line_number(); - fprintf(yyout, "\nif (sqlca.sqlcode < 0) "); - print_action(&when_error); - } - if ((mode&2) == 2) - fputc('}', yyout); - output_line_number(); -} - -/* - * Handling of variables. - */ - -/* - * brace level counter - */ -int braces_open; - /* * string concatenation */ @@ -180,7 +98,7 @@ cat_str(int count, ...) return(res_str); } -static char * +char * make_str(const char *str) { char * res_str = (char *)mm_alloc(strlen(str) + 1); @@ -225,49 +143,6 @@ make_name(void) return(name); } -static char * -hashline_number() -{ - if (input_filename) - { - char* line = mm_alloc(strlen("\n#line %d \"%s\"\n") + 21 + strlen(input_filename)); - sprintf(line, "\n#line %d \"%s\"\n", yylineno, input_filename); - - return line; - } - - return EMPTY; -} - -static void -output_statement(char * stmt, int mode) -{ - int i, j=strlen(stmt); - - fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"", connection ? connection : "NULL"); - - /* do this char by char as we have to filter '\"' */ - for (i = 0;i < j; i++) { - if (stmt[i] != '\"') - fputc(stmt[i], yyout); - 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); - mode |= 2; - whenever_action(mode); - free(stmt); - if (connection != NULL) - free(connection); -} - %} %union { @@ -279,6 +154,7 @@ output_statement(char * stmt, int mode) int tagname; struct this_type type; enum ECPGttype type_enum; + struct fetch_desc descriptor; } /* special embedded SQL token */ @@ -482,7 +358,8 @@ output_statement(char * stmt, int mode) %type s_struct s_union union_type ECPGSetAutocommit on_off %type ECPGAllocateDescr ECPGDeallocateDescr %type ECPGGetDescriptor ECPGGetDescriptorHeader -%type FetchDescriptorStmt + +%type ECPGFetchDescStmt %type simple_type signed_type unsigned_type varchar_type @@ -509,64 +386,63 @@ statement: ecpgstart opt_at stmt ';' { connection = NULL; } opt_at: SQL_AT connection_target { connection = $2; } -stmt: AlterTableStmt { output_statement($1, 0); } - | AlterGroupStmt { output_statement($1, 0); } - | AlterUserStmt { output_statement($1, 0); } - | ClosePortalStmt { output_statement($1, 0); } - | CommentStmt { output_statement($1, 0); } - | CopyStmt { output_statement($1, 0); } - | CreateStmt { output_statement($1, 0); } - | CreateAsStmt { output_statement($1, 0); } - | CreateGroupStmt { output_statement($1, 0); } - | CreateSeqStmt { output_statement($1, 0); } - | CreatePLangStmt { output_statement($1, 0); } - | CreateTrigStmt { output_statement($1, 0); } - | CreateUserStmt { output_statement($1, 0); } - | ClusterStmt { output_statement($1, 0); } - | DefineStmt { output_statement($1, 0); } - | DropStmt { output_statement($1, 0); } - | TruncateStmt { output_statement($1, 0); } - | DropGroupStmt { output_statement($1, 0); } - | DropPLangStmt { output_statement($1, 0); } - | DropTrigStmt { output_statement($1, 0); } - | DropUserStmt { output_statement($1, 0); } - | ExtendStmt { output_statement($1, 0); } - | ExplainStmt { output_statement($1, 0); } - | FetchStmt { output_statement($1, 1); } - | FetchDescriptorStmt { output_statement_desc($1, 1); } - | GrantStmt { output_statement($1, 0); } - | IndexStmt { output_statement($1, 0); } - | ListenStmt { output_statement($1, 0); } - | UnlistenStmt { output_statement($1, 0); } - | LockStmt { output_statement($1, 0); } - | ProcedureStmt { output_statement($1, 0); } - | RemoveAggrStmt { output_statement($1, 0); } - | RemoveOperStmt { output_statement($1, 0); } - | RemoveFuncStmt { output_statement($1, 0); } - | RemoveStmt { output_statement($1, 0); } - | RenameStmt { output_statement($1, 0); } - | RevokeStmt { output_statement($1, 0); } +stmt: AlterTableStmt { output_statement($1, 0, NULL); } + | AlterGroupStmt { output_statement($1, 0, NULL); } + | AlterUserStmt { output_statement($1, 0, NULL); } + | ClosePortalStmt { output_statement($1, 0, NULL); } + | CommentStmt { output_statement($1, 0, NULL); } + | CopyStmt { output_statement($1, 0, NULL); } + | CreateStmt { output_statement($1, 0, NULL); } + | CreateAsStmt { output_statement($1, 0, NULL); } + | CreateGroupStmt { output_statement($1, 0, NULL); } + | CreateSeqStmt { output_statement($1, 0, NULL); } + | CreatePLangStmt { output_statement($1, 0, NULL); } + | CreateTrigStmt { output_statement($1, 0, NULL); } + | CreateUserStmt { output_statement($1, 0, NULL); } + | ClusterStmt { output_statement($1, 0, NULL); } + | DefineStmt { output_statement($1, 0, NULL); } + | DropStmt { output_statement($1, 0, NULL); } + | TruncateStmt { output_statement($1, 0, NULL); } + | DropGroupStmt { output_statement($1, 0, NULL); } + | DropPLangStmt { output_statement($1, 0, NULL); } + | DropTrigStmt { output_statement($1, 0, NULL); } + | DropUserStmt { output_statement($1, 0, NULL); } + | ExtendStmt { output_statement($1, 0, NULL); } + | ExplainStmt { output_statement($1, 0, NULL); } + | FetchStmt { output_statement($1, 1, NULL); } + | GrantStmt { output_statement($1, 0, NULL); } + | IndexStmt { output_statement($1, 0, NULL); } + | ListenStmt { output_statement($1, 0, NULL); } + | UnlistenStmt { output_statement($1, 0, NULL); } + | LockStmt { output_statement($1, 0, NULL); } + | ProcedureStmt { output_statement($1, 0, NULL); } + | RemoveAggrStmt { output_statement($1, 0, NULL); } + | RemoveOperStmt { output_statement($1, 0, NULL); } + | RemoveFuncStmt { output_statement($1, 0, NULL); } + | RemoveStmt { output_statement($1, 0, NULL); } + | RenameStmt { output_statement($1, 0, NULL); } + | RevokeStmt { output_statement($1, 0, NULL); } | OptimizableStmt { if (strncmp($1, "/* " , sizeof("/* ")-1) == 0) output_simple_statement($1); else - output_statement($1, 1); + output_statement($1, 1, NULL); } - | RuleStmt { output_statement($1, 0); } + | RuleStmt { output_statement($1, 0, NULL); } | TransactionStmt { fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1); whenever_action(2); free($1); } - | ViewStmt { output_statement($1, 0); } - | LoadStmt { output_statement($1, 0); } - | CreatedbStmt { output_statement($1, 0); } - | DropdbStmt { output_statement($1, 0); } - | VacuumStmt { output_statement($1, 0); } - | VariableSetStmt { output_statement($1, 0); } - | VariableShowStmt { output_statement($1, 0); } - | VariableResetStmt { output_statement($1, 0); } - | ConstraintsSetStmt { output_statement($1, 0); } + | ViewStmt { output_statement($1, 0, NULL); } + | LoadStmt { output_statement($1, 0, NULL); } + | CreatedbStmt { output_statement($1, 0, NULL); } + | DropdbStmt { output_statement($1, 0, NULL); } + | VacuumStmt { output_statement($1, 0, NULL); } + | VariableSetStmt { output_statement($1, 0, NULL); } + | VariableShowStmt { output_statement($1, 0, NULL); } + | VariableResetStmt { output_statement($1, 0, NULL); } + | ConstraintsSetStmt { output_statement($1, 0, NULL); } | ECPGAllocateDescr { fprintf(yyout,"ECPGallocate_desc(__LINE__, \"%s\");",$1); whenever_action(0); free($1); @@ -606,9 +482,8 @@ stmt: AlterTableStmt { output_statement($1, 0); } whenever_action(2); free($1); } - | ECPGExecute { - output_statement($1, 0); - } + | ECPGExecute { output_statement($1, 0, NULL); } + | ECPGFetchDescStmt { output_statement($1.str, 1, $1.name); } | ECPGFree { fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1); @@ -4754,30 +4629,30 @@ ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR ident SQL_VALUE cvariable ECPGGetDescI * *****************************************************************************/ -FetchDescriptorStmt: FETCH direction fetch_how_many from_in name INTO SQL_SQL SQL_DESCRIPTOR ident +ECPGFetchDescStmt: FETCH direction fetch_how_many from_in name INTO SQL_SQL SQL_DESCRIPTOR ident { - $$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5); - descriptor_name=$9; + $$.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 ident { - $$ = cat_str(4, make_str("fetch"), $2, $3, $4); - descriptor_name=$8; + $$.str = cat_str(4, make_str("fetch"), $2, $3, $4); + $$.name=$8; } | FETCH direction from_in name INTO SQL_SQL SQL_DESCRIPTOR ident { - $$ = cat_str(4, make_str("fetch"), $2, $3, $4); - descriptor_name=$8; + $$.str = cat_str(4, make_str("fetch"), $2, $3, $4); + $$.name=$8; } | FETCH from_in name INTO SQL_SQL SQL_DESCRIPTOR ident { - $$ = cat_str(3, make_str("fetch"), $2, $3); - descriptor_name=$7; + $$.str = cat_str(3, make_str("fetch"), $2, $3); + $$.name=$7; } | FETCH name INTO SQL_SQL SQL_DESCRIPTOR ident { - $$ = cat2_str(make_str("fetch"), $2); - descriptor_name=$6; + $$.str = cat2_str(make_str("fetch"), $2); + $$.name=$6; } ; diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h index 4a8814fcdd..dd393d0d40 100644 --- a/src/interfaces/ecpg/preproc/type.h +++ b/src/interfaces/ecpg/preproc/type.h @@ -154,3 +154,9 @@ struct assignment }; enum errortype {ET_WARN, ET_ERROR, ET_FATAL}; + +struct fetch_desc +{ + char *str; + char *name; +}; -- GitLab