summaryrefslogtreecommitdiff
path: root/storage/connect/jsonudf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/connect/jsonudf.cpp')
-rw-r--r--storage/connect/jsonudf.cpp442
1 files changed, 351 insertions, 91 deletions
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 7b82ba2d627..e94d3817926 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -1,6 +1,6 @@
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
-/* PROGRAM NAME: jsonudf Version 1.3 */
-/* (C) Copyright to the author Olivier BERTRAND 2015 */
+/* PROGRAM NAME: jsonudf Version 1.4 */
+/* (C) Copyright to the author Olivier BERTRAND 2015-2016 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
@@ -1433,7 +1433,7 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
char *p = args->args[0];
// Is this a file name?
- if (!strchr("[{ \t\r\n", *p) && (len = GetFileLength(p)))
+ if (p && !strchr("[{ \t\r\n", *p) && (len = GetFileLength(p)))
ml += len * (M + 1);
else
ml += args->lengths[0] * M;
@@ -1805,7 +1805,20 @@ my_bool json_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa
} else
CalcLen(args, false, reslen, memlen);
- return JsonInit(initid, args, message, true, reslen, memlen);
+ if (!JsonInit(initid, args, message, true, reslen, memlen)) {
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ // This is a constant function
+ g->N = (initid->const_item) ? 1 : 0;
+
+ // This is to avoid double execution when using prepared statements
+ if (IsJson(args, 0) > 1)
+ initid->const_item = 0;
+
+ return false;
+ } else
+ return true;
+
} // end of json_array_add_values_init
char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -1850,7 +1863,7 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
} // endif str
// Keep result of constant function
- g->Xchk = (initid->const_item) ? str : NULL;
+ g->Xchk = (g->N) ? str : NULL;
} else
str = (char*)g->Xchk;
@@ -1873,7 +1886,7 @@ void json_array_add_values_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
- unsigned long reslen, memlen;
+ unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
@@ -1884,7 +1897,20 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} else
CalcLen(args, false, reslen, memlen, true);
- return JsonInit(initid, args, message, true, reslen, memlen);
+ if (!JsonInit(initid, args, message, true, reslen, memlen)) {
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ // This is a constant function
+ g->N = (initid->const_item) ? 1 : 0;
+
+ // This is to avoid double execution when using prepared statements
+ if (IsJson(args, 0) > 1)
+ initid->const_item = 0;
+
+ return false;
+ } else
+ return true;
+
} // end of json_array_add_init
char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -1930,7 +1956,7 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!str)
str = MakePSZ(g, args, 0);
- if (initid->const_item)
+ if (g->N)
// Keep result of constant function
g->Xchk = str;
@@ -1966,7 +1992,20 @@ my_bool json_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} else
CalcLen(args, false, reslen, memlen, true);
- return JsonInit(initid, args, message, true, reslen, memlen);
+ if (!JsonInit(initid, args, message, true, reslen, memlen)) {
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ // This is a constant function
+ g->N = (initid->const_item) ? 1 : 0;
+
+ // This is to avoid double execution when using prepared statements
+ if (IsJson(args, 0) > 1)
+ initid->const_item = 0;
+
+ return false;
+ } else
+ return true;
+
} // end of json_array_delete_init
char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -2008,7 +2047,7 @@ char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!str)
str = MakePSZ(g, args, 0);
- if (initid->const_item)
+ if (g->N)
// Keep result of constant function
g->Xchk = str;
@@ -2184,7 +2223,20 @@ my_bool json_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} else
CalcLen(args, true, reslen, memlen, true);
- return JsonInit(initid, args, message, true, reslen, memlen);
+ if (!JsonInit(initid, args, message, true, reslen, memlen)) {
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ // This is a constant function
+ g->N = (initid->const_item) ? 1 : 0;
+
+ // This is to avoid double execution when using prepared statements
+ if (IsJson(args, 0) > 1)
+ initid->const_item = 0;
+
+ return false;
+ } else
+ return true;
+
} // end of json_object_add_init
char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -2227,7 +2279,7 @@ char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!str)
str = MakePSZ(g, args, 0);
- if (initid->const_item)
+ if (g->N)
// Keep result of constant function
g->Xchk = str;
@@ -2266,7 +2318,20 @@ my_bool json_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} else
CalcLen(args, true, reslen, memlen, true);
- return JsonInit(initid, args, message, true, reslen, memlen);
+ if (!JsonInit(initid, args, message, true, reslen, memlen)) {
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ // This is a constant function
+ g->N = (initid->const_item) ? 1 : 0;
+
+ // This is to avoid double execution when using prepared statements
+ if (IsJson(args, 0) > 1)
+ initid->const_item = 0;
+
+ return false;
+ } else
+ return true;
+
} // end of json_object_delete_init
char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -2307,7 +2372,7 @@ char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!str)
str = MakePSZ(g, args, 0);
- if (initid->const_item)
+ if (g->N)
// Keep result of constant function
g->Xchk = str;
@@ -2605,7 +2670,20 @@ my_bool json_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} else
CalcLen(args, false, reslen, memlen, true);
- return JsonInit(initid, args, message, true, reslen, memlen);
+ if (!JsonInit(initid, args, message, true, reslen, memlen)) {
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ // This is a constant function
+ g->N = (initid->const_item) ? 1 : 0;
+
+ // This is to avoid double execution when using prepared statements
+ if (IsJson(args, 0) > 1)
+ initid->const_item = 0;
+
+ return false;
+ } else
+ return true;
+
} // end of json_item_merge_init
char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -2651,7 +2729,7 @@ char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!str)
str = MakePSZ(g, args, 0);
- if (initid->const_item)
+ if (g->N)
// Keep result of constant function
g->Xchk = str;
@@ -3538,37 +3616,9 @@ void jsoncontains_path_deinit(UDF_INIT* initid)
} // end of jsoncontains_path_deinit
/*********************************************************************************/
-/* Set Json items of a Json document according to path. */
+/* This function is used by the json_set/insert/update_item functions. */
/*********************************************************************************/
-my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
-{
- unsigned long reslen, memlen;
- int n = IsJson(args, 0);
-
- if (!(args->arg_count % 2)) {
- strcpy(message, "This function must have an odd number of arguments");
- return true;
- } else if (!n && args->arg_type[0] != STRING_RESULT) {
- strcpy(message, "First argument must be a json item");
- return true;
- } else
- CalcLen(args, false, reslen, memlen);
-
- if (n == 2 && args->args[0]) {
- char fn[_MAX_PATH];
- long fl;
-
- memcpy(fn, args->args[0], args->lengths[0]);
- fn[args->lengths[0]] = 0;
- fl = GetFileLength(fn);
- memlen += fl * 3;
- } else if (n != 3)
- memlen += args->lengths[0] * 3;
-
- return JsonInit(initid, args, message, true, reslen, memlen);
-} // end of json_set_item_init
-
-char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
+char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
char *p, *path, *str = NULL;
@@ -3580,18 +3630,22 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
PGLOBAL g = (PGLOBAL)initid->ptr;
PGLOBAL gb = GetMemPtr(g, args, 0);
- if (g->N) {
+ if (g->Alchecked) {
str = (char*)g->Activityp;
goto fin;
- } else if (initid->const_item)
- g->N = 1;
+ } else if (g->N)
+ g->Alchecked = 1;
- if (!strcmp(result, "$insert"))
+ if (!strcmp(result, "$set"))
+ w = 0;
+ else if (!strcmp(result, "$insert"))
w = 1;
else if (!strcmp(result, "$update"))
w = 2;
- else
- w = 0;
+ else {
+ PUSH_WARNING("Logical error, please contact CONNECT developer");
+ goto err;
+ } // endelse
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
@@ -3656,14 +3710,14 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!(str = MakeResult(g, args, jsp, INT_MAX32)))
str = MakePSZ(g, args, 0);
- if (initid->const_item)
+ if (g->N)
// Keep result of constant function
g->Activityp = (PACTIVITY)str;
- err:
+err:
g->jump_level--;
- fin:
+fin:
if (!str) {
*is_null = 1;
*res_length = 0;
@@ -3671,6 +3725,58 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
*res_length = strlen(str);
return str;
+} // end of handle_item
+
+/*********************************************************************************/
+/* Set Json items of a Json document according to path. */
+/*********************************************************************************/
+my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen;
+ int n = IsJson(args, 0);
+
+ if (!(args->arg_count % 2)) {
+ strcpy(message, "This function must have an odd number of arguments");
+ return true;
+ } else if (!n && args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "First argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ if (n == 2 && args->args[0]) {
+ char fn[_MAX_PATH];
+ long fl;
+
+ memcpy(fn, args->args[0], args->lengths[0]);
+ fn[args->lengths[0]] = 0;
+ fl = GetFileLength(fn);
+ memlen += fl * 3;
+ } else if (n != 3)
+ memlen += args->lengths[0] * 3;
+
+ if (!JsonInit(initid, args, message, true, reslen, memlen)) {
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ // This is a constant function
+ g->N = (initid->const_item) ? 1 : 0;
+
+ // This is to avoid double execution when using prepared statements
+ if (IsJson(args, 0) > 1)
+ initid->const_item = 0;
+
+ g->Alchecked = 0;
+ return false;
+ } else
+ return true;
+
+} // end of json_set_item_init
+
+char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *is_null, char *p)
+{
+ strcpy(result, "$set");
+ return handle_item(initid, args, result, res_length, is_null, p);
} // end of json_set_item
void json_set_item_deinit(UDF_INIT* initid)
@@ -3690,7 +3796,7 @@ char *json_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *p)
{
strcpy(result, "$insert");
- return json_set_item(initid, args, result, res_length, is_null, p);
+ return handle_item(initid, args, result, res_length, is_null, p);
} // end of json_insert_item
void json_insert_item_deinit(UDF_INIT* initid)
@@ -3710,7 +3816,7 @@ char *json_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *p)
{
strcpy(result, "$update");
- return json_set_item(initid, args, result, res_length, is_null, p);
+ return handle_item(initid, args, result, res_length, is_null, p);
} // end of json_update_item
void json_update_item_deinit(UDF_INIT* initid)
@@ -3728,8 +3834,8 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count < 1 || args->arg_count > 4) {
strcpy(message, "This function only accepts 1 to 4 arguments");
return true;
- } else if (!args->args[0] || args->arg_type[0] != STRING_RESULT) {
- strcpy(message, "First argument must be a constant string (file name)");
+ } else if (args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "First argument must be a string (file name)");
return true;
} // endif's args[0]
@@ -3747,7 +3853,12 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
initid->maybe_null = 1;
CalcLen(args, false, reslen, memlen);
- fl = GetFileLength(args->args[0]);
+
+ if (args->args[0])
+ fl = GetFileLength(args->args[0]);
+ else
+ fl = 100; // What can be done here?
+
reslen += fl;
if (initid->const_item)
@@ -4006,7 +4117,18 @@ void jbin_array_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
- return json_array_add_values_init(initid, args, message);
+ unsigned long reslen, memlen;
+
+ if (args->arg_count < 2) {
+ strcpy(message, "This function must have at least 2 arguments");
+ return true;
+ } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "First argument must be a json string or item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
} // end of jbin_array_add_values_init
char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -4076,7 +4198,18 @@ void jbin_array_add_values_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
- return json_array_add_init(initid, args, message);
+ unsigned long reslen, memlen;
+
+ if (args->arg_count < 2) {
+ strcpy(message, "This function must have at least 2 arguments");
+ return true;
+ } else if (!IsJson(args, 0)) {
+ strcpy(message, "First argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen, true);
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
} // end of jbin_array_add_init
char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -4146,8 +4279,19 @@ void jbin_array_add_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
- return json_array_delete_init(initid, args, message);
-} // end of jbin_array_delete_init
+ unsigned long reslen, memlen;
+
+ if (args->arg_count < 2) {
+ strcpy(message, "This function must have at least 2 arguments");
+ return true;
+ } else if (!IsJson(args, 0)) {
+ strcpy(message, "First argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen, true);
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
+ } // end of jbin_array_delete_init
char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
@@ -4369,8 +4513,19 @@ void jbin_object_key_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
- return json_object_add_init(initid, args, message);
-} // end of jbin_object_add_init
+ unsigned long reslen, memlen;
+
+ if (args->arg_count < 2) {
+ strcpy(message, "This function must have at least 2 arguments");
+ return true;
+ } else if (!IsJson(args, 0)) {
+ strcpy(message, "First argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, true, reslen, memlen, true);
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
+ } // end of jbin_object_add_init
char *jbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
@@ -4435,8 +4590,22 @@ void jbin_object_add_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
- return json_object_delete_init(initid, args, message);
-} // end of jbin_object_delete_init
+ unsigned long reslen, memlen;
+
+ if (args->arg_count < 2) {
+ strcpy(message, "This function must have 2 or 3 arguments");
+ return true;
+ } else if (!IsJson(args, 0)) {
+ strcpy(message, "First argument must be a json item");
+ return true;
+ } else if (args->arg_type[1] != STRING_RESULT) {
+ strcpy(message, "Second argument must be a key string");
+ return true;
+ } else
+ CalcLen(args, true, reslen, memlen, true);
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
+ } // end of jbin_object_delete_init
char *jbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
@@ -4645,8 +4814,22 @@ void jbin_get_item_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
- return json_item_merge_init(initid, args, message);
-} // end of jbin_item_merge_init
+ unsigned long reslen, memlen;
+
+ if (args->arg_count < 2) {
+ strcpy(message, "This function must have at least 2 arguments");
+ return true;
+ } else if (!IsJson(args, 0)) {
+ strcpy(message, "First argument must be a json item");
+ return true;
+ } else if (!IsJson(args, 1)) {
+ strcpy(message, "Second argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen, true);
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
+ } // end of jbin_item_merge_init
char *jbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
@@ -4706,14 +4889,9 @@ void jbin_item_merge_deinit(UDF_INIT* initid)
} // end of jbin_item_merge_deinit
/*********************************************************************************/
-/* Set Json items of a Json document according to path. */
+/* This function is used by the jbin_set/insert/update functions. */
/*********************************************************************************/
-my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
-{
- return json_set_item_init(initid, args, message);
-} // end of jbin_set_item_init
-
-char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
+char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
char *p, *path;
@@ -4732,12 +4910,16 @@ char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
} else if (initid->const_item)
g->N = 1;
- if (!strcmp(result, "$insert"))
+ if (!strcmp(result, "$set"))
+ w = 0;
+ else if (!strcmp(result, "$insert"))
w = 1;
else if (!strcmp(result, "$update"))
w = 2;
- else
- w = 0;
+ else {
+ PUSH_WARNING("Logical error, please contact CONNECT developer");
+ goto fin;
+ } // endelse
if (!g->Xchk) {
if (CheckMemory(g, initid, args, 1, true, false, true)) {
@@ -4792,7 +4974,7 @@ char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
// Keep result of constant function
g->Activityp = (PACTIVITY)bsp;
- fin:
+fin:
if (!bsp) {
*is_null = 1;
*res_length = 0;
@@ -4800,6 +4982,44 @@ char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
*res_length = sizeof(BSON);
return (char*)bsp;
+} // end of bin_handle_item
+
+/*********************************************************************************/
+/* Set Json items of a Json document according to path. */
+/*********************************************************************************/
+my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen;
+ int n = IsJson(args, 0);
+
+ if (!(args->arg_count % 2)) {
+ strcpy(message, "This function must have an odd number of arguments");
+ return true;
+ } else if (!n && args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "First argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ if (n == 2 && args->args[0]) {
+ char fn[_MAX_PATH];
+ long fl;
+
+ memcpy(fn, args->args[0], args->lengths[0]);
+ fn[args->lengths[0]] = 0;
+ fl = GetFileLength(fn);
+ memlen += fl * 3;
+ } else if (n != 3)
+ memlen += args->lengths[0] * 3;
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
+ } // end of jbin_set_item_init
+
+char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *is_null, char *p)
+{
+ strcpy(result, "$set");
+ return bin_handle_item(initid, args, result, res_length, is_null, p);
} // end of jbin_set_item
void jbin_set_item_deinit(UDF_INIT* initid)
@@ -4819,7 +5039,7 @@ char *jbin_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *p)
{
strcpy(result, "$insert");
- return jbin_set_item(initid, args, result, res_length, is_null, p);
+ return bin_handle_item(initid, args, result, res_length, is_null, p);
} // end of jbin_insert_item
void jbin_insert_item_deinit(UDF_INIT* initid)
@@ -4839,7 +5059,7 @@ char *jbin_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *p)
{
strcpy(result, "$update");
- return jbin_set_item(initid, args, result, res_length, is_null, p);
+ return bin_handle_item(initid, args, result, res_length, is_null, p);
} // end of jbin_update_item
void jbin_update_item_deinit(UDF_INIT* initid)
@@ -4964,7 +5184,7 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count != 1) {
strcpy(message, "This function must have 1 argument");
return true;
- } else if (IsJson(args, 0) != 3) {
+ } else if (args->args[0] && IsJson(args, 0) != 3) {
strcpy(message, "Argument must be a Jbin tree");
return true;
} else
@@ -4974,21 +5194,27 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} // end of json_serialize_init
char *json_serialize(UDF_INIT *initid, UDF_ARGS *args, char *result,
- unsigned long *res_length, char *, char *)
+ unsigned long *res_length, char *, char *error)
{
char *str;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (!g->Xchk) {
- PBSON bsp = (PBSON)args->args[0];
+ if (IsJson(args, 0) == 3) {
+ PBSON bsp = (PBSON)args->args[0];
- JsonSubSet(g);
+ JsonSubSet(g);
- if (!(str = Serialize(g, bsp->Jsp, NULL, 0)))
- str = strcpy(result, g->Message);
+ if (!(str = Serialize(g, bsp->Jsp, NULL, 0)))
+ str = strcpy(result, g->Message);
+
+ // Keep result of constant function
+ g->Xchk = (initid->const_item) ? str : NULL;
+ } else {
+ *error = 1;
+ str = strcpy(result, "Argument is not a Jbin tree");
+ } // endif
- // Keep result of constant function
- g->Xchk = (initid->const_item) ? str : NULL;
} else
str = (char*)g->Xchk;
@@ -5000,3 +5226,37 @@ void json_serialize_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of json_serialize_deinit
+
+/*********************************************************************************/
+/* Utility function returning an environment variable value. */
+/*********************************************************************************/
+my_bool envar_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ if (args->arg_count != 1) {
+ strcpy(message, "Unique argument must be an environment variable name");
+ return true;
+ } else {
+ initid->maybe_null = true;
+ return false;
+ } // endif count
+
+} // end of envar_init
+
+char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *is_null, char *)
+{
+ char *str, name[256];
+ int n = MY_MIN(args->lengths[0], sizeof(name) - 1);
+
+ memcpy(name, args->args[0], n);
+ name[n] = 0;
+
+ if (!(str = getenv(name))) {
+ *res_length = 0;
+ *is_null = 1;
+ } else
+ *res_length = strlen(str);
+
+ return str;
+} // end of envar
+