Re: new json funcs - Mailing list pgsql-hackers
| From | Andrew Dunstan |
|---|---|
| Subject | Re: new json funcs |
| Date | |
| Msg-id | 52E81860.1040203@dunslane.net Whole thread Raw |
| In response to | Re: new json funcs (Alvaro Herrera <alvherre@2ndquadrant.com>) |
| List | pgsql-hackers |
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
pgsql-hackers by date: