RE: Issue with v11.0 within jsonb_plperl tests in 32bit on AIX

From: "REIX, Tony" <tony(dot)reix(at)atos(dot)net>
To: Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>
Cc: "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: RE: Issue with v11.0 within jsonb_plperl tests in 32bit on AIX
Date: 2018-11-07 10:21:22
Message-ID: HE1PR0202MB2812FFC433F5CEE2E898046686C40@HE1PR0202MB2812.eurprd02.prod.outlook.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


Hi Alvaro,

Thanks for your help.

Here is the regression.diffs file.

About the root cause, I noticed that, for the 2nd error:

< ERROR: cannot convert infinity to jsonb
< CONTEXT: PL/Perl function "roundtrip"
---
> roundtrip
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000266336287858179
> (1 row)

where an error message is expected, saying that converting infinity to jsonb is not possible, that deals with this code here below.

After generating the CPP pre-processed file jsonb_plperl.c by using -E, both for 32 and 64bit, I see that the 64 vs 32bit code of function SV_to_JsonbValuefunction differs only by:

# diff 64 32
34c34
< ((Numeric) pg_detoast_datum((struct varlena *) ((Pointer) (DirectFunctionCall1Coll(int8_numeric, ((Oid) 0), ((Datum) ((int64) ival))))))) ;
---
> ((Numeric) pg_detoast_datum((struct varlena *) ((Pointer) (DirectFunctionCall1Coll(int8_numeric, ((Oid) 0), Int64GetDatum((int64) ival)))))) ;

About your comment : "(I wonder if those values are actually representable in 32 bits.)" , I see that that works fine in 32bit on AIX in the build-farm. So, I guess that there is something wrong with Perl in 32bit on my machine...

Doing a complete diff of the 32bit vs 64bit versions of the jsonb_plperl.o by means of: gcc -E .... jsonb_plperl.c , I see that there 674 differences... 😞

postgresql-11.0/32bit/contrib/jsonb_plperl/jsonb_plperl.c :

static JsonbValue *
SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem)
{
...
/* Dereference references recursively. */
while (SvROK(in))
in = SvRV(in);

switch (SvTYPE(in))
{
....
default:
if (SvUOK(in))
{
...
}
else if (SvIOK(in))
{
...
}
else if (SvNOK(in))
{
double nval = SvNV(in);

/*
* jsonb doesn't allow infinity or NaN (per JSON
* specification), but the numeric type that is used for the
* storage accepts NaN, so we have to prevent it here
* explicitly. We don't really have to check for isinf()
* here, as numeric doesn't allow it and it would be caught
* later, but it makes for a nicer error message.
*/
if (isinf(nval))
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
(errmsg("cannot convert infinity to jsonb"))));

Result of building with -E on routine SV_to_JsonbValue :

There are plenty of complex low-level computations and calls to Perl...

static JsonbValue *
SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state,
# 179 "jsonb_plperl.c" 3 4
_Bool
# 179 "jsonb_plperl.c"
is_elem)
{
PerlInterpreter* my_perl __attribute__((unused)) = ((PerlInterpreter *)pthread_getspecific(PL_thr_key));
JsonbValue out;
while (((in)->sv_flags & 0x00000800))
in = ((in)->sv_u.svu_rv);
switch (((svtype)((in)->sv_flags & 0xff)))
{
case SVt_PVAV:
return AV_to_JsonbValue((AV *) in, jsonb_state);
case SVt_PVHV:
return HV_to_JsonbValue((HV *) in, jsonb_state);
case SVt_NULL:
out.type = jbvNull;
break;
default:
if ((((in)->sv_flags & (0x00000100|0x80000000)) == (0x00000100|0x80000000)))
{
const char *strval = ((((in)->sv_flags & (0x00000400|0x00200000)) == 0x00000400) ? ((in)->sv_u.svu_pv) : Perl_sv_2pv_flags(my_perl, in,0,2));
out.type = jbvNumeric;
out.val.numeric =
((Numeric) pg_detoast_datum((struct varlena *) ((Pointer) (DirectFunctionCall3Coll(numeric_in, ((Oid) 0), ((Datum) (strval)), ((Datum) (((Oid) 0))), ((Datum) (-1))))))) ;
}
else if (((in)->sv_flags & 0x00000100))
{
IV ival = ((((in)->sv_flags & (0x00000100|0x00200000)) == 0x00000100) ? ((XPVIV*) (in)->sv_any)->xiv_u.xivu_iv : Perl_sv_2iv_flags(my_perl, in,2));
out.type = jbvNumeric;
out.val.numeric =
((Numeric) pg_detoast_datum((struct varlena *) ((Pointer) (DirectFunctionCall1Coll(int8_numeric, ((Oid) 0), Int64GetDatum((int64) ival)))))) ;
}
else if (((in)->sv_flags & 0x00000200))
{
double nval = ((((in)->sv_flags & (0x00000200|0x00200000)) == 0x00000200) ? ((XPVNV*) (in)->sv_any)->xnv_u.xnv_nv : Perl_sv_2nv_flags(my_perl, in,2));
# 239 "jsonb_plperl.c"
if (
# 239 "jsonb_plperl.c" 3 4
((1) ? ((sizeof(
# 239 "jsonb_plperl.c"
nval
# 239 "jsonb_plperl.c" 3 4
) == sizeof(float)) ? _isinff(
# 239 "jsonb_plperl.c"
nval
# 239 "jsonb_plperl.c" 3 4
) : _isinf(
# 239 "jsonb_plperl.c"
nval
# 239 "jsonb_plperl.c" 3 4
)) : (0))
# 239 "jsonb_plperl.c"
)
do { if (errstart(20,
"jsonb_plperl.c"
# 240 "jsonb_plperl.c"
,
242
# 240 "jsonb_plperl.c"
, __func__,
# 240 "jsonb_plperl.c" 3 4
((void *)0)
# 240 "jsonb_plperl.c"
)) errfinish (errcode((((('2') - '0') & 0x3F) + (((('2') - '0') & 0x3F) << 6) + (((('0') - '0') & 0x3F) << 12) + (((('0') - '0') & 0x3F) << 18) + (((('3') - '0') & 0x3F) << 24))), (errmsg("cannot convert infinity to jsonb"))); if (__builtin_constant_p(20) && (20) >= 20) __builtin_unreachable(); } while(0) ;
if (
# 243 "jsonb_plperl.c" 3 4
((1) ? ((sizeof(
# 243 "jsonb_plperl.c"
nval
# 243 "jsonb_plperl.c" 3 4
) == sizeof(float)) ? _isnanf(
# 243 "jsonb_plperl.c"
nval
# 243 "jsonb_plperl.c" 3 4
) : _isnan(
# 243 "jsonb_plperl.c"
nval
# 243 "jsonb_plperl.c" 3 4
)) : (0))
# 243 "jsonb_plperl.c"
)
do { if (errstart(20,
"jsonb_plperl.c"
# 244 "jsonb_plperl.c"
,
246
# 244 "jsonb_plperl.c"
, __func__,
# 244 "jsonb_plperl.c" 3 4
((void *)0)
# 244 "jsonb_plperl.c"
)) errfinish (errcode((((('2') - '0') & 0x3F) + (((('2') - '0') & 0x3F) << 6) + (((('0') - '0') & 0x3F) << 12) + (((('0') - '0') & 0x3F) << 18) + (((('3') - '0') & 0x3F) << 24))), (errmsg("cannot convert NaN to jsonb"))); if (__builtin_constant_p(20) && (20) >= 20) __builtin_unreachable(); } while(0) ;
out.type = jbvNumeric;
out.val.numeric =
((Numeric) pg_detoast_datum((struct varlena *) ((Pointer) (DirectFunctionCall1Coll(float8_numeric, ((Oid) 0), Float8GetDatum(nval)))))) ;
}
else if (((in)->sv_flags & 0x00000400))
{
out.type = jbvString;
out.val.string.val = sv2cstr(in);
out.val.string.len = strlen(out.val.string.val);
}
else
{
do { if (errstart(20,
"jsonb_plperl.c"
# 265 "jsonb_plperl.c"
,
267
# 265 "jsonb_plperl.c"
, __func__,
# 265 "jsonb_plperl.c" 3 4
((void *)0)
# 265 "jsonb_plperl.c"
)) errfinish (errcode((((('0') - '0') & 0x3F) + (((('A') - '0') & 0x3F) << 6) + (((('0') - '0') & 0x3F) << 12) + (((('0') - '0') & 0x3F) << 18) + (((('0') - '0') & 0x3F) << 24))), (errmsg("cannot transform this Perl type to jsonb"))); if (__builtin_constant_p(20) && (20) >= 20) __builtin_unreachable(); } while(0) ;
return
# 268 "jsonb_plperl.c" 3 4
((void *)0)
# 268 "jsonb_plperl.c"
;
}
}
return *jsonb_state
? pushJsonbValue(jsonb_state, is_elem ? WJB_ELEM : WJB_VALUE, &out)
: memcpy(palloc(sizeof(JsonbValue)), &out, sizeof(JsonbValue));
}

Cordialement,

Tony Reix

tony(dot)reix(at)atos(dot)net

ATOS / Bull SAS
ATOS Expert
IBM Coop Architect & Technical Leader
Office : +33 (0) 4 76 29 72 67
1 rue de Provence - 38432 Échirolles - France
www.atos.net<https://mail.ad.bull.net/owa/redir.aspx?C=PvphmPvCZkGrAgHVnWGsdMcDKgzl_dEIsM6rX0g4u4v8V81YffzBGkWrtQeAXNovd3ttkJL8JIc.&URL=http%3a%2f%2fwww.atos.net%2f>

________________________________
De : Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>
Envoyé : mardi 6 novembre 2018 18:45
À : REIX, Tony
Cc : pgsql-hackers(at)postgresql(dot)org
Objet : Re: Issue with v11.0 within jsonb_plperl tests in 32bit on AIX

On 2018-Nov-06, REIX, Tony wrote:

> Hummm The buildfarm does show that these tests are OK on AIX machines in 32bit, with GCC 4.8.1 .
>
> Nuts !
>
>
> Attached is the full diff between the expected results and the real results.

Standard diffs are awful to read. Would you mind using context or
unified diffs please (diff -c or diff -u)? Also, keep in mind that the
regression tests save a file "regression.diffs" with all the diffs in
context format, so there's no need to create them yourself.

That said, this looks like there's an ABI mismatch somewhere, where
this:

< roundtrip
< ---------------------------------
< {"1": {"2": [3, 4, 5]}, "2": 3}

ends up as

{
"1": {
"2": [
0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000531017013119972,
0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000531146529464635,
0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000530757980430645
]
},
"2": 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026632835514017
}

Note that keys seem okay, but the values are corrupted. (I wonder if
those values are actually representable in 32 bits.) What catches my
attention is that the values for "3" in the two places where it appears
are different.

--
Álvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachment Content-Type Size
regression.diffs application/octet-stream 48.2 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Masahiko Sawada 2018-11-07 10:31:00 Re: Connection slots reserved for replication
Previous Message Etsuro Fujita 2018-11-07 10:03:32 Re: BUG #15449: file_fdw using program cause exit code error when using LIMIT