mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge branch '10.4' into 10.5
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1144,25 +1174,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)
|
||||
@@ -1174,15 +1207,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;
|
||||
|
||||
@@ -1207,7 +1240,7 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
|
||||
} else
|
||||
Top = jsp;
|
||||
|
||||
return RC_OK;
|
||||
return false;
|
||||
} // end of MakeTopTree
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -1277,6 +1310,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
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -1296,6 +1330,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
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -1535,6 +1570,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
|
||||
@@ -1568,8 +1607,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++)
|
||||
{
|
||||
@@ -1608,6 +1649,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
|
||||
case '*':
|
||||
if (*(p2 - 1) == '.' && !*(p1 + 1)) {
|
||||
p2--; // Suppress last :*
|
||||
Sgfy = true;
|
||||
break;
|
||||
} // endif p2
|
||||
/* falls through */
|
||||
@@ -1616,6 +1658,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
|
||||
break;
|
||||
} // endswitch p1;
|
||||
}
|
||||
|
||||
if (*(p2 - 1) == '.')
|
||||
p2--;
|
||||
|
||||
*p2 = 0;
|
||||
return mgopath;
|
||||
} else
|
||||
@@ -1744,10 +1790,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());
|
||||
|
||||
@@ -2126,10 +2178,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)
|
||||
@@ -2558,8 +2614,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);
|
||||
@@ -2567,15 +2623,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
|
||||
|
||||
|
Reference in New Issue
Block a user