Commit 6ccfc4f4 authored by Michael Meskes's avatar Michael Meskes

- Issue a warning if a cursor is declared but not opened.

- Fixed prototype for ECPGprepared_statement to not moan about "const char"
- Fixed parsing of nested structures.
- Added option to parse header files.
parent 31a0f1d3
...@@ -1728,3 +1728,11 @@ Wed Dec 17 16:11:16 CET 2003 ...@@ -1728,3 +1728,11 @@ Wed Dec 17 16:11:16 CET 2003
- Set pgtypes library to 1.1.0 - Set pgtypes library to 1.1.0
- Set compat library to 1.1.0 - Set compat library to 1.1.0
Mon Jan 26 21:57:14 CET 2004
- Issue a warning if a cursor is declared but not opened.
- Fixed prototype for ECPGprepared_statement to not moan about "const
char"
- Fixed parsing of nested structures.
- Added option to parse header files.
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.31 2004/01/07 18:56:29 neilc Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.32 2004/01/28 09:52:14 meskes Exp $ */
/* /*
* The aim is to get a simpler inteface to the database routines. * The aim is to get a simpler inteface to the database routines.
...@@ -333,7 +333,7 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia ...@@ -333,7 +333,7 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia
} }
PQclear(query); PQclear(query);
ECPGtypeinfocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno); ECPGtypeinfocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno);
ECPGlog("ECPGexecute line %d: TYPE database: %d C: %d array: %d\n", stmt->lineno, type, var->type, isarray); ECPGlog("ECPGis_type_an_array line %d: TYPE database: %d C: %d array: %d\n", stmt->lineno, type, var->type, isarray);
return isarray; return isarray;
} }
...@@ -356,7 +356,7 @@ ECPGstore_result(const PGresult *results, int act_field, ...@@ -356,7 +356,7 @@ ECPGstore_result(const PGresult *results, int act_field,
*/ */
if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize)) if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
{ {
ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n", ECPGlog("ECPGstore_result line %d: Incorrect number of matches: %d don't fit into array of %d\n",
stmt->lineno, ntuples, var->arrsize); stmt->lineno, ntuples, var->arrsize);
ECPGraise(stmt->lineno, INFORMIX_MODE(stmt->compat)?ECPG_INFORMIX_SUBSELECT_NOT_ONE:ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL); ECPGraise(stmt->lineno, INFORMIX_MODE(stmt->compat)?ECPG_INFORMIX_SUBSELECT_NOT_ONE:ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
return false; return false;
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.10 2003/11/29 19:52:08 pgsql Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.11 2004/01/28 09:52:14 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL #define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -169,7 +169,7 @@ ECPGdeallocate_all(int lineno) ...@@ -169,7 +169,7 @@ ECPGdeallocate_all(int lineno)
/* return the prepared statement */ /* return the prepared statement */
char * char *
ECPGprepared_statement(char *name) ECPGprepared_statement(const char *name)
{ {
struct prepared_statement *this; struct prepared_statement *this;
......
...@@ -54,7 +54,7 @@ bool ECPGprepare(int, char *, char *); ...@@ -54,7 +54,7 @@ bool ECPGprepare(int, char *, char *);
bool ECPGdeallocate(int, int, char *); bool ECPGdeallocate(int, int, char *);
bool ECPGdeallocate_one(int, char *); bool ECPGdeallocate_one(int, char *);
bool ECPGdeallocate_all(int); bool ECPGdeallocate_all(int);
char *ECPGprepared_statement(char *); char *ECPGprepared_statement(const char *);
void ECPGlog(const char *format,...); void ECPGlog(const char *format,...);
char *ECPGerrmsg(void); char *ECPGerrmsg(void);
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.83 2003/12/18 18:55:09 petere Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.84 2004/01/28 09:52:14 meskes Exp $ */
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */ /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */ /* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
...@@ -22,6 +22,7 @@ int ret_value = 0, ...@@ -22,6 +22,7 @@ int ret_value = 0,
auto_create_c = false, auto_create_c = false,
system_includes = false, system_includes = false,
force_indicator = true; force_indicator = true;
header_mode = false;
enum COMPAT_MODE compat = ECPG_COMPAT_PGSQL; enum COMPAT_MODE compat = ECPG_COMPAT_PGSQL;
...@@ -47,6 +48,7 @@ help(const char *progname) ...@@ -47,6 +48,7 @@ help(const char *progname)
printf(" -d generate parser debug output\n"); printf(" -d generate parser debug output\n");
#endif #endif
printf(" -D SYMBOL define SYMBOL\n"); printf(" -D SYMBOL define SYMBOL\n");
printf(" -h parse a header file, this option includes option \"-c\"\n");
printf(" -i parse system include files as well\n"); printf(" -i parse system include files as well\n");
printf(" -I DIRECTORY search DIRECTORY for include files\n"); printf(" -I DIRECTORY search DIRECTORY for include files\n");
printf(" -o OUTFILE write result to OUTFILE\n"); printf(" -o OUTFILE write result to OUTFILE\n");
...@@ -136,7 +138,7 @@ main(int argc, char *const argv[]) ...@@ -136,7 +138,7 @@ main(int argc, char *const argv[])
} }
} }
while ((c = getopt(argc, argv, "vcio:I:tD:dC:r:")) != -1) while ((c = getopt(argc, argv, "vcio:I:tD:dC:r:h")) != -1)
{ {
switch (c) switch (c)
{ {
...@@ -160,6 +162,10 @@ main(int argc, char *const argv[]) ...@@ -160,6 +162,10 @@ main(int argc, char *const argv[])
case 'v': case 'v':
verbose = true; verbose = true;
break; break;
case 'h':
header_mode = true;
/* this must include "-c" to make sense */
/* so do not place a break; here */
case 'c': case 'c':
auto_create_c = true; auto_create_c = true;
break; break;
...@@ -259,11 +265,11 @@ main(int argc, char *const argv[]) ...@@ -259,11 +265,11 @@ main(int argc, char *const argv[])
{ {
ptr2ext = input_filename + strlen(input_filename); ptr2ext = input_filename + strlen(input_filename);
/* no extension => add .pgc */ /* no extension => add .pgc or .pgh */
ptr2ext[0] = '.'; ptr2ext[0] = '.';
ptr2ext[1] = 'p'; ptr2ext[1] = 'p';
ptr2ext[2] = 'g'; ptr2ext[2] = 'g';
ptr2ext[3] = 'c'; ptr2ext[3] = (header_mode == true)? 'h' : 'c';
ptr2ext[4] = '\0'; ptr2ext[4] = '\0';
} }
...@@ -279,8 +285,8 @@ main(int argc, char *const argv[]) ...@@ -279,8 +285,8 @@ main(int argc, char *const argv[])
output_filename = strdup(input_filename); output_filename = strdup(input_filename);
ptr2ext = strrchr(output_filename, '.'); ptr2ext = strrchr(output_filename, '.');
/* make extension = .c */ /* make extension = .c resp. .h */
ptr2ext[1] = 'c'; ptr2ext[1] = (header_mode == true)? 'h' : 'c';
ptr2ext[2] = '\0'; ptr2ext[2] = '\0';
yyout = fopen(output_filename, PG_BINARY_W); yyout = fopen(output_filename, PG_BINARY_W);
...@@ -383,17 +389,39 @@ main(int argc, char *const argv[]) ...@@ -383,17 +389,39 @@ main(int argc, char *const argv[])
lex_init(); lex_init();
/* we need several includes */ /* we need several includes */
fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/* These include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n#include <ecpgerrno.h>\n#include <sqlca.h>\n#line 1 \"%s\"\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, input_filename); /* but not if we are in header mode */
fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
if (header_mode == false)
{
fprintf(yyout, "/* These include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n#include <ecpgerrno.h>\n#include <sqlca.h>\n");
/* add some compatibility headers */ /* add some compatibility headers */
if (INFORMIX_MODE) if (INFORMIX_MODE)
fprintf(yyout, "/* Needed for informix compatibility */\n#include <ecpg_informix.h>\n"); fprintf(yyout, "/* Needed for informix compatibility */\n#include <ecpg_informix.h>\n");
fprintf(yyout, "/* End of automatic include section */\n"); fprintf(yyout, "/* End of automatic include section */\n");
}
fprintf(yyout, "#line 1 \"%s\"\n", input_filename);
/* and parse the source */ /* and parse the source */
yyparse(); yyparse();
/* check if all cursors were indeed opened */
for (ptr = cur; ptr != NULL;)
{
char errortext[128];
if (!(ptr->opened))
{
/* Does not really make sense to declare a cursor but not open it */
snprintf(errortext, sizeof(errortext), "cursor `%s´ has been declared but ot opened\n", ptr->name);
mmerror(PARSE_ERROR, ET_WARNING, errortext);
}
ptr = ptr->next;
}
if (yyin != NULL && yyin != stdin) if (yyin != NULL && yyin != stdin)
fclose(yyin); fclose(yyin);
if (out_option == 0 && yyout != stdout) if (out_option == 0 && yyout != stdout)
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.270 2004/01/21 14:09:34 meskes Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.271 2004/01/28 09:52:14 meskes Exp $ */
/* Copyright comment */ /* Copyright comment */
%{ %{
...@@ -778,6 +778,7 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); } ...@@ -778,6 +778,7 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
if ((ptr = add_additional_variables($1, true)) != NULL) if ((ptr = add_additional_variables($1, true)) != NULL)
output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL); output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL);
ptr->opened = true;
} }
| ECPGPrepare | ECPGPrepare
{ {
...@@ -2780,6 +2781,7 @@ DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt ...@@ -2780,6 +2781,7 @@ DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
this->next = cur; this->next = cur;
this->name = $2; this->name = $2;
this->connection = connection; this->connection = connection;
this->opened = false;
this->command = cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7); this->command = cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7);
this->argsinsert = argsinsert; this->argsinsert = argsinsert;
this->argsresult = argsresult; this->argsresult = argsresult;
......
...@@ -47,6 +47,10 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm) ...@@ -47,6 +47,10 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm)
type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->struct_sizeof); type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->struct_sizeof);
break; break;
case ECPGt_array: case ECPGt_array:
/* if this array does contain a struct again, we have to create the struct too */
if (rm->type->u.element->type == ECPGt_struct)
type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->struct_sizeof);
else
type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size), rm->type->size); type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size), rm->type->size);
break; break;
default: default:
......
...@@ -115,6 +115,7 @@ struct cursor ...@@ -115,6 +115,7 @@ struct cursor
char *name; char *name;
char *command; char *command;
char *connection; char *connection;
bool opened;
struct arguments *argsinsert; struct arguments *argsinsert;
struct arguments *argsresult; struct arguments *argsresult;
struct cursor *next; struct cursor *next;
......
...@@ -31,9 +31,11 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in ...@@ -31,9 +31,11 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
c = *next; c = *next;
*next = '\0'; *next = '\0';
} }
printf("MM: Need to search for %s\n", str);
for (; members; members = members->next) for (; members; members = members->next)
{ {
printf("MM: comparing %s\n", members->name);
if (strcmp(members->name, str) == 0) if (strcmp(members->name, str) == 0)
{ {
if (next == NULL) if (next == NULL)
...@@ -104,10 +106,11 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in ...@@ -104,10 +106,11 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
return (find_struct_member(name, end, members->type->u.element->u.members, brace_level)); return (find_struct_member(name, end, members->type->u.element->u.members, brace_level));
break; break;
case '.': case '.':
if (members->type->type != ECPGt_array) printf("MM: Now searching for %s \n", end);
if (members->type->type == ECPGt_array)
return (find_struct_member(name, end, members->type->u.element->u.members, brace_level)); return (find_struct_member(name, end, members->type->u.element->u.members, brace_level));
else else
return (find_struct_member(name, next, members->type->u.members, brace_level)); return (find_struct_member(name, end, members->type->u.members, brace_level));
break; break;
default: default:
snprintf(errortext, sizeof(errortext), "incorrectly formed variable %s", name); snprintf(errortext, sizeof(errortext), "incorrectly formed variable %s", name);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment