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

Поиск
Список
Период
Сортировка
От REIX, Tony
Тема RE: Issue with v11.0 within jsonb_plperl tests in 32bit on AIX
Дата
Msg-id HE1PR0202MB2812FFC433F5CEE2E898046686C40@HE1PR0202MB2812.eurprd02.prod.outlook.com
обсуждение исходный текст
Ответ на Re: Issue with v11.0 within jsonb_plperl tests in 32bit on AIX  (Alvaro Herrera <alvherre@2ndquadrant.com>)
Список 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.reix@atos.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



De : Alvaro Herrera <alvherre@2ndquadrant.com>
Envoyé : mardi 6 novembre 2018 18:45
À : REIX, Tony
Cc : pgsql-hackers@postgresql.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
Вложения

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Alexey Kondratov
Дата:
Сообщение: Re: [Patch] pg_rewind: options to use restore_command fromrecovery.conf or command line
Следующее
От: Masahiko Sawada
Дата:
Сообщение: Re: Connection slots reserved for replication