# regression testing setup
REGRESS = plproxy_init plproxy_test plproxy_select plproxy_many \
plproxy_errors plproxy_clustermap plproxy_dynamic_record \
- plproxy_encoding plproxy_split
+ plproxy_encoding plproxy_split plproxy_target
# SQL files
PLPROXY_SQL = plproxy_lang.sql
SELECT * FROM set_profiles(ARRAY['bar'], ARRAY['b']);
+== TARGET ==
+
+Specify function name on remote side to be called. By default
+PL/Proxy uses current function name.
+
+Following function:
+
+ CREATE FUNCTION some_function(username text, num int4)
+ RETURNS SETOF text AS $$
+ CLUSTER 'userdb';
+ RUN ON hashtext(username);
+ TARGET other_function;
+ $$ LANGUAGE plproxy;
+
+will run following query on remote side:
+
+ SELECT * FROM other_function(username, num);
+
== SELECT ==
SELECT .... ;
static ProxyFunction *xfunc;
/* remember what happened */
-static int got_run, got_cluster, got_connect, got_split;
+static int got_run, got_cluster, got_connect, got_split, got_target;
static QueryBuffer *cluster_sql;
static QueryBuffer *select_sql;
/* keep the resetting code together with variables */
static void reset_parser_vars(void)
{
- got_run = got_cluster = got_connect = got_split = 0;
+ got_run = got_cluster = got_connect = got_split = got_target = 0;
cur_sql = select_sql = cluster_sql = hash_sql = connect_sql = NULL;
xfunc = NULL;
}
%token <str> CONNECT CLUSTER RUN ON ALL ANY SELECT
%token <str> IDENT NUMBER FNCALL SPLIT STRING
-%token <str> SQLIDENT SQLPART
+%token <str> SQLIDENT SQLPART TARGET
%union
{
body: | body stmt ;
-stmt: cluster_stmt | split_stmt | run_stmt | select_stmt | connect_stmt ;
+stmt: cluster_stmt | split_stmt | run_stmt | select_stmt | connect_stmt | target_stmt;
connect_stmt: CONNECT connect_spec ';' {
if (got_connect)
cluster_name: STRING { xfunc->cluster_name = plproxy_func_strdup(xfunc, $1); }
;
+target_stmt: TARGET target_name ';' {
+ if (got_target)
+ yyerror("Only one TARGET statement allowed");
+ got_target = 1; }
+ ;
+
+target_name: IDENT { xfunc->target_name = plproxy_func_strdup(xfunc, $1); }
+ ;
+
split_stmt: SPLIT split_spec ';' {
if (got_split)
yyerror("Only one SPLIT statement allowed");
yyerror("SELECT statement not allowed");
#endif
+ if (select_sql && got_target)
+ yyerror("TARGET cannot be used with SELECT");
+
/* release scanner resources */
plproxy_yylex_destroy();
{
StringInfoData sql;
ProxyQuery *pq;
+ const char *target;
int i,
len;
appendStringInfo(&sql, "r::%s", func->ret_scalar->name);
/* function call */
- appendStringInfo(&sql, " from %s(", func->name);
+ target = func->target_name ? func->target_name : func->name;
+ appendStringInfo(&sql, " from %s(", target);
/* fill in function arguments */
for (i = 0; i < func->arg_count; i++)