Skip to content

Commit

Permalink
handle empty arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
steve-chavez committed Nov 26, 2023
1 parent 12b10e1 commit c75c14e
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 26 deletions.
29 changes: 15 additions & 14 deletions src/plmustache.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ Datum plmustache_handler(PG_FUNCTION_ARGS)
NullableDatum arg = fcinfo->args[i];
Oid arg_type = call_info.argtypes[i];
Oid array_elem_type = get_element_type(arg_type);
bool arg_is_array = array_elem_type != InvalidOid;

if(arg.isnull){
params[i].prm_value = NULL;
Expand All @@ -203,22 +204,22 @@ Datum plmustache_handler(PG_FUNCTION_ARGS)
else
params[i].enters_section = true;

params[i].is_array = array_elem_type != InvalidOid;

if(params[i].is_array){
int j = 0;
Datum value;
bool isnull;
if(arg_is_array){
params[i].is_array = true;
ArrayType *array = DatumGetArrayTypeP(arg.value);
ArrayIterator array_iterator = array_create_iterator(array, 0, NULL);
int num = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
params[i].prm_arr_length = num;
params[i].prm_arr = palloc0(sizeof(char*) * num);

while (array_iterate(array_iterator, &value, &isnull)) {
params[i].prm_arr[j] = isnull? NULL : datum_to_cstring(value, array_elem_type);
j++;
}
int arr_length = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
if(arr_length > 0){
Datum value; bool isnull; int j = 0;
params[i].prm_arr_length = arr_length;
params[i].prm_arr = palloc0(sizeof(char*) * arr_length);

while (array_iterate(array_iterator, &value, &isnull)) {
params[i].prm_arr[j] = isnull? NULL : datum_to_cstring(value, array_elem_type);
j++;
}
} else
params[i].enters_section = false;
}

}
Expand Down
36 changes: 28 additions & 8 deletions test/expected/sections.out
Original file line number Diff line number Diff line change
Expand Up @@ -82,46 +82,66 @@ select foo_null_test(true);
(1 row)

create or replace function foo_array(arr text[]) returns text as $$
foo is {{#arr}}{{.}}, {{/arr}}
arr is {{#arr}}{{.}}, {{/arr}}
$$ language plmustache;
\echo

select foo_array(ARRAY['one', 'two', 'three']);
foo_array
--------------------------
foo is one, two, three,
arr is one, two, three,
(1 row)

create or replace function foo_array(arr int[]) returns text as $$
foo is {{#arr}}{{.}}, {{/arr}}
arr is {{#arr}}{{.}}, {{/arr}}
$$ language plmustache;
\echo

select foo_array(ARRAY[1, 2, 3]::int[]);
foo_array
------------------
foo is 1, 2, 3,
arr is 1, 2, 3,
(1 row)

-- empty array is handled properly
select foo_array(ARRAY[]::int[]);
foo_array
-----------
arr is
(1 row)

create or replace function mixed_var_array(var int, arr int[]) returns text as $$
bar is {{var}}, foo is {{#arr}}{{.}}, {{/arr}}
var is {{var}}, arr is {{#arr}}{{.}}, {{/arr}}
$$ language plmustache;
\echo

select mixed_var_array(4, ARRAY[1, 2, 3]::int[]);
mixed_var_array
----------------------------
bar is 4, foo is 1, 2, 3,
var is 4, arr is 1, 2, 3,
(1 row)

create or replace function mixed_array_var(arr int[], var int) returns text as $$
foo is {{#arr}}{{.}}, {{/arr}} bar is {{var}}
arr is {{#arr}}{{.}}, {{/arr}} var is {{var}}
$$ language plmustache;
\echo

select mixed_array_var(ARRAY[1, 2, 3]::int[], 4);
mixed_array_var
---------------------------
foo is 1, 2, 3, bar is 4
arr is 1, 2, 3, var is 4
(1 row)

create or replace function mixed_array_var_array(arr1 int[], var text, arr2 int[]) returns text as $$
arr1 is {{#arr1}}{{.}}, {{/arr1}} var is {{var}}
arr2 is {{#arr2}}{{.}}, {{/arr2}} var is {{var}}
$$ language plmustache;
\echo

select mixed_array_var_array(ARRAY[1, 2, 3], 'something', ARRAY[4, 5, 6]);
mixed_array_var_array
------------------------------------
arr1 is 1, 2, 3, var is something+
arr2 is 4, 5, 6, var is something
(1 row)

19 changes: 15 additions & 4 deletions test/sql/sections.sql
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,40 @@ select foo_null_test(null);
select foo_null_test(true);

create or replace function foo_array(arr text[]) returns text as $$
foo is {{#arr}}{{.}}, {{/arr}}
arr is {{#arr}}{{.}}, {{/arr}}
$$ language plmustache;
\echo

select foo_array(ARRAY['one', 'two', 'three']);

create or replace function foo_array(arr int[]) returns text as $$
foo is {{#arr}}{{.}}, {{/arr}}
arr is {{#arr}}{{.}}, {{/arr}}
$$ language plmustache;
\echo

select foo_array(ARRAY[1, 2, 3]::int[]);

-- empty array is handled properly
select foo_array(ARRAY[]::int[]);

create or replace function mixed_var_array(var int, arr int[]) returns text as $$
bar is {{var}}, foo is {{#arr}}{{.}}, {{/arr}}
var is {{var}}, arr is {{#arr}}{{.}}, {{/arr}}
$$ language plmustache;
\echo

select mixed_var_array(4, ARRAY[1, 2, 3]::int[]);

create or replace function mixed_array_var(arr int[], var int) returns text as $$
foo is {{#arr}}{{.}}, {{/arr}} bar is {{var}}
arr is {{#arr}}{{.}}, {{/arr}} var is {{var}}
$$ language plmustache;
\echo

select mixed_array_var(ARRAY[1, 2, 3]::int[], 4);

create or replace function mixed_array_var_array(arr1 int[], var text, arr2 int[]) returns text as $$
arr1 is {{#arr1}}{{.}}, {{/arr1}} var is {{var}}
arr2 is {{#arr2}}{{.}}, {{/arr2}} var is {{var}}
$$ language plmustache;
\echo

select mixed_array_var_array(ARRAY[1, 2, 3], 'something', ARRAY[4, 5, 6]);

0 comments on commit c75c14e

Please sign in to comment.