From d3c72e23df6ef1fde8122db589d12d49c8495535 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 9 May 2014 11:32:28 +0300 Subject: [PATCH] Avoid some pnstrdup()s when constructing jsonb This speeds up text to jsonb parsing and hstore to jsonb conversions somewhat. --- contrib/hstore/hstore_io.c | 8 ++++---- src/backend/utils/adt/json.c | 3 --- src/backend/utils/adt/jsonb.c | 4 ++-- src/include/utils/jsonapi.h | 4 ++++ 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c index 441dbf4a7c..6ce3047215 100644 --- a/contrib/hstore/hstore_io.c +++ b/contrib/hstore/hstore_io.c @@ -1386,7 +1386,7 @@ hstore_to_jsonb(PG_FUNCTION_ARGS) key.type = jbvString; key.val.string.len = HS_KEYLEN(entries, i); - key.val.string.val = pnstrdup(HS_KEY(entries, base, i), key.val.string.len); + key.val.string.val = HS_KEY(entries, base, i); res = pushJsonbValue(&state, WJB_KEY, &key); @@ -1398,7 +1398,7 @@ hstore_to_jsonb(PG_FUNCTION_ARGS) { val.type = jbvString; val.val.string.len = HS_VALLEN(entries, i); - val.val.string.val = pnstrdup(HS_VAL(entries, base, i), val.val.string.len); + val.val.string.val = HS_VAL(entries, base, i); } res = pushJsonbValue(&state, WJB_VALUE, &val); } @@ -1433,7 +1433,7 @@ hstore_to_jsonb_loose(PG_FUNCTION_ARGS) key.type = jbvString; key.val.string.len = HS_KEYLEN(entries, i); - key.val.string.val = pnstrdup(HS_KEY(entries, base, i), key.val.string.len); + key.val.string.val = HS_KEY(entries, base, i); res = pushJsonbValue(&state, WJB_KEY, &key); @@ -1507,7 +1507,7 @@ hstore_to_jsonb_loose(PG_FUNCTION_ARGS) { val.type = jbvString; val.val.string.len = HS_VALLEN(entries, i); - val.val.string.val = pnstrdup(HS_VAL(entries, base, i), val.val.string.len); + val.val.string.val = HS_VAL(entries, base, i); } } res = pushJsonbValue(&state, WJB_VALUE, &val); diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index 16f4eccc06..e2db24520e 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -381,9 +381,6 @@ parse_object_field(JsonLexContext *lex, JsonSemAction *sem) if (oend != NULL) (*oend) (sem->semstate, fname, isnull); - - if (fname != NULL) - pfree(fname); } static void diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c index e1fe45f712..2fd87fc9e1 100644 --- a/src/backend/utils/adt/jsonb.c +++ b/src/backend/utils/adt/jsonb.c @@ -247,7 +247,7 @@ jsonb_in_object_field_start(void *pstate, char *fname, bool isnull) Assert(fname != NULL); v.type = jbvString; v.val.string.len = checkStringLen(strlen(fname)); - v.val.string.val = pnstrdup(fname, v.val.string.len); + v.val.string.val = fname; _state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v); } @@ -295,7 +295,7 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype) Assert(token != NULL); v.type = jbvString; v.val.string.len = checkStringLen(strlen(token)); - v.val.string.val = pnstrdup(token, v.val.string.len); + v.val.string.val = token; break; case JSON_TOKEN_NUMBER: diff --git a/src/include/utils/jsonapi.h b/src/include/utils/jsonapi.h index 889364fb30..df057121a1 100644 --- a/src/include/utils/jsonapi.h +++ b/src/include/utils/jsonapi.h @@ -73,6 +73,10 @@ typedef void (*json_scalar_action) (void *state, char *token, JsonTokenType toke * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts * to doing a pure parse with no side-effects, and is therefore exactly * what the json input routines do. + * + * The 'fname' and 'token' strings passed to these actions are palloc'd. + * They are not free'd or used further by the parser, so the action function + * is free to do what it wishes with them. */ typedef struct JsonSemAction {