diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2021-08-02 10:11:41 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2021-08-02 10:11:41 +0200 |
commit | 6efb5e9f5e3cd3ec811ae832a67e1878c14f0dea (patch) | |
tree | b7c1a18b8bbc638ee12951d1d04db6d21bebcaed /storage/connect/tabjson.cpp | |
parent | 07674e6a741a82d2e30f9798f699209a6c34dfef (diff) | |
parent | ec8882b9ddbba2f9fc3571a1ac2ade0dabf412d9 (diff) | |
download | mariadb-git-6efb5e9f5e3cd3ec811ae832a67e1878c14f0dea.tar.gz |
Merge branch '10.5' into 10.6
Diffstat (limited to 'storage/connect/tabjson.cpp')
-rw-r--r-- | storage/connect/tabjson.cpp | 148 |
1 files changed, 102 insertions, 46 deletions
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index 6ef39391849..07a4712e8b0 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -1,5 +1,5 @@ /************* tabjson C++ Program Source Code File (.CPP) *************/ -/* PROGRAM NAME: tabjson Version 1.8 */ +/* PROGRAM NAME: tabjson Version 1.9 */ /* (C) Copyright to the author Olivier BERTRAND 2014 - 2021 */ /* This program are the JSON class DB execution routines. */ /***********************************************************************/ @@ -58,6 +58,7 @@ USETEMP UseTemp(void); bool JsonAllPath(void); int GetDefaultDepth(void); char *GetJsonNull(void); +bool Stringified(PCSZ, char*); /***********************************************************************/ /* JSONColumns: construct the result blocks containing the description */ @@ -178,8 +179,8 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) lvl = GetIntegerTableOption(g, topt, "Depth", lvl); sep = GetStringTableOption(g, topt, "Separator", "."); strfy = GetStringTableOption(g, topt, "Stringify", NULL); - sz = GetIntegerTableOption(g, topt, "Jsize", 250); - limit = GetIntegerTableOption(g, topt, "Limit", 10); + sz = GetIntegerTableOption(g, topt, "Jsize", 1024); + limit = GetIntegerTableOption(g, topt, "Limit", 50); /*********************************************************************/ /* Open the input file. */ @@ -191,13 +192,19 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) #endif // ZIP_SUPPORT tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL); - if (!tdp->Fn && topt->http) + if (!tdp->Fn && topt->http) { tdp->Fn = GetStringTableOption(g, topt, "Subtype", NULL); + topt->subtype = NULL; + } // endif fn if (!(tdp->Database = SetPath(g, db))) return 0; - tdp->Objname = GetStringTableOption(g, topt, "Object", NULL); + if ((tdp->Objname = GetStringTableOption(g, topt, "Object", NULL))) { + if (*tdp->Objname == '$') tdp->Objname++; + if (*tdp->Objname == '.') tdp->Objname++; + } // endif Objname + tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0; tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2); tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL); @@ -222,8 +229,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) if (tdp->Uri) { #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT) - tdp->Collname = GetStringTableOption(g, topt, "Name", NULL); - tdp->Collname = GetStringTableOption(g, topt, "Tabname", tdp->Collname); + tdp->Collname = GetStringTableOption(g, topt, "Tabname", NULL); tdp->Schema = GetStringTableOption(g, topt, "Dbname", "test"); tdp->Options = (PSZ)GetStringTableOption(g, topt, "Colist", "all"); tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false); @@ -442,7 +448,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j) jcol.Type = TYPE_UNKNOWN; jcol.Len = jcol.Scale = 0; jcol.Cbn = true; - } else if (j < lvl && !(strfy && !stricmp(strfy, colname))) { + } else if (j < lvl && !Stringified(strfy, colname)) { if (!fmt[bf]) strcat(fmt, colname); @@ -512,7 +518,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j) } // endswitch Type } else if (lvl >= 0) { - if (strfy && !stricmp(strfy, colname)) { + if (Stringified(strfy, colname)) { if (!fmt[bf]) strcat(fmt, colname); @@ -633,10 +639,15 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { Schema = GetStringCatInfo(g, "DBname", Schema); Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT); - Objname = GetStringCatInfo(g, "Object", NULL); + + if ((Objname = GetStringCatInfo(g, "Object", NULL))) { + if (*Objname == '$') Objname++; + if (*Objname == '.') Objname++; + } // endif Objname + Xcol = GetStringCatInfo(g, "Expand", NULL); Pretty = GetIntCatInfo("Pretty", 2); - Limit = GetIntCatInfo("Limit", 10); + Limit = GetIntCatInfo("Limit", 50); Base = GetIntCatInfo("Base", 0) ? 1 : 0; Sep = *GetStringCatInfo(g, "Separator", "."); Accept = GetBoolCatInfo("Accept", false); @@ -647,7 +658,7 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Collname = GetStringCatInfo(g, "Name", (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); Collname = GetStringCatInfo(g, "Tabname", Collname); - Options = GetStringCatInfo(g, "Colist", NULL); + Options = GetStringCatInfo(g, "Colist", Xcol ? "all" : NULL); Filter = GetStringCatInfo(g, "Filter", NULL); Pipe = GetBoolCatInfo("Pipeline", false); Driver = GetStringCatInfo(g, "Driver", NULL); @@ -716,6 +727,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) #endif // !MONGO_SUPPORT } // endif Driver + Pretty = 4; // Not a file } else if (Zipped) { #if defined(ZIP_SUPPORT) if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) { @@ -761,7 +773,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) G->jump_level = 0; ((TDBJSN*)tdbp)->G = G; #endif // 0 - ((TDBJSN*)tdbp)->G = PlugInit(NULL, (size_t)Lrecl * (Pretty >= 0 ? 10 : 2)); + ((TDBJSN*)tdbp)->G = PlugInit(NULL, (size_t)Lrecl * (Pretty >= 0 ? 12 : 4)); } else { strcpy(g->Message, "LRECL is not defined"); return NULL; @@ -950,23 +962,29 @@ int TDBJSN::EstimatedLength(void) /***********************************************************************/ PJSON TDBJSN::FindRow(PGLOBAL g) { - char *p, *objpath; + char *p, *objpath = PlugDup(g, Objname); + char *sep = (char*)(Sep == ':' ? ":[" : ".["); + bool bp = false, b = false; PJSON jsp = Row; PJVAL val = NULL; - for (objpath = PlugDup(g, Objname); jsp && objpath; objpath = p) { - if ((p = strchr(objpath, Sep))) + for (; jsp && objpath; objpath = p, bp = b) { + if ((p = strpbrk(objpath + 1, sep))) { + b = (*p == '['); *p++ = 0; + } // endif p - if (*objpath != '[' && !IsNum(objpath)) { // objpass is a key + if (!bp && *objpath != '[' && !IsNum(objpath)) { // objpass is a key val = (jsp->GetType() == TYPE_JOB) ? jsp->GetObject()->GetKeyValue(objpath) : NULL; } else { - if (*objpath == '[') { - if (objpath[strlen(objpath) - 1] == ']') - objpath++; - else + if (bp || *objpath == '[') { + if (objpath[strlen(objpath) - 1] != ']') { + sprintf(g->Message, "Invalid Table path %s", Objname); return NULL; + } else if (!bp) + objpath++; + } // endif [ val = (jsp->GetType() == TYPE_JAR) ? @@ -976,6 +994,18 @@ PJSON TDBJSN::FindRow(PGLOBAL g) jsp = (val) ? val->GetJson() : NULL; } // endfor objpath + if (jsp && jsp->GetType() != TYPE_JOB) { + if (jsp->GetType() == TYPE_JAR) { + jsp = jsp->GetArray()->GetArrayValue(B); + + if (jsp->GetType() != TYPE_JOB) + jsp = NULL; + + } else + jsp = NULL; + + } // endif Type + return jsp; } // end of FindRow @@ -1143,25 +1173,28 @@ int TDBJSN::ReadDB(PGLOBAL g) { /***********************************************************************/ /* Make the top tree from the object path. */ /***********************************************************************/ -int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) +bool TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) { if (Objname) { if (!Val) { // Parse and allocate Objname item(s) - char *p; - char *objpath = PlugDup(g, Objname); + char *p, *objpath = PlugDup(g, Objname); + char *sep = (char*)(Sep == ':' ? ":[" : ".["); int i; + bool bp = false, b = false; PJOB objp; PJAR arp; PJVAL val = NULL; Top = NULL; - for (; objpath; objpath = p) { - if ((p = strchr(objpath, Sep))) + for (; objpath; objpath = p, bp = b) { + if ((p = strpbrk(objpath + 1, sep))) { + b = (*p == '['); *p++ = 0; + } // endif p - if (*objpath != '[' && !IsNum(objpath)) { + if (!bp && *objpath != '[' && !IsNum(objpath)) { objp = new(g) JOBJECT; if (!Top) @@ -1173,15 +1206,15 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) val = new(g) JVALUE; objp->SetKeyValue(g, val, objpath); } else { - if (*objpath == '[') { + if (bp || *objpath == '[') { // Old style if (objpath[strlen(objpath) - 1] != ']') { sprintf(g->Message, "Invalid Table path %s", Objname); - return RC_FX; - } else + return true; + } else if (!bp) objpath++; - } // endif objpath + } // endif bp arp = new(g) JARRAY; @@ -1206,7 +1239,7 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) } else Top = jsp; - return RC_OK; + return false; } // end of MakeTopTree /***********************************************************************/ @@ -1276,6 +1309,7 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) Xpd = false; Parsed = false; Warned = false; + Sgfy = false; } // end of JSONCOL constructor /***********************************************************************/ @@ -1295,6 +1329,7 @@ JSONCOL::JSONCOL(JSONCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp) Xpd = col1->Xpd; Parsed = col1->Parsed; Warned = col1->Warned; + Sgfy = col1->Sgfy; } // end of JSONCOL copy constructor /***********************************************************************/ @@ -1534,6 +1569,10 @@ bool JSONCOL::ParseJpath(PGLOBAL g) // Analyse intermediate array processing if (SetArrayOptions(g, p, i, Nodes[i - 1].Key)) return true; + else if (Xpd && Tjp->Mode == MODE_DELETE) { + strcpy(g->Message, "Cannot delete expanded columns"); + return true; + } // endif Xpd } else if (*p == '*') { // Return JSON @@ -1567,8 +1606,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) if (*p1 == '$') p1++; if (*p1 == '.') p1++; mgopath = PlugDup(g, p1); - } else + } else { + Sgfy = true; return NULL; + } // endif for (p1 = p2 = mgopath; *p1; p1++) { @@ -1607,6 +1648,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) case '*': if (*(p2 - 1) == '.' && !*(p1 + 1)) { p2--; // Suppress last :* + Sgfy = true; break; } // endif p2 /* falls through */ @@ -1615,6 +1657,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) break; } // endswitch p1; } + + if (*(p2 - 1) == '.') + p2--; + *p2 = 0; return mgopath; } else @@ -1743,10 +1789,16 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL jvp) break; case TYPE_DATE: if (jvp->GetValType() == TYPE_STRG) { - if (!((DTVAL*)vp)->IsFormatted()) - ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0); + PSZ dat = jvp->GetString(g); + + if (!IsNum(dat)) { + if (!((DTVAL*)vp)->IsFormatted()) + ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0); + + vp->SetValue_psz(dat); + } else + vp->SetValue(atoi(dat)); - vp->SetValue_psz(jvp->GetString(g)); } else vp->SetValue(jvp->GetInteger()); @@ -2125,10 +2177,14 @@ void JSONCOL::WriteColumn(PGLOBAL g) if (Nodes[Nod-1].Op == OP_XX) { s = Value->GetCharValue(); - if (!(jsp = ParseJson(G, s, strlen(s)))) { - strcpy(g->Message, s); - throw 666; - } // endif jsp + if (s && *s) { + if (!(jsp = ParseJson(G, s, strlen(s)))) { + strcpy(g->Message, s); + throw 666; + } // endif jsp + + } else + jsp = NULL; if (arp) { if (Nod > 1 && Nodes[Nod-2].Op == OP_EQ) @@ -2557,8 +2613,8 @@ int TDBJSON::WriteDB(PGLOBAL g) if (Mode == MODE_INSERT) { Doc->AddArrayValue(g, vp); Row = new(g) JOBJECT; - } else if (Doc->SetArrayValue(g, vp, Fpos)) - return RC_FX; + } else + Doc->SetArrayValue(g, vp, Fpos); } else if (Jmode == MODE_ARRAY) { PJVAL vp = new(g) JVALUE(Row); @@ -2566,15 +2622,15 @@ int TDBJSON::WriteDB(PGLOBAL g) if (Mode == MODE_INSERT) { Doc->AddArrayValue(g, vp); Row = new(g) JARRAY; - } else if (Doc->SetArrayValue(g, vp, Fpos)) - return RC_FX; + } else + Doc->SetArrayValue(g, vp, Fpos); } else { // if (Jmode == MODE_VALUE) if (Mode == MODE_INSERT) { Doc->AddArrayValue(g, (PJVAL)Row); Row = new(g) JVALUE; - } else if (Doc->SetArrayValue(g, (PJVAL)Row, Fpos)) - return RC_FX; + } else + Doc->SetArrayValue(g, (PJVAL)Row, Fpos); } // endif Jmode |