Skip to content

Commit 6ccfc4f

Browse files
author
Michael Meskes
committed
- 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.
1 parent 31a0f1d commit 6ccfc4f

File tree

9 files changed

+67
-21
lines changed

9 files changed

+67
-21
lines changed

src/interfaces/ecpg/ChangeLog

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,3 +1728,11 @@ Wed Dec 17 16:11:16 CET 2003
17281728
- Set pgtypes library to 1.1.0
17291729
- Set compat library to 1.1.0
17301730

1731+
Mon Jan 26 21:57:14 CET 2004
1732+
1733+
- Issue a warning if a cursor is declared but not opened.
1734+
- Fixed prototype for ECPGprepared_statement to not moan about "const
1735+
char"
1736+
- Fixed parsing of nested structures.
1737+
- Added option to parse header files.
1738+

src/interfaces/ecpg/ecpglib/execute.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.31 2004/01/07 18:56:29 neilc Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.32 2004/01/28 09:52:14 meskes Exp $ */
22

33
/*
44
* 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
333333
}
334334
PQclear(query);
335335
ECPGtypeinfocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno);
336-
ECPGlog("ECPGexecute line %d: TYPE database: %d C: %d array: %d\n", stmt->lineno, type, var->type, isarray);
336+
ECPGlog("ECPGis_type_an_array line %d: TYPE database: %d C: %d array: %d\n", stmt->lineno, type, var->type, isarray);
337337
return isarray;
338338
}
339339

@@ -356,7 +356,7 @@ ECPGstore_result(const PGresult *results, int act_field,
356356
*/
357357
if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
358358
{
359-
ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
359+
ECPGlog("ECPGstore_result line %d: Incorrect number of matches: %d don't fit into array of %d\n",
360360
stmt->lineno, ntuples, var->arrsize);
361361
ECPGraise(stmt->lineno, INFORMIX_MODE(stmt->compat)?ECPG_INFORMIX_SUBSELECT_NOT_ONE:ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
362362
return false;

src/interfaces/ecpg/ecpglib/prepare.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.10 2003/11/29 19:52:08 pgsql Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.11 2004/01/28 09:52:14 meskes Exp $ */
22

33
#define POSTGRES_ECPG_INTERNAL
44
#include "postgres_fe.h"
@@ -169,7 +169,7 @@ ECPGdeallocate_all(int lineno)
169169

170170
/* return the prepared statement */
171171
char *
172-
ECPGprepared_statement(char *name)
172+
ECPGprepared_statement(const char *name)
173173
{
174174
struct prepared_statement *this;
175175

src/interfaces/ecpg/include/ecpglib.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ bool ECPGprepare(int, char *, char *);
5454
bool ECPGdeallocate(int, int, char *);
5555
bool ECPGdeallocate_one(int, char *);
5656
bool ECPGdeallocate_all(int);
57-
char *ECPGprepared_statement(char *);
57+
char *ECPGprepared_statement(const char *);
5858

5959
void ECPGlog(const char *format,...);
6060
char *ECPGerrmsg(void);

src/interfaces/ecpg/preproc/ecpg.c

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.83 2003/12/18 18:55:09 petere Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.84 2004/01/28 09:52:14 meskes Exp $ */
22

33
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
44
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
@@ -22,6 +22,7 @@ int ret_value = 0,
2222
auto_create_c = false,
2323
system_includes = false,
2424
force_indicator = true;
25+
header_mode = false;
2526

2627
enum COMPAT_MODE compat = ECPG_COMPAT_PGSQL;
2728

@@ -47,6 +48,7 @@ help(const char *progname)
4748
printf(" -d generate parser debug output\n");
4849
#endif
4950
printf(" -D SYMBOL define SYMBOL\n");
51+
printf(" -h parse a header file, this option includes option \"-c\"\n");
5052
printf(" -i parse system include files as well\n");
5153
printf(" -I DIRECTORY search DIRECTORY for include files\n");
5254
printf(" -o OUTFILE write result to OUTFILE\n");
@@ -136,7 +138,7 @@ main(int argc, char *const argv[])
136138
}
137139
}
138140

139-
while ((c = getopt(argc, argv, "vcio:I:tD:dC:r:")) != -1)
141+
while ((c = getopt(argc, argv, "vcio:I:tD:dC:r:h")) != -1)
140142
{
141143
switch (c)
142144
{
@@ -160,6 +162,10 @@ main(int argc, char *const argv[])
160162
case 'v':
161163
verbose = true;
162164
break;
165+
case 'h':
166+
header_mode = true;
167+
/* this must include "-c" to make sense */
168+
/* so do not place a break; here */
163169
case 'c':
164170
auto_create_c = true;
165171
break;
@@ -259,11 +265,11 @@ main(int argc, char *const argv[])
259265
{
260266
ptr2ext = input_filename + strlen(input_filename);
261267

262-
/* no extension => add .pgc */
268+
/* no extension => add .pgc or .pgh */
263269
ptr2ext[0] = '.';
264270
ptr2ext[1] = 'p';
265271
ptr2ext[2] = 'g';
266-
ptr2ext[3] = 'c';
272+
ptr2ext[3] = (header_mode == true)? 'h' : 'c';
267273
ptr2ext[4] = '\0';
268274
}
269275

@@ -279,8 +285,8 @@ main(int argc, char *const argv[])
279285
output_filename = strdup(input_filename);
280286

281287
ptr2ext = strrchr(output_filename, '.');
282-
/* make extension = .c */
283-
ptr2ext[1] = 'c';
288+
/* make extension = .c resp. .h */
289+
ptr2ext[1] = (header_mode == true)? 'h' : 'c';
284290
ptr2ext[2] = '\0';
285291

286292
yyout = fopen(output_filename, PG_BINARY_W);
@@ -383,17 +389,39 @@ main(int argc, char *const argv[])
383389
lex_init();
384390

385391
/* we need several includes */
386-
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);
392+
/* but not if we are in header mode */
393+
fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
394+
395+
if (header_mode == false)
396+
{
397+
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");
387398

388-
/* add some compatibility headers */
389-
if (INFORMIX_MODE)
390-
fprintf(yyout, "/* Needed for informix compatibility */\n#include <ecpg_informix.h>\n");
399+
/* add some compatibility headers */
400+
if (INFORMIX_MODE)
401+
fprintf(yyout, "/* Needed for informix compatibility */\n#include <ecpg_informix.h>\n");
391402

392-
fprintf(yyout, "/* End of automatic include section */\n");
403+
fprintf(yyout, "/* End of automatic include section */\n");
404+
}
393405

406+
fprintf(yyout, "#line 1 \"%s\"\n", input_filename);
407+
394408
/* and parse the source */
395409
yyparse();
396410

411+
/* check if all cursors were indeed opened */
412+
for (ptr = cur; ptr != NULL;)
413+
{
414+
char errortext[128];
415+
416+
if (!(ptr->opened))
417+
{
418+
/* Does not really make sense to declare a cursor but not open it */
419+
snprintf(errortext, sizeof(errortext), "cursor `%s´ has been declared but ot opened\n", ptr->name);
420+
mmerror(PARSE_ERROR, ET_WARNING, errortext);
421+
}
422+
ptr = ptr->next;
423+
}
424+
397425
if (yyin != NULL && yyin != stdin)
398426
fclose(yyin);
399427
if (out_option == 0 && yyout != stdout)

src/interfaces/ecpg/preproc/preproc.y

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.270 2004/01/21 14:09:34 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.271 2004/01/28 09:52:14 meskes Exp $ */
22

33
/* Copyright comment */
44
%{
@@ -778,6 +778,7 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
778778

779779
if ((ptr = add_additional_variables($1, true)) != NULL)
780780
output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL);
781+
ptr->opened = true;
781782
}
782783
| ECPGPrepare
783784
{
@@ -2780,6 +2781,7 @@ DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
27802781
this->next = cur;
27812782
this->name = $2;
27822783
this->connection = connection;
2784+
this->opened = false;
27832785
this->command = cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7);
27842786
this->argsinsert = argsinsert;
27852787
this->argsresult = argsresult;

src/interfaces/ecpg/preproc/type.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm)
4747
type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->struct_sizeof);
4848
break;
4949
case ECPGt_array:
50-
type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size), rm->type->size);
50+
/* if this array does contain a struct again, we have to create the struct too */
51+
if (rm->type->u.element->type == ECPGt_struct)
52+
type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->struct_sizeof);
53+
else
54+
type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size), rm->type->size);
5155
break;
5256
default:
5357
type = ECPGmake_simple_type(rm->type->type, rm->type->size);

src/interfaces/ecpg/preproc/type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ struct cursor
115115
char *name;
116116
char *command;
117117
char *connection;
118+
bool opened;
118119
struct arguments *argsinsert;
119120
struct arguments *argsresult;
120121
struct cursor *next;

src/interfaces/ecpg/preproc/variable.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
3131
c = *next;
3232
*next = '\0';
3333
}
34+
printf("MM: Need to search for %s\n", str);
3435

3536
for (; members; members = members->next)
3637
{
38+
printf("MM: comparing %s\n§", members->name);
3739
if (strcmp(members->name, str) == 0)
3840
{
3941
if (next == NULL)
@@ -104,10 +106,11 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
104106
return (find_struct_member(name, end, members->type->u.element->u.members, brace_level));
105107
break;
106108
case '.':
107-
if (members->type->type != ECPGt_array)
109+
printf("MM: Now searching for %s \n", end);
110+
if (members->type->type == ECPGt_array)
108111
return (find_struct_member(name, end, members->type->u.element->u.members, brace_level));
109112
else
110-
return (find_struct_member(name, next, members->type->u.members, brace_level));
113+
return (find_struct_member(name, end, members->type->u.members, brace_level));
111114
break;
112115
default:
113116
snprintf(errortext, sizeof(errortext), "incorrectly formed variable %s", name);

0 commit comments

Comments
 (0)