summaryrefslogtreecommitdiff
path: root/storage/connect/jsonudf.cpp
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-04-24 20:28:31 +0200
committerSergei Golubchik <serg@mariadb.org>2018-04-26 14:15:18 +0200
commit5ae2656b69e8a232107890aa0be517358739e997 (patch)
tree7f044f33d7fbfeb8bb4b9c008296008bd3b99c9e /storage/connect/jsonudf.cpp
parent1bd33ca82b951dd408b50b010b25a490063818e5 (diff)
downloadmariadb-git-5ae2656b69e8a232107890aa0be517358739e997.tar.gz
Squashed commit of connect/10.0:
commit c545d544378483bf68c4fb713cd4ec872d0df2c4 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Tue Mar 27 23:13:14 2018 +0200 - Fix MDEV-15577 CONNECT engine JDBC remote index prevents UPDATE Fixed in TDBJDBC::OpenDB because query can be null for updates modified: storage/connect/tabjdbc.cpp commit c4f1fe2e8e74566e9c3296f435448d9f5c718b23 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Wed Mar 14 12:21:17 2018 +0100 - Fix MDEV-15429 CONNECT engine JDBC handling Postgresql UUID type Also handle Postgresql sending type VARCHAR for TEXT column and setting length to b x7FFFFFF when the length is unknown. modified: storage/connect/Client.java modified: storage/connect/JavaWrappers.jar modified: storage/connect/JdbcInterface.java modified: storage/connect/PostgresqlInterface.java modified: storage/connect/global.h modified: storage/connect/ha_connect.cc modified: storage/connect/jdbconn.cpp modified: storage/connect/jdbconn.h modified: storage/connect/mysql-test/connect/r/jdbc_postgresql.result modified: storage/connect/mysql-test/connect/t/jdbc_postgresql.test modified: storage/connect/mysql-test/connect/t/jdbconn.inc modified: storage/connect/plgdbsem.h modified: storage/connect/tabjdbc.cpp modified: storage/connect/tabjdbc.h added: storage/connect/mysql-test/connect/std_data/JavaWrappers.jar commit 3068bb4882a316c6c32c624609db2bf24ae3ad40 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Mon Feb 26 19:40:27 2018 +0100 Revert to old cmake file to avoid compile error commit da8c1c0bd6a327fd03bd321be3170f468122ef67 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Mon Feb 26 16:13:39 2018 +0100 - Remove warning on not used tabtyp variable in connect_assisted_discovery modified: storage/connect/ha_connect.cc - Fix a bug causing CONNECT to loop when expanding a JSON column when the expanded column value is null or void array. - Adding the FullArray option to JSON tables. - Skipping expanded JSON lines when the expanded column value is null. modified: storage/connect/connect.cc modified: storage/connect/tabdos.h modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h - Fix MDEV-13353 No file privilege for ODBC, JDBC, MONGO, MAC, WMI file types. modified: storage/connect/ha_connect.cc - Make some Json UDFs to accept a non JSON item as 1st parameter. modified: storage/connect/json.cpp modified: storage/connect/json.h modified: storage/connect/jsonudf.cpp modified: storage/connect/jsonudf.h - Update Json UDF tests to cope with above changes. modified: storage/connect/mysql-test/connect/r/json_udf.result modified: storage/connect/mysql-test/connect/r/json_udf_bin.result modified: storage/connect/mysql-test/connect/r/vcol.result modified: storage/connect/mysql-test/connect/t/json_udf.test modified: storage/connect/mysql-test/connect/t/vcol.test - Fix some compiler warning treated as error PlugSubAlloc no more exported because it does throw. modified: storage/connect/global.h modified: storage/connect/ha_connect.cc modified: storage/connect/jsonudf.cpp modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h - Other files modified (?) when going back to wrong merge modified: storage/connect/CMakeLists.txt modified: storage/connect/array.cpp modified: storage/connect/colblk.cpp modified: storage/connect/connect.cc modified: storage/connect/csort.cpp modified: storage/connect/domdoc.cpp modified: storage/connect/filamap.cpp modified: storage/connect/filamgz.cpp modified: storage/connect/filamtxt.cpp modified: storage/connect/filamzip.cpp modified: storage/connect/filter.cpp modified: storage/connect/fmdlex.c modified: storage/connect/jdbconn.cpp modified: storage/connect/macutil.cpp modified: storage/connect/myconn.cpp modified: storage/connect/odbconn.cpp modified: storage/connect/plgdbutl.cpp modified: storage/connect/plugutil.cpp modified: storage/connect/preparse.h modified: storage/connect/rcmsg.c modified: storage/connect/rcmsg.h modified: storage/connect/reldef.cpp modified: storage/connect/tabdos.cpp modified: storage/connect/tabfmt.cpp modified: storage/connect/tabmac.cpp modified: storage/connect/tabmul.cpp modified: storage/connect/tabmysql.cpp modified: storage/connect/tabmysql.h modified: storage/connect/tabodbc.cpp modified: storage/connect/tabtbl.cpp modified: storage/connect/tabxml.cpp modified: storage/connect/value.cpp modified: storage/connect/xobject.cpp commit 5095628b31ed8c94bd7c794c6b0162894a9040b1 Author: Olivier Bertrand <bertrandop@gmail.com> Date: Tue Feb 13 14:29:00 2018 +0100 - Fix a bug causing CONNECT to loop when expanding a JSON column when the expanded column value is null or void array. - Adding the FullArray option to JSON tables. - Skipping expanded JSON lines when the expanded column value is null. modified: storage/connect/connect.cc modified: storage/connect/tabdos.h modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h commit 9896174328da42016735630c893fd09eb128b48e Author: Olivier Bertrand <bertrandop@gmail.com> Date: Fri Feb 2 15:48:57 2018 +0100 - Remove warning on not used tabtyp variable in connect_assisted_discovery modified: storage/connect/ha_connect.cc commit d7e254c05f88173eb04d8dafc813013eb42ccdbe Author: Olivier Bertrand <bertrandop@gmail.com> Date: Wed Jan 31 14:42:45 2018 +0100 - Use delayed load for the MongoDB C Drive on Windows modified: storage/connect/CMakeLists.txt modified: storage/connect/cmgoconn.cpp modified: storage/connect/ha_connect.cc - Add FORCE to the connect_type_conv enum values This will translate binary values to TYPE_STRING modified: storage/connect/checklvl.h modified: storage/connect/ha_connect.cc modified: storage/connect/odbconn.cpp - Change the connect_xtrace variable to from int to set modified: storage/connect/array.cpp modified: storage/connect/blkfil.cpp modified: storage/connect/block.h modified: storage/connect/cmgoconn.cpp modified: storage/connect/colblk.cpp modified: storage/connect/connect.cc modified: storage/connect/filamap.cpp modified: storage/connect/filamdbf.cpp modified: storage/connect/filamfix.cpp modified: storage/connect/filamgz.cpp modified: storage/connect/filamtxt.cpp modified: storage/connect/filamvct.cpp modified: storage/connect/filamzip.cpp modified: storage/connect/filter.cpp modified: storage/connect/global.h modified: storage/connect/ha_connect.cc modified: storage/connect/inihandl.cpp modified: storage/connect/javaconn.cpp modified: storage/connect/jdbconn.cpp modified: storage/connect/jmgfam.cpp modified: storage/connect/jmgoconn.cpp modified: storage/connect/json.cpp modified: storage/connect/jsonudf.cpp modified: storage/connect/libdoc.cpp modified: storage/connect/mongo.cpp modified: storage/connect/mycat.cc modified: storage/connect/myconn.cpp modified: storage/connect/odbconn.cpp modified: storage/connect/plgdbutl.cpp modified: storage/connect/plugutil.cpp modified: storage/connect/reldef.cpp modified: storage/connect/tabcol.cpp modified: storage/connect/tabdos.cpp modified: storage/connect/tabext.cpp modified: storage/connect/tabfix.cpp modified: storage/connect/tabfmt.cpp modified: storage/connect/tabjdbc.cpp modified: storage/connect/tabjson.cpp modified: storage/connect/table.cpp modified: storage/connect/tabmul.cpp modified: storage/connect/tabmysql.cpp modified: storage/connect/tabodbc.cpp modified: storage/connect/tabpivot.cpp modified: storage/connect/tabsys.cpp modified: storage/connect/tabtbl.cpp modified: storage/connect/tabutil.cpp modified: storage/connect/tabvct.cpp modified: storage/connect/tabwmi.cpp modified: storage/connect/tabxml.cpp modified: storage/connect/user_connect.cc modified: storage/connect/valblk.cpp modified: storage/connect/value.cpp modified: storage/connect/xindex.cpp - Restore connect_enable_mongo variable (but undocumented) modified: storage/connect/ha_connect.cc modified: storage/connect/mycat.cc modified: storage/connect/mysql-test/connect/r/json_java_2.result modified: storage/connect/mysql-test/connect/r/json_java_3.result modified: storage/connect/mysql-test/connect/r/json_mongo_c.result modified: storage/connect/mysql-test/connect/r/mongo_c.result modified: storage/connect/mysql-test/connect/r/mongo_java_2.result modified: storage/connect/mysql-test/connect/r/mongo_java_3.result modified: storage/connect/mysql-test/connect/r/tbl_thread.result modified: storage/connect/mysql-test/connect/t/mongo.inc modified: storage/connect/mysql-test/connect/t/mongo_test.inc modified: storage/connect/mysql-test/connect/t/tbl_thread.test
Diffstat (limited to 'storage/connect/jsonudf.cpp')
-rw-r--r--storage/connect/jsonudf.cpp862
1 files changed, 576 insertions, 286 deletions
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index eb783807190..e45846ea23b 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.6 */
-/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
+/* PROGRAM NAME: jsonudf Version 1.7 */
+/* (C) Copyright to the author Olivier BERTRAND 2015-2018 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
@@ -31,16 +31,39 @@ bool IsNum(PSZ s);
char *NextChr(PSZ s, char sep);
char *GetJsonNull(void);
uint GetJsonGrpSize(void);
-static int IsJson(UDF_ARGS *args, uint i);
+static int IsJson(UDF_ARGS *args, uint i, bool b = false);
static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
static char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error);
static char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error);
+static PJSON JsonNew(PGLOBAL g, JTYP type);
+static PJVAL JvalNew(PGLOBAL g, JTYP type, void *vp = NULL);
+static PJSNX JsnxNew(PGLOBAL g, PJSON jsp, int type, int len = 64);
static uint JsonGrpSize = 10;
-/* ----------------------------------- JSNX ------------------------------------ */
+/*********************************************************************************/
+/* SubAlloc a new JSNX class with protection against memory exhaustion. */
+/*********************************************************************************/
+static PJSNX JsnxNew(PGLOBAL g, PJSON jsp, int type, int len)
+{
+ PJSNX jsx;
+
+ try {
+ jsx = new(g) JSNX(g, jsp, type, len);
+ } catch (...) {
+ if (trace(1023))
+ htrc("%s\n", g->Message);
+
+ PUSH_WARNING(g->Message);
+ jsx = NULL;
+ } // end try/catch
+
+ return jsx;
+} /* end of JsnxNew */
+
+ /* ----------------------------------- JSNX ------------------------------------ */
/*********************************************************************************/
/* JSNX public constructor. */
@@ -81,21 +104,7 @@ my_bool JSNX::SetJpath(PGLOBAL g, char *path, my_bool jb)
return true;
Value->SetNullable(true);
-
-#if 0
- if (jb) {
- // Path must return a Json item
- size_t n = strlen(path);
-
- if (!n || path[n - 1] != '*') {
- Jpath = (char*)PlugSubAlloc(g, NULL, n + 3);
- strcat(strcpy(Jpath, path), (n) ? ":*" : "*");
- } else
- Jpath = path;
-
- } else
-#endif // 0
- Jpath = path;
+ Jpath = path;
// Parse the json path
Parsed = false;
@@ -182,7 +191,7 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
// Set concat intermediate string
p[n - 1] = 0;
- if (trace)
+ if (trace(1))
htrc("Concat string=%s\n", p + 1);
jnp->CncVal = AllocateValue(g, p + 1, TYPE_STRING);
@@ -246,7 +255,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
// Jpath = Name;
return true;
- if (trace)
+ if (trace(1))
htrc("ParseJpath %s\n", SVP(Jpath));
if (!(pbuf = PlgDBDup(g, Jpath)))
@@ -309,7 +318,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
Nod = i;
MulVal = AllocateValue(g, Value);
- if (trace)
+ if (trace(1))
for (i = 0; i < Nod; i++)
htrc("Node(%d) Key=%s Op=%d Rank=%d\n",
i, SVP(Nodes[i].Key), Nodes[i].Op, Nodes[i].Rank);
@@ -506,13 +515,13 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
vp->Reset();
- if (trace)
+ if (trace(1))
htrc("CalculateArray size=%d op=%d\n", ars, op);
- for (i = 0; i < arp->size(); i++) {
+ for (i = 0; i < ars; i++) {
jvrp = arp->GetValue(i);
- if (trace)
+ if (trace(1))
htrc("i=%d nv=%d\n", i, nv);
if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) {
@@ -525,7 +534,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
} else
jvp = jvrp;
- if (trace)
+ if (trace(1))
htrc("jvp=%s null=%d\n",
jvp->GetString(g), jvp->IsNull() ? 1 : 0);
@@ -561,7 +570,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (err)
vp->Reset();
- if (trace) {
+ if (trace(1)) {
char buf(32);
htrc("vp='%s' err=%d\n",
@@ -753,6 +762,7 @@ my_bool JSNX::WriteValue(PGLOBAL g, PJVAL jvalp)
/*********************************************************************************/
PSZ JSNX::Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k)
{
+ PSZ str = NULL;
my_bool b = false, err = true;
g->Message[0] = 0;
@@ -762,37 +772,47 @@ PSZ JSNX::Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k)
return NULL;
} // endif jsp
- // Write to the path string
- Jp = new(g) JOUTSTR(g);
- Jp->WriteChr('$');
- Jvalp = jvp;
- K = k;
+ try {
+ // Write to the path string
+ Jp = new(g) JOUTSTR(g);
+ Jp->WriteChr('$');
+ Jvalp = jvp;
+ K = k;
- switch (jsp->GetType()) {
- case TYPE_JAR:
- err = LocateArray((PJAR)jsp);
- break;
- case TYPE_JOB:
- err = LocateObject((PJOB)jsp);
- break;
- case TYPE_JVAL:
- err = LocateValue((PJVAL)jsp);
- break;
- default:
- err = true;
+ switch (jsp->GetType()) {
+ case TYPE_JAR:
+ err = LocateArray((PJAR)jsp);
+ break;
+ case TYPE_JOB:
+ err = LocateObject((PJOB)jsp);
+ break;
+ case TYPE_JVAL:
+ err = LocateValue((PJVAL)jsp);
+ break;
+ default:
+ err = true;
} // endswitch Type
- if (err) {
- if (!g->Message[0])
- strcpy(g->Message, "Invalid json tree");
+ if (err) {
+ if (!g->Message[0])
+ strcpy(g->Message, "Invalid json tree");
- } else if (Found) {
- Jp->WriteChr('\0');
- PlugSubAlloc(g, NULL, Jp->N);
- return Jp->Strp;
- } // endif's
+ } else if (Found) {
+ Jp->WriteChr('\0');
+ PlugSubAlloc(g, NULL, Jp->N);
+ str = Jp->Strp;
+ } // endif's
- return NULL;
+ } catch (int n) {
+ if (trace(1))
+ htrc("Exception %d: %s\n", n, g->Message);
+
+ PUSH_WARNING(g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
+
+ return str;
} // end of Locate
/*********************************************************************************/
@@ -864,53 +884,62 @@ my_bool JSNX::LocateValue(PJVAL jvp)
/*********************************************************************************/
PSZ JSNX::LocateAll(PGLOBAL g, PJSON jsp, PJVAL jvp, int mx)
{
+ PSZ str = NULL;
my_bool b = false, err = true;
- PJPN jnp = (PJPN)PlugSubAlloc(g, NULL, sizeof(JPN) * mx);
-
- memset(jnp, 0, sizeof(JPN) * mx);
- g->Message[0] = 0;
-
+ PJPN jnp;
+
if (!jsp) {
strcpy(g->Message, "Null json tree");
return NULL;
} // endif jsp
- // Write to the path string
- Jp = new(g)JOUTSTR(g);
- Jvalp = jvp;
- Imax = mx - 1;
- Jpnp = jnp;
- Jp->WriteChr('[');
+ try {
+ jnp = (PJPN)PlugSubAlloc(g, NULL, sizeof(JPN) * mx);
+ memset(jnp, 0, sizeof(JPN) * mx);
+ g->Message[0] = 0;
+
+ // Write to the path string
+ Jp = new(g)JOUTSTR(g);
+ Jvalp = jvp;
+ Imax = mx - 1;
+ Jpnp = jnp;
+ Jp->WriteChr('[');
+
+ switch (jsp->GetType()) {
+ case TYPE_JAR:
+ err = LocateArrayAll((PJAR)jsp);
+ break;
+ case TYPE_JOB:
+ err = LocateObjectAll((PJOB)jsp);
+ break;
+ case TYPE_JVAL:
+ err = LocateValueAll((PJVAL)jsp);
+ break;
+ default:
+ err = true;
+ } // endswitch Type
- switch (jsp->GetType()) {
- case TYPE_JAR:
- err = LocateArrayAll((PJAR)jsp);
- break;
- case TYPE_JOB:
- err = LocateObjectAll((PJOB)jsp);
- break;
- case TYPE_JVAL:
- err = LocateValueAll((PJVAL)jsp);
- break;
- default:
- err = true;
- } // endswitch Type
+ if (!err) {
+ if (Jp->N > 1)
+ Jp->N--;
- if (err) {
- if (!g->Message[0])
+ Jp->WriteChr(']');
+ Jp->WriteChr('\0');
+ PlugSubAlloc(g, NULL, Jp->N);
+ str = Jp->Strp;
+ } else if (!g->Message[0])
strcpy(g->Message, "Invalid json tree");
- return NULL;
- } else {
- if (Jp->N > 1)
- Jp->N--;
+ } catch (int n) {
+ if (trace(1))
+ htrc("Exception %d: %s\n", n, g->Message);
- Jp->WriteChr(']');
- Jp->WriteChr('\0');
- PlugSubAlloc(g, NULL, Jp->N);
- return Jp->Strp;
- } // endif's
+ PUSH_WARNING(g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
+ return str;
} // end of LocateAll
/*********************************************************************************/
@@ -1138,6 +1167,72 @@ inline void JsonFreeMem(PGLOBAL g)
} /* end of JsonFreeMem */
/*********************************************************************************/
+/* SubAlloc a new JSON item with protection against memory exhaustion. */
+/*********************************************************************************/
+static PJSON JsonNew(PGLOBAL g, JTYP type)
+{
+ PJSON jsp = NULL;
+
+ try {
+ switch (type) {
+ case TYPE_JAR:
+ jsp = new(g) JARRAY;
+ break;
+ case TYPE_JOB:
+ jsp = new(g) JOBJECT;
+ break;
+ default:
+ break;
+ } // endswitch type
+
+ } catch (...) {
+ if (trace(1023))
+ htrc("%s\n", g->Message);
+
+ PUSH_WARNING(g->Message);
+ } // end try/catch
+
+ return jsp;
+} /* end of JsonNew */
+
+/*********************************************************************************/
+/* SubAlloc a new JValue with protection against memory exhaustion. */
+/*********************************************************************************/
+static PJVAL JvalNew(PGLOBAL g, JTYP type, void *vp)
+{
+ PJVAL jvp = NULL;
+
+ try {
+ if (!vp)
+ jvp = new (g) JVALUE;
+ else switch (type) {
+ case TYPE_JSON:
+ case TYPE_JVAL:
+ case TYPE_JAR:
+ case TYPE_JOB:
+ jvp = new(g) JVALUE((PJSON)vp);
+ break;
+ case TYPE_VAL:
+ jvp = new(g) JVALUE(g, (PVAL)vp);
+ break;
+ case TYPE_STRG:
+ jvp = new(g) JVALUE(g, (PCSZ)vp);
+ break;
+ default:
+ break;
+ } // endswitch type
+
+ } catch (...) {
+ if (trace(1023))
+ htrc("%s\n", g->Message);
+
+ PUSH_WARNING(g->Message);
+ } // end try/catch
+
+ return jvp;
+} /* end of JsonNew */
+
+/*********************************************************************************/
/* Allocate and initialise the memory area. */
/*********************************************************************************/
static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
@@ -1289,8 +1384,11 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n)
for (uint i = n; i < args->arg_count; i++)
if (args->arg_type[i] == INT_RESULT) {
if (args->args[i]) {
- x = (int*)PlugSubAlloc(g, NULL, sizeof(int));
- *x = (int)*(longlong*)args->args[i];
+ if ((x = (int*)PlgDBSubAlloc(g, NULL, sizeof(int))))
+ *x = (int)*(longlong*)args->args[i];
+ else
+ PUSH_WARNING(g->Message);
+
} // endif args
n = i + 1;
@@ -1303,7 +1401,7 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n)
/*********************************************************************************/
/* Returns not 0 if the argument is a JSON item or file name. */
/*********************************************************************************/
-static int IsJson(UDF_ARGS *args, uint i)
+static int IsJson(UDF_ARGS *args, uint i, bool b)
{
int n = 0;
@@ -1320,8 +1418,20 @@ static int IsJson(UDF_ARGS *args, uint i)
else
n = 2; // A file name may have been returned
- } else if (!strnicmp(args->attributes[i], "Jfile_", 6))
+ } else if (!strnicmp(args->attributes[i], "Jfile_", 6)) {
n = 2; // arg is a json file name
+ } else if (b) {
+ char *sap;
+ PGLOBAL g = PlugInit(NULL, args->lengths[i] * M + 1024);
+
+ JsonSubSet(g);
+ sap = MakePSZ(g, args, i);
+
+ if (ParseJson(g, sap, strlen(sap)))
+ n = 4;
+
+ JsonFreeMem(g);
+ } // endif's
return n;
} // end of IsJson
@@ -1534,10 +1644,14 @@ static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i)
{
if (args->arg_count > (unsigned)i && args->args[i]) {
int n = args->lengths[i];
- PSZ s = (PSZ)PlugSubAlloc(g, NULL, n + 1);
+ PSZ s = (PSZ)PlgDBSubAlloc(g, NULL, n + 1);
+
+ if (s) {
+ memcpy(s, args->args[i], n);
+ s[n] = 0;
+ } else
+ PUSH_WARNING(g->Message);
- memcpy(s, args->args[i], n);
- s[n] = 0;
return s;
} else
return NULL;
@@ -1574,9 +1688,12 @@ static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
return "Key";
if (!b) {
- p = (PSZ)PlugSubAlloc(g, NULL, n + 1);
- memcpy(p, s, n);
- p[n] = 0;
+ if ((p = (PSZ)PlgDBSubAlloc(g, NULL, n + 1))) {
+ memcpy(p, s, n);
+ p[n] = 0;
+ } else
+ PUSH_WARNING(g->Message);
+
s = p;
} // endif b
@@ -1665,15 +1782,16 @@ static char *GetJsonFile(PGLOBAL g, char *fn)
return NULL;
} // endif len
- str = (char*)PlugSubAlloc(g, NULL, len + 1);
-
- if ((n = read(h, str, len)) < 0) {
- sprintf(g->Message, "Error %d reading %d bytes from %s", errno, len, fn);
- return NULL;
- } // endif n
+ if ((str = (char*)PlgDBSubAlloc(g, NULL, len + 1))) {
+ if ((n = read(h, str, len)) < 0) {
+ sprintf(g->Message, "Error %d reading %d bytes from %s", errno, len, fn);
+ return NULL;
+ } // endif n
- str[n] = 0;
- close(h);
+ str[n] = 0;
+ close(h);
+ } // endif str
+
return str;
} // end of GetJsonFile
@@ -1760,6 +1878,41 @@ static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, uint i, PJSON *top = NULL)
} // end of MakeValue
/*********************************************************************************/
+/* Try making a JSON value of the passed type from the passed argument. */
+/*********************************************************************************/
+static PJVAL MakeTypedValue(PGLOBAL g, UDF_ARGS *args, uint i,
+ JTYP type, PJSON *top = NULL)
+{
+ char *sap;
+ PJSON jsp;
+ PJVAL jvp = MakeValue(g, args, i, top);
+
+ //if (type == TYPE_JSON) {
+ // if (jvp->GetValType() >= TYPE_JSON)
+ // return jvp;
+
+ //} else if (jvp->GetValType() == type)
+ // return jvp;
+
+ if (jvp->GetValType() == TYPE_STRG) {
+ sap = jvp->GetString(g);
+
+ if ((jsp = ParseJson(g, sap, strlen(sap)))) {
+ if ((type == TYPE_JSON && jsp->GetType() != TYPE_JVAL) || jsp->GetType() == type) {
+ if (top)
+ *top = jsp;
+
+ jvp->SetValue(jsp);
+ } // endif Type
+
+ } // endif jsp
+
+ } // endif Type
+
+ return jvp;
+} // end of MakeTypedValue
+
+/*********************************************************************************/
/* Make a Json value containing the parameter. */
/*********************************************************************************/
my_bool jsonvalue_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
@@ -1861,9 +2014,9 @@ my_bool json_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa
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 if (!IsJson(args, 0, true)) {
+ // strcpy(message, "First argument must be a valid json string or item");
+ // return true;
} else
CalcLen(args, false, reslen, memlen);
@@ -1891,23 +2044,14 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
- char *p;
PJSON top;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JAR, &top);
- if ((p = jvp->GetString(g))) {
- if (!(top = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- return NULL;
- } // endif jsp
-
- jvp->SetValue(top);
- } // endif p
-
if (jvp->GetValType() != TYPE_JAR) {
arp = new(g)JARRAY;
arp->AddValue(g, jvp);
+ top = arp;
} else
arp = jvp->GetArray();
@@ -1915,7 +2059,6 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
arp->AddValue(g, MakeValue(g, args, i));
arp->InitArray(g);
-// str = Serialize(g, arp, NULL, 0);
str = MakeResult(g, args, top, args->arg_count);
} // endif CheckMemory
@@ -1952,10 +2095,10 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
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;
+ return true;
+ //} else if (!IsJson(args, 0, true)) {
+ // strcpy(message, "First argument is not a valid Json item");
+ // return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -1994,22 +2137,38 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
PJVAL jvp;
PJAR arp;
- jvp = MakeValue(g, args, 0, &top);
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
jsp = jvp->GetJson();
x = GetIntArgPtr(g, args, n);
if (CheckPath(g, args, jsp, jvp, 2))
PUSH_WARNING(g->Message);
- else if (jvp && jvp->GetValType() == TYPE_JAR) {
+ else if (jvp) {
PGLOBAL gb = GetMemPtr(g, args, 0);
- arp = jvp->GetArray();
- arp->AddValue(gb, MakeValue(gb, args, 1), x);
- arp->InitArray(gb);
- str = MakeResult(g, args, top, n);
+ if (jvp->GetValType() != TYPE_JAR) {
+ if ((arp = (PJAR)JsonNew(gb, TYPE_JAR))) {
+ arp->AddValue(gb, JvalNew(gb, TYPE_JVAL, jvp));
+ jvp->SetValue(arp);
+
+ if (!top)
+ top = arp;
+
+ } // endif arp
+
+ } else
+ arp = jvp->GetArray();
+
+ if (arp) {
+ arp->AddValue(gb, MakeValue(gb, args, 1), x);
+ arp->InitArray(gb);
+ str = MakeResult(g, args, top, n);
+ } else
+ PUSH_WARNING(gb->Message);
+
} else {
- PUSH_WARNING("First argument target is not an array");
-// if (g->Mrr) *error = 1; (only if no path)
+ PUSH_WARNING("Target is not an array");
+ // if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
} // endif CheckMemory
@@ -2048,9 +2207,6 @@ my_bool json_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
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);
@@ -2087,7 +2243,7 @@ char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
uint n = 1;
PJSON top;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
if (!(x = GetIntArgPtr(g, args, n)))
PUSH_WARNING("Missing or null array index");
@@ -2186,9 +2342,14 @@ long long jsonsum_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *err
if (g->N) {
// Keep result of constant function
- long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ long long *np;
+
+ if ((np = (long long*)PlgDBSubAlloc(g, NULL, sizeof(long long)))) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else
+ PUSH_WARNING(g->Message);
+
} // endif const_item
return n;
@@ -2252,13 +2413,21 @@ double jsonsum_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error
} else {
*error = 1;
n = -1.0;
- } // end of CheckMemory
+ } // endif CheckMemory
if (g->N) {
// Keep result of constant function
- double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ double *np;
+
+ if ((np = (double*)PlgDBSubAlloc(g, NULL, sizeof(double)))) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else {
+ PUSH_WARNING(g->Message);
+ *error = 1;
+ n = -1.0;
+ } // endif np
+
} // endif const_item
return n;
@@ -2312,13 +2481,20 @@ double jsonavg_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error
} else {
*error = 1;
n = -1.0;
- } // end of CheckMemory
+ } // endif CheckMemory
if (g->N) {
// Keep result of constant function
- double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ double *np;
+
+ if ((np = (double*)PlgDBSubAlloc(g, NULL, sizeof(double)))) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else {
+ *error = 1;
+ n = -1.0;
+ } // endif np
+
} // endif const_item
return n;
@@ -2348,12 +2524,15 @@ char *json_make_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false, false, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
- for (uint i = 0; i < args->arg_count; i++)
- objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
+ str = Serialize(g, objp, NULL, 0);
+ } // endif objp
- str = Serialize(g, objp, NULL, 0);
} // endif CheckMemory
if (!str)
@@ -2394,13 +2573,16 @@ char *json_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
PJVAL jvp;
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ if (!(jvp = MakeValue(g, args, i))->IsNull())
+ objp->SetValue(g, jvp, MakeKey(g, args, i));
- for (uint i = 0; i < args->arg_count; i++)
- if (!(jvp = MakeValue(g, args, i))->IsNull())
- objp->SetValue(g, jvp, MakeKey(g, args, i));
+ str = Serialize(g, objp, NULL, 0);
+ } // endif objp
- str = Serialize(g, objp, NULL, 0);
} // endif CheckMemory
if (!str)
@@ -2444,12 +2626,15 @@ char *json_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i += 2)
+ objp->SetValue(g, MakeValue(g, args, i + 1), MakePSZ(g, args, i));
- for (uint i = 0; i < args->arg_count; i += 2)
- objp->SetValue(g, MakeValue(g, args, i+1), MakePSZ(g, args, i));
+ str = Serialize(g, objp, NULL, 0);
+ } // endif objp
- str = Serialize(g, objp, NULL, 0);
} // endif CheckMemory
if (!str)
@@ -2732,6 +2917,82 @@ void json_object_list_deinit(UDF_INIT* initid)
} // end of json_object_list_deinit
/*********************************************************************************/
+/* Returns an array of the Json object values. */
+/*********************************************************************************/
+my_bool json_object_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen;
+
+ if (args->arg_count != 1) {
+ strcpy(message, "This function must have 1 argument");
+ return true;
+ } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "Argument must be a json object");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
+} // end of json_object_list_init
+
+char *json_object_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *is_null, char *error)
+{
+ char *str = NULL;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ if (!g->N) {
+ if (!CheckMemory(g, initid, args, 1, true, true)) {
+ char *p;
+ PJSON jsp;
+ PJVAL jvp = MakeValue(g, args, 0);
+
+ if ((p = jvp->GetString(g))) {
+ if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ PUSH_WARNING(g->Message);
+ return NULL;
+ } // endif jsp
+
+ } else
+ jsp = jvp->GetJson();
+
+ if (jsp->GetType() == TYPE_JOB) {
+ PJAR jarp = ((PJOB)jsp)->GetValList(g);
+
+ if (!(str = Serialize(g, jarp, NULL, 0)))
+ PUSH_WARNING(g->Message);
+
+ } else {
+ PUSH_WARNING("First argument is not an object");
+ if (g->Mrr) *error = 1;
+ } // endif jvp
+
+ } // endif CheckMemory
+
+ if (initid->const_item) {
+ // Keep result of constant function
+ g->Xchk = str;
+ g->N = 1; // str can be NULL
+ } // endif const_item
+
+ } else
+ str = (char*)g->Xchk;
+
+ if (!str) {
+ *is_null = 1;
+ *res_length = 0;
+ } else
+ *res_length = strlen(str);
+
+ return str;
+} // end of json_object_values
+
+void json_object_values_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of json_object_values_deinit
+
+/*********************************************************************************/
/* Set the value of JsonGrpSize. */
/*********************************************************************************/
my_bool jsonset_grp_size_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
@@ -2795,7 +3056,7 @@ my_bool json_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JARRAY;
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
g->N = (int)n;
return false;
} // end of json_array_grp_init
@@ -2805,7 +3066,7 @@ void json_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PJAR arp = (PJAR)g->Activityp;
- if (g->N-- > 0)
+ if (arp && g->N-- > 0)
arp->AddValue(g, MakeValue(g, args, 0));
} // end of json_array_grp_add
@@ -2820,12 +3081,16 @@ char *json_array_grp(UDF_INIT *initid, UDF_ARGS *, char *result,
if (g->N < 0)
PUSH_WARNING("Result truncated to json_grp_size values");
- arp->InitArray(g);
+ if (arp) {
+ arp->InitArray(g);
+ str = Serialize(g, arp, NULL, 0);
+ } else
+ str = NULL;
- if (!(str = Serialize(g, arp, NULL, 0)))
- str = strcpy(result, g->Message);
+ if (!str)
+ str = strcpy(result, g->Message);
- *res_length = strlen(str);
+ *res_length = strlen(str);
return str;
} // end of json_array_grp
@@ -2834,8 +3099,8 @@ void json_array_grp_clear(UDF_INIT *initid, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JARRAY;
- g->N = GetJsonGroupSize();
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
+ g->N = GetJsonGroupSize();
} // end of json_array_grp_clear
void json_array_grp_deinit(UDF_INIT* initid)
@@ -2868,7 +3133,7 @@ my_bool json_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JOBJECT;
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
g->N = (int)n;
return false;
} // end of json_object_grp_init
@@ -2893,7 +3158,7 @@ char *json_object_grp(UDF_INIT *initid, UDF_ARGS *, char *result,
if (g->N < 0)
PUSH_WARNING("Result truncated to json_grp_size values");
- if (!(str = Serialize(g, objp, NULL, 0)))
+ if (!objp || !(str = Serialize(g, objp, NULL, 0)))
str = strcpy(result, g->Message);
*res_length = strlen(str);
@@ -2905,8 +3170,8 @@ void json_object_grp_clear(UDF_INIT *initid, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JOBJECT;
- g->N = GetJsonGroupSize();
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
+ g->N = GetJsonGroupSize();
} // end of json_object_grp_clear
void json_object_grp_deinit(UDF_INIT* initid)
@@ -3051,7 +3316,7 @@ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *)
{
- char *p, *path, *str = NULL;
+ char *path, *str = NULL;
PJSON jsp;
PJVAL jvp;
PJSNX jsx;
@@ -3067,17 +3332,10 @@ char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (CheckMemory(g, initid, args, 1, true, true)) {
PUSH_WARNING("CheckMemory error");
goto fin;
- } else
- jvp = MakeValue(g, args, 0);
-
- if ((p = jvp->GetString(g))) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- return NULL;
- } // endif jsp
+ } // endif CheckMemory
- } else
- jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON);
+ jsp = jvp->GetJson();
if (g->Mrr) { // First argument is a constant
g->Xchk = jsp;
@@ -3088,9 +3346,9 @@ char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ jsx = JsnxNew(g, jsp, TYPE_STRING, initid->max_length);
- if (jsx->SetJpath(g, path, true)) {
+ if (!jsx || jsx->SetJpath(g, path, true)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return NULL;
@@ -3203,9 +3461,9 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ jsx = JsnxNew(g, jsp, TYPE_STRING, initid->max_length);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
goto err;
} // endif SetJpath
@@ -3220,7 +3478,7 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
g->Activityp = (PACTIVITY)str;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
@@ -3320,9 +3578,9 @@ long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_BIGINT);
+ jsx = JsnxNew(g, jsp, TYPE_BIGINT);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return 0;
@@ -3339,9 +3597,14 @@ long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
if (initid->const_item) {
// Keep result of constant function
- long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ long long *np = (long long*)PlgDBSubAlloc(g, NULL, sizeof(long long));
+
+ if (np) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else
+ PUSH_WARNING(g->Message);
+
} // endif const_item
return n;
@@ -3434,9 +3697,9 @@ double jsonget_real(UDF_INIT *initid, UDF_ARGS *args,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_DOUBLE);
+ jsx = JsnxNew(g, jsp, TYPE_DOUBLE);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return 0.0;
@@ -3453,9 +3716,17 @@ double jsonget_real(UDF_INIT *initid, UDF_ARGS *args,
if (initid->const_item) {
// Keep result of constant function
- double *dp = (double*)PlugSubAlloc(g, NULL, sizeof(double));
- *dp = d;
- g->Activityp = (PACTIVITY)dp;
+ double *dp;
+
+ if ((dp = (double*)PlgDBSubAlloc(g, NULL, sizeof(double)))) {
+ *dp = d;
+ g->Activityp = (PACTIVITY)dp;
+ } else {
+ PUSH_WARNING(g->Message);
+ *is_null = 1;
+ return 0.0;
+ } // endif dp
+
} // endif const_item
return d;
@@ -3501,7 +3772,7 @@ my_bool jsonlocate_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
- char *p, *path = NULL;
+ char *path = NULL;
int k;
PJVAL jvp, jvp2;
PJSON jsp;
@@ -3529,16 +3800,20 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
*error = 1;
goto err;
} else
- jvp = MakeValue(g, args, 0);
-
- if ((p = jvp->GetString(g))) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto err;
- } // endif jsp
-
- } else
- jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON);
+
+ //if ((p = jvp->GetString(g))) {
+ // if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ // PUSH_WARNING(g->Message);
+ // goto err;
+ // } // endif jsp
+ //} else
+ // jsp = jvp->GetJson();
+
+ if (!(jsp = jvp->GetJson())) {
+ PUSH_WARNING("First argument is not a valid JSON item");
+ goto err;
+ } // endif jsp
if (g->Mrr) { // First argument is a constant
g->Xchk = jsp;
@@ -3561,7 +3836,7 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
g->Activityp = (PACTIVITY)path;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
@@ -3686,7 +3961,7 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
g->Activityp = (PACTIVITY)path;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
@@ -3845,9 +4120,9 @@ long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g)JSNX(g, jsp, TYPE_BIGINT);
+ jsx = JsnxNew(g, jsp, TYPE_BIGINT);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
goto err;
} // endif SetJpath
@@ -3856,9 +4131,14 @@ long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (initid->const_item) {
// Keep result of constant function
- long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ long long *np = (long long*)PlgDBSubAlloc(g, NULL, sizeof(long long));
+
+ if (np) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else
+ PUSH_WARNING(g->Message);
+
} // endif const_item
return n;
@@ -3961,7 +4241,7 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
g->Activityp = (PACTIVITY)str;
} catch (int n) {
- if (trace)
+ if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
@@ -4335,18 +4615,23 @@ char *jbin_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false)) {
- PJAR arp = new(g) JARRAY;
+ PJAR arp;
- bsp = JbinAlloc(g, args, initid->max_length, arp);
- strcat(bsp->Msg, " array");
+ if ((arp = (PJAR)JsonNew(g, TYPE_JAR)) &&
+ (bsp = JbinAlloc(g, args, initid->max_length, arp))) {
+ strcat(bsp->Msg, " array");
- for (uint i = 0; i < args->arg_count; i++)
- arp->AddValue(g, MakeValue(g, args, i));
+ for (uint i = 0; i < args->arg_count; i++)
+ arp->AddValue(g, MakeValue(g, args, i));
+
+ arp->InitArray(g);
+ } // endif arp && bsp
- arp->InitArray(g);
} else
- if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
- strncpy(bsp->Msg, g->Message, 139);
+ bsp = NULL;
+
+ if (!bsp && (bsp = JbinAlloc(g, args, initid->max_length, NULL)))
+ strncpy(bsp->Msg, g->Message, 139);
// Keep result of constant function
g->Xchk = (initid->const_item) ? bsp : NULL;
@@ -4377,9 +4662,6 @@ my_bool jbin_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa
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);
@@ -4394,24 +4676,17 @@ char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
- char *p;
PJSON top;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JAR, &top);
PGLOBAL gb = GetMemPtr(g, args, 0);
- if ((p = jvp->GetString(g))) {
- if (!(top = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- return NULL;
- } // endif jsp
-
- jvp->SetValue(top);
- } // endif p
-
if (jvp->GetValType() != TYPE_JAR) {
- arp = new(gb)JARRAY;
- arp->AddValue(gb, jvp);
+ if ((arp = (PJAR)JsonNew(gb, TYPE_JAR))) {
+ arp->AddValue(gb, jvp);
+ top = arp;
+ } // endif arp
+
} else
arp = jvp->GetArray();
@@ -4458,9 +4733,9 @@ my_bool jbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
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, 0)) {
+ // strcpy(message, "First argument must be a json item");
+ // return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -4488,20 +4763,32 @@ char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
PJVAL jvp;
PJAR arp;
- jvp = MakeValue(g, args, 0, &top);
-// jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
+ // jsp = jvp->GetJson();
x = GetIntArgPtr(g, args, n);
if (CheckPath(g, args, top, jvp, n))
PUSH_WARNING(g->Message);
- else if (jvp && jvp->GetValType() == TYPE_JAR) {
+ else if (jvp) {
PGLOBAL gb = GetMemPtr(g, args, 0);
- arp = jvp->GetArray();
+ if (jvp->GetValType() != TYPE_JAR) {
+ if ((arp = (PJAR)JsonNew(gb, TYPE_JAR))) {
+ arp->AddValue(gb, (PJVAL)JvalNew(gb, TYPE_JVAL, jvp));
+ jvp->SetValue(arp);
+
+ if (!top)
+ top = arp;
+
+ } // endif arp
+
+ } else
+ arp = jvp->GetArray();
+
arp->AddValue(gb, MakeValue(gb, args, 1), x);
arp->InitArray(gb);
} else {
- PUSH_WARNING("First argument is not an array");
+ PUSH_WARNING("First argument target is not an array");
// if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
@@ -4539,9 +4826,6 @@ my_bool jbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
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);
@@ -4565,7 +4849,7 @@ char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
int *x;
uint n = 1;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
if (CheckPath(g, args, top, jvp, 1))
PUSH_WARNING(g->Message);
@@ -4578,8 +4862,8 @@ char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
PUSH_WARNING("Missing or null array index");
} else {
- PUSH_WARNING("First argument is not an array");
- if (g->Mrr) *error = 1;
+ PUSH_WARNING("First argument target is not an array");
+// if (g->Mrr) *error = 1;
} // endif jvp
} // endif CheckMemory
@@ -4625,13 +4909,18 @@ char *jbin_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
- for (uint i = 0; i < args->arg_count; i++)
- objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
+
+
+ if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
+ strcat(bsp->Msg, " object");
- if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ } else
+ bsp = NULL;
} else
if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
@@ -4676,14 +4965,18 @@ char *jbin_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
PJVAL jvp;
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
- for (uint i = 0; i < args->arg_count; i++)
- if (!(jvp = MakeValue(g, args, i))->IsNull())
- objp->SetValue(g, jvp, MakeKey(g, args, i));
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ if (!(jvp = MakeValue(g, args, i))->IsNull())
+ objp->SetValue(g, jvp, MakeKey(g, args, i));
- if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
+ strcat(bsp->Msg, " object");
+
+ } else
+ bsp = NULL;
} else
if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
@@ -4732,13 +5025,17 @@ char *jbin_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i += 2)
+ objp->SetValue(g, MakeValue(g, args, i + 1), MakePSZ(g, args, i));
- for (uint i = 0; i < args->arg_count; i += 2)
- objp->SetValue(g, MakeValue(g, args, i+1), MakePSZ(g, args, i));
+ if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
+ strcat(bsp->Msg, " object");
- if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ } else
+ bsp = NULL;
} else
if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
@@ -4989,7 +5286,7 @@ my_bool jbin_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
- char *p, *path;
+ char *path;
PJSON jsp;
PJSNX jsx;
PJVAL jvp;
@@ -5006,17 +5303,10 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (CheckMemory(g, initid, args, 1, true, true)) {
PUSH_WARNING("CheckMemory error");
goto fin;
- } else
- jvp = MakeValue(g, args, 0);
-
- if ((p = jvp->GetString(g))) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto fin;
- } // endif jsp
+ } // endif CheckMemory
- } else
- jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON);
+ jsp = jvp->GetJson();
if (g->Mrr) { // First argument is a constant
g->Xchk = jsp;
@@ -5027,16 +5317,16 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ jsx = JsnxNew(g, jsp, TYPE_STRING, initid->max_length);
- if (jsx->SetJpath(g, path, false)) {
+ if (!jsx || jsx->SetJpath(g, path, false)) {
PUSH_WARNING(g->Message);
goto fin;
} // endif SetJpath
// Get the json tree
if ((jvp = jsx->GetRowValue(g, jsp, 0, false))) {
- jsp = (jvp->GetJsp()) ? jvp->GetJsp() : new(g) JVALUE(g, jvp->GetValue());
+ jsp = (jvp->GetJsp()) ? jvp->GetJsp() : JvalNew(g, TYPE_VAL, jvp->GetValue());
if ((bsp = JbinAlloc(g, args, initid->max_length, jsp)))
strcat(bsp->Msg, " item");