summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/hstore_plperl/expected/hstore_plperl.out19
-rw-r--r--contrib/hstore_plperl/hstore_plperl.c14
-rw-r--r--contrib/hstore_plperl/sql/hstore_plperl.sql19
3 files changed, 51 insertions, 1 deletions
diff --git a/contrib/hstore_plperl/expected/hstore_plperl.out b/contrib/hstore_plperl/expected/hstore_plperl.out
index 25fc506c23f..1ab09a94cda 100644
--- a/contrib/hstore_plperl/expected/hstore_plperl.out
+++ b/contrib/hstore_plperl/expected/hstore_plperl.out
@@ -41,6 +41,25 @@ SELECT test2arr();
{"\"a\"=>\"1\", \"b\"=>\"boo\", \"c\"=>NULL","\"d\"=>\"2\""}
(1 row)
+-- check error cases
+CREATE OR REPLACE FUNCTION test2() RETURNS hstore
+LANGUAGE plperl
+TRANSFORM FOR TYPE hstore
+AS $$
+return 42;
+$$;
+SELECT test2();
+ERROR: cannot transform non-hash Perl value to hstore
+CONTEXT: PL/Perl function "test2"
+CREATE OR REPLACE FUNCTION test2() RETURNS hstore
+LANGUAGE plperl
+TRANSFORM FOR TYPE hstore
+AS $$
+return [1, 2];
+$$;
+SELECT test2();
+ERROR: cannot transform non-hash Perl value to hstore
+CONTEXT: PL/Perl function "test2"
DROP FUNCTION test2();
DROP FUNCTION test2arr();
DROP EXTENSION hstore_plperl;
diff --git a/contrib/hstore_plperl/hstore_plperl.c b/contrib/hstore_plperl/hstore_plperl.c
index 6bc3bb37fc3..c09bd38d090 100644
--- a/contrib/hstore_plperl/hstore_plperl.c
+++ b/contrib/hstore_plperl/hstore_plperl.c
@@ -101,7 +101,8 @@ Datum
plperl_to_hstore(PG_FUNCTION_ARGS)
{
dTHX;
- HV *hv = (HV *) SvRV((SV *) PG_GETARG_POINTER(0));
+ SV *in = (SV *) PG_GETARG_POINTER(0);
+ HV *hv;
HE *he;
int32 buflen;
int32 i;
@@ -109,6 +110,17 @@ plperl_to_hstore(PG_FUNCTION_ARGS)
HStore *out;
Pairs *pairs;
+ /* Dereference references recursively. */
+ while (SvROK(in))
+ in = SvRV(in);
+
+ /* Now we must have a hash. */
+ if (SvTYPE(in) != SVt_PVHV)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ (errmsg("cannot transform non-hash Perl value to hstore"))));
+ hv = (HV *) in;
+
pcount = hv_iterinit(hv);
pairs = palloc(pcount * sizeof(Pairs));
diff --git a/contrib/hstore_plperl/sql/hstore_plperl.sql b/contrib/hstore_plperl/sql/hstore_plperl.sql
index 9398aedfbbd..ad1db7eae17 100644
--- a/contrib/hstore_plperl/sql/hstore_plperl.sql
+++ b/contrib/hstore_plperl/sql/hstore_plperl.sql
@@ -31,6 +31,25 @@ $$;
SELECT test2arr();
+-- check error cases
+CREATE OR REPLACE FUNCTION test2() RETURNS hstore
+LANGUAGE plperl
+TRANSFORM FOR TYPE hstore
+AS $$
+return 42;
+$$;
+
+SELECT test2();
+
+CREATE OR REPLACE FUNCTION test2() RETURNS hstore
+LANGUAGE plperl
+TRANSFORM FOR TYPE hstore
+AS $$
+return [1, 2];
+$$;
+
+SELECT test2();
+
DROP FUNCTION test2();
DROP FUNCTION test2arr();