Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 93b6e03

Browse files
committed
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
1 parent e3b7f7c commit 93b6e03

File tree

5 files changed

+72
-3
lines changed

5 files changed

+72
-3
lines changed

contrib/jsonb_plperl/expected/jsonb_plperl.out

+15-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ SELECT testSVToJsonb();
3939
1
4040
(1 row)
4141

42+
CREATE FUNCTION testUVToJsonb() RETURNS jsonb
43+
LANGUAGE plperl
44+
TRANSFORM FOR TYPE jsonb
45+
as $$
46+
$val = ~0;
47+
return $val;
48+
$$;
49+
-- this might produce either 18446744073709551615 or 4294967295
50+
SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb);
51+
?column?
52+
----------
53+
t
54+
(1 row)
55+
4256
-- this revealed a bug in the original implementation
4357
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
4458
LANGUAGE plperl
@@ -216,4 +230,4 @@ SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}', 'HASH');
216230

217231
\set VERBOSITY terse \\ -- suppress cascade details
218232
DROP EXTENSION plperl CASCADE;
219-
NOTICE: drop cascades to 6 other objects
233+
NOTICE: drop cascades to 7 other objects

contrib/jsonb_plperl/expected/jsonb_plperlu.out

+15-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ SELECT testSVToJsonb();
3939
1
4040
(1 row)
4141

42+
CREATE FUNCTION testUVToJsonb() RETURNS jsonb
43+
LANGUAGE plperlu
44+
TRANSFORM FOR TYPE jsonb
45+
as $$
46+
$val = ~0;
47+
return $val;
48+
$$;
49+
-- this might produce either 18446744073709551615 or 4294967295
50+
SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb);
51+
?column?
52+
----------
53+
t
54+
(1 row)
55+
4256
-- this revealed a bug in the original implementation
4357
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
4458
LANGUAGE plperlu
@@ -243,4 +257,4 @@ INFO: $VAR1 = {'1' => {'2' => ['3','4','5']},'2' => '3'};
243257

244258
\set VERBOSITY terse \\ -- suppress cascade details
245259
DROP EXTENSION plperlu CASCADE;
246-
NOTICE: drop cascades to 6 other objects
260+
NOTICE: drop cascades to 7 other objects

contrib/jsonb_plperl/jsonb_plperl.c

+18-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,24 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem)
198198
break;
199199

200200
default:
201-
if (SvIOK(in))
201+
if (SvUOK(in))
202+
{
203+
/*
204+
* If UV is >=64 bits, we have no better way to make this
205+
* happen than converting to text and back. Given the low
206+
* usage of UV in Perl code, it's not clear it's worth working
207+
* hard to provide alternate code paths.
208+
*/
209+
const char *strval = SvPV_nolen(in);
210+
211+
out.type = jbvNumeric;
212+
out.val.numeric =
213+
DatumGetNumeric(DirectFunctionCall3(numeric_in,
214+
CStringGetDatum(strval),
215+
ObjectIdGetDatum(InvalidOid),
216+
Int32GetDatum(-1)));
217+
}
218+
else if (SvIOK(in))
202219
{
203220
IV ival = SvIV(in);
204221

contrib/jsonb_plperl/sql/jsonb_plperl.sql

+12
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ $$;
3434
SELECT testSVToJsonb();
3535

3636

37+
CREATE FUNCTION testUVToJsonb() RETURNS jsonb
38+
LANGUAGE plperl
39+
TRANSFORM FOR TYPE jsonb
40+
as $$
41+
$val = ~0;
42+
return $val;
43+
$$;
44+
45+
-- this might produce either 18446744073709551615 or 4294967295
46+
SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb);
47+
48+
3749
-- this revealed a bug in the original implementation
3850
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
3951
LANGUAGE plperl

contrib/jsonb_plperl/sql/jsonb_plperlu.sql

+12
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ $$;
3434
SELECT testSVToJsonb();
3535

3636

37+
CREATE FUNCTION testUVToJsonb() RETURNS jsonb
38+
LANGUAGE plperlu
39+
TRANSFORM FOR TYPE jsonb
40+
as $$
41+
$val = ~0;
42+
return $val;
43+
$$;
44+
45+
-- this might produce either 18446744073709551615 or 4294967295
46+
SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb);
47+
48+
3749
-- this revealed a bug in the original implementation
3850
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
3951
LANGUAGE plperlu

0 commit comments

Comments
 (0)