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/28336.1528393969@sss.pgh.pa.us
This commit is contained in:
parent
3a382983d1
commit
e3b7f7cc50
|
@ -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
|
||||||
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)
|
||||||
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 @@ $$;
|
||||||
|
|
||||||
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();
|
||||||
|
|
Loading…
Reference in New Issue