Permalink
Browse files

Added json_object_to_string to build a json string

  • Loading branch information...
theirix committed Sep 3, 2012
1 parent 37a59c7 commit 5b71a10a09d5218e505ff34b1eebe4bf19694159
@@ -1,5 +1,5 @@
set client_min_messages to 'error';
-drop extension if exists "postgre-json-functions";
+drop extension if exists "postgre-json-functions" cascade;
create extension "postgre-json-functions";
set client_min_messages to 'notice';
\t on
@@ -69,5 +69,17 @@ select json_object_get_numeric_array('{"foo":"qq", "bar": [42.4242,43.4343]}', '
-- {"Tue Dec 01 01:23:45 2009","Sat Dec 01 01:23:45 2012"}
select json_object_get_timestamp_array('{"foo":"qq", "bar": ["2009-12-01 01:23:45", "2012-12-01 01:23:45"]}', 'bar');
{"Tue Dec 01 01:23:45 2009","Sat Dec 01 01:23:45 2012"}
+-- "qq"
+select json_object_to_string('{"foo":"qq", "bar": ["baz1", "baz2", "baz3"]}', 'foo');
+"qq"
+-- ["baz1","baz2","baz3"]
+select json_object_to_string('{"foo":"qq", "bar": ["baz1", "baz2", "baz3"]}', 'bar');
+["baz1","baz2","baz3"]
+-- {baz1,baz2,baz3}
+select json_array_to_text_array(json_object_to_string('{"foo":"qq", "bar": ["baz1", "baz2", "baz3"]}', 'bar'));
+{baz1,baz2,baz3}
+-- baz2
+select (json_array_to_text_array(json_object_to_string('{"foo":"qq", "bar": ["baz1", "baz2", "baz3"]}', 'bar')))[2];
+baz2
\t off
\pset format aligned
@@ -65,6 +65,9 @@ create or replace function json_object_get_numeric_array(text, text) returns num
create or replace function json_object_get_timestamp_array(text, text) returns timestamp without time zone[]
as 'MODULE_PATHNAME' language C immutable strict;
+-- JSON builder
+create or replace function json_object_to_string(text, text) returns text
+ as 'MODULE_PATHNAME' language C immutable strict;
-- GIN support
View
@@ -54,6 +54,9 @@ PG_MODULE_MAGIC;
/* TODO a little hackish format string */
#define NUMERIC_FMT "99999999999999999999999999999999999999.99999999999999999999999999999999999999"
+/* Choosen to not override with any of cJSON types */
+#define CJSON_TYPE_ANY 99
+
/*
* Internal functions declarations
*/
@@ -88,6 +91,8 @@ bool extract_bigint_array(cJSON *elem, DatumPtr result);
bool extract_numeric_array(cJSON *elem, DatumPtr result);
bool extract_timestamp_array(cJSON *elem, DatumPtr result);
+bool extract_json_to_string(cJSON *elem, DatumPtr result);
+
/*
* Exported functions
*/
@@ -111,6 +116,8 @@ Datum json_object_get_bigint_array(PG_FUNCTION_ARGS);
Datum json_object_get_numeric_array(PG_FUNCTION_ARGS);
Datum json_object_get_timestamp_array(PG_FUNCTION_ARGS);
+Datum json_object_to_string(PG_FUNCTION_ARGS);
+
Datum json_gin_compare(PG_FUNCTION_ARGS);
Datum json_gin_extract_value(PG_FUNCTION_ARGS);
Datum json_gin_extract_query(PG_FUNCTION_ARGS);
@@ -146,6 +153,8 @@ PG_FUNCTION_INFO_V1(json_object_get_bigint_array);
PG_FUNCTION_INFO_V1(json_object_get_numeric_array);
PG_FUNCTION_INFO_V1(json_object_get_timestamp_array);
+PG_FUNCTION_INFO_V1(json_object_to_string);
+
PG_FUNCTION_INFO_V1(json_gin_compare);
PG_FUNCTION_INFO_V1(json_gin_extract_value);
PG_FUNCTION_INFO_V1(json_gin_extract_query);
@@ -225,7 +234,7 @@ Datum json_object_get_generic(text *argJson, text *argKey, int json_type, pextra
sel = cJSON_GetObjectItem(root, strKey);
if (sel)
{
- if (match_json_types(json_type, sel->type))
+ if (json_type == CJSON_TYPE_ANY || match_json_types(json_type, sel->type))
{
if (extractor(sel, &result))
{
@@ -311,7 +320,7 @@ Datum json_array_to_array_generic_impl(cJSON *jsonArray, int json_type, Oid elem
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("no childs allowed")));
- if (!match_json_types(json_type, elem->type))
+ if (!(json_type == CJSON_TYPE_ANY || match_json_types(json_type, elem->type)))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("expected value of type %s, actual %s at %d position",
@@ -482,6 +491,16 @@ bool extract_timestamp_array(cJSON *elem, DatumPtr result)
return true;
}
+bool extract_json_to_string(cJSON *elem, DatumPtr result)
+{
+ char *pstr;
+ pstr = cJSON_PrintUnformatted(elem);
+ *result = PointerGetDatum(cstring_to_text(pstr));
+ free(pstr);
+ return true;
+}
+
+
/**
*
* Exported functions
@@ -559,6 +578,7 @@ Datum json_array_to_timestamp_array(PG_FUNCTION_ARGS)
/*
* Indirect array functions
*/
+
Datum json_object_get_text_array(PG_FUNCTION_ARGS)
{
return json_object_get_generic_args(fcinfo, cJSON_Array, extract_text_array);
@@ -589,6 +609,14 @@ Datum json_object_get_timestamp_array(PG_FUNCTION_ARGS)
return json_object_get_generic_args(fcinfo, cJSON_Array, extract_timestamp_array);
}
+/* Get object by key and converts it back to text
+ * Used as a proxy call
+ */
+Datum json_object_to_string(PG_FUNCTION_ARGS)
+{
+ return json_object_get_generic_args(fcinfo, CJSON_TYPE_ANY, extract_json_to_string);
+}
+
/**
*
* Operator support
@@ -900,7 +928,7 @@ json_gin_extract_query(PG_FUNCTION_ARGS)
StrategyNumber strategy = PG_GETARG_UINT16(2);
bool **pmatch = (bool**)PG_GETARG_POINTER(3);
bool **nullFlags = (bool**)PG_GETARG_POINTER(5);
- int32 *searchMode = (int32*)PG_GETARG_POINTER(6);
+ /* int32 *searchMode = (int32*)PG_GETARG_POINTER(6);*/
ArrayType *queryArray;
Datum *keys;
@@ -1,5 +1,5 @@
set client_min_messages to 'error';
-drop extension if exists "postgre-json-functions";
+drop extension if exists "postgre-json-functions" cascade;
create extension "postgre-json-functions";
set client_min_messages to 'notice';
@@ -54,5 +54,14 @@ select json_object_get_numeric_array('{"foo":"qq", "bar": [42.4242,43.4343]}', '
-- {"Tue Dec 01 01:23:45 2009","Sat Dec 01 01:23:45 2012"}
select json_object_get_timestamp_array('{"foo":"qq", "bar": ["2009-12-01 01:23:45", "2012-12-01 01:23:45"]}', 'bar');
+-- "qq"
+select json_object_to_string('{"foo":"qq", "bar": ["baz1", "baz2", "baz3"]}', 'foo');
+-- ["baz1","baz2","baz3"]
+select json_object_to_string('{"foo":"qq", "bar": ["baz1", "baz2", "baz3"]}', 'bar');
+-- {baz1,baz2,baz3}
+select json_array_to_text_array(json_object_to_string('{"foo":"qq", "bar": ["baz1", "baz2", "baz3"]}', 'bar'));
+-- baz2
+select (json_array_to_text_array(json_object_to_string('{"foo":"qq", "bar": ["baz1", "baz2", "baz3"]}', 'bar')))[2];
+
\t off
\pset format aligned

0 comments on commit 5b71a10

Please sign in to comment.