On 01/28/2014 01:22 PM, Alvaro Herrera wrote:
Josh Berkus wrote:
On 01/27/2014 01:06 PM, Alvaro Herrera wrote:
Andrew Dunstan escribió:

I'm not sure I understand the need. This is the difference between
the _text variants and their parents. Why would you call
json_object_field when you want the dequoted text?
Because I first need to know its type.  Sometimes it's an array, or an
object, or a boolean, and for those I won't call the _text version
afterwards but just use the original.
It would make more sense to extract them as JSON, check the type, and
convert.
That's what I'm already doing.  My question is how do I convert it?
I have this, but would like to get rid of it:

/*
  * dequote_jsonval
  *             Take a string value extracted from a JSON object, and return a 
copy of it
  *             with the quoting removed.
  *
  * Another alternative to this would be to run the extraction routine again,
  * using the "_text" variant which returns the value without quotes; but this
  * complicates the logic a lot because not all values are extracted in
  * the same way (some are extracted using json_object_field, others
  * using json_array_element).  Dequoting the object already at hand is a
  * lot easier.
  */
static char *
dequote_jsonval(char *jsonval)
{
        char   *result;
        int             inputlen = strlen(jsonval);
        int             i;
        int             j = 0;

        result = palloc(strlen(jsonval) + 1);

        /* skip the start and end quotes right away */
        for (i = 1; i < inputlen - 1; i++)
        {
                /*
                 * XXX this skips the \ in a \" sequence but leaves other 
escaped
                 * sequences in place.  Are there other cases we need to handle
                 * specially?
                 */
                if (jsonval[i] == '\\' &&
                        jsonval[i + 1] == '"')
                {
                        i++;
                        continue;
                }

                result[j++] = jsonval[i];
        }
        result[j] = '\0';

        return result;
}




Well, TIMTOWTDI. Here's roughly what I would do, in json.c, making the json lexer do the work for us:

   extern char *
   dequote_scalar_json_string(char *jsonval)
   {
        text *json = cstring_to_text(jsonval);
        JsonLexContext *lex = makeJsonLexContext(json, true);
        JsonTokenType tok;
        char *ret;

        json_lex(lex);
        tok = lex_peek(lex);
        if (tok == JSON_TOKEN_STRING)
            ret=pstrdup(lex->strval->data);
        else
            ret = jsonval;
        pfree(lex->strval->data);
        pfree(lex->strval);
        pfree(lex);
        pfree(json);

        return ret;
   }


I'm not sure if we should have a gadget like this at the SQL level also.


cheers

andrew


--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to