commit d9ff326b4bed2929253aeac519a9b19b1e132646 Author: Böszörményi Zoltán Date: Fri Dec 6 12:28:57 2013 +0100 ECPG: Split ecpg_do() further and introduce ecpg_do_prologue(). Add an error path to return if ecpg_strdup(setlocale()) fails. diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 551902d..c43b59c 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -1704,21 +1704,27 @@ ecpg_execute(struct statement * stmt) } /* - * Execute SQL statements in the backend. - * The input/output parameters (variable argument list) are passed - * in a va_list, so other functions can use this interface. + * ecpg_do_prologue + * Initialize various infrastructure elements for executing the statement: + * - create the statement structure + * - set the C locale for communicating with the backend + * - preprocess the variable list of input/output parameters into + * linked lists */ bool -ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args) +ecpg_do_prologue(int lineno, const int compat, const int force_indicator, + const char *connection_name, const bool questionmarks, + enum ECPG_statement_type statement_type, const char *query, + va_list args, struct statement **stmt_out) { struct statement *stmt; struct connection *con; - bool status; enum ECPGttype type; struct variable **list; - enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st; char *prepname; + *stmt_out = NULL; + if (!query) { ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL); @@ -1733,6 +1739,11 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha /* Make sure we do NOT honor the locale for numeric input/output */ /* since the database wants the standard decimal point */ stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno); + if (stmt->oldlocale == NULL) + { + ecpg_do_epilogue(stmt); + return false; + } setlocale(LC_NUMERIC, "C"); #ifdef ENABLE_THREAD_SAFETY @@ -1905,12 +1916,9 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha /* initialize auto_mem struct */ ecpg_clear_auto_mem(); - status = ecpg_execute(stmt); + *stmt_out = stmt; - /* and reset locale value so our application is not affected */ - ecpg_do_epilogue(stmt); - - return (status); + return true; } /* @@ -1929,6 +1937,34 @@ ecpg_do_epilogue(struct statement *stmt) /* * Execute SQL statements in the backend. + * The input/output parameters (variable argument list) are passed + * in a va_list, so other functions can use this interface. + */ +bool +ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args) +{ + struct statement *stmt; + bool status; + + if (!ecpg_do_prologue(lineno, compat, force_indicator, + connection_name, questionmarks, + (enum ECPG_statement_type) st, + query, args, &stmt)) + { + ecpg_do_epilogue(stmt); + return false; + } + + status = ecpg_execute(stmt); + + /* and reset locale value so our application is not affected */ + ecpg_do_epilogue(stmt); + + return (status); +} + +/* + * Execute SQL statements in the backend. * The input/output parameters are passed as variable-length argument list. */ bool diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h index c469220..83ea011 100644 --- a/src/interfaces/ecpg/ecpglib/extern.h +++ b/src/interfaces/ecpg/ecpglib/extern.h @@ -169,7 +169,11 @@ bool ecpg_store_result(const PGresult *results, int act_field, bool ecpg_store_input(const int, const bool, const struct variable *, char **, bool); void ecpg_free_params(struct statement *stmt, bool print); void ecpg_do_epilogue(struct statement *); -bool ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list); +bool ecpg_do_prologue(int, const int, const int, const char *, const bool, + enum ECPG_statement_type, const char *, va_list, + struct statement **); +bool ecpg_do(const int, const int, const int, const char *, const bool, + const int, const char *, va_list); bool ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE); void ecpg_raise(int line, int code, const char *sqlstate, const char *str);