diff options
author | Tom Lane | 2018-06-18 19:55:06 +0000 |
---|---|---|
committer | Tom Lane | 2018-06-18 19:55:06 +0000 |
commit | e3b7f7cc50630dac958a48b533cce04e4222892b (patch) | |
tree | c9112a11982f1f408e89e233b23e278b4daa0fc3 | |
parent | 3a382983d142ca270fe49c63fa6d4a95037ebee3 (diff) |
Fix contrib/hstore_plperl to look through scalar refs.
Bring this transform function into sync with the policy established
by commit 3a382983d.
Also, fix it to make sure that what it drills down to is indeed a
hash, and not some other kind of Perl SV. Previously, the test
cases added here provoked crashes.
Because of the crash hazard, back-patch to 9.5 where this module
was introduced.
Discussion: https://postgr.es/m/[email protected]
-rw-r--r-- | contrib/hstore_plperl/expected/hstore_plperl.out | 19 | ||||
-rw-r--r-- | contrib/hstore_plperl/hstore_plperl.c | 14 | ||||
-rw-r--r-- | contrib/hstore_plperl/sql/hstore_plperl.sql | 19 |
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 25fc506c23..1ab09a94cd 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 6bc3bb37fc..c09bd38d09 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 9398aedfbb..ad1db7eae1 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(); |