diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2014-06-29 13:50:58 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2014-06-29 13:50:58 -0400 |
commit | a749a23d7af4dba9b3468076ec561d2cbf69af09 (patch) | |
tree | a2e0ebac0a075c5004156a2ca5b96272f0827ae6 /src/backend/utils/adt/jsonfuncs.c | |
parent | 51adcaa0df81da5e94b582d47de64ebb17129937 (diff) | |
download | postgresql-a749a23d7af4dba9b3468076ec561d2cbf69af09.tar.gz postgresql-a749a23d7af4dba9b3468076ec561d2cbf69af09.zip |
Remove use_json_as_text options from json_to_record/json_populate_record.
The "false" case was really quite useless since all it did was to throw
an error; a definition not helped in the least by making it the default.
Instead let's just have the "true" case, which emits nested objects and
arrays in JSON syntax. We might later want to provide the ability to
emit sub-objects in Postgres record or array syntax, but we'd be best off
to drive that off a check of the target field datatype, not a separate
argument.
For the functions newly added in 9.4, we can just remove the flag arguments
outright. We can't do that for json_populate_record[set], which already
existed in 9.3, but we can ignore the argument and always behave as if it
were "true". It helps that the flag arguments were optional and not
documented in any useful fashion anyway.
Diffstat (limited to 'src/backend/utils/adt/jsonfuncs.c')
-rw-r--r-- | src/backend/utils/adt/jsonfuncs.c | 60 |
1 files changed, 6 insertions, 54 deletions
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index bd1241b620f..6c16a953dd3 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -85,8 +85,7 @@ static void elements_array_element_end(void *state, bool isnull); static void elements_scalar(void *state, char *token, JsonTokenType tokentype); /* turn a json object into a hash table */ -static HTAB *get_json_object_as_hash(text *json, const char *funcname, - bool use_json_as_text); +static HTAB *get_json_object_as_hash(text *json, const char *funcname); /* common worker for populate_record and to_record */ static Datum populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, @@ -198,7 +197,6 @@ typedef struct JhashState HTAB *hash; char *saved_scalar; char *save_json_start; - bool use_json_as_text; } JHashState; /* hashtable element */ @@ -235,7 +233,6 @@ typedef struct PopulateRecordsetState HTAB *json_hash; char *saved_scalar; char *save_json_start; - bool use_json_as_text; Tuplestorestate *tuple_store; TupleDesc ret_tdesc; HeapTupleHeader rec; @@ -1989,7 +1986,6 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, Oid jtype = get_fn_expr_argtype(fcinfo->flinfo, json_arg_num); text *json; Jsonb *jb = NULL; - bool use_json_as_text; HTAB *json_hash = NULL; HeapTupleHeader rec = NULL; Oid tupType = InvalidOid; @@ -2005,9 +2001,6 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, Assert(jtype == JSONOID || jtype == JSONBOID); - use_json_as_text = PG_ARGISNULL(json_arg_num + 1) ? false : - PG_GETARG_BOOL(json_arg_num + 1); - if (have_record_arg) { Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0); @@ -2065,7 +2058,7 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, /* just get the text */ json = PG_GETARG_TEXT_P(json_arg_num); - json_hash = get_json_object_as_hash(json, funcname, use_json_as_text); + json_hash = get_json_object_as_hash(json, funcname); /* * if the input json is empty, we can only skip the rest if we were @@ -2227,10 +2220,6 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, else if (v->type == jbvNumeric) s = DatumGetCString(DirectFunctionCall1(numeric_out, PointerGetDatum(v->val.numeric))); - else if (!use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot populate with a nested object unless use_json_as_text is true"))); else if (v->type == jbvBinary) s = JsonbToCString(NULL, (JsonbContainer *) v->val.binary.data, v->val.binary.len); else @@ -2258,15 +2247,9 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, * get_json_object_as_hash * * decompose a json object into a hash table. - * - * Currently doesn't allow anything but a flat object. Should this - * change? - * - * funcname argument allows caller to pass in its name for use in - * error messages. */ static HTAB * -get_json_object_as_hash(text *json, const char *funcname, bool use_json_as_text) +get_json_object_as_hash(text *json, const char *funcname) { HASHCTL ctl; HTAB *tab; @@ -2289,7 +2272,6 @@ get_json_object_as_hash(text *json, const char *funcname, bool use_json_as_text) state->function_name = funcname; state->hash = tab; state->lex = lex; - state->use_json_as_text = use_json_as_text; sem->semstate = (void *) state; sem->array_start = hash_array_start; @@ -2313,11 +2295,7 @@ hash_object_field_start(void *state, char *fname, bool isnull) if (_state->lex->token_type == JSON_TOKEN_ARRAY_START || _state->lex->token_type == JSON_TOKEN_OBJECT_START) { - if (!_state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot call %s on a nested object", - _state->function_name))); + /* remember start position of the whole text of the subobject */ _state->save_json_start = _state->lex->token_start; } else @@ -2535,10 +2513,6 @@ make_row_from_rec_and_jsonb(Jsonb *element, PopulateRecordsetState *state) else if (v->type == jbvNumeric) s = DatumGetCString(DirectFunctionCall1(numeric_out, PointerGetDatum(v->val.numeric))); - else if (!state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot populate with a nested object unless use_json_as_text is true"))); else if (v->type == jbvBinary) s = JsonbToCString(NULL, (JsonbContainer *) v->val.binary.data, v->val.binary.len); else @@ -2565,7 +2539,6 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, { int json_arg_num = have_record_arg ? 1 : 0; Oid jtype = get_fn_expr_argtype(fcinfo->flinfo, json_arg_num); - bool use_json_as_text; ReturnSetInfo *rsi; MemoryContext old_cxt; Oid tupType; @@ -2576,8 +2549,6 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, int ncolumns; PopulateRecordsetState *state; - use_json_as_text = PG_ARGISNULL(json_arg_num + 1) ? false : PG_GETARG_BOOL(json_arg_num + 1); - if (have_record_arg) { Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0); @@ -2667,7 +2638,6 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, state->function_name = funcname; state->my_extra = my_extra; state->rec = rec; - state->use_json_as_text = use_json_as_text; state->fn_mcxt = fcinfo->flinfo->fn_mcxt; if (jtype == JSONOID) @@ -2749,16 +2719,9 @@ populate_recordset_object_start(void *state) errmsg("cannot call %s on an object", _state->function_name))); - /* Nested objects, if allowed, require no special processing */ + /* Nested objects require no special processing */ if (lex_level > 1) - { - if (!_state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot call %s with nested objects", - _state->function_name))); return; - } /* Object at level 1: set up a new hash table for this object */ memset(&ctl, 0, sizeof(ctl)); @@ -2903,13 +2866,7 @@ populate_recordset_array_element_start(void *state, bool isnull) static void populate_recordset_array_start(void *state) { - PopulateRecordsetState *_state = (PopulateRecordsetState *) state; - - if (_state->lex->lex_level != 0 && !_state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot call %s with nested arrays", - _state->function_name))); + /* nothing to do */ } static void @@ -2938,11 +2895,6 @@ populate_recordset_object_field_start(void *state, char *fname, bool isnull) if (_state->lex->token_type == JSON_TOKEN_ARRAY_START || _state->lex->token_type == JSON_TOKEN_OBJECT_START) { - if (!_state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot call %s on a nested object", - _state->function_name))); _state->save_json_start = _state->lex->token_start; } else |