Re: PATCH: recursive json_populate_record()

Nikita Glukhov <n.gluhov@postgrespro.ru>

From: Nikita Glukhov <n.gluhov@postgrespro.ru>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Aleksander Alekseev <a.alekseev@postgrespro.ru>, Michael Paquier <michael.paquier@gmail.com>, PostgreSQL mailing lists <pgsql-hackers@postgresql.org>
Date: 2017-01-25T21:36:53Z
Lists: pgsql-hackers
On 25.01.2017 23:58, Tom Lane wrote:
> I think you need to take a second look at the code you're producing
> and realize that it's not so clean either.  This extract from
> populate_record_field, for example, is pretty horrid:

But what if we introduce some helper macros like this:

#define JsValueIsNull(jsv) \
     ((jsv)->is_json ? !(jsv)->val.json.str \
         : !(jsv)->val.jsonb || (jsv)->val.jsonb->type == jbvNull)

#define JsValueIsString(jsv) \
     ((jsv)->is_json ? (jsv)->val.json.type == JSON_TOKEN_STRING \
         : (jsv)->val.jsonb && (jsv)->val.jsonb->type == jbvString)


      /* prepare column metadata cache for the given type */
      if (col->typid != typid || col->typmod != typmod)
          prepare_column_cache(col, typid, typmod, mcxt, jsv->is_json);

      *isnull = JsValueIsNull(jsv);

      typcat = col->typcat;

      /* try to convert json string to a non-scalar type through input function */
      if (JsValueIsString(jsv) &&
          (typcat == TYPECAT_ARRAY || typcat == TYPECAT_COMPOSITE))
          typcat = TYPECAT_SCALAR;

      /* we must perform domain checks for NULLs */
      if (*isnull && typcat != TYPECAT_DOMAIN)
          return (Datum) 0;

-- 
Nikita Glukhov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company



Commits

  1. Make edge-case behavior of jsonb_populate_record match json_populate_record

  2. Fix thinko in JsObjectSize() macro.

  3. Introduce convenience macros to hide JsonbContainer header accesses better.