commit 7be47896829ee333f3d1e81f3a7cdddffdef3e80
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:26:18 2013 +0100

    ECPG: Introduce ecpg_do(). The core function of ECPGdo() is
    separated out, so va_start and va_end are done centrally, and
    the function can be used elsewhere.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e977a4e..b97e241 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1702,10 +1702,14 @@ ecpg_execute(struct statement * stmt)
 	return status;
 }
 
+/*
+ * 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
-ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+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)
 {
-	va_list		args;
 	struct statement *stmt;
 	struct connection *con;
 	bool		status;
@@ -1740,9 +1744,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		return (false);
 	}
 
-	/* construct statement in our own structure */
-	va_start(args, query);
-
 	/*
 	 * create a list of variables The variables are listed with input
 	 * variables preceding outputvariables The end of each group is marked by
@@ -1765,7 +1766,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 
@@ -1795,7 +1795,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 	}
@@ -1823,7 +1822,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1879,7 +1877,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1894,8 +1891,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		type = va_arg(args, enum ECPGttype);
 	}
 
-	va_end(args);
-
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
@@ -1929,6 +1924,24 @@ ecpg_do_epilogue(struct statement *stmt)
 	free_statement(stmt);
 }
 
+/*
+ * Execute SQL statements in the backend.
+ * The input/output parameters are passed as variable-length argument list.
+ */
+bool
+ECPGdo(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;
+	bool		ret;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name,
+							questionmarks,
+							st, query, args);
+	va_end(args);
+	return ret;
+}
+
 /* old descriptor interface */
 bool
 ECPGdo_descriptor(int line, const char *connection,
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f9a861f..f0e9b3c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -166,6 +166,7 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 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_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
