aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/jsonfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-06-29 13:50:58 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2014-06-29 13:50:58 -0400
commita749a23d7af4dba9b3468076ec561d2cbf69af09 (patch)
treea2e0ebac0a075c5004156a2ca5b96272f0827ae6 /src/backend/utils/adt/jsonfuncs.c
parent51adcaa0df81da5e94b582d47de64ebb17129937 (diff)
downloadpostgresql-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.c60
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