summaryrefslogtreecommitdiff
path: root/storage/connect/jsonudf.cpp
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2017-07-18 13:16:55 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2017-07-18 13:16:55 +0200
commitf590296c28ec54007692181e010d7064c1071ff2 (patch)
tree8ca5932a93f59bb60abfb0928ef483e96ed999d6 /storage/connect/jsonudf.cpp
parenta9d32010d0ba36cc9b9d7fb58eeace687bb13f7a (diff)
downloadmariadb-git-f590296c28ec54007692181e010d7064c1071ff2.tar.gz
-- Finalize work on MongoDB access
Implement discovery for the MongoDB Java Driver Create classes to minimize code and avoid dupicates Rearrange and rename implied files modified: storage/connect/CMakeLists.txt renamed: storage/connect/mongofam.cpp -> storage/connect/cmgfam.cpp renamed: storage/connect/mongofam.h -> storage/connect/cmgfam.h modified: storage/connect/cmgoconn.h modified: storage/connect/javaconn.h modified: storage/connect/jdbconn.cpp modified: storage/connect/jmgoconn.cpp modified: storage/connect/jmgoconn.h modified: storage/connect/mongo.cpp modified: storage/connect/mongo.h renamed: storage/connect/tabmgo.cpp -> storage/connect/tabcmg.cpp renamed: storage/connect/tabmgo.h -> storage/connect/tabcmg.h modified: storage/connect/tabjmg.cpp modified: storage/connect/tabjmg.h modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h -- Trace Sarea allocation and freeing modified: storage/connect/connect.cc modified: storage/connect/plugutil.cpp modified: storage/connect/user_connect.cc -- Null Json values where not mark as null in JSNX::SetJsonValue This was added in TYPE_NULL (declared as TYPE_VOID) modified: storage/connect/json.cpp modified: storage/connect/json.h modified: storage/connect/jsonudf.cpp -- Null JValues are ignored in JSNX::CalculateArray Also done in tabjson.cpp for JSONCOL::CalculateArray modified: storage/connect/json.h modified: storage/connect/jsonudf.cpp modified: storage/connect/tabjson.cpp -- Null JSON values now represented by connect_json_null session variable modified: storage/connect/json.cpp modified: storage/connect/json.h modified: storage/connect/jsonudf.cpp modified: storage/connect/tabjson.cpp -- JVALUE has size = 1 modified: storage/connect/json.h -- Fix by vuvova because Debian compilation failure. modified: storage/connect/value.cpp
Diffstat (limited to 'storage/connect/jsonudf.cpp')
-rw-r--r--storage/connect/jsonudf.cpp270
1 files changed, 241 insertions, 29 deletions
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 124e5bdc6ad..eb98510c702 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -1,5 +1,5 @@
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
-/* PROGRAM NAME: jsonudf Version 1.5 */
+/* PROGRAM NAME: jsonudf Version 1.6 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
@@ -29,6 +29,7 @@
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 PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
@@ -347,11 +348,13 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
SetJsonValue(g, vp, val->GetArray()->GetValue(0), n);
break;
case TYPE_JOB:
- // if (!vp->IsTypeNum() || !Strict) {
+// if (!vp->IsTypeNum() || !Strict) {
vp->SetValue_psz(val->GetObject()->GetText(g, NULL));
break;
- // } // endif Type
+// } // endif Type
+ case TYPE_NULL:
+ vp->SetNull(true);
default:
vp->Reset();
} // endswitch Type
@@ -488,15 +491,16 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
JVALUE jval;
vp->Reset();
-//ars = MY_MIN(Tjp->Limit, arp->size());
ars = arp->size();
for (i = 0; i < ars; i++) {
jvrp = arp->GetValue(i);
-// do {
- if (n < Nod - 1 && jvrp->GetJson()) {
-// Tjp->NextSame = nextsame;
+ if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) {
+ if (jvrp->IsNull()) {
+ jvrp->Value = AllocateValue(g, GetJsonNull(), TYPE_STRING);
+ jvp = jvrp;
+ } else if (n < Nod - 1 && jvrp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvrp->GetJson(), n + 1));
jvp = &jval;
} else
@@ -510,25 +514,25 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (!MulVal->IsZero()) {
switch (op) {
- case OP_CNC:
- if (Nodes[n].CncVal) {
- val[0] = Nodes[n].CncVal;
- err = vp->Compute(g, val, 1, op);
- } // endif CncVal
+ case OP_CNC:
+ if (Nodes[n].CncVal) {
+ val[0] = Nodes[n].CncVal;
+ err = vp->Compute(g, val, 1, op);
+ } // endif CncVal
- val[0] = MulVal;
- err = vp->Compute(g, val, 1, op);
- break;
- // case OP_NUM:
- case OP_SEP:
- val[0] = Nodes[n].Valp;
- val[1] = MulVal;
- err = vp->Compute(g, val, 2, OP_ADD);
- break;
- default:
- val[0] = Nodes[n].Valp;
- val[1] = MulVal;
- err = vp->Compute(g, val, 2, op);
+ val[0] = MulVal;
+ err = vp->Compute(g, val, 1, op);
+ break;
+// case OP_NUM:
+ case OP_SEP:
+ val[0] = Nodes[n].Valp;
+ val[1] = MulVal;
+ err = vp->Compute(g, val, 2, OP_ADD);
+ break;
+ default:
+ val[0] = Nodes[n].Valp;
+ val[1] = MulVal;
+ err = vp->Compute(g, val, 2, op);
} // endswitch Op
if (err)
@@ -536,7 +540,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
} // endif Zero
-// } while (Tjp->NextSame > nextsame);
+ } // endif jvrp
} // endfor i
@@ -1100,6 +1104,7 @@ inline void JsonMemSave(PGLOBAL g)
/*********************************************************************************/
inline void JsonFreeMem(PGLOBAL g)
{
+ g->Activityp = NULL;
PlugExit(g);
} /* end of JsonFreeMem */
@@ -1111,7 +1116,7 @@ static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
unsigned long reslen, unsigned long memlen,
unsigned long more = 0)
{
- PGLOBAL g = PlugInit(NULL, memlen + more);
+ PGLOBAL g = PlugInit(NULL, memlen + more + 500); // +500 to avoid CheckMem
if (!g) {
strcpy(message, "Allocation error");
@@ -1471,6 +1476,9 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
ml += g->More;
if (ml > g->Sarea_Size) {
+ if (trace)
+ htrc("Freeing Sarea size=%d\n", g->Sarea_Size);
+
free(g->Sarea);
if (!(g->Sarea = PlugAllocMem(g, ml))) {
@@ -1814,7 +1822,7 @@ char *json_make_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
return str;
} // end of json_make_array
-void json_array_deinit(UDF_INIT* initid)
+void json_make_array_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of json_make_array_deinit
@@ -2098,6 +2106,206 @@ void json_array_delete_deinit(UDF_INIT* initid)
} // end of json_array_delete_deinit
/*********************************************************************************/
+/* Sum big integer values from a Json array. */
+/*********************************************************************************/
+my_bool jsonsum_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen, more;
+
+ 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, "First argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ // TODO: calculate this
+ more = (IsJson(args, 0) != 3) ? 1000 : 0;
+
+ return JsonInit(initid, args, message, true, reslen, memlen, more);
+} // end of jsonsum_int_init
+
+long long jsonsum_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
+{
+ long long n = 0LL;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ if (g->N) {
+ if (!g->Activityp) {
+ *is_null = 1;
+ return 0LL;
+ } else
+ return *(long long*)g->Activityp;
+
+ } else if (initid->const_item)
+ g->N = 1;
+
+ if (!CheckMemory(g, initid, args, 1, false, false, true)) {
+ PJVAL jvp = MakeValue(g, args, 0);
+
+ if (jvp && jvp->GetValType() == TYPE_JAR) {
+ PJAR arp = jvp->GetArray();
+
+ for (int i = 0; i < arp->size(); i++)
+ n += arp->GetValue(i)->GetBigint();
+
+ } else {
+ PUSH_WARNING("First argument target is not an array");
+ } // endif jvp
+
+ } else {
+ *error = 1;
+ n = -1LL;
+ } // end of CheckMemory
+
+ 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;
+ } // endif const_item
+
+ return n;
+} // end of jsonsum_int
+
+void jsonsum_int_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of jsonsum_int_deinit
+
+/*********************************************************************************/
+/* Sum big integer values from a Json array. */
+/*********************************************************************************/
+my_bool jsonsum_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen, more;
+
+ 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, "First argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ // TODO: calculate this
+ more = (IsJson(args, 0) != 3) ? 1000 : 0;
+
+ return JsonInit(initid, args, message, true, reslen, memlen, more);
+} // end of jsonsum_real_init
+
+double jsonsum_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
+{
+ double n = 0.0;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ if (g->N) {
+ if (!g->Activityp) {
+ *is_null = 1;
+ return 0.0;
+ } else
+ return *(double*)g->Activityp;
+
+ } else if (initid->const_item)
+ g->N = 1;
+
+ if (!CheckMemory(g, initid, args, 1, false, false, true)) {
+ PJVAL jvp = MakeValue(g, args, 0);
+
+ if (jvp && jvp->GetValType() == TYPE_JAR) {
+ PJAR arp = jvp->GetArray();
+
+ for (int i = 0; i < arp->size(); i++)
+ n += arp->GetValue(i)->GetFloat();
+
+ } else {
+ PUSH_WARNING("First argument target is not an array");
+ } // endif jvp
+
+ } else {
+ *error = 1;
+ n = -1.0;
+ } // end of CheckMemory
+
+ if (g->N) {
+ // Keep result of constant function
+ double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } // endif const_item
+
+ return n;
+} // end of jsonsum_real
+
+void jsonsum_real_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of jsonsum_real_deinit
+
+/*********************************************************************************/
+/* Returns the average of big integer values from a Json array. */
+/*********************************************************************************/
+my_bool jsonavg_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ return jsonsum_real_init(initid, args, message);
+} // end of jsonavg_real_init
+
+double jsonavg_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
+{
+ double n = 0.0;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ if (g->N) {
+ if (!g->Activityp) {
+ *is_null = 1;
+ return 0.0;
+ } else
+ return *(double*)g->Activityp;
+
+ } else if (initid->const_item)
+ g->N = 1;
+
+ if (!CheckMemory(g, initid, args, 1, false, false, true)) {
+ PJVAL jvp = MakeValue(g, args, 0);
+
+ if (jvp && jvp->GetValType() == TYPE_JAR) {
+ PJAR arp = jvp->GetArray();
+
+ if (arp->size()) {
+ for (int i = 0; i < arp->size(); i++)
+ n += arp->GetValue(i)->GetFloat();
+
+ n /= arp->size();
+ } // endif size
+
+ } else {
+ PUSH_WARNING("First argument target is not an array");
+ } // endif jvp
+
+ } else {
+ *error = 1;
+ n = -1.0;
+ } // end of CheckMemory
+
+ if (g->N) {
+ // Keep result of constant function
+ double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } // endif const_item
+
+ return n;
+} // end of jsonavg_real
+
+void jsonavg_real_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of jsonavg_real_deinit
+
+/*********************************************************************************/
/* Make a Json Object containing all the parameters. */
/*********************************************************************************/
my_bool json_make_object_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
@@ -2990,6 +3198,7 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
+
PUSH_WARNING(g->Message);
str = NULL;
} catch (const char *msg) {
@@ -3039,7 +3248,7 @@ my_bool jsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} // end of jsonget_int_init
long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
- char *is_null, char *error)
+ char *is_null, char *error)
{
char *p, *path;
long long n;
@@ -3330,6 +3539,7 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
+
PUSH_WARNING(g->Message);
*error = 1;
path = NULL;
@@ -3454,6 +3664,7 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
+
PUSH_WARNING(g->Message);
*error = 1;
path = NULL;
@@ -3728,6 +3939,7 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
+
PUSH_WARNING(g->Message);
str = NULL;
} catch (const char *msg) {