summaryrefslogtreecommitdiff
path: root/src/execute.c
diff options
context:
space:
mode:
authorMarko Kreen2010-01-11 10:55:58 +0000
committerMarko Kreen2010-01-11 10:55:58 +0000
commit868ccca247e0e50ca4a4759e4e659f05590d9283 (patch)
treeee1413838dfc0e7f4b2d21c2c61656b03ce05383 /src/execute.c
parentcb91cec92b5976455bd60fd95979a1cc39a57ea1 (diff)
Improved remote error and notice handling.
- Register libpq notice handler with PQsetNoticeReceiver - Extract details from err/notice with PQresultErrorField and pass to ereport(). - Improve state-machine in another_result().
Diffstat (limited to 'src/execute.c')
-rw-r--r--src/execute.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/execute.c b/src/execute.c
index b8517e9..8cb83e9 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -258,6 +258,13 @@ intr_loop:
return true;
}
+static void
+handle_notice(void *arg, const PGresult *res)
+{
+ ProxyCluster *cluster = arg;
+ plproxy_remote_error(cluster->cur_func, res, false);
+}
+
/* check existing conn status or launch new conn */
static void
prepare_conn(ProxyFunction *func, ProxyConnection *conn)
@@ -301,6 +308,9 @@ prepare_conn(ProxyFunction *func, ProxyConnection *conn)
if (PQstatus(conn->db) == CONNECTION_BAD)
conn_error(func, conn, "PQconnectStart");
+
+ /* override default notice handler */
+ PQsetNoticeReceiver(conn->db, handle_notice, func->cur_cluster);
}
/*
@@ -329,15 +339,29 @@ another_result(ProxyFunction *func, ProxyConnection *conn)
{
case PGRES_TUPLES_OK:
if (conn->res)
+ {
+ PQclear(res);
conn_error(func, conn, "double result?");
+ }
conn->res = res;
break;
case PGRES_COMMAND_OK:
PQclear(res);
break;
+ case PGRES_FATAL_ERROR:
+ if (conn->res)
+ PQclear(conn->res);
+ conn->res = res;
+
+ plproxy_remote_error(func, res, true);
+ break;
default:
- PQclear(res);
- conn_error(func, conn, "remote error");
+ if (conn->res)
+ PQclear(conn->res);
+ conn->res = res;
+
+ plproxy_error(func, "Unexpected result type: %s", PQresStatus(PQresultStatus(res)));
+ break;
}
return true;
}
@@ -993,6 +1017,7 @@ plproxy_exec(ProxyFunction *func, FunctionCallInfo fcinfo)
PG_TRY();
{
func->cur_cluster->busy = true;
+ func->cur_cluster->cur_func = func;
/* clean old results */
plproxy_clean_results(func->cur_cluster);
@@ -1013,6 +1038,10 @@ plproxy_exec(ProxyFunction *func, FunctionCallInfo fcinfo)
if (geterrcode() == ERRCODE_QUERY_CANCELED)
remote_cancel(func);
+
+ /* plproxy_remote_error() cannot clean itself, do it here */
+ plproxy_clean_results(func->cur_cluster);
+
PG_RE_THROW();
}
PG_END_TRY();