diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 38d8e28e21..c574dfcf4d 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -544,5 +544,17 @@ Mon Mar 22 19:22:38 CET 1999 - Fixed incorrect password entry in parser. - Made no_auto_trans available for each connection seperately. + +Sat Apr 10 20:10:50 CEST 1999 + + - Allow ecpg handle a floating point constants. + - Fix ecpg runtime library memory leak (patch by Masaaki Sakaida). + +Mon Apr 12 17:56:14 CEST 1999 + + - Fixed ECPG variable handling. + - Make no_auto_trans be accessible via SET command. + - Do not eat comments so line numbering should be correct. - Set library version to 3.0.0 - Set ecpg version to 2.6.0 + diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h index 0c06e117e6..f15fbbe6fe 100644 --- a/src/interfaces/ecpg/include/ecpglib.h +++ b/src/interfaces/ecpg/include/ecpglib.h @@ -7,6 +7,7 @@ extern "C" void ECPGdebug(int, FILE *); bool ECPGstatus(int, const char *); + bool ECPGsetcommit(int, const char *, const char *); bool ECPGsetconn(int, const char *); bool ECPGconnect(int, const char *, const char *, const char *, const char *, int); bool ECPGdo(int, const char *, char *,...); diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c index 28ef35f69e..5da78f8194 100644 --- a/src/interfaces/ecpg/lib/ecpglib.c +++ b/src/interfaces/ecpg/lib/ecpglib.c @@ -370,6 +370,34 @@ create_statement(int lineno, struct connection *connection, struct statement ** return (true); } +static void +free_variable(struct variable *var) +{ + struct variable *var_next; + + if( var == (struct variable *)NULL ) + return; + var_next = var->next; + free(var); + + while(var_next) + { + var = var_next; + var_next = var->next; + free(var); + } +} + +static void +free_statement(struct statement *stmt) +{ + if( stmt == (struct statement *)NULL ) + return; + free_variable(stmt->inlist); + free_variable(stmt->outlist); + free(stmt); +} + static char * next_insert(char *text) { @@ -981,7 +1009,6 @@ ECPGexecute(struct statement * stmt) status = false; } - PQclear(results); break; case PGRES_EMPTY_QUERY: /* do nothing */ @@ -1017,6 +1044,7 @@ ECPGexecute(struct statement * stmt) status = false; break; } + PQclear(results); } /* check for asynchronous returns */ @@ -1037,10 +1065,11 @@ ECPGdo(int lineno, const char *connection_name, char *query,...) va_list args; struct statement *stmt; struct connection *con = get_connection(connection_name); + bool status; if (con == NULL) { - register_error(ECPG_NO_CONN, "No such connection %s in line %d.", connection_name, lineno); + register_error(ECPG_NO_CONN, "No such connection %s in line %d.", connection_name ? connection_name : "NULL", lineno); return (false); } @@ -1057,7 +1086,9 @@ ECPGdo(int lineno, const char *connection_name, char *query,...) return false; } - return (ECPGexecute(stmt)); + status = ECPGexecute(stmt); + free_statement(stmt); + return (status); } bool @@ -1067,7 +1098,7 @@ ECPGstatus(int lineno, const char *connection_name) if (con == NULL) { - register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno); + register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); return (false); } @@ -1090,7 +1121,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction) if (con == NULL) { - register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno); + register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); return (false); } @@ -1125,6 +1156,52 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction) return true; } +bool +ECPGsetcommit(int lineno, const char *mode, const char *connection_name) +{ + struct connection *con = get_connection(connection_name); + PGresult *results; + + if (con) + { + if (con->no_auto_trans == true && strncmp(mode, "ON", strlen("ON")) == 0) + { + if (con->committed) + { + if ((results = PQexec(con->connection, "begin transaction")) == NULL) + { + register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno); + return false; + } + PQclear(results); + con->committed = false; + } + con->no_auto_trans = false; + } + else if (con->no_auto_trans == false && strncmp(mode, "OFF", strlen("OFF")) == 0) + { + if (!con->committed) + { + if ((results = PQexec(con->connection, "commit")) == NULL) + { + register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno); + return false; + } + PQclear(results); + con->committed = true; + } + con->no_auto_trans = true; + } + } + else + { + register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); + return false; + } + + return true; +} + bool ECPGsetconn(int lineno, const char *connection_name) { @@ -1137,7 +1214,7 @@ ECPGsetconn(int lineno, const char *connection_name) } else { - register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno); + register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); return false; } } @@ -1207,8 +1284,8 @@ ECPGdisconnect(int lineno, const char *connection_name) if (con == NULL) { - ECPGlog("disconnect: not connected to connection %s\n", connection_name); - register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno); + ECPGlog("disconnect: not connected to connection %s\n", connection_name ? connection_name : "NULL"); + register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); return false; } else diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index c86c51021c..b9d5bdd79e 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -178,17 +178,18 @@ cppline {space}*#.*(\\{space}*\n)*\n* %% {comment} { /* ignore */ } -{xcline} { /* ignore */ } +{xcline} { ECHO; } -{xcstar} { /* ignore */ } +{xcstar} { ECHO; } {xcstart} { before_comment = YYSTATE; + ECHO; BEGIN(xc); } -{xcstop} { BEGIN(before_comment); } +{xcstop} { ECHO; BEGIN(before_comment); } -{xcinside} { /* ignore */ } +{xcinside} { ECHO; } {xbstart} { BEGIN(xb); @@ -376,7 +377,7 @@ cppline {space}*#.*(\\{space}*\n)*\n* } } } -{integer}/{space}*-{number} { +{integer}/{space}*-{number} { char* endptr; BEGIN(xm); @@ -393,7 +394,7 @@ cppline {space}*#.*(\\{space}*\n)*\n* } return ICONST; } -{real}/{space}*-{number} { +{real}/{space}*-{number} { char* endptr; BEGIN(xm); @@ -403,7 +404,7 @@ cppline {space}*#.*(\\{space}*\n)*\n* yyerror("ERROR: Bad float8 input"); return FCONST; } -{integer} { +{integer} { char* endptr; errno = 0; @@ -419,7 +420,7 @@ cppline {space}*#.*(\\{space}*\n)*\n* } return ICONST; } -{real} { +{real} { char* endptr; errno = 0; @@ -428,39 +429,6 @@ cppline {space}*#.*(\\{space}*\n)*\n* yyerror("ERROR: Bad float input"); return FCONST; } -{integer}/{space}*-{number} { - char* endptr; - - BEGIN(xm); - errno = 0; - yylval.ival = strtol((char *)yytext,&endptr,10); - if (*endptr != '\0' || errno == ERANGE) - { - errno = 0; - yylval.dval = strtod(((char *)yytext),&endptr); - if (*endptr != '\0' || errno == ERANGE) - yyerror("ERROR: Bad integer input"); - yyerror("WARNING: Integer input is out of range; promoted to float"); - return FCONST; - } - return ICONST; - } -{integer} { - char* endptr; - - errno = 0; - yylval.ival = strtol((char *)yytext,&endptr,10); - if (*endptr != '\0' || errno == ERANGE) - { - errno = 0; - yylval.dval = strtod(((char *)yytext),&endptr); - if (*endptr != '\0' || errno == ERANGE) - yyerror("ERROR: Bad integer input"); - yyerror("WARNING: Integer input is out of range; promoted to float"); - return FCONST; - } - return ICONST; - } :{identifier}(("->"|\.){identifier})* { yylval.str = mm_strdup((char*)yytext+1); return(CVARIABLE);