aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/ecpg/ChangeLog5
-rw-r--r--src/interfaces/ecpg/TODO2
-rw-r--r--src/interfaces/ecpg/include/ecpglib.h16
-rw-r--r--src/interfaces/ecpg/lib/descriptor.c15
-rw-r--r--src/interfaces/ecpg/lib/dynamic.c22
-rw-r--r--src/interfaces/ecpg/preproc/Makefile2
-rw-r--r--src/interfaces/ecpg/preproc/descriptor.c211
-rw-r--r--src/interfaces/ecpg/preproc/extern.h19
-rw-r--r--src/interfaces/ecpg/preproc/output.c126
-rw-r--r--src/interfaces/ecpg/preproc/preproc.y257
-rw-r--r--src/interfaces/ecpg/preproc/type.h6
11 files changed, 346 insertions, 335 deletions
diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 157f219a303..d733e9e0df0 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 <christof.petig@wtal.de> 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 8be5f3f5fb8..d7546c7925e 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 f50a2bb09d8..b3105e943a1 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 00000000000..09815b2d103
--- /dev/null
+++ b/src/interfaces/ecpg/lib/descriptor.c
@@ -0,0 +1,15 @@
+#include <ecpgtype.h>
+#include <ecpglib.h>
+
+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 752c02cfc0d..b66883b934a 100644
--- a/src/interfaces/ecpg/lib/dynamic.c
+++ b/src/interfaces/ecpg/lib/dynamic.c
@@ -2,7 +2,7 @@
*
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
*
- * $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 72240e2efc9..3fa7307de21 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 c2b09fa076c..247e48f234d 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 cbee29e0a58..3ec8a596b1e 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 00000000000..c60adf8f408
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/output.c
@@ -0,0 +1,126 @@
+#include <stdarg.h>
+
+#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 41354d87122..2b1f1c304aa 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:
@@ -64,86 +62,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 <str> s_struct s_union union_type ECPGSetAutocommit on_off
%type <str> ECPGAllocateDescr ECPGDeallocateDescr
%type <str> ECPGGetDescriptor ECPGGetDescriptorHeader
-%type <str> FetchDescriptorStmt
+
+%type <descriptor> ECPGFetchDescStmt
%type <type_enum> 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 4a8814fcddd..dd393d0d40e 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;
+};