diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2017-05-23 19:35:50 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2017-05-23 19:35:50 +0200 |
commit | 3e36eb230b65d53acc8e02b00a024e72ed249425 (patch) | |
tree | be89d99353fc70488a5b43707fac12b960f2f29b /storage/connect/json.cpp | |
parent | e8333389c89c946d3794ec9ea708d308318301a3 (diff) | |
download | mariadb-git-3e36eb230b65d53acc8e02b00a024e72ed249425.tar.gz |
Fix gcc compiler warnings reported by Sergei
modified: storage/connect/array.cpp
modified: storage/connect/array.h
modified: storage/connect/blkfil.cpp
modified: storage/connect/blkfil.h
modified: storage/connect/block.h
modified: storage/connect/colblk.cpp
modified: storage/connect/colblk.h
modified: storage/connect/csort.h
modified: storage/connect/filamvct.cpp
modified: storage/connect/filter.cpp
modified: storage/connect/filter.h
modified: storage/connect/global.h
modified: storage/connect/json.h
modified: storage/connect/plgdbsem.h
modified: storage/connect/plgdbutl.cpp
modified: storage/connect/tabcol.cpp
modified: storage/connect/tabcol.h
modified: storage/connect/tabdos.cpp
modified: storage/connect/tabdos.h
modified: storage/connect/tabjson.cpp
modified: storage/connect/table.cpp
modified: storage/connect/tabodbc.cpp
modified: storage/connect/tabodbc.h
modified: storage/connect/tabsys.h
modified: storage/connect/tabxml.h
modified: storage/connect/value.cpp
modified: storage/connect/value.h
modified: storage/connect/xindex.cpp
modified: storage/connect/xindex.h
modified: storage/connect/xobject.cpp
modified: storage/connect/xobject.h
modified: storage/connect/xtable.h
Set values as nullable when retrieving catalog info
modified: storage/connect/jdbconn.cpp
modified: storage/connect/mysql-test/connect/r/odbc_oracle.result
modified: storage/connect/odbconn.cpp
Change format of Jpath
modified: storage/connect/json.cpp
modified: storage/connect/jsonudf.cpp
modified: storage/connect/mysql-test/connect/r/json.result
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/zip.result
modified: storage/connect/mysql-test/connect/t/json.test
modified: storage/connect/mysql-test/connect/t/json_udf.test
modified: storage/connect/mysql-test/connect/t/json_udf_bin.test
modified: storage/connect/mysql-test/connect/t/zip.test
modified: storage/connect/tabjson.cpp
modified: storage/connect/tabjson.h
modified: storage/connect/tabmgo.cpp
Change null representation from ??? to <null>
modified: storage/connect/json.cpp
Change the name of UDF that are equal to a native JSON function name
modified: storage/connect/jsonudf.cpp
modified: storage/connect/jsonudf.h
modified: storage/connect/mysql-test/connect/t/json_udf.inc
modified: storage/connect/mysql-test/connect/t/json_udf2.inc
Fix bug in making JSON project info
modified: storage/connect/mongofam.cpp
Fix COMPUTE when one argument is null
modified: storage/connect/value.cpp
Value is null only when nullable
modified: storage/connect/value.h
Diffstat (limited to 'storage/connect/json.cpp')
-rw-r--r-- | storage/connect/json.cpp | 386 |
1 files changed, 202 insertions, 184 deletions
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp index b473871e9f7..44758e7b0ad 100644 --- a/storage/connect/json.cpp +++ b/storage/connect/json.cpp @@ -53,6 +53,36 @@ void trans_func(unsigned int u, _EXCEPTION_POINTERS* pExp) char *GetExceptionDesc(PGLOBAL g, unsigned int e); #endif // SE_CATCH +/***********************************************************************/ +/* IsNum: check whether this string is all digits. */ +/***********************************************************************/ +bool IsNum(PSZ s) +{ + for (char *p = s; *p; p++) + if (*p == ']') + break; + else if (!isdigit(*p) || *p == '-') + return false; + + return true; +} // end of IsNum + +/***********************************************************************/ +/* NextChr: return the first found '[' or Sep pointer. */ +/***********************************************************************/ +char *NextChr(PSZ s, char sep) +{ + char *p1 = strchr(s, '['); + char *p2 = strchr(s, sep); + + if (!p2) + return p1; + else if (p1) + return MY_MIN(p1, p2); + + return p2; +} // end of NextChr + /***********************************************************************/ /* Parse a json string. */ @@ -60,7 +90,7 @@ char *GetExceptionDesc(PGLOBAL g, unsigned int e); /***********************************************************************/ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma) { - int i, rc, pretty = (ptyp) ? *ptyp : 3; + int i, pretty = (ptyp) ? *ptyp : 3; bool b = false, pty[3] = {true, true, true}; PJSON jsp = NULL; STRG src; @@ -81,117 +111,91 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma) if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n'))) pty[0] = false; - - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return NULL; - } // endif jump_level - -#if defined(SE_CATCH) - // Let's try to recover from any kind of interrupt - _se_translator_function f = _set_se_translator(trans_func); - try { -#endif // SE_CATCH --------------------- try section -------------------- - if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) { - goto err; - } // endif rc - -#if defined(SE_CATCH) // ------------- end of try section ----------------- - } catch (SE_Exception e) { - sprintf(g->Message, "ParseJson: exception doing setjmp: %s (rc=%hd)", - GetExceptionDesc(g, e.nSE), e.nSE); - _set_se_translator(f); - goto err; - } catch (...) { - strcpy(g->Message, "Exception doing setjmp"); - _set_se_translator(f); - goto err; - } // end of try-catches - - _set_se_translator(f); -#endif // SE_CATCH - - for (i = 0; i < len; i++) - switch (s[i]) { - case '[': - if (jsp) - goto tryit; - else if (!(jsp = ParseArray(g, ++i, src, pty))) - goto err; - - break; - case '{': - if (jsp) - goto tryit; - else if (!(jsp = ParseObject(g, ++i, src, pty))) - goto err; - - break; - case ' ': - case '\t': - case '\n': - case '\r': - break; - case ',': - if (jsp && (pretty == 1 || pretty == 3)) { - if (comma) - *comma = true; - - pty[0] = pty[2] = false; - break; - } // endif pretty - - sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty); - goto err; - case '(': - b = true; - break; - case ')': - if (b) { - b = false; - break; - } // endif b - - default: - if (jsp) - goto tryit; - else if (!(jsp = ParseValue(g, i, src, pty))) - goto err; - - break; - }; // endswitch s[i] - - if (!jsp) - sprintf(g->Message, "Invalid Json string '%.*s'", 50, s); - else if (ptyp && pretty == 3) { - *ptyp = 3; // Not recognized pretty - - for (i = 0; i < 3; i++) - if (pty[i]) { - *ptyp = i; - break; - } // endif pty - - } // endif ptyp - - g->jump_level--; - return jsp; + for (i = 0; i < len; i++) + switch (s[i]) { + case '[': + if (jsp) + goto tryit; + else if (!(jsp = ParseArray(g, ++i, src, pty))) + throw 1; + + break; + case '{': + if (jsp) + goto tryit; + else if (!(jsp = ParseObject(g, ++i, src, pty))) + throw 2; + + break; + case ' ': + case '\t': + case '\n': + case '\r': + break; + case ',': + if (jsp && (pretty == 1 || pretty == 3)) { + if (comma) + *comma = true; + + pty[0] = pty[2] = false; + break; + } // endif pretty + + sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty); + throw 3; + case '(': + b = true; + break; + case ')': + if (b) { + b = false; + break; + } // endif b + + default: + if (jsp) + goto tryit; + else if (!(jsp = ParseValue(g, i, src, pty))) + throw 4; + + break; + }; // endswitch s[i] + + if (!jsp) + sprintf(g->Message, "Invalid Json string '%.*s'", 50, s); + else if (ptyp && pretty == 3) { + *ptyp = 3; // Not recognized pretty + + for (i = 0; i < 3; i++) + if (pty[i]) { + *ptyp = i; + break; + } // endif pty + + } // endif ptyp + + } catch (int n) { + if (trace) + htrc("Exception %d: %s\n", n, g->Message); + jsp = NULL; + } catch (const char *msg) { + strcpy(g->Message, msg); + jsp = NULL; + } // end catch + + return jsp; tryit: if (pty[0] && (!pretty || pretty > 2)) { if ((jsp = ParseArray(g, (i = 0), src, pty)) && ptyp && pretty == 3) *ptyp = (pty[0]) ? 0 : 3; - g->jump_level--; return jsp; } else strcpy(g->Message, "More than one item in file"); -err: - g->jump_level--; - return NULL; + return NULL; } // end of ParseJson /***********************************************************************/ @@ -335,16 +339,16 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty) PJVAL jvp = new(g) JVALUE; for (; i < len; i++) - switch (s[i]) { - case '\n': - pty[0] = pty[1] = false; - case '\r': - case ' ': - case '\t': - break; - default: - goto suite; - } // endswitch + switch (s[i]) { + case '\n': + pty[0] = pty[1] = false; + case '\r': + case ' ': + case '\t': + break; + default: + goto suite; + } // endswitch suite: switch (s[i]) { @@ -585,78 +589,75 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src) PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty) { PSZ str = NULL; - bool b = false, err = true; - JOUT *jp; + bool b = false, err = true; + JOUT *jp; FILE *fs = NULL; g->Message[0] = 0; - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return NULL; - } // endif jump_level - - if (setjmp(g->jumper[++g->jump_level])) { - str = NULL; - goto fin; - } // endif jmp - - if (!jsp) { - strcpy(g->Message, "Null json tree"); - goto fin; - } else if (!fn) { - // Serialize to a string - jp = new(g) JOUTSTR(g); - b = pretty == 1; - } else { - if (!(fs = fopen(fn, "wb"))) { - sprintf(g->Message, MSG(OPEN_MODE_ERROR), - "w", (int)errno, fn); - strcat(strcat(g->Message, ": "), strerror(errno)); - goto fin;; - } else if (pretty >= 2) { - // Serialize to a pretty file - jp = new(g)JOUTPRT(g, fs); + try { + if (!jsp) { + strcpy(g->Message, "Null json tree"); + throw 1; + } else if (!fn) { + // Serialize to a string + jp = new(g) JOUTSTR(g); + b = pretty == 1; } else { - // Serialize to a flat file - b = true; - jp = new(g)JOUTFILE(g, fs, pretty); - } // endif's - - } // endif's - - switch (jsp->GetType()) { - case TYPE_JAR: - err = SerializeArray(jp, (PJAR)jsp, b); - break; - case TYPE_JOB: - err = ((b && jp->Prty()) && jp->WriteChr('\t')); - err |= SerializeObject(jp, (PJOB)jsp); - break; - case TYPE_JVAL: - err = SerializeValue(jp, (PJVAL)jsp); - break; - default: - strcpy(g->Message, "Invalid json tree"); - } // endswitch Type + if (!(fs = fopen(fn, "wb"))) { + sprintf(g->Message, MSG(OPEN_MODE_ERROR), + "w", (int)errno, fn); + strcat(strcat(g->Message, ": "), strerror(errno)); + throw 2; + } else if (pretty >= 2) { + // Serialize to a pretty file + jp = new(g)JOUTPRT(g, fs); + } else { + // Serialize to a flat file + b = true; + jp = new(g)JOUTFILE(g, fs, pretty); + } // endif's + + } // endif's + + switch (jsp->GetType()) { + case TYPE_JAR: + err = SerializeArray(jp, (PJAR)jsp, b); + break; + case TYPE_JOB: + err = ((b && jp->Prty()) && jp->WriteChr('\t')); + err |= SerializeObject(jp, (PJOB)jsp); + break; + case TYPE_JVAL: + err = SerializeValue(jp, (PJVAL)jsp); + break; + default: + strcpy(g->Message, "Invalid json tree"); + } // endswitch Type + + if (fs) { + fputs(EL, fs); + fclose(fs); + str = (err) ? NULL : strcpy(g->Message, "Ok"); + } else if (!err) { + str = ((JOUTSTR*)jp)->Strp; + jp->WriteChr('\0'); + PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N); + } else { + if (!g->Message[0]) + strcpy(g->Message, "Error in Serialize"); - if (fs) { - fputs(EL, fs); - fclose(fs); - str = (err) ? NULL : strcpy(g->Message, "Ok"); - } else if (!err) { - str = ((JOUTSTR*)jp)->Strp; - jp->WriteChr('\0'); - PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N); - } else { - if (!g->Message[0]) - strcpy(g->Message, "Error in Serialize"); + } // endif's - } // endif's + } catch (int n) { + if (trace) + htrc("Exception %d: %s\n", n, g->Message); + str = NULL; + } catch (const char *msg) { + strcpy(g->Message, msg); + str = NULL; + } // end catch -fin: - g->jump_level--; return str; } // end of Serialize @@ -965,7 +966,7 @@ return false; /***********************************************************************/ /* Add a new pair to an Object. */ /***********************************************************************/ -PJPR JOBJECT::AddPair(PGLOBAL g, PSZ key) +PJPR JOBJECT::AddPair(PGLOBAL g, PCSZ key) { PJPR jpp = new(g) JPAIR(key); @@ -1021,7 +1022,24 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSZ text) if (!First && n) return NULL; - else for (PJPR jp = First; jp; jp = jp->Next) + else if (n == 1 && Size == 1 && !strcmp(First->GetKey(), "$date")) { + int i; + + First->Val->GetText(g, text); + i = (text[1] == '-' ? 2 : 1); + + if (IsNum(text + i)) { + // Date is in milliseconds + int j = (int)strlen(text); + + if (j >= 4 + i) + text[j - 3] = 0; // Change it to seconds + else + strcpy(text, " 0"); + + } // endif text + + } else for (PJPR jp = First; jp; jp = jp->Next) jp->Val->GetText(g, text); if (n) @@ -1051,7 +1069,7 @@ bool JOBJECT::Merge(PGLOBAL g, PJSON jsp) /***********************************************************************/ /* Set or add a value corresponding to the given key. */ /***********************************************************************/ -void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key) +void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PCSZ key) { PJPR jp; @@ -1071,7 +1089,7 @@ void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key) /***********************************************************************/ /* Delete a value corresponding to the given key. */ /***********************************************************************/ -void JOBJECT::DeleteKey(PSZ key) +void JOBJECT::DeleteKey(PCSZ key) { PJPR jp, *pjp = &First; @@ -1250,10 +1268,10 @@ JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON() /***********************************************************************/ /* Constructor for a given string. */ /***********************************************************************/ -JVALUE::JVALUE(PGLOBAL g, PSZ strp) : JSON() +JVALUE::JVALUE(PGLOBAL g, PCSZ strp) : JSON() { Jsp = NULL; - Value = AllocateValue(g, strp, TYPE_STRING); + Value = AllocateValue(g, (void*)strp, TYPE_STRING); Next = NULL; Del = false; } // end of JVALUE constructor @@ -1341,7 +1359,7 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text) if (s) strcat(strcat(text, " "), s); else - strcat(text, " ???"); + strcat(text, " <null>"); return text; } // end of GetText @@ -1374,7 +1392,7 @@ void JVALUE::SetTiny(PGLOBAL g, char n) { Value = AllocateValue(g, &n, TYPE_TINY); Jsp = NULL; -} // end of SetInteger +} // end of SetTiny /***********************************************************************/ /* Set the Value's value as the given big integer. */ @@ -1408,6 +1426,6 @@ void JVALUE::SetString(PGLOBAL g, PSZ s, short c) /***********************************************************************/ bool JVALUE::IsNull(void) { - return (Jsp) ? Jsp->IsNull() : (Value) ? Value->IsZero() : true; + return (Jsp) ? Jsp->IsNull() : (Value) ? Value->IsNull() : true; } // end of IsNull |