diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 36b592670c..38d8e28e21 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -535,5 +535,14 @@ Sat Mar 20 19:57:42 CET 1999 - Synced preproc.y with gram.y. - Fixed handling of ';' character. + +Sun Mar 21 13:05:50 CET 1999 + + - Synced preproc.y with gram.y. + +Mon Mar 22 19:22:38 CET 1999 + + - Fixed incorrect password entry in parser. + - Made no_auto_trans available for each connection seperately. - Set library version to 3.0.0 - Set ecpg version to 2.6.0 diff --git a/src/interfaces/ecpg/TODO b/src/interfaces/ecpg/TODO index 005fe05c9a..114500850c 100644 --- a/src/interfaces/ecpg/TODO +++ b/src/interfaces/ecpg/TODO @@ -1,8 +1,6 @@ The complete structure definition has to be listed inside the declare section of the structure variable for ecpg to be able to understand it. -Variable type bool has to be tested. I never used it so far. - The error message for "no data" in an exec sql insert select from statement has to be 100. @@ -13,6 +11,9 @@ it would be nice to be able to use :var[:index] as cvariable support for dynamic SQL with unknown number of variables with DESCRIPTORS +The line numbering is not exact. + Missing statements: - exec sql allocate + - exec sql deallocate - SQLSTATE diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h index a5af239f79..0c06e117e6 100644 --- a/src/interfaces/ecpg/include/ecpglib.h +++ b/src/interfaces/ecpg/include/ecpglib.h @@ -8,7 +8,7 @@ extern "C" void ECPGdebug(int, FILE *); bool ECPGstatus(int, const char *); bool ECPGsetconn(int, const char *); - bool ECPGconnect(int, const char *, const char *, const char *, const char *); + bool ECPGconnect(int, const char *, const char *, const char *, const char *, int); bool ECPGdo(int, const char *, char *,...); bool ECPGtrans(int, const char *, const char *); bool ECPGdisconnect(int, const char *); diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c index 4d13f6dcb1..28ef35f69e 100644 --- a/src/interfaces/ecpg/lib/ecpglib.c +++ b/src/interfaces/ecpg/lib/ecpglib.c @@ -26,8 +26,6 @@ #include /* variables visible to the programs */ -int no_auto_trans; - static struct sqlca sqlca_init = { {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '}, @@ -56,7 +54,8 @@ static struct connection { char *name; PGconn *connection; - int committed; + bool committed; + int no_auto_trans; struct connection *next; } *all_connections = NULL, *actual_connection = NULL; @@ -633,7 +632,7 @@ ECPGexecute(struct statement * stmt) /* Now the request is built. */ - if (stmt->connection->committed && !no_auto_trans) + if (stmt->connection->committed && !stmt->connection->no_auto_trans) { if ((results = PQexec(stmt->connection->connection, "begin transaction")) == NULL) { @@ -1144,7 +1143,7 @@ ECPGsetconn(int lineno, const char *connection_name) } bool -ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char *connection_name) +ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char *connection_name, int no_auto_trans) { struct connection *this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno); @@ -1182,6 +1181,7 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd } this->committed = true; + this->no_auto_trans = no_auto_trans; return true; } diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h index 94c76a507a..3558ce3f5d 100644 --- a/src/interfaces/ecpg/preproc/extern.h +++ b/src/interfaces/ecpg/preproc/extern.h @@ -23,6 +23,7 @@ extern struct arguments *argsresult; /* functions */ +extern void output_line_number(void); extern void lex_init(void); extern char *input_filename; extern int yyparse(void); diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index ab75a552cf..c86c51021c 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -149,12 +149,12 @@ real [\-]?(((({digit}*\.{digit}+)|({digit}+\.{digit}*))([Ee][-+]?{digit}+)?)|( param \${integer} comment ("--"|"//").*\n +ccomment "//".*\n space [ \t\n\f] other . /* some stuff needed for ecpg */ -ccomment "//".*\n exec [eE][xX][eE][cC] define [dD][eE][fF][iI][nN][eE] include [iI][nN][cC][lL][uU][dD][eE] @@ -659,6 +659,7 @@ cppline {space}*#.*(\\{space}*\n)*\n* input_filename = mm_strdup(inc_file); yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE )); yylineno = 0; + output_line_number(); BEGIN C; } @@ -682,9 +683,9 @@ cppline {space}*#.*(\\{space}*\n)*\n* yy_buffer = yy_buffer->next; free(yb); + output_line_number(); } } - %% void lex_init(void) diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 820a941719..878d1f20ce 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -37,11 +37,19 @@ struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}}; */ char * input_filename = NULL; -static void +void output_line_number() { if (input_filename) - fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename); + fprintf(yyout, "\n#line %d \"%s\"\n", yylineno + 1, input_filename); +} + +static void +output_simple_statement(char *cmd) +{ + fputs(cmd, yyout); + output_line_number(); + free(cmd); } /* @@ -883,10 +891,7 @@ stmt: AddAttrStmt { output_statement($1, 0); } | RevokeStmt { output_statement($1, 0); } | OptimizableStmt { if (strncmp($1, "/* " , sizeof("/* ")-1) == 0) - { - fputs($1, yyout); - free($1); - } + output_simple_statement($1); else output_statement($1, 1); } @@ -908,14 +913,12 @@ stmt: AddAttrStmt { output_statement($1, 0); } if (connection) yyerror("no at option for connect statement.\n"); - fprintf(yyout, "no_auto_trans = %d;\n", no_auto_trans); - fprintf(yyout, "ECPGconnect(__LINE__, %s);", $1); + fprintf(yyout, "ECPGconnect(__LINE__, %s, %d);", $1, no_auto_trans); whenever_action(0); free($1); } | ECPGCursorStmt { - fputs($1, yyout); - free($1); + output_simple_statement($1); } | ECPGDeallocate { if (connection) @@ -926,8 +929,7 @@ stmt: AddAttrStmt { output_statement($1, 0); } free($1); } | ECPGDeclare { - fputs($1, yyout); - free($1); + output_simple_statement($1); } | ECPGDisconnect { if (connection) @@ -991,23 +993,19 @@ stmt: AddAttrStmt { output_statement($1, 0); } if (connection) yyerror("no at option for typedef statement.\n"); - fputs($1, yyout); - free($1); + output_simple_statement($1); } | ECPGVar { if (connection) yyerror("no at option for var statement.\n"); - fputs($1, yyout); - free($1); + output_simple_statement($1); } | ECPGWhenever { if (connection) yyerror("no at option for whenever statement.\n"); - fputs($1, yyout); - output_line_number(); - free($1); + output_simple_statement($1); } ; @@ -3572,6 +3570,10 @@ a_expr: attr opt_indirection } | '-' a_expr %prec UMINUS { $$ = cat2_str(make1_str("-"), $2); } + | '%' a_expr + { $$ = cat2_str(make1_str("%"), $2); } + | a_expr '%' + { $$ = cat2_str($1, make1_str("%")); } | a_expr '+' a_expr { $$ = cat3_str($1, make1_str("+"), $3); } | a_expr '-' a_expr @@ -3663,7 +3665,6 @@ a_expr: attr opt_indirection { $$ = make1_str("user"); } - | EXISTS '(' SubSelect ')' { $$ = make3_str(make1_str("exists("), $3, make1_str(")")); @@ -3879,6 +3880,10 @@ b_expr: attr opt_indirection } | '-' b_expr %prec UMINUS { $$ = cat2_str(make1_str("-"), $2); } + | '%' b_expr + { $$ = cat2_str(make1_str("%"), $2); } + | b_expr '%' + { $$ = cat2_str($1, make1_str("%")); } | b_expr '+' b_expr { $$ = cat3_str($1, make1_str("+"), $3); } | b_expr '-' b_expr @@ -4677,7 +4682,7 @@ ora_user: user_name { $$ = make2_str($1, make1_str(",NULL")); } - | user_name '/' ColId + | user_name '/' user_name { $$ = make3_str($1, make1_str(","), $3); } @@ -5604,6 +5609,10 @@ ecpg_expr: attr opt_indirection } | '-' ecpg_expr %prec UMINUS { $$ = cat2_str(make1_str("-"), $2); } + | '%' ecpg_expr + { $$ = cat2_str(make1_str("%"), $2); } + | a_expr '%' + { $$ = cat2_str($1, make1_str("%")); } | a_expr '+' ecpg_expr { $$ = cat3_str($1, make1_str("+"), $3); } | a_expr '-' ecpg_expr @@ -5618,6 +5627,10 @@ ecpg_expr: attr opt_indirection { $$ = cat3_str($1, make1_str("<"), $3); } | a_expr '>' ecpg_expr { $$ = cat3_str($1, make1_str(">"), $3); } + | a_expr '=' NULL_P + { $$ = cat2_str($1, make1_str("= NULL")); } + | NULL_P '=' a_expr + { $$ = cat2_str(make1_str("= NULL"), $3); } | a_expr '=' ecpg_expr { $$ = cat3_str($1, make1_str("="), $3); } /* | ':' ecpg_expr @@ -5686,6 +5699,10 @@ ecpg_expr: attr opt_indirection { $$ = make1_str("current_user"); } + | USER + { + $$ = make1_str("user"); + } | EXISTS '(' SubSelect ')' { $$ = make3_str(make1_str("exists("), $3, make1_str(")")); @@ -5758,11 +5775,11 @@ ecpg_expr: attr opt_indirection } | a_expr IN '(' in_expr ')' { - $$ = make4_str($1, make1_str("in ("), $4, make1_str(")")); + $$ = make4_str($1, make1_str(" in ("), $4, make1_str(")")); } | a_expr NOT IN '(' not_in_expr ')' { - $$ = make4_str($1, make1_str("not in ("), $5, make1_str(")")); + $$ = make4_str($1, make1_str(" not in ("), $5, make1_str(")")); } | a_expr Op '(' SubSelect ')' { @@ -5838,7 +5855,7 @@ ecpg_expr: attr opt_indirection } | a_expr Op ALL '(' SubSelect ')' { - $$ = make3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")"))); + $$ = cat3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")"))); } | a_expr '+' ALL '(' SubSelect ')' { @@ -5878,6 +5895,8 @@ ecpg_expr: attr opt_indirection { $$ = cat3_str($1, make1_str("or"), $3); } | NOT ecpg_expr { $$ = cat2_str(make1_str("not"), $2); } + | case_expr + { $$ = $1; } | civariableonly { $$ = $1; } ; diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c index 3399def4e7..3c5d2f3ed0 100644 --- a/src/interfaces/ecpg/preproc/type.c +++ b/src/interfaces/ecpg/preproc/type.c @@ -269,7 +269,6 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ, char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4); char *offset = (char *) mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1); -/* if (varcharsize == 0 || arrsize >= 0)*/ /* we have to use the pointer except for arrays with given bounds */ if (arrsize > 0) sprintf(variable, "(%s%s)", prefix ? prefix : "", name);