From e027f5e8d5d966f11d7f38825a8e316ff9d4dd79 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 24 Feb 2015 23:18:04 +0100 Subject: [PATCH] - Fix MDEV-7616 by adding SQLCOM_SET_OPTION to the accepted command list. modified: storage/connect/ha_connect.cc - Add new JSON UDF functions and JSON functionalities. modified: storage/connect/json.cpp storage/connect/json.h storage/connect/jsonudf.cpp storage/connect/tabjson.cpp --- storage/connect/ha_connect.cc | 1 + storage/connect/json.cpp | 82 ++++++++++++++++++++++++++++------- storage/connect/json.h | 9 +++- storage/connect/jsonudf.cpp | 44 +++++++++++++++++++ storage/connect/tabjson.cpp | 4 +- 5 files changed, 120 insertions(+), 20 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index e73a64a150c98..64c81272b5984 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -4112,6 +4112,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd, case SQLCOM_UPDATE_MULTI: case SQLCOM_SELECT: case SQLCOM_OPTIMIZE: + case SQLCOM_SET_OPTION: break; case SQLCOM_LOCK_TABLES: locked= 1; diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp index 8031ba51b1929..7356a86d53ca4 100644 --- a/storage/connect/json.cpp +++ b/storage/connect/json.cpp @@ -881,27 +881,26 @@ PJVAL JOBJECT::GetValue(const char* key) /***********************************************************************/ /* Return the text corresponding to all keys (XML like). */ /***********************************************************************/ -PSZ JOBJECT::GetText(PGLOBAL g) +PSZ JOBJECT::GetText(PGLOBAL g, PSZ text) { - char *p, *text = (char*)PlugSubAlloc(g, NULL, 0); - bool b = true; + int n; - if (!First) - return NULL; - else for (PJPR jp = First; jp; jp = jp->Next) { - if (!(p = jp->Val->GetString())) - p = "???"; + if (!text) { + text = (char*)PlugSubAlloc(g, NULL, 0); + text[0] = 0; + n = 1; + } else + n = 0; - if (b) { - strcpy(text, p); - b = false; - } else - strcat(strcat(text, " "), p); + if (!First && n) + return NULL; + else for (PJPR jp = First; jp; jp = jp->Next) + jp->Val->GetText(g, text); - } // endfor jp + if (n) + PlugSubAlloc(g, NULL, strlen(text) + 1); - PlugSubAlloc(g, NULL, strlen(text) + 1); - return text; + return text + n; } // end of GetValue; /***********************************************************************/ @@ -924,6 +923,18 @@ void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key) } // end of SetValue +/***********************************************************************/ +/* True if void or if all members are nulls. */ +/***********************************************************************/ +bool JOBJECT::IsNull(void) +{ + for (PJPR jp = First; jp; jp = jp->Next) + if (!jp->Val->IsNull()) + return false; + + return true; +} // end of IsNull + /* -------------------------- Class JARRAY --------------------------- */ /***********************************************************************/ @@ -1012,6 +1023,18 @@ bool JARRAY::DeleteValue(int n) } // end of DeleteValue +/***********************************************************************/ +/* True if void or if all members are nulls. */ +/***********************************************************************/ +bool JARRAY::IsNull(void) +{ + for (int i = 0; i < Size; i++) + if (!Mvals[i]->IsNull()) + return false; + + return true; +} // end of IsNull + /* -------------------------- Class JVALUE- -------------------------- */ /***********************************************************************/ @@ -1086,6 +1109,25 @@ PSZ JVALUE::GetString(void) return (Value) ? Value->GetCharString(buf) : NULL; } // end of GetString +/***********************************************************************/ +/* Return the Value's String value. */ +/***********************************************************************/ +PSZ JVALUE::GetText(PGLOBAL g, PSZ text) +{ + if (Jsp && Jsp->GetType() == TYPE_JOB) + return Jsp->GetText(g, text); + + char buf[32]; + PSZ s = (Value) ? Value->GetCharString(buf) : NULL; + + if (s) + strcat(strcat(text, " "), s); + else + strcat(text, " ???"); + + return text; +} // end of GetText + /***********************************************************************/ /* Set the Value's value as the given integer. */ /***********************************************************************/ @@ -1110,3 +1152,11 @@ void JVALUE::SetString(PGLOBAL g, PSZ s) Value = AllocateValue(g, s, TYPE_STRING); } // end of AddFloat +/***********************************************************************/ +/* True when its JSON or normal value is null. */ +/***********************************************************************/ +bool JVALUE::IsNull(void) +{ + return (Jsp) ? Jsp->IsNull() : (Value) ? Value->IsNull() : true; +} // end of IsNull + diff --git a/storage/connect/json.h b/storage/connect/json.h index e56803f63c983..cdf9034e07fdc 100644 --- a/storage/connect/json.h +++ b/storage/connect/json.h @@ -152,7 +152,7 @@ class JSON : public BLOCK { virtual int GetInteger(void) {X return 0;} virtual double GetFloat() {X return 0.0;} virtual PSZ GetString() {X return NULL;} - virtual PSZ GetText(PGLOBAL g) {X return NULL;} + virtual PSZ GetText(PGLOBAL g, PSZ text) {X return NULL;} virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i) {X return true;} virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key) {X} virtual void SetValue(PVAL valp) {X} @@ -161,6 +161,7 @@ class JSON : public BLOCK { virtual void SetInteger(PGLOBAL g, int n) {X} virtual void SetFloat(PGLOBAL g, double f) {X} virtual bool DeleteValue(int i) {X return true;} + virtual bool IsNull(void) {X return true;} protected: int Size; @@ -182,8 +183,9 @@ class JOBJECT : public JSON { virtual PJPR AddPair(PGLOBAL g, PSZ key); virtual PJOB GetObject(void) {return this;} virtual PJVAL GetValue(const char* key); - virtual PSZ GetText(PGLOBAL g); + virtual PSZ GetText(PGLOBAL g, PSZ text); virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key); + virtual bool IsNull(void); protected: PJPR First; @@ -208,6 +210,7 @@ class JARRAY : public JSON { virtual PJVAL GetValue(int i); virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i); virtual bool DeleteValue(int n); + virtual bool IsNull(void); protected: // Members @@ -244,11 +247,13 @@ class JVALUE : public JSON { virtual int GetInteger(void); virtual double GetFloat(void); virtual PSZ GetString(void); + virtual PSZ GetText(PGLOBAL g, PSZ text); virtual void SetValue(PVAL valp) {Value = valp;} virtual void SetValue(PJSON jsp) {Jsp = jsp;} virtual void SetString(PGLOBAL g, PSZ s); virtual void SetInteger(PGLOBAL g, int n); virtual void SetFloat(PGLOBAL g, double f); + virtual bool IsNull(void); protected: PJSON Jsp; // To the json value diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index b100f377295ed..36ea87630cd75 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -37,6 +37,10 @@ DllExport my_bool Json_Object_init(UDF_INIT*, UDF_ARGS*, char*); DllExport char *Json_Object(UDF_INIT*, UDF_ARGS*, char*, unsigned long*, char *, char *); DllExport void Json_Object_deinit(UDF_INIT*); +DllExport my_bool Json_Object_Nonull_init(UDF_INIT*, UDF_ARGS*, char*); +DllExport char *Json_Object_Nonull(UDF_INIT*, UDF_ARGS*, char*, + unsigned long*, char *, char *); +DllExport void Json_Object_Nonull_deinit(UDF_INIT*); DllExport my_bool Json_Array_Grp_init(UDF_INIT*, UDF_ARGS*, char*); DllExport void Json_Array_Grp_add(UDF_INIT *, UDF_ARGS *, char *, char *); DllExport char *Json_Array_Grp(UDF_INIT*, UDF_ARGS*, char*, @@ -437,6 +441,46 @@ void Json_Object_deinit(UDF_INIT* initid) PlugExit((PGLOBAL)initid->ptr); } // end of Json_Object_deinit +/***********************************************************************/ +/* Make a Json Oject containing all not null parameters. */ +/***********************************************************************/ +my_bool Json_Object_Nonull_init(UDF_INIT *initid, UDF_ARGS *args, + char *message) +{ + unsigned long reslen, memlen; + + CalcLen(args, true, reslen, memlen); + return JsonInit(initid, message, reslen, memlen); +} // end of Json_Object_Nonull_init + +char *Json_Object_Nonull(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *error) +{ + char *str; + uint i; + PJOB objp; + PJVAL jvp; + PGLOBAL g = (PGLOBAL)initid->ptr; + + PlugSubSet(g, g->Sarea, g->Sarea_Size); + objp = new(g) JOBJECT; + + for (i = 0; i < args->arg_count; i++) + if (!(jvp = MakeValue(g, args, i))->IsNull()) + objp->SetValue(g, jvp, MakeKey(g, args, i)); + + if (!(str = Serialize(g, objp, NULL, 0))) + str = strcpy(result, g->Message); + + *res_length = strlen(str); + return str; +} // end of Json_Object_Nonull + +void Json_Object_Nonull_deinit(UDF_INIT* initid) +{ + PlugExit((PGLOBAL)initid->ptr); +} // end of Json_Object_nonull_deinit + /***********************************************************************/ /* Make a Json array from values comming from rows. */ /***********************************************************************/ diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index f99b0d2ef1d2a..827828c06ee42 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -493,7 +493,7 @@ bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm) if (!IsTypeChar(Buf_Type)) jnp->Valp = AllocateValue(g, Buf_Type, 0, GetPrecision()); else - jnp->Valp = AllocateValue(g, TYPE_DOUBLE); + jnp->Valp = AllocateValue(g, TYPE_DOUBLE, 0, 2); break; case OP_MIN: @@ -610,7 +610,7 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n) break; case TYPE_JOB: // if (!vp->IsTypeNum() || !Strict) { - vp->SetValue_psz(val->GetObject()->GetText(g)); + vp->SetValue_psz(val->GetObject()->GetText(g, NULL)); break; // } // endif Type