Adds "SPLIT ALL" to specify that all array arguments
authorMartin Pihlak <martin.pihlak@gmail.com>
Thu, 12 Nov 2009 14:45:42 +0000 (16:45 +0200)
committerMarko Kreen <markokr@gmail.com>
Mon, 11 Jan 2010 09:53:08 +0000 (11:53 +0200)
are to be split.

doc/syntax.txt
expected/plproxy_split.out
sql/plproxy_split.sql
src/function.c
src/parser.y
src/plproxy.h

index 689b4333260ec5c1b4045938addb8ec668e88357..95805db029d120c704f4435799cdf435b4951d1b 100644 (file)
@@ -76,6 +76,7 @@ Take hash value directly from function argument.  _(New in 2.0.8)_
 == 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
index 4001b869a83c8ff2b964ba8ed72a6f76340e0303..5db901a5e345348b9b3bd53827716b14f9ae3714 100644 (file)
@@ -102,6 +102,37 @@ select * from test_array('{}'::text[], '{}'::text[], 'foo');
 ------------
 (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;
index d17d7237c88422f73fb6d982b5051aa137c7adb0..d65edf247d58aba74831ff9ae066044124c0d074 100644 (file)
@@ -75,6 +75,22 @@ select * from test_array(array['a','b','c','d'], array['e','f','g','h'], 'foo');
 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;
index 42a97e23b924a321a5a8161190a4f33158480db8..b30e00ec890b3fb382a8b63a95e12fc2bd71325a 100644 (file)
@@ -101,7 +101,22 @@ plproxy_get_parameter_index(ProxyFunction *func, const char *ident)
        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)
 {
@@ -118,17 +133,21 @@ 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 */
index 987ef7a5935317e38daf248f8f5fc912176a33f4..cd5f327e20bd368ae0823e9a7af364355aa01a88 100644 (file)
@@ -117,13 +117,17 @@ cluster_func: FNCALL      { cluster_sql = plproxy_query_start(xfunc, false);
 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
                        ;
index 4abc503181f7679d5e755c0f6c3f3adc5aaa2caf..5704d6d133f6ecbee5cce1782889797126308d20 100644 (file)
@@ -335,6 +335,7 @@ void           *plproxy_func_alloc(ProxyFunction *func, int size);
 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 */