are to be split.
== SPLIT ==
SPLIT array_arg_1 [ , array_arg_2 ... ] ;
+ SPLIT ALL ;
Split the input arrays based on RUN ON statement into per-partition arrays.
This is done by evaluating RUN ON condition for each array element and building
------------
(0 rows)
+-- run on text hash, split all arrays
+create or replace function test_array(a text[], b text[], c text) returns setof text as
+$$ split all; cluster 'testcluster'; run on ascii(c);$$ language plproxy;
+select * from test_array(array['a','b','c','d'], array['e','f','g','h'], 'foo');
+ test_array
+-----------------------------------------
+ test_part2 $1:a,b,c,d $2:e,f,g,h $3:foo
+(1 row)
+
+-- run on text hash, attempt to split all arrays but none are present
+create or replace function test_nonarray_split(a text, b text, c text) returns setof text as
+$$ split all; cluster 'testcluster'; run on ascii(a); select * from test_array(array[a], array[b], c);
+$$ language plproxy;
+select * from test_nonarray_split('a', 'b', 'c');
+ test_nonarray_split
+---------------------------
+ test_part1 $1:a $2:b $3:c
+(1 row)
+
+-- run on array hash, split all arrays
+create or replace function test_array(a text[], b text[], c text) returns setof text as
+$$ split all; cluster 'testcluster'; run on ascii(a);$$ language plproxy;
+select * from test_array(array['a','b','c','d'], array['e','f','g','h'], 'foo');
+ test_array
+-----------------------------
+ test_part0 $1:d $2:h $3:foo
+ test_part1 $1:a $2:e $3:foo
+ test_part2 $1:b $2:f $3:foo
+ test_part3 $1:c $2:g $3:foo
+(4 rows)
+
-- run on arg
create or replace function test_array_direct(a integer[], b text[], c text) returns setof text as
$$ split a; cluster 'testcluster'; run on a; select test_array('{}'::text[], b, c);$$ language plproxy;
select * from test_array(null, null, null);
select * from test_array('{}'::text[], '{}'::text[], 'foo');
+-- run on text hash, split all arrays
+create or replace function test_array(a text[], b text[], c text) returns setof text as
+$$ split all; cluster 'testcluster'; run on ascii(c);$$ language plproxy;
+select * from test_array(array['a','b','c','d'], array['e','f','g','h'], 'foo');
+
+-- run on text hash, attempt to split all arrays but none are present
+create or replace function test_nonarray_split(a text, b text, c text) returns setof text as
+$$ split all; cluster 'testcluster'; run on ascii(a); select * from test_array(array[a], array[b], c);
+$$ language plproxy;
+select * from test_nonarray_split('a', 'b', 'c');
+
+-- run on array hash, split all arrays
+create or replace function test_array(a text[], b text[], c text) returns setof text as
+$$ split all; cluster 'testcluster'; run on ascii(a);$$ language plproxy;
+select * from test_array(array['a','b','c','d'], array['e','f','g','h'], 'foo');
+
-- run on arg
create or replace function test_array_direct(a integer[], b text[], c text) returns setof text as
$$ split a; cluster 'testcluster'; run on a; select test_array('{}'::text[], b, c);$$ language plproxy;
return -1;
}
-/* Add a new split argument */
+/* Add a new split argument by position */
+static void
+plproxy_split_add_arg(ProxyFunction *func, int argindex)
+{
+ if (!func->split_args)
+ {
+ size_t alloc_size = sizeof(*func->split_args) * func->arg_count;
+
+ func->split_args = plproxy_func_alloc(func, alloc_size);
+ MemSet(func->split_args, 0, alloc_size);
+ }
+
+ func->split_args[argindex] = true;
+}
+
+/* Add a new split argument by argument name */
bool
plproxy_split_add_ident(ProxyFunction *func, const char *ident)
{
if (!func->arg_types[argindex]->is_array)
plproxy_error(func, "SPLIT parameter is not an array: %s", ident);
- if (!func->split_args)
- {
- size_t alloc_size = sizeof(*func->split_args) * func->arg_count;
+ plproxy_split_add_arg(func, argindex);
- func->split_args = plproxy_func_alloc(func, alloc_size);
- MemSet(func->split_args, 0, alloc_size);
- }
+ return true;
+}
- func->split_args[argindex] = true;
+/* Tag all array arguments for splitting */
+void
+plproxy_split_all_arrays(ProxyFunction *func)
+{
+ int i;
- return true;
+ for (i = 0; i < func->arg_count; i++) {
+ if (func->arg_types[i]->is_array)
+ plproxy_split_add_arg(func, i);
+ }
}
/* Initialize PL/Proxy function cache */
cluster_name: STRING { xfunc->cluster_name = plproxy_func_strdup(xfunc, $1); }
;
-split_stmt: SPLIT split_param_list ';' {
+split_stmt: SPLIT split_spec ';' {
if (got_split)
yyerror("Only one SPLIT statement allowed");
got_split = 1;
}
;
+split_spec: ALL { plproxy_split_all_arrays(xfunc); }
+ | split_param_list
+ ;
+
split_param_list: split_param
| split_param_list ',' split_param
;
char *plproxy_func_strdup(ProxyFunction *func, const char *s);
int plproxy_get_parameter_index(ProxyFunction *func, const char *ident);
bool plproxy_split_add_ident(ProxyFunction *func, const char *ident);
+void plproxy_split_all_arrays(ProxyFunction *func);
ProxyFunction *plproxy_compile(FunctionCallInfo fcinfo, bool validate);
/* execute.c */