[asterisk-commits] markm: trunk r300882 - /trunk/res/res_config_pgsql.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jan 7 01:47:43 UTC 2011


Author: markm
Date: Fri Jan  7 01:47:36 2011
New Revision: 300882

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=300882
Log:
Added support for postgres database retry query on disconnection to res_config_pgsql

If your postgres connection died suddenly in between res_config_pgsql
queries, the next query will fail because the query is executed on a
disconnected/disconnecting handle.  The query is abandoned and is
returned from in error.

Now we will reconnect and try again if a query was run on a
disconnected connection.

(closes issue #18071)

Modified:
    trunk/res/res_config_pgsql.c

Modified: trunk/res/res_config_pgsql.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_config_pgsql.c?view=diff&rev=300882&r1=300881&r2=300882
==============================================================================
--- trunk/res/res_config_pgsql.c (original)
+++ trunk/res/res_config_pgsql.c Fri Jan  7 01:47:36 2011
@@ -125,13 +125,134 @@
 	ast_free(table);
 }
 
-static struct tables *find_table(const char *orig_tablename)
+/*! \brief Helper function for pgsql_exec.  For running querys, use pgsql_exec()
+ *
+ *  Connect if not currently connected.  Run the given query.
+ *
+ *  \param database   database name we are connected to (used for error logging)
+ *  \param tablename  table  name we are connected to (used for error logging)
+ *  \param sql        sql query string to execute
+ *  \param result     pointer for where to store the result handle
+ *
+ *  \return -1 on fatal query error
+ *  \return -2 on query failure that resulted in disconnection
+ *  \return 0 on success
+ *
+ *  \example see pgsql_exec for full example
+ */
+static int _pgsql_exec(const char *database, const char *tablename, const char *sql, PGresult **result)
+{
+	ExecStatusType result_status;
+
+	if (!pgsqlConn) {
+		ast_debug(1, "PostgreSQL connection not defined, connecting\n");
+
+		if (pgsql_reconnect(database) != 1) {
+			ast_log(LOG_NOTICE, "reconnect failed\n");
+			*result = NULL;
+			return -1;
+		}
+
+		ast_debug(1, "PostgreSQL connection successful\n");
+	}
+
+	*result = PQexec(pgsqlConn, sql);
+	result_status = PQresultStatus(*result);
+	if (result_status != PGRES_COMMAND_OK
+		&& result_status != PGRES_TUPLES_OK
+		&& result_status != PGRES_NONFATAL_ERROR) {
+
+		ast_log(LOG_ERROR, "PostgreSQL RealTime: Failed to query '%s@%s'.\n", tablename, database);
+		ast_log(LOG_ERROR, "PostgreSQL RealTime: Query Failed: %s\n", sql);
+		ast_log(LOG_ERROR, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
+			PQresultErrorMessage(*result),
+			PQresStatus(result_status));
+
+		/* we may have tried to run a command on a disconnected/disconnecting handle */
+		/* are we no longer connected to the database... if not try again */
+		if (PQstatus(pgsqlConn) != CONNECTION_OK) {
+			PQfinish(pgsqlConn);
+			pgsqlConn = NULL;
+			return -2;
+		}
+
+		/* connection still okay, which means the query is just plain bad */
+		return -1;
+	}
+
+	ast_debug(1, "PostgreSQL query successful: %s\n", sql);
+	return 0;
+}
+
+/*! \brief Do a postgres query, with reconnection support
+ *
+ *  Connect if not currently connected.  Run the given query
+ *  and if we're disconnected afterwards, reconnect and query again.
+ *
+ *  \param database   database name we are connected to (used for error logging)
+ *  \param tablename  table  name we are connected to (used for error logging)
+ *  \param sql        sql query string to execute
+ *  \param result     pointer for where to store the result handle
+ *
+ *  \return -1 on query failure
+ *  \return 0 on success
+ *
+ *  \example
+ *	int i, rows;
+ *	PGresult *result;
+ *	char *field_name, *field_type, *field_len, *field_notnull, *field_default;
+ *
+ *	pgsql_exec("db", "table", "SELECT 1", &result)
+ *
+ *	rows = PQntuples(result);
+ *	for (i = 0; i < rows; i++) {
+ *		field_name    = PQgetvalue(result, i, 0);
+ *		field_type    = PQgetvalue(result, i, 1);
+ *		field_len     = PQgetvalue(result, i, 2);
+ *		field_notnull = PQgetvalue(result, i, 3);
+ *		field_default = PQgetvalue(result, i, 4);
+ *	}
+ *
+ */
+static int pgsql_exec(const char *database, const char *tablename, const char *sql, PGresult **result)
+{
+	int attempts = 0;
+	int res;
+
+	/* Try the query, note failure if any */
+	/* On first failure, reconnect and try again (_pgsql_exec handles reconnect) */
+	/* On second failure, treat as fatal query error */
+
+	while (attempts++ < 2) {
+		ast_debug(1, "PostgreSQL query attempt %d\n", attempts);
+		res = _pgsql_exec(database, tablename, sql, result);
+
+		if (res == 0) {
+			if (attempts > 1) {
+				ast_log(LOG_NOTICE, "PostgreSQL RealTime: Query finally succeeded: %s\n", sql);
+			}
+
+			return 0;
+		}
+
+		if (res == -1) {
+			return -1; /* Still connected to db, but could not process query (fatal error) */
+		}
+
+		/* res == -2 (query on a disconnected handle) */
+		ast_debug(1, "PostgreSQL query attempt %d failed, trying again\n", attempts);
+	}
+
+	return -1;
+}
+
+static struct tables *find_table(const char *database, const char *orig_tablename)
 {
 	struct columns *column;
 	struct tables *table;
 	struct ast_str *sql = ast_str_thread_get(&findtable_buf, 330);
-	char *pgerror;
-	PGresult *result;
+        PGresult *result;
+        int exec_result;
 	char *fname, *ftype, *flen, *fnotnull, *fdef;
 	int i, rows;
 
@@ -209,11 +330,10 @@
 		ast_str_set(&sql, 0, "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM pg_class c, pg_type t, pg_attribute a LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum WHERE c.oid = a.attrelid AND a.atttypid = t.oid AND (a.attnum > 0) AND c.relname = '%s' ORDER BY c.relname, attnum", orig_tablename);
 	}
 
-	result = PQexec(pgsqlConn, ast_str_buffer(sql));
+	exec_result = pgsql_exec(database, orig_tablename, ast_str_buffer(sql), &result);
 	ast_debug(1, "Query of table structure complete.  Now retrieving results.\n");
-	if (PQresultStatus(result) != PGRES_TUPLES_OK) {
-		pgerror = PQresultErrorMessage(result);
-		ast_log(LOG_ERROR, "Failed to query database columns: %s\n", pgerror);
+	if (exec_result != 0) {
+		ast_log(LOG_ERROR, "Failed to query database columns for table %s\n", orig_tablename);
 		PQclear(result);
 		AST_LIST_UNLOCK(&psql_tables);
 		return NULL;
@@ -327,7 +447,7 @@
 
 	ESCAPE_STRING(escapebuf, newval);
 	if (pgresult) {
-		ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
+		ast_log(LOG_ERROR, "PostgreSQL RealTime: detected invalid input: '%s'\n", newval);
 		va_end(ap);
 		return NULL;
 	}
@@ -342,7 +462,7 @@
 
 		ESCAPE_STRING(escapebuf, newval);
 		if (pgresult) {
-			ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
+			ast_log(LOG_ERROR, "PostgreSQL RealTime: detected invalid input: '%s'\n", newval);
 			va_end(ap);
 			return NULL;
 		}
@@ -353,32 +473,11 @@
 
 	/* We now have our complete statement; Lets connect to the server and execute it. */
 	ast_mutex_lock(&pgsql_lock);
-	if (!pgsql_reconnect(database)) {
+
+        if (pgsql_exec(database, tablename, ast_str_buffer(sql), &result) != 0) {
 		ast_mutex_unlock(&pgsql_lock);
 		return NULL;
-	}
-
-	if (!(result = PQexec(pgsqlConn, ast_str_buffer(sql)))) {
-		ast_log(LOG_WARNING,
-				"PostgreSQL RealTime: Failed to query '%s@%s'. Check debug for more info.\n", tablename, database);
-		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
-		ast_mutex_unlock(&pgsql_lock);
-		return NULL;
-	} else {
-		ExecStatusType result_status = PQresultStatus(result);
-		if (result_status != PGRES_COMMAND_OK
-			&& result_status != PGRES_TUPLES_OK
-			&& result_status != PGRES_NONFATAL_ERROR) {
-			ast_log(LOG_WARNING,
-					"PostgreSQL RealTime: Failed to query '%s@%s'. Check debug for more info.\n", tablename, database);
-			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
-						PQresultErrorMessage(result), PQresStatus(result_status));
-			ast_mutex_unlock(&pgsql_lock);
-			return NULL;
-		}
-	}
+        }
 
 	ast_debug(1, "PostgreSQL RealTime: Result=%p Query: %s\n", result, ast_str_buffer(sql));
 
@@ -477,7 +576,7 @@
 
 	ESCAPE_STRING(escapebuf, newval);
 	if (pgresult) {
-		ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
+		ast_log(LOG_ERROR, "PostgreSQL RealTime: detected invalid input: '%s'\n", newval);
 		va_end(ap);
 		return NULL;
 	}
@@ -492,7 +591,7 @@
 
 		ESCAPE_STRING(escapebuf, newval);
 		if (pgresult) {
-			ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
+			ast_log(LOG_ERROR, "PostgreSQL RealTime: detected invalid input: '%s'\n", newval);
 			va_end(ap);
 			return NULL;
 		}
@@ -508,32 +607,11 @@
 
 	/* We now have our complete statement; Lets connect to the server and execute it. */
 	ast_mutex_lock(&pgsql_lock);
-	if (!pgsql_reconnect(database)) {
+
+        if (pgsql_exec(database, table, ast_str_buffer(sql), &result) != 0) {
 		ast_mutex_unlock(&pgsql_lock);
-		return NULL;
-	}
-
-	if (!(result = PQexec(pgsqlConn, ast_str_buffer(sql)))) {
-		ast_log(LOG_WARNING,
-				"PostgreSQL RealTime: Failed to query %s@%s. Check debug for more info.\n", table, database);
-		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
-		ast_mutex_unlock(&pgsql_lock);
-		return NULL;
-	} else {
-		ExecStatusType result_status = PQresultStatus(result);
-		if (result_status != PGRES_COMMAND_OK
-			&& result_status != PGRES_TUPLES_OK
-			&& result_status != PGRES_NONFATAL_ERROR) {
-			ast_log(LOG_WARNING,
-					"PostgreSQL RealTime: Failed to query %s@%s. Check debug for more info.\n", table, database);
-			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
-						PQresultErrorMessage(result), PQresStatus(result_status));
-			ast_mutex_unlock(&pgsql_lock);
-			return NULL;
-		}
-	}
+                return NULL;
+        }
 
 	ast_debug(1, "PostgreSQL RealTime: Result=%p Query: %s\n", result, ast_str_buffer(sql));
 
@@ -599,7 +677,7 @@
 		return -1;
 	}
 
-	if (!(table = find_table(tablename))) {
+	if (!(table = find_table(database, tablename))) {
 		ast_log(LOG_ERROR, "Table '%s' does not exist!!\n", tablename);
 		return -1;
 	}
@@ -636,7 +714,7 @@
 
 	ESCAPE_STRING(escapebuf, newval);
 	if (pgresult) {
-		ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
+		ast_log(LOG_ERROR, "PostgreSQL RealTime: detected invalid input: '%s'\n", newval);
 		va_end(ap);
 		release_table(table);
 		return -1;
@@ -653,7 +731,7 @@
 
 		ESCAPE_STRING(escapebuf, newval);
 		if (pgresult) {
-			ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
+			ast_log(LOG_ERROR, "PostgreSQL RealTime: detected invalid input: '%s'\n", newval);
 			va_end(ap);
 			release_table(table);
 			return -1;
@@ -666,7 +744,7 @@
 
 	ESCAPE_STRING(escapebuf, lookup);
 	if (pgresult) {
-		ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", lookup);
+		ast_log(LOG_ERROR, "PostgreSQL RealTime: detected invalid input: '%s'\n", lookup);
 		va_end(ap);
 		return -1;
 	}
@@ -677,31 +755,10 @@
 
 	/* We now have our complete statement; Lets connect to the server and execute it. */
 	ast_mutex_lock(&pgsql_lock);
-	if (!pgsql_reconnect(database)) {
+
+	if (pgsql_exec(database, tablename, ast_str_buffer(sql), &result) != 0) {
 		ast_mutex_unlock(&pgsql_lock);
 		return -1;
-	}
-
-	if (!(result = PQexec(pgsqlConn, ast_str_buffer(sql)))) {
-		ast_log(LOG_WARNING,
-				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
-		ast_mutex_unlock(&pgsql_lock);
-		return -1;
-	} else {
-		ExecStatusType result_status = PQresultStatus(result);
-		if (result_status != PGRES_COMMAND_OK
-			&& result_status != PGRES_TUPLES_OK
-			&& result_status != PGRES_NONFATAL_ERROR) {
-			ast_log(LOG_WARNING,
-					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
-						PQresultErrorMessage(result), PQresStatus(result_status));
-			ast_mutex_unlock(&pgsql_lock);
-			return -1;
-		}
 	}
 
 	numrows = atoi(PQcmdTuples(result));
@@ -741,7 +798,7 @@
 		return -1;
 	}
 
-	if (!(table = find_table(tablename))) {
+	if (!(table = find_table(database, tablename))) {
 		ast_log(LOG_ERROR, "Table '%s' does not exist!!\n", tablename);
 		return -1;
 	}
@@ -759,7 +816,7 @@
 		newval = va_arg(ap, const char *);
 		ESCAPE_STRING(escapebuf, newval);
 		if (pgresult) {
-			ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
+			ast_log(LOG_ERROR, "PostgreSQL RealTime: detected invalid input: '%s'\n", newval);
 			release_table(table);
 			ast_free(sql);
 			return -1;
@@ -792,7 +849,7 @@
 
 		ESCAPE_STRING(escapebuf, newval);
 		if (pgresult) {
-			ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
+			ast_log(LOG_ERROR, "PostgreSQL RealTime: detected invalid input: '%s'\n", newval);
 			release_table(table);
 			ast_free(sql);
 			return -1;
@@ -807,33 +864,10 @@
 	ast_debug(1, "PostgreSQL RealTime: Update SQL: %s\n", ast_str_buffer(sql));
 
 	/* We now have our complete statement; connect to the server and execute it. */
-	ast_mutex_lock(&pgsql_lock);
-	if (!pgsql_reconnect(database)) {
+        if (pgsql_exec(database, tablename, ast_str_buffer(sql), &result) != 0) {
 		ast_mutex_unlock(&pgsql_lock);
-		return -1;
-	}
-
-	if (!(result = PQexec(pgsqlConn, ast_str_buffer(sql)))) {
-		ast_log(LOG_WARNING,
-				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
-		ast_mutex_unlock(&pgsql_lock);
-		return -1;
-	} else {
-		ExecStatusType result_status = PQresultStatus(result);
-		if (result_status != PGRES_COMMAND_OK
-			&& result_status != PGRES_TUPLES_OK
-			&& result_status != PGRES_NONFATAL_ERROR) {
-			ast_log(LOG_WARNING,
-					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
-						PQresultErrorMessage(result), PQresStatus(result_status));
-			ast_mutex_unlock(&pgsql_lock);
-			return -1;
-		}
-	}
+	        return -1;
+        }
 
 	numrows = atoi(PQcmdTuples(result));
 	ast_mutex_unlock(&pgsql_lock);
@@ -906,27 +940,10 @@
 
 	ast_debug(1, "PostgreSQL RealTime: Insert SQL: %s\n", ast_str_buffer(sql1));
 
-	if (!(result = PQexec(pgsqlConn, ast_str_buffer(sql1)))) {
-		ast_log(LOG_WARNING,
-				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql1));
-		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
+        if (pgsql_exec(database, table, ast_str_buffer(sql1), &result) != 0) {
 		ast_mutex_unlock(&pgsql_lock);
-		return -1;
-	} else {
-		ExecStatusType result_status = PQresultStatus(result);
-		if (result_status != PGRES_COMMAND_OK
-			&& result_status != PGRES_TUPLES_OK
-			&& result_status != PGRES_NONFATAL_ERROR) {
-			ast_log(LOG_WARNING,
-					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql1));
-			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
-						PQresultErrorMessage(result), PQresStatus(result_status));
-			ast_mutex_unlock(&pgsql_lock);
-			return -1;
-		}
-	}
+	        return -1;
+        }
 
 	insertid = PQoidValue(result);
 	ast_mutex_unlock(&pgsql_lock);
@@ -997,27 +1014,10 @@
 
 	ast_debug(1, "PostgreSQL RealTime: Delete SQL: %s\n", ast_str_buffer(sql));
 
-	if (!(result = PQexec(pgsqlConn, ast_str_buffer(sql)))) {
-		ast_log(LOG_WARNING,
-				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
+        if (pgsql_exec(database, table, ast_str_buffer(sql), &result) != 0) {
 		ast_mutex_unlock(&pgsql_lock);
-		return -1;
-	} else {
-		ExecStatusType result_status = PQresultStatus(result);
-		if (result_status != PGRES_COMMAND_OK
-			&& result_status != PGRES_TUPLES_OK
-			&& result_status != PGRES_NONFATAL_ERROR) {
-			ast_log(LOG_WARNING,
-					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
-						PQresultErrorMessage(result), PQresStatus(result_status));
-			ast_mutex_unlock(&pgsql_lock);
-			return -1;
-		}
-	}
+	        return -1;
+        }
 
 	numrows = atoi(PQcmdTuples(result));
 	ast_mutex_unlock(&pgsql_lock);
@@ -1057,39 +1057,18 @@
 	}
 
 	ast_str_set(&sql, 0, "SELECT category, var_name, var_val, cat_metric FROM %s "
-			"WHERE filename='%s' and commented=0"
+			"WHERE filename='%s' and commented=0 "
 			"ORDER BY cat_metric DESC, var_metric ASC, category, var_name ", table, file);
 
 	ast_debug(1, "PostgreSQL RealTime: Static SQL: %s\n", ast_str_buffer(sql));
 
+	ast_mutex_lock(&pgsql_lock);
+
 	/* We now have our complete statement; Lets connect to the server and execute it. */
-	ast_mutex_lock(&pgsql_lock);
-	if (!pgsql_reconnect(database)) {
+        if (pgsql_exec(database, table, ast_str_buffer(sql), &result) != 0) {
 		ast_mutex_unlock(&pgsql_lock);
-		return NULL;
-	}
-
-	if (!(result = PQexec(pgsqlConn, ast_str_buffer(sql)))) {
-		ast_log(LOG_WARNING,
-				"PostgreSQL RealTime: Failed to query '%s@%s'. Check debug for more info.\n", table, database);
-		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
-		ast_mutex_unlock(&pgsql_lock);
-		return NULL;
-	} else {
-		ExecStatusType result_status = PQresultStatus(result);
-		if (result_status != PGRES_COMMAND_OK
-			&& result_status != PGRES_TUPLES_OK
-			&& result_status != PGRES_NONFATAL_ERROR) {
-			ast_log(LOG_WARNING,
-					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", ast_str_buffer(sql));
-			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
-						PQresultErrorMessage(result), PQresStatus(result_status));
-			ast_mutex_unlock(&pgsql_lock);
-			return NULL;
-		}
-	}
+	        return NULL;
+        }
 
 	if ((num_rows = PQntuples(result)) > 0) {
 		int rowIndex = 0;
@@ -1135,7 +1114,7 @@
 static int require_pgsql(const char *database, const char *tablename, va_list ap)
 {
 	struct columns *column;
-	struct tables *table = find_table(tablename);
+	struct tables *table = find_table(database, tablename);
 	char *elm;
 	int type, size, res = 0;
 
@@ -1236,15 +1215,13 @@
 				ast_debug(1, "About to lock pgsql_lock (running alter on table '%s' to add column '%s')\n", tablename, elm);
 
 				ast_mutex_lock(&pgsql_lock);
-				if (!pgsql_reconnect(database)) {
+				ast_debug(1, "About to run ALTER query on table '%s' to add column '%s'\n", tablename, elm);
+
+			        if (pgsql_exec(database, tablename, ast_str_buffer(sql), &result) != 0) {
 					ast_mutex_unlock(&pgsql_lock);
-					ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
-					ast_free(sql);
-					continue;
-				}
-
-				ast_debug(1, "About to run ALTER query on table '%s' to add column '%s'\n", tablename, elm);
-				result = PQexec(pgsqlConn, ast_str_buffer(sql));
+				        return -1;
+			        }
+
 				ast_debug(1, "Finished running ALTER query on table '%s'\n", tablename);
 				if (PQresultStatus(result) != PGRES_COMMAND_OK) {
 					ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
@@ -1537,7 +1514,7 @@
 		AST_LIST_UNLOCK(&psql_tables);
 	} else if (a->argc == 5) {
 		/* List of columns */
-		if ((cur = find_table(a->argv[4]))) {
+		if ((cur = find_table(cur->name, a->argv[4]))) {
 			struct columns *col;
 			ast_cli(a->fd, "Columns for Table Cache '%s':\n", a->argv[4]);
 			ast_cli(a->fd, "%-20.20s %-20.20s %-3.3s %-8.8s\n", "Name", "Type", "Len", "Nullable");




More information about the asterisk-commits mailing list