|
1 | 1 | #include "postgres.h"
|
2 | 2 |
|
| 3 | +#include <float.h> |
| 4 | +#include <math.h> |
| 5 | + |
| 6 | +/* Defined by Perl */ |
3 | 7 | #undef _
|
4 | 8 |
|
5 | 9 | #include "fmgr.h"
|
6 | 10 | #include "plperl.h"
|
7 | 11 | #include "plperl_helpers.h"
|
8 |
| - |
9 | 12 | #include "utils/jsonb.h"
|
10 | 13 | #include "utils/fmgrprotos.h"
|
11 | 14 |
|
@@ -188,46 +191,51 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem)
|
188 | 191 | case SVt_PVHV:
|
189 | 192 | return HV_to_JsonbValue((HV *) in, jsonb_state);
|
190 | 193 |
|
191 |
| - case SVt_NV: |
192 |
| - case SVt_IV: |
| 194 | + case SVt_NULL: |
| 195 | + out.type = jbvNull; |
| 196 | + break; |
| 197 | + |
| 198 | + default: |
| 199 | + if (SvIOK(in)) |
193 | 200 | {
|
194 |
| - char *str = sv2cstr(in); |
| 201 | + IV ival = SvIV(in); |
195 | 202 |
|
196 |
| - /* |
197 |
| - * Use case-insensitive comparison because infinity |
198 |
| - * representation varies across Perl versions. |
199 |
| - */ |
200 |
| - if (pg_strcasecmp(str, "inf") == 0) |
| 203 | + out.type = jbvNumeric; |
| 204 | + out.val.numeric = |
| 205 | + DatumGetNumeric(DirectFunctionCall1(int8_numeric, |
| 206 | + Int64GetDatum((int64) ival))); |
| 207 | + } |
| 208 | + else if (SvNOK(in)) |
| 209 | + { |
| 210 | + double nval = SvNV(in); |
| 211 | + |
| 212 | + if (isinf(nval)) |
201 | 213 | ereport(ERROR,
|
202 |
| - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 214 | + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
203 | 215 | (errmsg("cannot convert infinite value to jsonb"))));
|
204 | 216 |
|
205 | 217 | out.type = jbvNumeric;
|
206 |
| - out.val.numeric = DatumGetNumeric(DirectFunctionCall3(numeric_in, |
207 |
| - CStringGetDatum(str), 0, -1)); |
| 218 | + out.val.numeric = |
| 219 | + DatumGetNumeric(DirectFunctionCall1(float8_numeric, |
| 220 | + Float8GetDatum(nval))); |
| 221 | + } |
| 222 | + else if (SvPOK(in)) |
| 223 | + { |
| 224 | + out.type = jbvString; |
| 225 | + out.val.string.val = sv2cstr(in); |
| 226 | + out.val.string.len = strlen(out.val.string.val); |
| 227 | + } |
| 228 | + else |
| 229 | + { |
| 230 | + /* |
| 231 | + * XXX It might be nice if we could include the Perl type in |
| 232 | + * the error message. |
| 233 | + */ |
| 234 | + ereport(ERROR, |
| 235 | + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 236 | + (errmsg("cannot transform this Perl type to jsonb")))); |
| 237 | + return NULL; |
208 | 238 | }
|
209 |
| - break; |
210 |
| - |
211 |
| - case SVt_NULL: |
212 |
| - out.type = jbvNull; |
213 |
| - break; |
214 |
| - |
215 |
| - case SVt_PV: /* string */ |
216 |
| - out.type = jbvString; |
217 |
| - out.val.string.val = sv2cstr(in); |
218 |
| - out.val.string.len = strlen(out.val.string.val); |
219 |
| - break; |
220 |
| - |
221 |
| - default: |
222 |
| - |
223 |
| - /* |
224 |
| - * XXX It might be nice if we could include the Perl type in the |
225 |
| - * error message. |
226 |
| - */ |
227 |
| - ereport(ERROR, |
228 |
| - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
229 |
| - (errmsg("cannot transform this Perl type to jsonb")))); |
230 |
| - return NULL; |
231 | 239 | }
|
232 | 240 |
|
233 | 241 | /* Push result into 'jsonb_state' unless it is a raw scalar. */
|
|
0 commit comments