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

Commit 1731e37

Browse files
committed
Fix excessive enreferencing in jsonb-to-plperl transform.
We want, say, 2 to be transformed as 2, not \\2 which is what the original coding produced. Perl's standard seems to be to add an RV wrapper only for hash and array SVs, so do it like that. This was missed originally because the test cases only checked what came out of a round trip back to SQL, and the strip-all-dereferences loop at the top of SV_to_JsonbValue hides the extra refs from view. As a better test, print the Perl value with Data::Dumper, like the hstore_plperlu tests do. While we can't do that in the plperl test, only plperlu, that should be good enough because this code is the same for both PLs. But also add a simplistic test for extra REFs, which we can do in both. That strip-all-dereferences behavior is now a bit dubious; it's unlike what happens for other Perl-to-SQL conversions. However, the best thing to do seems to be to leave it alone and make the other conversions act similarly. That will be done separately. Dagfinn Ilmari Mannsåker, adjusted a bit by me Discussion: https://postgr.es/m/d8jlgbq66t9.fsf@dalvik.ping.uio.no
1 parent 45e98ee commit 1731e37

File tree

5 files changed

+141
-83
lines changed

5 files changed

+141
-83
lines changed

contrib/jsonb_plperl/expected/jsonb_plperl.out

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,19 @@ SELECT testRegexpResultToJsonb();
5252
0
5353
(1 row)
5454

55-
CREATE FUNCTION roundtrip(val jsonb) RETURNS jsonb
55+
CREATE FUNCTION roundtrip(val jsonb, ref text = '') RETURNS jsonb
5656
LANGUAGE plperl
5757
TRANSFORM FOR TYPE jsonb
5858
AS $$
59+
# can't use Data::Dumper, but let's at least check for unexpected ref type
60+
die 'unexpected '.(ref($_[0]) || 'not a').' reference'
61+
if ref($_[0]) ne $_[1];
5962
return $_[0];
6063
$$;
61-
SELECT roundtrip('null');
62-
roundtrip
63-
-----------
64-
null
64+
SELECT roundtrip('null') is null;
65+
?column?
66+
----------
67+
t
6568
(1 row)
6669

6770
SELECT roundtrip('1');
@@ -115,91 +118,97 @@ SELECT roundtrip('false');
115118
0
116119
(1 row)
117120

118-
SELECT roundtrip('[]');
121+
SELECT roundtrip('[]', 'ARRAY');
119122
roundtrip
120123
-----------
121124
[]
122125
(1 row)
123126

124-
SELECT roundtrip('[null, null]');
127+
SELECT roundtrip('[null, null]', 'ARRAY');
125128
roundtrip
126129
--------------
127130
[null, null]
128131
(1 row)
129132

130-
SELECT roundtrip('[1, 2, 3]');
133+
SELECT roundtrip('[1, 2, 3]', 'ARRAY');
131134
roundtrip
132135
-----------
133136
[1, 2, 3]
134137
(1 row)
135138

136-
SELECT roundtrip('[-1, 2, -3]');
139+
SELECT roundtrip('[-1, 2, -3]', 'ARRAY');
137140
roundtrip
138141
-------------
139142
[-1, 2, -3]
140143
(1 row)
141144

142-
SELECT roundtrip('[1.2, 2.3, 3.4]');
145+
SELECT roundtrip('[1.2, 2.3, 3.4]', 'ARRAY');
143146
roundtrip
144147
-----------------
145148
[1.2, 2.3, 3.4]
146149
(1 row)
147150

148-
SELECT roundtrip('[-1.2, 2.3, -3.4]');
151+
SELECT roundtrip('[-1.2, 2.3, -3.4]', 'ARRAY');
149152
roundtrip
150153
-------------------
151154
[-1.2, 2.3, -3.4]
152155
(1 row)
153156

154-
SELECT roundtrip('["string1", "string2"]');
157+
SELECT roundtrip('["string1", "string2"]', 'ARRAY');
155158
roundtrip
156159
------------------------
157160
["string1", "string2"]
158161
(1 row)
159162

160-
SELECT roundtrip('{}');
163+
SELECT roundtrip('[["string1", "string2"]]', 'ARRAY');
164+
roundtrip
165+
--------------------------
166+
[["string1", "string2"]]
167+
(1 row)
168+
169+
SELECT roundtrip('{}', 'HASH');
161170
roundtrip
162171
-----------
163172
{}
164173
(1 row)
165174

166-
SELECT roundtrip('{"1": null}');
175+
SELECT roundtrip('{"1": null}', 'HASH');
167176
roundtrip
168177
-------------
169178
{"1": null}
170179
(1 row)
171180

172-
SELECT roundtrip('{"1": 1}');
181+
SELECT roundtrip('{"1": 1}', 'HASH');
173182
roundtrip
174183
-----------
175184
{"1": 1}
176185
(1 row)
177186

178-
SELECT roundtrip('{"1": -1}');
187+
SELECT roundtrip('{"1": -1}', 'HASH');
179188
roundtrip
180189
-----------
181190
{"1": -1}
182191
(1 row)
183192

184-
SELECT roundtrip('{"1": 1.1}');
193+
SELECT roundtrip('{"1": 1.1}', 'HASH');
185194
roundtrip
186195
------------
187196
{"1": 1.1}
188197
(1 row)
189198

190-
SELECT roundtrip('{"1": -1.1}');
199+
SELECT roundtrip('{"1": -1.1}', 'HASH');
191200
roundtrip
192201
-------------
193202
{"1": -1.1}
194203
(1 row)
195204

196-
SELECT roundtrip('{"1": "string1"}');
205+
SELECT roundtrip('{"1": "string1"}', 'HASH');
197206
roundtrip
198207
------------------
199208
{"1": "string1"}
200209
(1 row)
201210

202-
SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}');
211+
SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}', 'HASH');
203212
roundtrip
204213
---------------------------------
205214
{"1": {"2": [3, 4, 5]}, "2": 3}

contrib/jsonb_plperl/expected/jsonb_plperlu.out

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,154 +52,192 @@ SELECT testRegexpResultToJsonb();
5252
0
5353
(1 row)
5454

55-
CREATE FUNCTION roundtrip(val jsonb) RETURNS jsonb
55+
CREATE FUNCTION roundtrip(val jsonb, ref text = '') RETURNS jsonb
5656
LANGUAGE plperlu
5757
TRANSFORM FOR TYPE jsonb
5858
AS $$
59+
use Data::Dumper;
60+
$Data::Dumper::Sortkeys = 1;
61+
$Data::Dumper::Indent = 0;
62+
elog(INFO, Dumper($_[0]));
63+
die 'unexpected '.(ref($_[0]) || 'not a').' reference'
64+
if ref($_[0]) ne $_[1];
5965
return $_[0];
6066
$$;
61-
SELECT roundtrip('null');
62-
roundtrip
63-
-----------
64-
null
67+
SELECT roundtrip('null') is null;
68+
INFO: $VAR1 = undef;
69+
?column?
70+
----------
71+
t
6572
(1 row)
6673

6774
SELECT roundtrip('1');
75+
INFO: $VAR1 = '1';
6876
roundtrip
6977
-----------
7078
1
7179
(1 row)
7280

7381
SELECT roundtrip('1E+131071');
82+
INFO: $VAR1 = 'inf';
7483
ERROR: cannot convert infinity to jsonb
7584
CONTEXT: PL/Perl function "roundtrip"
7685
SELECT roundtrip('-1');
86+
INFO: $VAR1 = '-1';
7787
roundtrip
7888
-----------
7989
-1
8090
(1 row)
8191

8292
SELECT roundtrip('1.2');
93+
INFO: $VAR1 = '1.2';
8394
roundtrip
8495
-----------
8596
1.2
8697
(1 row)
8798

8899
SELECT roundtrip('-1.2');
100+
INFO: $VAR1 = '-1.2';
89101
roundtrip
90102
-----------
91103
-1.2
92104
(1 row)
93105

94106
SELECT roundtrip('"string"');
107+
INFO: $VAR1 = 'string';
95108
roundtrip
96109
-----------
97110
"string"
98111
(1 row)
99112

100113
SELECT roundtrip('"NaN"');
114+
INFO: $VAR1 = 'NaN';
101115
roundtrip
102116
-----------
103117
"NaN"
104118
(1 row)
105119

106120
SELECT roundtrip('true');
121+
INFO: $VAR1 = '1';
107122
roundtrip
108123
-----------
109124
1
110125
(1 row)
111126

112127
SELECT roundtrip('false');
128+
INFO: $VAR1 = '0';
113129
roundtrip
114130
-----------
115131
0
116132
(1 row)
117133

118-
SELECT roundtrip('[]');
134+
SELECT roundtrip('[]', 'ARRAY');
135+
INFO: $VAR1 = [];
119136
roundtrip
120137
-----------
121138
[]
122139
(1 row)
123140

124-
SELECT roundtrip('[null, null]');
141+
SELECT roundtrip('[null, null]', 'ARRAY');
142+
INFO: $VAR1 = [undef,undef];
125143
roundtrip
126144
--------------
127145
[null, null]
128146
(1 row)
129147

130-
SELECT roundtrip('[1, 2, 3]');
148+
SELECT roundtrip('[1, 2, 3]', 'ARRAY');
149+
INFO: $VAR1 = ['1','2','3'];
131150
roundtrip
132151
-----------
133152
[1, 2, 3]
134153
(1 row)
135154

136-
SELECT roundtrip('[-1, 2, -3]');
155+
SELECT roundtrip('[-1, 2, -3]', 'ARRAY');
156+
INFO: $VAR1 = ['-1','2','-3'];
137157
roundtrip
138158
-------------
139159
[-1, 2, -3]
140160
(1 row)
141161

142-
SELECT roundtrip('[1.2, 2.3, 3.4]');
162+
SELECT roundtrip('[1.2, 2.3, 3.4]', 'ARRAY');
163+
INFO: $VAR1 = ['1.2','2.3','3.4'];
143164
roundtrip
144165
-----------------
145166
[1.2, 2.3, 3.4]
146167
(1 row)
147168

148-
SELECT roundtrip('[-1.2, 2.3, -3.4]');
169+
SELECT roundtrip('[-1.2, 2.3, -3.4]', 'ARRAY');
170+
INFO: $VAR1 = ['-1.2','2.3','-3.4'];
149171
roundtrip
150172
-------------------
151173
[-1.2, 2.3, -3.4]
152174
(1 row)
153175

154-
SELECT roundtrip('["string1", "string2"]');
176+
SELECT roundtrip('["string1", "string2"]', 'ARRAY');
177+
INFO: $VAR1 = ['string1','string2'];
155178
roundtrip
156179
------------------------
157180
["string1", "string2"]
158181
(1 row)
159182

160-
SELECT roundtrip('{}');
183+
SELECT roundtrip('[["string1", "string2"]]', 'ARRAY');
184+
INFO: $VAR1 = [['string1','string2']];
185+
roundtrip
186+
--------------------------
187+
[["string1", "string2"]]
188+
(1 row)
189+
190+
SELECT roundtrip('{}', 'HASH');
191+
INFO: $VAR1 = {};
161192
roundtrip
162193
-----------
163194
{}
164195
(1 row)
165196

166-
SELECT roundtrip('{"1": null}');
197+
SELECT roundtrip('{"1": null}', 'HASH');
198+
INFO: $VAR1 = {'1' => undef};
167199
roundtrip
168200
-------------
169201
{"1": null}
170202
(1 row)
171203

172-
SELECT roundtrip('{"1": 1}');
204+
SELECT roundtrip('{"1": 1}', 'HASH');
205+
INFO: $VAR1 = {'1' => '1'};
173206
roundtrip
174207
-----------
175208
{"1": 1}
176209
(1 row)
177210

178-
SELECT roundtrip('{"1": -1}');
211+
SELECT roundtrip('{"1": -1}', 'HASH');
212+
INFO: $VAR1 = {'1' => '-1'};
179213
roundtrip
180214
-----------
181215
{"1": -1}
182216
(1 row)
183217

184-
SELECT roundtrip('{"1": 1.1}');
218+
SELECT roundtrip('{"1": 1.1}', 'HASH');
219+
INFO: $VAR1 = {'1' => '1.1'};
185220
roundtrip
186221
------------
187222
{"1": 1.1}
188223
(1 row)
189224

190-
SELECT roundtrip('{"1": -1.1}');
225+
SELECT roundtrip('{"1": -1.1}', 'HASH');
226+
INFO: $VAR1 = {'1' => '-1.1'};
191227
roundtrip
192228
-------------
193229
{"1": -1.1}
194230
(1 row)
195231

196-
SELECT roundtrip('{"1": "string1"}');
232+
SELECT roundtrip('{"1": "string1"}', 'HASH');
233+
INFO: $VAR1 = {'1' => 'string1'};
197234
roundtrip
198235
------------------
199236
{"1": "string1"}
200237
(1 row)
201238

202-
SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}');
239+
SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}', 'HASH');
240+
INFO: $VAR1 = {'1' => {'2' => ['3','4','5']},'2' => '3'};
203241
roundtrip
204242
---------------------------------
205243
{"1": {"2": [3, 4, 5]}, "2": 3}

contrib/jsonb_plperl/jsonb_plperl.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ JsonbValue_to_SV(JsonbValue *jbv)
2626
switch (jbv->type)
2727
{
2828
case jbvBinary:
29-
return newRV(Jsonb_to_SV(jbv->val.binary.data));
29+
return Jsonb_to_SV(jbv->val.binary.data);
3030

3131
case jbvNumeric:
3232
{
@@ -83,7 +83,7 @@ Jsonb_to_SV(JsonbContainer *jsonb)
8383
(r = JsonbIteratorNext(&it, &tmp, true)) != WJB_DONE)
8484
elog(ERROR, "unexpected jsonb token: %d", r);
8585

86-
return newRV(JsonbValue_to_SV(&v));
86+
return JsonbValue_to_SV(&v);
8787
}
8888
else
8989
{
@@ -95,7 +95,7 @@ Jsonb_to_SV(JsonbContainer *jsonb)
9595
av_push(av, JsonbValue_to_SV(&v));
9696
}
9797

98-
return (SV *) av;
98+
return newRV((SV *) av);
9999
}
100100

101101
case WJB_BEGIN_OBJECT:
@@ -120,7 +120,7 @@ Jsonb_to_SV(JsonbContainer *jsonb)
120120
}
121121
}
122122

123-
return (SV *) hv;
123+
return newRV((SV *) hv);
124124
}
125125

126126
default:
@@ -268,7 +268,7 @@ jsonb_to_plperl(PG_FUNCTION_ARGS)
268268
Jsonb *in = PG_GETARG_JSONB_P(0);
269269
SV *sv = Jsonb_to_SV(&in->root);
270270

271-
return PointerGetDatum(newRV(sv));
271+
return PointerGetDatum(sv);
272272
}
273273

274274

0 commit comments

Comments
 (0)