Fixed several bugs concerning indicators and added error messages instead of segfaults.

This commit is contained in:
Michael Meskes 2001-12-09 15:27:49 +00:00
parent eda51264c8
commit a4420c4970
5 changed files with 103 additions and 99 deletions

View File

@ -1170,5 +1170,10 @@ Thu Dec 6 14:02:56 CET 2001
Sat Dec 8 21:35:45 CET 2001 Sat Dec 8 21:35:45 CET 2001
- Fix ecpg to allow pointer to structs. - Fix ecpg to allow pointer to structs.
Sun Dec 9 16:21:30 CET 2001
- Fixed several bugs concerning indicators and added error messages
instead of segfaults.
- Set ecpg version to 2.9.0. - Set ecpg version to 2.9.0.
- Set library version to 3.3.0. - Set library version to 3.3.0.

View File

@ -55,7 +55,7 @@ extern int yylex(void);
extern void yyerror(char *); extern void yyerror(char *);
extern void *mm_alloc(size_t), *mm_realloc(void *, size_t); extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
extern char *mm_strdup(const char *); extern char *mm_strdup(const char *);
extern void mmerror(enum errortype, char *); extern void mmerror(int, enum errortype, char *);
extern ScanKeyword *ScanECPGKeywordLookup(char *); extern ScanKeyword *ScanECPGKeywordLookup(char *);
extern ScanKeyword *ScanCKeywordLookup(char *); extern ScanKeyword *ScanCKeywordLookup(char *);
extern void output_get_descr_header(char *); extern void output_get_descr_header(char *);
@ -85,3 +85,5 @@ extern ScanKeyword *ScanKeywordLookup(char *text);
#define PARSE_ERROR 3 #define PARSE_ERROR 3
#define INDICATOR_NOT_ARRAY 4 #define INDICATOR_NOT_ARRAY 4
#define OUT_OF_MEMORY 5 #define OUT_OF_MEMORY 5
#define INDICATOR_NOT_STRUCT 6
#define INDICATOR_NOT_SIMPLE 7

View File

@ -12,7 +12,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.81 2001/09/19 14:09:32 meskes Exp $ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.82 2001/12/09 15:27:49 meskes Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -306,7 +306,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xc>{xcinside} { ECHO; } <xc>{xcinside} { ECHO; }
<xc>{op_chars} { ECHO; } <xc>{op_chars} { ECHO; }
<xc><<EOF>> { mmerror(ET_ERROR, "Unterminated /* comment"); } <xc><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated /* comment"); }
<SQL>{xbitstart} { <SQL>{xbitstart} {
BEGIN(xbit); BEGIN(xbit);
@ -315,7 +315,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xbit>{xbitstop} { <xbit>{xbitstop} {
BEGIN(SQL); BEGIN(SQL);
if (literalbuf[strspn(literalbuf, "01") + 1] != '\0') if (literalbuf[strspn(literalbuf, "01") + 1] != '\0')
mmerror(ET_ERROR, "invalid bit string input."); mmerror(PARSE_ERROR, ET_ERROR, "invalid bit string input.");
yylval.str = literalbuf; yylval.str = literalbuf;
return BITCONST; return BITCONST;
} }
@ -328,7 +328,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xbit>{xbitcat} { <xbit>{xbitcat} {
/* ignore */ /* ignore */
} }
<xbit><<EOF>> { mmerror(ET_ERROR, "Unterminated bit string"); } <xbit><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated bit string"); }
<SQL>{xhstart} { <SQL>{xhstart} {
BEGIN(xh); BEGIN(xh);
@ -347,12 +347,12 @@ cppline {space}*#(.*\\{line_end})*.*
|| val != (long) ((int32) val) || val != (long) ((int32) val)
#endif #endif
) )
mmerror(ET_ERROR, "Bad hexadecimal integer input"); mmerror(PARSE_ERROR, ET_ERROR, "Bad hexadecimal integer input");
yylval.ival = val; yylval.ival = val;
return ICONST; return ICONST;
} }
<xh><<EOF>> { mmerror(ET_ERROR, "Unterminated hexadecimal integer"); } <xh><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated hexadecimal integer"); }
{xqstart} { {xqstart} {
state_before = YYSTATE; state_before = YYSTATE;
@ -373,7 +373,7 @@ cppline {space}*#(.*\\{line_end})*.*
/* ignore */ /* ignore */
} }
<xq><<EOF>> { mmerror(ET_ERROR, "Unterminated quoted string"); } <xq><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated quoted string"); }
<SQL>{xdstart} { <SQL>{xdstart} {
state_before = YYSTATE; state_before = YYSTATE;
@ -396,7 +396,7 @@ cppline {space}*#(.*\\{line_end})*.*
literalbuf, NAMEDATALEN-1, literalbuf); literalbuf, NAMEDATALEN-1, literalbuf);
literalbuf[NAMEDATALEN-1] = '\0'; literalbuf[NAMEDATALEN-1] = '\0';
#endif #endif
mmerror(ET_NOTICE, errortext); mmerror(PARSE_ERROR, ET_NOTICE, errortext);
} }
yylval.str = mm_strdup(literalbuf); yylval.str = mm_strdup(literalbuf);
@ -413,7 +413,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xd>{xdinside} { <xd>{xdinside} {
addlit(yytext, yyleng); addlit(yytext, yyleng);
} }
<xd,xdc><<EOF>> { mmerror(ET_ERROR, "Unterminated quoted identifier"); } <xd,xdc><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated quoted identifier"); }
{xdstart} { {xdstart} {
state_before = YYSTATE; state_before = YYSTATE;
BEGIN(xdc); BEGIN(xdc);
@ -687,10 +687,10 @@ cppline {space}*#(.*\\{line_end})*.*
<C,xskip>{exec_sql}{elif}{space_or_nl}* { /* pop stack */ <C,xskip>{exec_sql}{elif}{space_or_nl}* { /* pop stack */
if ( preproc_tos == 0 ) { if ( preproc_tos == 0 ) {
mmerror(ET_FATAL, "Missing matching 'EXEC SQL IFDEF / EXEC SQL IFNDEF'"); mmerror(PARSE_ERROR, ET_FATAL, "Missing matching 'EXEC SQL IFDEF / EXEC SQL IFNDEF'");
} }
else if ( stacked_if_value[preproc_tos].else_branch ) { else if ( stacked_if_value[preproc_tos].else_branch ) {
mmerror(ET_FATAL, "Missing 'EXEC SQL ENDIF;'"); mmerror(PARSE_ERROR, ET_FATAL, "Missing 'EXEC SQL ENDIF;'");
} }
else { else {
preproc_tos--; preproc_tos--;
@ -701,7 +701,7 @@ cppline {space}*#(.*\\{line_end})*.*
<C,xskip>{exec_sql}{else}{space_or_nl}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */ <C,xskip>{exec_sql}{else}{space_or_nl}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */
if ( stacked_if_value[preproc_tos].else_branch ) { if ( stacked_if_value[preproc_tos].else_branch ) {
mmerror(ET_FATAL, "Duplicated 'EXEC SQL ELSE;'"); mmerror(PARSE_ERROR, ET_FATAL, "Duplicated 'EXEC SQL ELSE;'");
} }
else { else {
stacked_if_value[preproc_tos].else_branch = TRUE; stacked_if_value[preproc_tos].else_branch = TRUE;
@ -719,7 +719,7 @@ cppline {space}*#(.*\\{line_end})*.*
} }
<C,xskip>{exec_sql}{endif}{space_or_nl}*";" { <C,xskip>{exec_sql}{endif}{space_or_nl}*";" {
if ( preproc_tos == 0 ) { if ( preproc_tos == 0 ) {
mmerror(ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'"); mmerror(PARSE_ERROR, ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'");
} }
else { else {
preproc_tos--; preproc_tos--;
@ -737,7 +737,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xcond>{identifier}{space_or_nl}*";" { <xcond>{identifier}{space_or_nl}*";" {
if ( preproc_tos >= MAX_NESTED_IF-1 ) { if ( preproc_tos >= MAX_NESTED_IF-1 ) {
mmerror(ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions"); mmerror(PARSE_ERROR, ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions");
} }
else { else {
struct _defines *defptr; struct _defines *defptr;
@ -864,7 +864,7 @@ cppline {space}*#(.*\\{line_end})*.*
if ( preproc_tos > 0 ) { if ( preproc_tos > 0 ) {
preproc_tos = 0; preproc_tos = 0;
mmerror(ET_FATAL, "Missing 'EXEC SQL ENDIF;'"); mmerror(PARSE_ERROR, ET_FATAL, "Missing 'EXEC SQL ENDIF;'");
} }
if (yy_buffer == NULL) if (yy_buffer == NULL)

View File

@ -31,7 +31,7 @@ struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}};
* Handle parsing errors and warnings * Handle parsing errors and warnings
*/ */
void void
mmerror(enum errortype type, char * error) mmerror(int error_code, enum errortype type, char * error)
{ {
switch(type) switch(type)
{ {
@ -40,11 +40,11 @@ mmerror(enum errortype type, char * error)
break; break;
case ET_ERROR: case ET_ERROR:
fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error); fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
ret_value = PARSE_ERROR; ret_value = error_code;
break; break;
case ET_FATAL: case ET_FATAL:
fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error); fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
exit(PARSE_ERROR); exit(error_code);
} }
} }
@ -471,7 +471,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, connection); }
} }
| ECPGConnect { | ECPGConnect {
if (connection) if (connection)
mmerror(ET_ERROR, "no at option for connect statement.\n"); mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
fprintf(yyout, "{ ECPGconnect(__LINE__, %s, %d); ", $1, autocommit); fprintf(yyout, "{ ECPGconnect(__LINE__, %s, %d); ", $1, autocommit);
@ -485,7 +485,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, connection); }
} }
| ECPGDeallocate { | ECPGDeallocate {
if (connection) if (connection)
mmerror(ET_ERROR, "no at option for connect statement.\n"); mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
fputc('{', yyout); fputc('{', yyout);
fputs($1, yyout); fputs($1, yyout);
@ -501,7 +501,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, connection); }
} }
| ECPGDisconnect { | ECPGDisconnect {
if (connection) if (connection)
mmerror(ET_ERROR, "no at option for disconnect statement.\n"); mmerror(PARSE_ERROR, ET_ERROR, "no at option for disconnect statement.\n");
fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);", $1); fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);", $1);
whenever_action(2); whenever_action(2);
@ -538,7 +538,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, connection); }
if (ptr == NULL) if (ptr == NULL)
{ {
sprintf(errortext, "trying to open undeclared cursor %s\n", $1); sprintf(errortext, "trying to open undeclared cursor %s\n", $1);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
/* merge variables given in prepare statement with those given here */ /* merge variables given in prepare statement with those given here */
@ -552,7 +552,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, connection); }
} }
| ECPGPrepare { | ECPGPrepare {
if (connection) if (connection)
mmerror(ET_ERROR, "no at option for set connection statement.\n"); mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement.\n");
fprintf(yyout, "{ ECPGprepare(__LINE__, %s);", $1); fprintf(yyout, "{ ECPGprepare(__LINE__, %s);", $1);
whenever_action(2); whenever_action(2);
@ -566,7 +566,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, connection); }
} }
| ECPGSetConnection { | ECPGSetConnection {
if (connection) if (connection)
mmerror(ET_ERROR, "no at option for set connection statement.\n"); mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement.\n");
fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1); fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
whenever_action(2); whenever_action(2);
@ -574,19 +574,19 @@ stmt: AlterSchemaStmt { output_statement($1, 0, connection); }
} }
| ECPGTypedef { | ECPGTypedef {
if (connection) if (connection)
mmerror(ET_ERROR, "no at option for typedef statement.\n"); mmerror(PARSE_ERROR, ET_ERROR, "no at option for typedef statement.\n");
output_simple_statement($1); output_simple_statement($1);
} }
| ECPGVar { | ECPGVar {
if (connection) if (connection)
mmerror(ET_ERROR, "no at option for var statement.\n"); mmerror(PARSE_ERROR, ET_ERROR, "no at option for var statement.\n");
output_simple_statement($1); output_simple_statement($1);
} }
| ECPGWhenever { | ECPGWhenever {
if (connection) if (connection)
mmerror(ET_ERROR, "no at option for whenever statement.\n"); mmerror(PARSE_ERROR, ET_ERROR, "no at option for whenever statement.\n");
output_simple_statement($1); output_simple_statement($1);
} }
@ -831,7 +831,7 @@ var_value: opt_boolean { $$ = $1; }
| AllConst { $$ = $1; } | AllConst { $$ = $1; }
| name_list { | name_list {
if (strlen($1) == 0) if (strlen($1) == 0)
mmerror(ET_ERROR, "SET must have at least one argument."); mmerror(PARSE_ERROR, ET_ERROR, "SET must have at least one argument.");
$$ = $1; $$ = $1;
} }
@ -1098,11 +1098,11 @@ OptTemp: TEMPORARY { $$ = make_str("temporary"); }
| LOCAL TEMPORARY { $$ = make_str("local temporary"); } | LOCAL TEMPORARY { $$ = make_str("local temporary"); }
| LOCAL TEMP { $$ = make_str("local temp"); } | LOCAL TEMP { $$ = make_str("local temp"); }
| GLOBAL TEMPORARY { | GLOBAL TEMPORARY {
mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
$$ = make_str("global temporary"); $$ = make_str("global temporary");
} }
| GLOBAL TEMP { | GLOBAL TEMP {
mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
$$ = make_str("global temp"); $$ = make_str("global temp");
} }
| /*EMPTY*/ { $$ = EMPTY; } | /*EMPTY*/ { $$ = EMPTY; }
@ -1128,7 +1128,7 @@ columnDef: ColId Typename ColQualList opt_collate
if (strlen($4) > 0) if (strlen($4) > 0)
{ {
sprintf(errortext, "Currently unsupported CREATE TABLE / COLLATE %s will be passed to backend", $4); sprintf(errortext, "Currently unsupported CREATE TABLE / COLLATE %s will be passed to backend", $4);
mmerror(ET_NOTICE, errortext); mmerror(PARSE_ERROR, ET_NOTICE, errortext);
} }
$$ = cat_str(4, $1, $2, $3, $4); $$ = cat_str(4, $1, $2, $3, $4);
} }
@ -1243,7 +1243,7 @@ key_match: MATCH FULL
} }
| MATCH PARTIAL | MATCH PARTIAL
{ {
mmerror(ET_NOTICE, "Currently unsupported FOREIGN KEY/MATCH PARTIAL will be passed to backend"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported FOREIGN KEY/MATCH PARTIAL will be passed to backend");
$$ = make_str("match partial"); $$ = make_str("match partial");
} }
| /*EMPTY*/ | /*EMPTY*/
@ -1289,7 +1289,7 @@ CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS
{ FoundInto = 0; } SelectStmt { FoundInto = 0; } SelectStmt
{ {
if (FoundInto == 1) if (FoundInto == 1)
mmerror(ET_ERROR, "CREATE TABLE / AS SELECT may not specify INTO"); mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE / AS SELECT may not specify INTO");
$$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, $5, make_str("as"), $8); $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, $5, make_str("as"), $8);
} }
@ -1474,7 +1474,7 @@ ConstraintAttributeSpec: ConstraintDeferrabilitySpec
| ConstraintDeferrabilitySpec ConstraintTimeSpec | ConstraintDeferrabilitySpec ConstraintTimeSpec
{ {
if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 ) if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 )
mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE"); mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
$$ = cat2_str($1, $2); $$ = cat2_str($1, $2);
} }
@ -1483,7 +1483,7 @@ ConstraintAttributeSpec: ConstraintDeferrabilitySpec
| ConstraintTimeSpec ConstraintDeferrabilitySpec | ConstraintTimeSpec ConstraintDeferrabilitySpec
{ {
if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 ) if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE"); mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
$$ = cat2_str($1, $2); $$ = cat2_str($1, $2);
} }
@ -1592,7 +1592,7 @@ TruncateStmt: TRUNCATE opt_table relation_name
FetchStmt: FETCH direction fetch_how_many from_in name ecpg_into FetchStmt: FETCH direction fetch_how_many from_in name ecpg_into
{ {
if (strcmp($2, "relative") == 0 && atol($3) == 0L) if (strcmp($2, "relative") == 0 && atol($3) == 0L)
mmerror(ET_ERROR, "FETCH/RELATIVE at current position is not supported"); mmerror(PARSE_ERROR, ET_ERROR, "FETCH/RELATIVE at current position is not supported");
$$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5); $$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5);
} }
@ -1638,7 +1638,7 @@ direction: FORWARD { $$ = make_str("forward"); }
| BACKWARD { $$ = make_str("backward"); } | BACKWARD { $$ = make_str("backward"); }
| RELATIVE { $$ = make_str("relative"); } | RELATIVE { $$ = make_str("relative"); }
| ABSOLUTE { | ABSOLUTE {
mmerror(ET_NOTICE, "Currently unsupported FETCH/ABSOLUTE will be passed to backend, backend will use RELATIVE"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported FETCH/ABSOLUTE will be passed to backend, backend will use RELATIVE");
$$ = make_str("absolute"); $$ = make_str("absolute");
} }
; ;
@ -1795,7 +1795,7 @@ grantee_list: grantee { $$ = $1; }
opt_with_grant: WITH GRANT OPTION opt_with_grant: WITH GRANT OPTION
{ {
mmerror(ET_NOTICE, "Currently unsupported GRANT/WITH GRANT OPTION will be passed to backend"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported GRANT/WITH GRANT OPTION will be passed to backend");
$$ = make_str("with grant option"); $$ = make_str("with grant option");
} }
| /*EMPTY*/ { $$ = EMPTY; } | /*EMPTY*/ { $$ = EMPTY; }
@ -1947,12 +1947,12 @@ func_arg: opt_arg func_type
opt_arg: IN { $$ = make_str("in"); } opt_arg: IN { $$ = make_str("in"); }
| OUT { | OUT {
mmerror(ET_NOTICE, "Currently unsupported CREATE FUNCTION/OUT will be passed to backend"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE FUNCTION/OUT will be passed to backend");
$$ = make_str("out"); $$ = make_str("out");
} }
| INOUT { | INOUT {
mmerror(ET_NOTICE, "Currently unsupported CREATE FUNCTION/INOUT will be passed to backend"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE FUNCTION/INOUT will be passed to backend");
$$ = make_str("inout"); $$ = make_str("inout");
} }
@ -2021,7 +2021,7 @@ RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
oper_argtypes: Typename oper_argtypes: Typename
{ {
mmerror(ET_ERROR, "parser: argument type missing (use NONE for unary operators)"); mmerror(PARSE_ERROR, ET_ERROR, "parser: argument type missing (use NONE for unary operators)");
} }
| Typename ',' Typename | Typename ',' Typename
{ $$ = cat_str(3, $1, make_str(","), $3); } { $$ = cat_str(3, $1, make_str(","), $3); }
@ -2192,7 +2192,7 @@ opt_trans: WORK { $$ = ""; }
opt_chain: AND NO CHAIN { $$ = make_str("and no chain"); } opt_chain: AND NO CHAIN { $$ = make_str("and no chain"); }
| AND CHAIN { | AND CHAIN {
mmerror(ET_NOTICE, "Currently unsupported COMMIT/CHAIN will be passed to backend"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported COMMIT/CHAIN will be passed to backend");
$$ = make_str("and chain"); $$ = make_str("and chain");
} }
@ -2505,7 +2505,7 @@ CursorStmt: DECLARE name opt_cursor CURSOR FOR SelectStmt
{ {
/* re-definition is a bug */ /* re-definition is a bug */
sprintf(errortext, "cursor %s already defined", $2); sprintf(errortext, "cursor %s already defined", $2);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
} }
@ -2637,12 +2637,12 @@ OptTempTableName: TEMPORARY opt_table relation_name
} }
| GLOBAL TEMPORARY opt_table relation_name | GLOBAL TEMPORARY opt_table relation_name
{ {
mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
$$ = cat_str(3, make_str("global temporary"), $3, $4); $$ = cat_str(3, make_str("global temporary"), $3, $4);
} }
| GLOBAL TEMP opt_table relation_name | GLOBAL TEMP opt_table relation_name
{ {
mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend"); mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
$$ = cat_str(3, make_str("global temp"), $3, $4); $$ = cat_str(3, make_str("global temp"), $3, $4);
} }
| TABLE relation_name | TABLE relation_name
@ -2701,7 +2701,7 @@ select_limit: LIMIT select_limit_value OFFSET select_offset_value
| LIMIT select_limit_value ',' select_offset_value | LIMIT select_limit_value ',' select_offset_value
{ $$ = cat_str(4, make_str("limit"), $2, make_str(","), $4); } { $$ = cat_str(4, make_str("limit"), $2, make_str(","), $4); }
/* enable this in 7.3, bjm 2001-10-22 /* enable this in 7.3, bjm 2001-10-22
{ mmerror(ET_NOTICE, "No longer supported LIMIT #,# syntax passed to backend."); } { mmerror(PARSE_ERROR, ET_NOTICE, "No longer supported LIMIT #,# syntax passed to backend."); }
*/ */
; ;
@ -2711,7 +2711,7 @@ opt_select_limit: select_limit { $$ = $1; }
select_limit_value: PosIntConst { select_limit_value: PosIntConst {
if (atoi($1) < 0) if (atoi($1) < 0)
mmerror(ET_ERROR, "LIMIT must not be negative"); mmerror(PARSE_ERROR, ET_ERROR, "LIMIT must not be negative");
$$ = $1; $$ = $1;
} }
| ALL { $$ = make_str("all"); } | ALL { $$ = make_str("all"); }
@ -2720,7 +2720,7 @@ select_limit_value: PosIntConst {
select_offset_value: PosIntConst { select_offset_value: PosIntConst {
if (atoi($1) < 0) if (atoi($1) < 0)
mmerror(ET_ERROR, "OFFSET must not be negative"); mmerror(PARSE_ERROR, ET_ERROR, "OFFSET must not be negative");
$$ = $1; $$ = $1;
} }
| PARAM { $$ = make_name(); } | PARAM { $$ = make_name(); }
@ -2809,7 +2809,7 @@ table_ref: relation_expr
} }
| select_with_parens | select_with_parens
{ {
mmerror(ET_ERROR, "sub-SELECT in FROM must have an alias"); mmerror(PARSE_ERROR, ET_ERROR, "sub-SELECT in FROM must have an alias");
} }
| select_with_parens alias_clause | select_with_parens alias_clause
{ {
@ -3838,14 +3838,14 @@ UserId: ColId { $$ = $1;};
SpecialRuleRelation: OLD SpecialRuleRelation: OLD
{ {
if (!QueryIsRule) if (!QueryIsRule)
mmerror(ET_ERROR, "OLD used in non-rule query"); mmerror(PARSE_ERROR, ET_ERROR, "OLD used in non-rule query");
$$ = make_str("old"); $$ = make_str("old");
} }
| NEW | NEW
{ {
if (!QueryIsRule) if (!QueryIsRule)
mmerror(ET_ERROR, "NEW used in non-rule query"); mmerror(PARSE_ERROR, ET_ERROR, "NEW used in non-rule query");
$$ = make_str("new"); $$ = make_str("new");
} }
@ -3878,7 +3878,7 @@ connection_target: database_name opt_server opt_port
if (strlen($2) > 0 && *($2) != '@') if (strlen($2) > 0 && *($2) != '@')
{ {
sprintf(errortext, "Expected '@', found '%s'", $2); sprintf(errortext, "Expected '@', found '%s'", $2);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
$$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\"")); $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
@ -3889,13 +3889,13 @@ connection_target: database_name opt_server opt_port
if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0) if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0)
{ {
sprintf(errortext, "only protocols 'tcp' and 'unix' and database type 'postgresql' are supported"); sprintf(errortext, "only protocols 'tcp' and 'unix' and database type 'postgresql' are supported");
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
if (strncmp($3, "//", strlen("//")) != 0) if (strncmp($3, "//", strlen("//")) != 0)
{ {
sprintf(errortext, "Expected '://', found '%s'", $3); sprintf(errortext, "Expected '://', found '%s'", $3);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
if (strncmp($1, "unix", strlen("unix")) == 0 && if (strncmp($1, "unix", strlen("unix")) == 0 &&
@ -3903,7 +3903,7 @@ connection_target: database_name opt_server opt_port
strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0) strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
{ {
sprintf(errortext, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $3 + strlen("//")); sprintf(errortext, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $3 + strlen("//"));
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
$$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6), $7, make_str("\""))); $$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6), $7, make_str("\"")));
@ -3935,13 +3935,13 @@ db_prefix: ident cvariable
if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0) if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
{ {
sprintf(errortext, "Expected 'postgresql', found '%s'", $2); sprintf(errortext, "Expected 'postgresql', found '%s'", $2);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0) if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
{ {
sprintf(errortext, "Illegal connection type %s", $1); sprintf(errortext, "Illegal connection type %s", $1);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
$$ = make3_str($1, make_str(":"), $2); $$ = make3_str($1, make_str(":"), $2);
@ -3952,7 +3952,7 @@ server: Op server_name
if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0) if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
{ {
sprintf(errortext, "Expected '@' or '://', found '%s'", $1); sprintf(errortext, "Expected '@' or '://', found '%s'", $1);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
$$ = make2_str($1, $2); $$ = make2_str($1, $2);
@ -4037,7 +4037,7 @@ char_variable: cvariable
$$ = make2_str($1, make_str(".arr")); $$ = make2_str($1, make_str(".arr"));
break; break;
default: default:
mmerror(ET_ERROR, "invalid datatype"); mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
break; break;
} }
} }
@ -4045,12 +4045,12 @@ char_variable: cvariable
opt_options: Op ColId opt_options: Op ColId
{ {
if (strlen($1) == 0) if (strlen($1) == 0)
mmerror(ET_ERROR, "incomplete statement"); mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
if (strcmp($1, "?") != 0) if (strcmp($1, "?") != 0)
{ {
sprintf(errortext, "unrecognised token '%s'", $1); sprintf(errortext, "unrecognised token '%s'", $1);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
$$ = make2_str(make_str("?"), $2); $$ = make2_str(make_str("?"), $2);
@ -4073,7 +4073,7 @@ ECPGCursorStmt: DECLARE name opt_cursor CURSOR FOR ident
{ {
/* re-definition is a bug */ /* re-definition is a bug */
sprintf(errortext, "cursor %s already defined", $2); sprintf(errortext, "cursor %s already defined", $2);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
} }
@ -4268,7 +4268,7 @@ s_struct: SQL_STRUCT opt_symbol
{ {
struct_member_list[struct_level++] = NULL; struct_member_list[struct_level++] = NULL;
if (struct_level >= STRUCT_DEPTH) if (struct_level >= STRUCT_DEPTH)
mmerror(ET_ERROR, "Too many levels in nested structure definition"); mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
$$ = cat2_str(make_str("struct"), $2); $$ = cat2_str(make_str("struct"), $2);
}; };
@ -4277,7 +4277,7 @@ s_union: UNION opt_symbol
{ {
struct_member_list[struct_level++] = NULL; struct_member_list[struct_level++] = NULL;
if (struct_level >= STRUCT_DEPTH) if (struct_level >= STRUCT_DEPTH)
mmerror(ET_ERROR, "Too many levels in nested structure definition"); mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
$$ = cat2_str(make_str("union"), $2); $$ = cat2_str(make_str("union"), $2);
}; };
@ -4386,7 +4386,7 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer
sprintf(ascii_len, "%d", length); sprintf(ascii_len, "%d", length);
if (length == 0) if (length == 0)
mmerror(ET_ERROR, "pointer to varchar are not implemented"); mmerror(PARSE_ERROR, ET_ERROR, "pointer to varchar are not implemented");
if (dimension == 0) if (dimension == 0)
$$ = cat_str(7, mm_strdup(actual_storage[struct_level]), make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(ascii_len), make_str("]; } *"), mm_strdup($2), $4); $$ = cat_str(7, mm_strdup(actual_storage[struct_level]), make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(ascii_len), make_str("]; } *"), mm_strdup($2), $4);
@ -4615,7 +4615,7 @@ ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE cvari
ECPGRelease: TransactionStmt SQL_RELEASE ECPGRelease: TransactionStmt SQL_RELEASE
{ {
if (strcmp($1, "begin") == 0) if (strcmp($1, "begin") == 0)
mmerror(ET_ERROR, "RELEASE does not make sense when beginning a transaction"); mmerror(PARSE_ERROR, ET_ERROR, "RELEASE does not make sense when beginning a transaction");
fprintf(yyout, "ECPGtrans(__LINE__, %s, \"%s\");", fprintf(yyout, "ECPGtrans(__LINE__, %s, \"%s\");",
connection ? connection : "NULL", $1); connection ? connection : "NULL", $1);
@ -4669,7 +4669,7 @@ ECPGTypedef: TYPE_P
$5.type_enum == ECPGt_union) && $5.type_enum == ECPGt_union) &&
initializer == 1) initializer == 1)
{ {
mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command"); mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
} }
else else
{ {
@ -4679,7 +4679,7 @@ ECPGTypedef: TYPE_P
{ {
/* re-definition is a bug */ /* re-definition is a bug */
sprintf(errortext, "Type %s already defined", $3); sprintf(errortext, "Type %s already defined", $3);
mmerror(ET_ERROR, errortext); mmerror(PARSE_ERROR, ET_ERROR, errortext);
} }
} }
@ -4702,7 +4702,7 @@ ECPGTypedef: TYPE_P
$5.type_enum != ECPGt_char && $5.type_enum != ECPGt_char &&
$5.type_enum != ECPGt_unsigned_char && $5.type_enum != ECPGt_unsigned_char &&
this->type->type_index >= 0) this->type->type_index >= 0)
mmerror(ET_ERROR, "No multi-dimensional array support for simple data types"); mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
types = this; types = this;
} }
@ -4772,7 +4772,7 @@ ECPGVar: SQL_VAR
$5.type_enum == ECPGt_union) && $5.type_enum == ECPGt_union) &&
initializer == 1) initializer == 1)
{ {
mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command"); mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
} }
else else
{ {
@ -4804,7 +4804,7 @@ ECPGVar: SQL_VAR
break; break;
default: default:
if (length >= 0) if (length >= 0)
mmerror(ET_ERROR, "No multi-dimensional array support for simple data types"); mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
if (dimension < 0) if (dimension < 0)
type = ECPGmake_simple_type($5.type_enum, 1); type = ECPGmake_simple_type($5.type_enum, 1);
@ -5338,7 +5338,7 @@ coutputvariable: cvariable indicator
civarind: cvariable indicator civarind: cvariable indicator
{ {
if ($2 != NULL && (find_variable($2))->type->typ == ECPGt_array) if ($2 != NULL && (find_variable($2))->type->typ == ECPGt_array)
mmerror(ET_ERROR, "arrays of indicators are not allowed on input"); mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2)); add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
}; };
@ -5472,5 +5472,5 @@ void yyerror( char * error)
{ char buf[1024]; { char buf[1024];
snprintf(buf,sizeof buf,"%s at or near \"%s\"",error,yytext); snprintf(buf,sizeof buf,"%s at or near \"%s\"",error,yytext);
buf[sizeof(buf)-1]=0; buf[sizeof(buf)-1]=0;
mmerror(ET_ERROR, buf); mmerror(PARSE_ERROR, ET_ERROR, buf);
} }

View File

@ -2,6 +2,8 @@
#include "extern.h" #include "extern.h"
#define indicator_set ind_typ != NULL && ind_typ->typ != ECPGt_NO_INDICATOR
struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL}; struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL};
/* malloc + error check */ /* malloc + error check */
@ -11,10 +13,7 @@ mm_alloc(size_t size)
void *ptr = malloc(size); void *ptr = malloc(size);
if (ptr == NULL) if (ptr == NULL)
{ mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n");
fprintf(stderr, "Out of memory\n");
exit(OUT_OF_MEMORY);
}
return ptr; return ptr;
} }
@ -26,11 +25,8 @@ mm_strdup(const char *string)
char *new = strdup(string); char *new = strdup(string);
if (new == NULL) if (new == NULL)
{ mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n");
fprintf(stderr, "Out of memory\n");
exit(OUT_OF_MEMORY);
}
return new; return new;
} }
@ -202,23 +198,19 @@ static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, long arrsiz, static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, long arrsiz,
struct ECPGtype * typ, struct ECPGtype * ind_typ, const char *offset, const char *prefix, const char *ind_prefix); struct ECPGtype * typ, struct ECPGtype * ind_typ, const char *offset, const char *prefix, const char *ind_prefix);
void void
ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *ind_name, struct ECPGtype * ind_typ, const char *prefix, const char *ind_prefix) ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *ind_name, struct ECPGtype * ind_typ, const char *prefix, const char *ind_prefix)
{ {
/* if (ind_typ == NULL)
{
ind_typ = &ecpg_no_indicator;
ind_name = "no_indicator";
}*/
switch (typ->typ) switch (typ->typ)
{ {
case ECPGt_array: case ECPGt_array:
if (indicator_set && ind_typ->typ != ECPGt_array)
mmerror(INDICATOR_NOT_ARRAY, ET_FATAL, "Indicator for array/pointer has to be array/pointer.\n");
switch (typ->u.element->typ) switch (typ->u.element->typ)
{ {
case ECPGt_array: case ECPGt_array:
yyerror("No nested arrays allowed (except strings)"); /* array of array */ mmerror(PARSE_ERROR, ET_ERROR, "No nested arrays allowed (except strings)"); /* array of array */
break; break;
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
@ -235,33 +227,38 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
if (ind_typ->typ == ECPGt_NO_INDICATOR) if (ind_typ->typ == ECPGt_NO_INDICATOR)
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
else else
{
if (ind_typ->typ != ECPGt_array)
{
fprintf(stderr, "Indicator for an array has to be array too.\n");
exit(INDICATOR_NOT_ARRAY);
}
ECPGdump_a_simple(o, ind_name, ind_typ->u.element->typ, ECPGdump_a_simple(o, ind_name, ind_typ->u.element->typ,
ind_typ->u.element->size, ind_typ->size, NULL, prefix); ind_typ->u.element->size, ind_typ->size, NULL, prefix);
}
} }
} }
break; break;
case ECPGt_struct: case ECPGt_struct:
if (indicator_set && ind_typ->typ != ECPGt_struct)
mmerror(INDICATOR_NOT_STRUCT, ET_FATAL, "Indicator for struct has to be struct.\n");
ECPGdump_a_struct(o, name, ind_name, 1, typ, ind_typ, NULL, prefix, ind_prefix); ECPGdump_a_struct(o, name, ind_name, 1, typ, ind_typ, NULL, prefix, ind_prefix);
break; break;
case ECPGt_union: /* cannot dump a complete union */ case ECPGt_union: /* cannot dump a complete union */
yyerror("Type of union has to be specified"); yyerror("Type of union has to be specified");
break; break;
case ECPGt_char_variable: case ECPGt_char_variable:
if (indicator_set && (ind_typ->typ == ECPGt_struct || ind_typ->typ == ECPGt_array))
mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
ECPGdump_a_simple(o, name, typ->typ, 1, 1, NULL, prefix); 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); ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
break; break;
case ECPGt_descriptor: case ECPGt_descriptor:
if (indicator_set && (ind_typ->typ == ECPGt_struct || ind_typ->typ == ECPGt_array))
mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
ECPGdump_a_simple(o, name, typ->typ, 0, -1, NULL, prefix); 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); ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
break; break;
default: default:
if (indicator_set && (ind_typ->typ == ECPGt_struct || ind_typ->typ == ECPGt_array))
mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix); ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix);
if (ind_typ != NULL) if (ind_typ != NULL)
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
@ -361,7 +358,7 @@ ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, long arrsiz,
struct ECPGstruct_member *p, struct ECPGstruct_member *p,
*ind_p = NULL; *ind_p = NULL;
char obuf[BUFSIZ]; char obuf[BUFSIZ];
char pbuf[BUFSIZ*2], char pbuf[BUFSIZ],
ind_pbuf[BUFSIZ]; ind_pbuf[BUFSIZ];
const char *offset; const char *offset;