Skip to content

Commit

Permalink
Added json_object_to_string to build a json string
Browse files Browse the repository at this point in the history
  • Loading branch information
theirix committed Sep 3, 2012
1 parent 37a59c7 commit 5b71a10
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 5 deletions.
14 changes: 13 additions & 1 deletion expected/postgre-json-functions.out
@@ -1,5 +1,5 @@
set client_min_messages to 'error'; 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"; create extension "postgre-json-functions";
set client_min_messages to 'notice'; set client_min_messages to 'notice';
\t on \t on
Expand Down Expand Up @@ -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"} -- {"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'); 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"} {"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 \t off
\pset format aligned \pset format aligned
3 changes: 3 additions & 0 deletions postgre-json-functions--1.0.sql
Expand Up @@ -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[] create or replace function json_object_get_timestamp_array(text, text) returns timestamp without time zone[]
as 'MODULE_PATHNAME' language C immutable strict; 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 -- GIN support


Expand Down
34 changes: 31 additions & 3 deletions postgre-json-functions.c
Expand Up @@ -54,6 +54,9 @@ PG_MODULE_MAGIC;
/* TODO a little hackish format string */ /* TODO a little hackish format string */
#define NUMERIC_FMT "99999999999999999999999999999999999999.99999999999999999999999999999999999999" #define NUMERIC_FMT "99999999999999999999999999999999999999.99999999999999999999999999999999999999"


/* Choosen to not override with any of cJSON types */
#define CJSON_TYPE_ANY 99

/* /*
* Internal functions declarations * Internal functions declarations
*/ */
Expand Down Expand Up @@ -88,6 +91,8 @@ bool extract_bigint_array(cJSON *elem, DatumPtr result);
bool extract_numeric_array(cJSON *elem, DatumPtr result); bool extract_numeric_array(cJSON *elem, DatumPtr result);
bool extract_timestamp_array(cJSON *elem, DatumPtr result); bool extract_timestamp_array(cJSON *elem, DatumPtr result);


bool extract_json_to_string(cJSON *elem, DatumPtr result);

/* /*
* Exported functions * Exported functions
*/ */
Expand All @@ -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_numeric_array(PG_FUNCTION_ARGS);
Datum json_object_get_timestamp_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_compare(PG_FUNCTION_ARGS);
Datum json_gin_extract_value(PG_FUNCTION_ARGS); Datum json_gin_extract_value(PG_FUNCTION_ARGS);
Datum json_gin_extract_query(PG_FUNCTION_ARGS); Datum json_gin_extract_query(PG_FUNCTION_ARGS);
Expand Down Expand Up @@ -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_numeric_array);
PG_FUNCTION_INFO_V1(json_object_get_timestamp_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_compare);
PG_FUNCTION_INFO_V1(json_gin_extract_value); PG_FUNCTION_INFO_V1(json_gin_extract_value);
PG_FUNCTION_INFO_V1(json_gin_extract_query); PG_FUNCTION_INFO_V1(json_gin_extract_query);
Expand Down Expand Up @@ -225,7 +234,7 @@ Datum json_object_get_generic(text *argJson, text *argKey, int json_type, pextra
sel = cJSON_GetObjectItem(root, strKey); sel = cJSON_GetObjectItem(root, strKey);
if (sel) 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)) if (extractor(sel, &result))
{ {
Expand Down Expand Up @@ -311,7 +320,7 @@ Datum json_array_to_array_generic_impl(cJSON *jsonArray, int json_type, Oid elem
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE), (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("no childs allowed"))); 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, ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE), (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("expected value of type %s, actual %s at %d position", errmsg("expected value of type %s, actual %s at %d position",
Expand Down Expand Up @@ -482,6 +491,16 @@ bool extract_timestamp_array(cJSON *elem, DatumPtr result)
return true; 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 * Exported functions
Expand Down Expand Up @@ -559,6 +578,7 @@ Datum json_array_to_timestamp_array(PG_FUNCTION_ARGS)
/* /*
* Indirect array functions * Indirect array functions
*/ */

Datum json_object_get_text_array(PG_FUNCTION_ARGS) Datum json_object_get_text_array(PG_FUNCTION_ARGS)
{ {
return json_object_get_generic_args(fcinfo, cJSON_Array, extract_text_array); return json_object_get_generic_args(fcinfo, cJSON_Array, extract_text_array);
Expand Down Expand Up @@ -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); 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 * Operator support
Expand Down Expand Up @@ -900,7 +928,7 @@ json_gin_extract_query(PG_FUNCTION_ARGS)
StrategyNumber strategy = PG_GETARG_UINT16(2); StrategyNumber strategy = PG_GETARG_UINT16(2);
bool **pmatch = (bool**)PG_GETARG_POINTER(3); bool **pmatch = (bool**)PG_GETARG_POINTER(3);
bool **nullFlags = (bool**)PG_GETARG_POINTER(5); bool **nullFlags = (bool**)PG_GETARG_POINTER(5);
int32 *searchMode = (int32*)PG_GETARG_POINTER(6); /* int32 *searchMode = (int32*)PG_GETARG_POINTER(6);*/


ArrayType *queryArray; ArrayType *queryArray;
Datum *keys; Datum *keys;
Expand Down
11 changes: 10 additions & 1 deletion sql/postgre-json-functions.sql
@@ -1,5 +1,5 @@
set client_min_messages to 'error'; 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"; create extension "postgre-json-functions";
set client_min_messages to 'notice'; set client_min_messages to 'notice';


Expand Down Expand Up @@ -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"} -- {"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'); 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 \t off
\pset format aligned \pset format aligned

0 comments on commit 5b71a10

Please sign in to comment.