diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2017-07-18 13:16:55 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2017-07-18 13:16:55 +0200 |
commit | f590296c28ec54007692181e010d7064c1071ff2 (patch) | |
tree | 8ca5932a93f59bb60abfb0928ef483e96ed999d6 /storage/connect/jsonudf.cpp | |
parent | a9d32010d0ba36cc9b9d7fb58eeace687bb13f7a (diff) | |
download | mariadb-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.cpp | 270 |
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) { |