Fix jsonb_plperl to convert Perl UV values correctly.
Values greater than IV_MAX were incorrectly converted to SQL, for instance ~0 would become -1 rather than 18446744073709551615 (on a 64-bit machine). Dagfinn Ilmari Mannsåker, adjusted a bit by me Discussion: https://postgr.es/m/d8jtvskjzzs.fsf@dalvik.ping.uio.no
This commit is contained in:
parent
e3b7f7cc50
commit
93b6e03ab4
@ -39,6 +39,20 @@ SELECT testSVToJsonb();
|
|||||||
1
|
1
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
CREATE FUNCTION testUVToJsonb() RETURNS jsonb
|
||||||
|
LANGUAGE plperl
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
as $$
|
||||||
|
$val = ~0;
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
-- this might produce either 18446744073709551615 or 4294967295
|
||||||
|
SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb);
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- this revealed a bug in the original implementation
|
-- this revealed a bug in the original implementation
|
||||||
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
||||||
LANGUAGE plperl
|
LANGUAGE plperl
|
||||||
@ -216,4 +230,4 @@ SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}', 'HASH');
|
|||||||
|
|
||||||
\set VERBOSITY terse \\ -- suppress cascade details
|
\set VERBOSITY terse \\ -- suppress cascade details
|
||||||
DROP EXTENSION plperl CASCADE;
|
DROP EXTENSION plperl CASCADE;
|
||||||
NOTICE: drop cascades to 6 other objects
|
NOTICE: drop cascades to 7 other objects
|
||||||
|
@ -39,6 +39,20 @@ SELECT testSVToJsonb();
|
|||||||
1
|
1
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
CREATE FUNCTION testUVToJsonb() RETURNS jsonb
|
||||||
|
LANGUAGE plperlu
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
as $$
|
||||||
|
$val = ~0;
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
-- this might produce either 18446744073709551615 or 4294967295
|
||||||
|
SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb);
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- this revealed a bug in the original implementation
|
-- this revealed a bug in the original implementation
|
||||||
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
||||||
LANGUAGE plperlu
|
LANGUAGE plperlu
|
||||||
@ -243,4 +257,4 @@ INFO: $VAR1 = {'1' => {'2' => ['3','4','5']},'2' => '3'};
|
|||||||
|
|
||||||
\set VERBOSITY terse \\ -- suppress cascade details
|
\set VERBOSITY terse \\ -- suppress cascade details
|
||||||
DROP EXTENSION plperlu CASCADE;
|
DROP EXTENSION plperlu CASCADE;
|
||||||
NOTICE: drop cascades to 6 other objects
|
NOTICE: drop cascades to 7 other objects
|
||||||
|
@ -198,7 +198,24 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (SvIOK(in))
|
if (SvUOK(in))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If UV is >=64 bits, we have no better way to make this
|
||||||
|
* happen than converting to text and back. Given the low
|
||||||
|
* usage of UV in Perl code, it's not clear it's worth working
|
||||||
|
* hard to provide alternate code paths.
|
||||||
|
*/
|
||||||
|
const char *strval = SvPV_nolen(in);
|
||||||
|
|
||||||
|
out.type = jbvNumeric;
|
||||||
|
out.val.numeric =
|
||||||
|
DatumGetNumeric(DirectFunctionCall3(numeric_in,
|
||||||
|
CStringGetDatum(strval),
|
||||||
|
ObjectIdGetDatum(InvalidOid),
|
||||||
|
Int32GetDatum(-1)));
|
||||||
|
}
|
||||||
|
else if (SvIOK(in))
|
||||||
{
|
{
|
||||||
IV ival = SvIV(in);
|
IV ival = SvIV(in);
|
||||||
|
|
||||||
|
@ -34,6 +34,18 @@ $$;
|
|||||||
SELECT testSVToJsonb();
|
SELECT testSVToJsonb();
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION testUVToJsonb() RETURNS jsonb
|
||||||
|
LANGUAGE plperl
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
as $$
|
||||||
|
$val = ~0;
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- this might produce either 18446744073709551615 or 4294967295
|
||||||
|
SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb);
|
||||||
|
|
||||||
|
|
||||||
-- this revealed a bug in the original implementation
|
-- this revealed a bug in the original implementation
|
||||||
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
||||||
LANGUAGE plperl
|
LANGUAGE plperl
|
||||||
|
@ -34,6 +34,18 @@ $$;
|
|||||||
SELECT testSVToJsonb();
|
SELECT testSVToJsonb();
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION testUVToJsonb() RETURNS jsonb
|
||||||
|
LANGUAGE plperlu
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
as $$
|
||||||
|
$val = ~0;
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- this might produce either 18446744073709551615 or 4294967295
|
||||||
|
SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb);
|
||||||
|
|
||||||
|
|
||||||
-- this revealed a bug in the original implementation
|
-- this revealed a bug in the original implementation
|
||||||
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
||||||
LANGUAGE plperlu
|
LANGUAGE plperlu
|
||||||
|
Loading…
x
Reference in New Issue
Block a user