Commit e3b7f7cc authored by Tom Lane's avatar Tom Lane

Fix contrib/hstore_plperl to look through scalar refs.

Bring this transform function into sync with the policy established
by commit 3a382983.

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/28336.1528393969@sss.pgh.pa.us
parent 3a382983
...@@ -41,6 +41,25 @@ SELECT test2arr(); ...@@ -41,6 +41,25 @@ SELECT test2arr();
{"\"a\"=>\"1\", \"b\"=>\"boo\", \"c\"=>NULL","\"d\"=>\"2\""} {"\"a\"=>\"1\", \"b\"=>\"boo\", \"c\"=>NULL","\"d\"=>\"2\""}
(1 row) (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 test2();
DROP FUNCTION test2arr(); DROP FUNCTION test2arr();
DROP EXTENSION hstore_plperl; DROP EXTENSION hstore_plperl;
......
...@@ -101,7 +101,8 @@ Datum ...@@ -101,7 +101,8 @@ Datum
plperl_to_hstore(PG_FUNCTION_ARGS) plperl_to_hstore(PG_FUNCTION_ARGS)
{ {
dTHX; dTHX;
HV *hv = (HV *) SvRV((SV *) PG_GETARG_POINTER(0)); SV *in = (SV *) PG_GETARG_POINTER(0);
HV *hv;
HE *he; HE *he;
int32 buflen; int32 buflen;
int32 i; int32 i;
...@@ -109,6 +110,17 @@ plperl_to_hstore(PG_FUNCTION_ARGS) ...@@ -109,6 +110,17 @@ plperl_to_hstore(PG_FUNCTION_ARGS)
HStore *out; HStore *out;
Pairs *pairs; 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); pcount = hv_iterinit(hv);
pairs = palloc(pcount * sizeof(Pairs)); pairs = palloc(pcount * sizeof(Pairs));
......
...@@ -31,6 +31,25 @@ $$; ...@@ -31,6 +31,25 @@ $$;
SELECT test2arr(); 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 test2();
DROP FUNCTION test2arr(); DROP FUNCTION test2arr();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment