Commit 100be0b6 authored by Olivier Bertrand's avatar Olivier Bertrand

Update JSON UDFs to version 1.04.0004

  modified:   storage/connect/json.cpp
  modified:   storage/connect/json.h
  modified:   storage/connect/jsonudf.cpp
  modified:   storage/connect/mysql-test/connect/r/json_udf.result
  modified:   storage/connect/mysql-test/connect/std_data/biblio.json
  modified:   storage/connect/mysql-test/connect/t/json_udf.inc
  modified:   storage/connect/mysql-test/connect/t/json_udf.test
  modified:   storage/connect/tabjson.cpp
parent 608ad38a
......@@ -33,10 +33,10 @@
/* Parse a json string. */
/* Note: when pretty is not known, the caller set pretty to 3. */
/***********************************************************************/
PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
{
int i, rc;
bool b = false;
int i, rc, pretty = (ptyp) ? *ptyp : 3;
bool b = false, pty[3] = {true, true, true};
PJSON jsp = NULL;
STRG src;
......@@ -49,6 +49,10 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
src.str = s;
src.len = len;
// Trying to guess the pretty format
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));
......@@ -62,26 +66,16 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
for (i = 0; i < len; i++)
switch (s[i]) {
case '[':
if (jsp) {
if (pretty && pretty < 3) {
strcpy(g->Message, "More than one item in file");
goto err;
} else
goto tryit;
} else if (!(jsp = ParseArray(g, ++i, src)))
if (jsp)
goto tryit;
else if (!(jsp = ParseArray(g, ++i, src, pty)))
goto err;
break;
case '{':
if (jsp) {
if (pretty && pretty < 3) {
strcpy(g->Message, "More than one item in file");
goto err;
} else
goto tryit;
} else if (!(jsp = ParseObject(g, ++i, src)))
if (jsp)
goto tryit;
else if (!(jsp = ParseObject(g, ++i, src, pty)))
goto err;
break;
......@@ -91,10 +85,11 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
case '\r':
break;
case ',':
if (jsp && pretty == 1) {
if (jsp && (pretty == 1 || pretty == 3)) {
if (comma)
*comma = true;
pty[0] = pty[2] = false;
break;
} // endif pretty
......@@ -110,23 +105,39 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
} // endif b
default:
if (!(jsp = ParseValue(g, i, src)))
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);
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;
tryit:
i = 0;
jsp = ParseArray(g, i, src);
g->jump_level--;
return jsp;
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--;
......@@ -136,12 +147,12 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
/***********************************************************************/
/* Parse a JSON Array. */
/***********************************************************************/
PJAR ParseArray(PGLOBAL g, int& i, STRG& src)
PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty)
{
char *s = src.str;
int len = src.len;
int level = 0;
bool pty = (!i);
bool b = (!i);
PJAR jarp = new(g) JARRAY;
PJVAL jvp = NULL;
......@@ -163,29 +174,31 @@ PJAR ParseArray(PGLOBAL g, int& i, STRG& src)
jarp->InitArray(g);
return jarp;
case ' ':
case '\n':
if (!b)
pty[0] = pty[1] = false;
case '\r':
case ' ':
case '\t':
case '\n':
case '\r':
break;
default:
if (level == 2) {
sprintf(g->Message, "Unexpected value near %.*s", ARGS);
return NULL;
} else if ((jvp = ParseValue(g, i, src)))
} else if ((jvp = ParseValue(g, i, src, pty)))
jarp->AddValue(g, jvp);
else
return NULL;
level = (pty) ? 1 : 2;
level = (b) ? 1 : 2;
break;
}; // endswitch s[i]
if (pty) {
if (b) {
// Case of Pretty == 0
jarp->InitArray(g);
return jarp;
} // endif pty
} // endif b
strcpy(g->Message, "Unexpected EOF in array");
return NULL;
......@@ -194,7 +207,7 @@ PJAR ParseArray(PGLOBAL g, int& i, STRG& src)
/***********************************************************************/
/* Parse a JSON Object. */
/***********************************************************************/
PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty)
{
PSZ key;
char *s = src.str;
......@@ -221,7 +234,7 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
break;
case ':':
if (level == 1) {
if (!(jpp->Val = ParseValue(g, ++i, src)))
if (!(jpp->Val = ParseValue(g, ++i, src, pty)))
return NULL;
level = 2;
......@@ -246,10 +259,11 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
} // endif level
return jobp;
case ' ':
case '\n':
pty[0] = pty[1] = false;
case '\r':
case ' ':
case '\t':
case '\n':
case '\r':
break;
default:
sprintf(g->Message, "Unexpected character '%c' near %.*s",
......@@ -264,7 +278,7 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
/***********************************************************************/
/* Parse a JSON Value. */
/***********************************************************************/
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty)
{
char *strval, *s = src.str;
int n, len = src.len;
......@@ -272,10 +286,11 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
for (; i < len; i++)
switch (s[i]) {
case ' ':
case '\n':
pty[0] = pty[1] = false;
case '\r':
case ' ':
case '\t':
case '\n':
case '\r':
break;
default:
goto suite;
......@@ -284,12 +299,12 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
suite:
switch (s[i]) {
case '[':
if (!(jvp->Jsp = ParseArray(g, ++i, src)))
if (!(jvp->Jsp = ParseArray(g, ++i, src, pty)))
return NULL;
break;
case '{':
if (!(jvp->Jsp = ParseObject(g, ++i, src)))
if (!(jvp->Jsp = ParseObject(g, ++i, src, pty)))
return NULL;
break;
......@@ -497,9 +512,9 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
valp = AllocateValue(g, &dv, TYPE_DOUBLE, nd);
} else {
int iv = strtol(buf, NULL, 10);
long long iv = strtoll(buf, NULL, 10);
valp = AllocateValue(g, &iv, TYPE_INT);
valp = AllocateValue(g, &iv, TYPE_BIGINT);
} // endif has
i--; // Unstack following character
......@@ -543,18 +558,18 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty)
jp = new(g)JOUTPRT(g, fs);
} else {
// Serialize to a flat file
jp = new(g)JOUTFILE(g, fs);
b = pretty == 1;
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->WriteChr('\t'));
err = ((b && jp->Prty()) && jp->WriteChr('\t'));
err |= SerializeObject(jp, (PJOB)jsp);
break;
case TYPE_JVAL:
......@@ -565,7 +580,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty)
} // endswitch Type
if (fs) {
fputc('\n', fs);
fputs(EL, fs);
fclose(fs);
return (err) ? g->Message : NULL;
} else if (!err) {
......@@ -590,29 +605,40 @@ bool SerializeArray(JOUT *js, PJAR jarp, bool b)
{
bool first = true;
if (b) {
if (js->Prty()) {
if (js->WriteChr('['))
return true;
else if (js->Prty() == 1 && (js->WriteStr(EL) || js->WriteChr('\t')))
return true;
if (js->WriteChr('['))
return true;
else if (b && (js->WriteStr(EL) || js->WriteChr('\t')))
return true;
} // endif Prty
} else if (js->WriteChr('['))
return true;
for (int i = 0; i < jarp->size(); i++) {
if (first)
first = false;
else if (js->WriteChr(','))
return true;
else if (b && (js->WriteStr(EL) || js->WriteChr('\t')))
else if ((!b || js->Prty()) && js->WriteChr(','))
return true;
else if (b) {
if (js->Prty() < 2 && js->WriteStr(EL))
return true;
else if (js->Prty() == 1 && js->WriteChr('\t'))
return true;
} // endif b
if (SerializeValue(js, jarp->GetValue(i)))
return true;
} // endfor i
if (b && js->WriteStr(EL))
if (b && js->Prty() == 1 && js->WriteStr(EL))
return true;
return js->WriteChr(']');
return ((!b || js->Prty()) && js->WriteChr(']'));
} // end of SerializeArray
/***********************************************************************/
......@@ -672,8 +698,8 @@ bool SerializeValue(JOUT *js, PJVAL jvp)
} // endswitch Type
strcpy(js->g->Message, "Unrecognized value");
return true;
strcpy(js->g->Message, "Unrecognized value");
return true;
} // end of SerializeValue
/* -------------------------- Class JOUTSTR -------------------------- */
......@@ -1262,6 +1288,16 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
void JVALUE::SetInteger(PGLOBAL g, int n)
{
Value = AllocateValue(g, &n, TYPE_INT);
Jsp = NULL;
} // end of SetInteger
/***********************************************************************/
/* Set the Value's Boolean value as a tiny integer. */
/***********************************************************************/
void JVALUE::SetTiny(PGLOBAL g, char n)
{
Value = AllocateValue(g, &n, TYPE_TINY);
Jsp = NULL;
} // end of SetInteger
/***********************************************************************/
......@@ -1270,6 +1306,7 @@ void JVALUE::SetInteger(PGLOBAL g, int n)
void JVALUE::SetBigint(PGLOBAL g, long long ll)
{
Value = AllocateValue(g, &ll, TYPE_BIGINT);
Jsp = NULL;
} // end of SetBigint
/***********************************************************************/
......@@ -1278,6 +1315,7 @@ void JVALUE::SetBigint(PGLOBAL g, long long ll)
void JVALUE::SetFloat(PGLOBAL g, double f)
{
Value = AllocateValue(g, &f, TYPE_DOUBLE, 6);
Jsp = NULL;
} // end of SetFloat
/***********************************************************************/
......@@ -1286,6 +1324,7 @@ void JVALUE::SetFloat(PGLOBAL g, double f)
void JVALUE::SetString(PGLOBAL g, PSZ s, short c)
{
Value = AllocateValue(g, s, TYPE_STRING, c);
Jsp = NULL;
} // end of SetString
/***********************************************************************/
......
......@@ -41,10 +41,10 @@ typedef struct {
int len;
} STRG, *PSG;
PJSON ParseJson(PGLOBAL g, char *s, int n, int prty = 2, bool *b = NULL);
PJAR ParseArray(PGLOBAL g, int& i, STRG& src);
PJOB ParseObject(PGLOBAL g, int& i, STRG& src);
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src);
PJSON ParseJson(PGLOBAL g, char *s, int n, int *prty = NULL, bool *b = NULL);
PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty);
PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty);
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty);
char *ParseString(PGLOBAL g, int& i, STRG& src);
PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src);
PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty);
......@@ -57,14 +57,16 @@ bool SerializeValue(JOUT *js, PJVAL jvp);
/***********************************************************************/
class JOUT : public BLOCK {
public:
JOUT(PGLOBAL gp) : BLOCK() {g = gp;}
JOUT(PGLOBAL gp) : BLOCK() {g = gp; Pretty = 3;}
virtual bool WriteStr(const char *s) = 0;
virtual bool WriteChr(const char c) = 0;
virtual bool Escape(const char *s) = 0;
int Prty(void) {return Pretty;}
// Member
PGLOBAL g;
int Pretty;
}; // end of class JOUT
/***********************************************************************/
......@@ -89,7 +91,7 @@ class JOUTSTR : public JOUT {
/***********************************************************************/
class JOUTFILE : public JOUT {
public:
JOUTFILE(PGLOBAL g, FILE *str) : JOUT(g) {Stream = str;}
JOUTFILE(PGLOBAL g, FILE *str, int pty) : JOUT(g) {Stream = str; Pretty = pty;}
virtual bool WriteStr(const char *s);
virtual bool WriteChr(const char c);
......@@ -104,7 +106,7 @@ class JOUTFILE : public JOUT {
/***********************************************************************/
class JOUTPRT : public JOUTFILE {
public:
JOUTPRT(PGLOBAL g, FILE *str) : JOUTFILE(g, str) {M = 0; B = false;}
JOUTPRT(PGLOBAL g, FILE *str) : JOUTFILE(g, str, 2) {M = 0; B = false;}
virtual bool WriteStr(const char *s);
virtual bool WriteChr(const char c);
......@@ -120,7 +122,7 @@ class JOUTPRT : public JOUTFILE {
class JPAIR : public BLOCK {
friend class JOBJECT;
friend class JSNX;
friend PJOB ParseObject(PGLOBAL, int&, STRG&);
friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeObject(JOUT *, PJOB);
public:
JPAIR(PSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;}
......@@ -182,7 +184,7 @@ class JSON : public BLOCK {
/* Class JOBJECT: contains a list of value pairs. */
/***********************************************************************/
class JOBJECT : public JSON {
friend PJOB ParseObject(PGLOBAL, int&, STRG&);
friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeObject(JOUT *, PJOB);
friend class JSNX;
public:
......@@ -212,7 +214,7 @@ class JOBJECT : public JSON {
/* Class JARRAY. */
/***********************************************************************/
class JARRAY : public JSON {
friend PJAR ParseArray(PGLOBAL, int&, STRG&);
friend PJAR ParseArray(PGLOBAL, int&, STRG&, bool*);
public:
JARRAY(void) : JSON() {Alloc = 0; First = Last = NULL; Mvals = NULL;}
......@@ -243,7 +245,7 @@ class JARRAY : public JSON {
class JVALUE : public JSON {
friend class JARRAY;
friend class JSNX;
friend PJVAL ParseValue(PGLOBAL, int&, STRG&);
friend PJVAL ParseValue(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeValue(JOUT *, PJVAL);
public:
JVALUE(void) : JSON()
......@@ -269,13 +271,14 @@ class JVALUE : public JSON {
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 SetValue(PVAL valp) {Value = valp; Jsp = NULL;}
virtual void SetValue(PJSON jsp) {Jsp = jsp; Value = NULL;}
virtual void SetString(PGLOBAL g, PSZ s, short c = 0);
virtual void SetInteger(PGLOBAL g, int n);
virtual void SetBigint(PGLOBAL g, longlong ll);
virtual void SetFloat(PGLOBAL g, double f);
virtual bool IsNull(void);
virtual void SetTiny(PGLOBAL g, char f);
virtual bool IsNull(void);
protected:
PJSON Jsp; // To the json value
......
......@@ -117,7 +117,7 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
if (b) {
// Return 1st value (B is the index base)
jnp->Rank = B;
jnp->Op = OP_EQ;
jnp->Op = OP_LE;
} else if (!Value->IsTypeNum()) {
jnp->CncVal = AllocateValue(g, (void*)", ", TYPE_STRING);
jnp->Op = OP_CNC;
......@@ -359,10 +359,16 @@ PJVAL JSNX::GetValue(PGLOBAL g, PJSON row, int i, my_bool b)
case TYPE_JOB:
if (!Nodes[i].Key) {
// Expected Array was not there
if (i < Nod-1)
continue;
else
val = new(g) JVALUE(row);
if (Nodes[i].Op == OP_LE) {
if (i < Nod-1)
continue;
else
val = new(g)JVALUE(row);
} else {
strcpy(g->Message, "Unexpected object");
val = NULL;
} //endif Op
} else
val = ((PJOB)row)->GetValue(Nodes[i].Key);
......@@ -372,7 +378,7 @@ PJVAL JSNX::GetValue(PGLOBAL g, PJSON row, int i, my_bool b)
arp = (PJAR)row;
if (!Nodes[i].Key) {
if (Nodes[i].Op == OP_EQ)
if (Nodes[i].Op == OP_EQ || Nodes[i].Op == OP_LE)
val = arp->GetValue(Nodes[i].Rank);
else if (Nodes[i].Op == OP_EXP)
return (PJVAL)ExpandArray(g, arp, i);
......@@ -805,6 +811,7 @@ struct BSON {
int Pretty;
ulong Reslen;
my_bool Changed;
PJSON Top;
PJSON Jsp;
PBSON Bsp;
}; // end of struct BSON
......@@ -822,7 +829,7 @@ static PBSON JbinAlloc(PGLOBAL g, UDF_ARGS *args, ulong len, PJSON jsp)
bsp->Pretty = 2;
bsp->Reslen = len;
bsp->Changed = false;
bsp->Jsp = jsp;
bsp->Top = bsp->Jsp = jsp;
bsp->Bsp = (IsJson(args, 0) == 3) ? (PBSON)args->args[0] : NULL;
return bsp;
} /* end of JbinAlloc */
......@@ -894,21 +901,28 @@ static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
/*********************************************************************************/
/* Check if a path was specified and set jvp according to it. */
/*********************************************************************************/
static my_bool CheckPath(PGLOBAL g, UDF_ARGS *args, PJSON top, PJVAL& jvp, int n)
static my_bool CheckPath(PGLOBAL g, UDF_ARGS *args, PJSON jsp, PJVAL& jvp, int n)
{
for (uint i = n; i < args->arg_count; i++)
if (args->arg_type[i] == STRING_RESULT) {
if (args->arg_type[i] == STRING_RESULT && args->args[i]) {
// A path to a subset of the json tree is given
char *path = MakePSZ(g, args, i);
PJSNX jsx = new(g) JSNX(g, top, TYPE_STRING);
if (jsx->SetJpath(g, path))
return true;
if (path) {
PJSNX jsx = new(g)JSNX(g, jsp, TYPE_STRING);
if (jsx->SetJpath(g, path))
return true;
if (!(jvp = jsx->GetJson(g))) {
sprintf(g->Message, "No sub-item at '%s'", path);
return true;
} // endif jvp
if (!(jvp = jsx->GetJson(g))) {
sprintf(g->Message, "No sub-item at '%s'", path);
} else {
strcpy(g->Message, "Path argument is null");
return true;
} // endif jvp
} // endif path
break;
} // endif type
......@@ -919,7 +933,7 @@ static my_bool CheckPath(PGLOBAL g, UDF_ARGS *args, PJSON top, PJVAL& jvp, int n
/*********************************************************************************/
/* Make the result according to the first argument type. */
/*********************************************************************************/
static char *MakeResult(PGLOBAL g, UDF_ARGS *args, PJSON top, int n = 2)
static char *MakeResult(PGLOBAL g, UDF_ARGS *args, PJSON top, uint n = 2)
{
char *str;
......@@ -976,14 +990,19 @@ static PBSON MakeBinResult(PGLOBAL g, UDF_ARGS *args, PJSON top, ulong len, int
} // endif type
bsnp->Pretty = pretty;
bsnp->Filename = (char*)args->args[0];
strncpy(bsnp->Msg, (char*)args->args[0], BMX);
if (bsnp->Filename = (char*)args->args[0])
strncpy(bsnp->Msg, (char*)args->args[0], BMX);
else
strncpy(bsnp->Msg, "null filename", BMX);
} else if (IsJson(args, 0) == 3) {
PBSON bsp = (PBSON)args->args[0];
if (bsp->Filename) {
bsnp->Filename = bsp->Filename;
strncpy(bsnp->Msg, bsp->Filename, BMX);
bsnp->Pretty = bsp->Pretty;
} else
strcpy(bsnp->Msg, "Json Binary item");
......@@ -993,6 +1012,27 @@ static PBSON MakeBinResult(PGLOBAL g, UDF_ARGS *args, PJSON top, ulong len, int
return bsnp;
} // end of MakeBinResult
/*********************************************************************************/
/* Returns a pointer to the first integer argument found from the nth argument. */
/*********************************************************************************/
static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n)
{
int *x = NULL;
for (uint i = n; i < args->arg_count; i++)
if (args->arg_type[i] == INT_RESULT) {
if (args->args[i]) {
x = (int*)PlugSubAlloc(g, NULL, sizeof(int));
*x = (int)*(longlong*)args->args[i];
} // endif args
n = i + 1;
break;
} // endif arg_type
return x;
} // end of GetIntArgPtr
/*********************************************************************************/
/* Returns not 0 if the argument is a JSON item or file name. */
/*********************************************************************************/
......@@ -1002,8 +1042,8 @@ static int IsJson(UDF_ARGS *args, uint i)
if (i >= args->arg_count || args->arg_type[i] != STRING_RESULT) {
} else if (!strnicmp(args->attributes[i], "Json_", 5)) {
if (!args->args[i] || *args->args[i] == '[' || *args->args[i] == '{')
n = 1; // arg is a json item
if (!args->args[i] || strchr("[{ \t\r\n", *args->args[i]))
n = 1; // arg should be is a json item
else
n = 2; // A file name may have been returned
......@@ -1256,6 +1296,58 @@ static PSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
return "Key";
} // end of MakeKey
/*********************************************************************************/
/* Parse a json file. */
/*********************************************************************************/
static PJSON ParseJsonFile(PGLOBAL g, char *fn, int *pretty, int& len)
{
char *memory;
HANDLE hFile;
MEMMAP mm;
PJSON jsp;
/*******************************************************************************/
/* Create the mapping file object. */
/*******************************************************************************/
hFile = CreateFileMap(g, fn, &mm, MODE_READ, false);
if (hFile == INVALID_HANDLE_VALUE) {
DWORD rc = GetLastError();
if (!(*g->Message))
sprintf(g->Message, MSG(OPEN_MODE_ERROR), "map", (int)rc, fn);
return NULL;
} // endif hFile
/*******************************************************************************/
/* Get the file size (assuming file is smaller than 4 GB) */
/*******************************************************************************/
len = mm.lenL;
memory = (char *)mm.memory;
if (!len) { // Empty or deleted file
CloseFileHandle(hFile);
return NULL;
} // endif len
if (!memory) {
CloseFileHandle(hFile);
sprintf(g->Message, MSG(MAP_VIEW_ERROR), fn, GetLastError());
return NULL;
} // endif Memory
CloseFileHandle(hFile); // Not used anymore
/*********************************************************************************/
/* Parse the json file and allocate its tree structure. */
/*********************************************************************************/
g->Message[0] = 0;
jsp = ParseJson(g, memory, len, pretty);
CloseMemMap(memory, len);
return jsp;
} // end of ParseJsonFile
/*********************************************************************************/
/* Return a json file contains. */
/*********************************************************************************/
......@@ -1292,7 +1384,7 @@ static char *GetJsonFile(PGLOBAL g, char *fn)
/*********************************************************************************/
/* Make a JSON value from the passed argument. */
/*********************************************************************************/
static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, uint i)
static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, uint i, PJSON *top = NULL)
{
char *sap = (args->arg_count > i) ? args->args[i] : NULL;
int n, len;
......@@ -1301,6 +1393,9 @@ static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, uint i)
PJSON jsp;
PJVAL jvp = new(g) JVALUE;
if (top)
*top = NULL;
if (sap) switch (args->arg_type[i]) {
case STRING_RESULT:
if ((len = args->lengths[i])) {
......@@ -1309,17 +1404,25 @@ static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, uint i)
if (n) {
if (n == 3) {
if (top)
*top = ((PBSON)sap)->Top;
jsp = ((PBSON)sap)->Jsp;
} else {
if (n == 2) {
if (!(sap = GetJsonFile(g, sap)))
if (!(sap = GetJsonFile(g, sap))) {
PUSH_WARNING(g->Message);
return jvp;
} // endif sap
len = (sap) ? strlen(sap) : 0;
len = strlen(sap);
} // endif n
if (!(jsp = ParseJson(g, sap, len, 3)))
if (!(jsp = ParseJson(g, sap, strlen(sap))))
PUSH_WARNING(g->Message);
else if (top)
*top = jsp;
} // endif's n
if (jsp && jsp->GetType() == TYPE_JVAL)
......@@ -1338,10 +1441,11 @@ static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, uint i)
case INT_RESULT:
bigint = *(long long*)sap;
if (bigint > INT_MAX32 || bigint < INT_MIN32)
jvp->SetFloat(g, (double)bigint);
if ((bigint == 0LL && !strcmp(args->attributes[i], "FALSE")) ||
(bigint == 1LL && !strcmp(args->attributes[i], "TRUE")))
jvp->SetTiny(g, (char)bigint);
else
jvp->SetInteger(g, (int)bigint);
jvp->SetBigint(g, bigint);
break;
case REAL_RESULT:
......@@ -1367,7 +1471,7 @@ my_bool jsonvalue_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count > 1) {
strcpy(message, "jsonvalue cannot accept more than 1 argument");
strcpy(message, "Cannot accept more than 1 argument");
return true;
} else
CalcLen(args, false, reslen, memlen);
......@@ -1459,10 +1563,10 @@ my_bool json_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "json_array_add_values must have at least 2 arguments");
strcpy(message, "This function must have at least 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "json_array_add_values first argument must be a json string");
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "First argument must be a json string or item");
return true;
} else
CalcLen(args, false, reslen, memlen);
......@@ -1478,9 +1582,20 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false)) {
char *p;
PJSON top;
PJAR arp;
PJVAL jvp = MakeValue(g, args, 0);
PJVAL jvp = MakeValue(g, args, 0, &top);
if ((p = jvp->GetString())) {
if (!(top = ParseJson(g, p, strlen(p)))) {
PUSH_WARNING(g->Message);
return NULL;
} // endif jsp
jvp->SetValue(top);
} // endif p
if (jvp->GetValType() != TYPE_JAR) {
arp = new(g)JARRAY;
arp->AddValue(g, jvp);
......@@ -1491,7 +1606,8 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
arp->AddValue(g, MakeValue(g, args, i));
arp->InitArray(g);
str = Serialize(g, arp, NULL, 0);
// str = Serialize(g, arp, NULL, 0);
str = MakeResult(g, args, top, args->arg_count);
} // endif CheckMemory
if (!str) {
......@@ -1526,10 +1642,10 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "json_array_add must have at least 2 arguments");
strcpy(message, "This function must have at least 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "json_array_add first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
......@@ -1538,7 +1654,7 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} // end of json_array_add_init
char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *, char *error)
unsigned long *res_length, char *is_null, char *error)
{
char *str = NULL;
PGLOBAL g = (PGLOBAL)initid->ptr;
......@@ -1546,30 +1662,21 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (g->Xchk) {
// This constant function was recalled
str = (char*)g->Xchk;
*res_length = strlen(str);
return str;
goto fin;
} // endif Xchk
if (!CheckMemory(g, initid, args, 2, false, true)) {
int *x = NULL, n = 2;
PJSON top;
int *x;
uint n = 2;
PJSON jsp, top;
PJVAL jvp;
PJAR arp;
jvp = MakeValue(g, args, 0);
top = jvp->GetJson();
if (args->arg_count > 2) {
if (args->arg_type[2] == INT_RESULT) {
x = (int*)PlugSubAlloc(g, NULL, sizeof(int));
*x = (int)*(longlong*)args->args[2];
n = 3;
} else if (!args->args[2])
n = 3;
} // endif count
jvp = MakeValue(g, args, 0, &top);
jsp = jvp->GetJson();
x = GetIntArgPtr(g, args, n);
if (CheckPath(g, args, top, jvp, n))
if (CheckPath(g, args, jsp, jvp, 2))
PUSH_WARNING(g->Message);
else if (jvp && jvp->GetValType() == TYPE_JAR) {
arp = jvp->GetArray();
......@@ -1577,8 +1684,8 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
arp->InitArray(g);
str = MakeResult(g, args, top, n);
} else {
PUSH_WARNING("First argument is not an array");
if (g->Mrr) *error = 1;
PUSH_WARNING("First argument target is not an array");
// if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
} // endif CheckMemory
......@@ -1591,7 +1698,13 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
// Keep result of constant function
g->Xchk = str;
*res_length = strlen(str);
fin:
if (!str) {
*res_length = 0;
*is_null = 1;
} else
*res_length = strlen(str);
return str;
} // end of json_array_add
......@@ -1608,13 +1721,10 @@ my_bool json_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "json_array_delete must have at lest 2 arguments");
strcpy(message, "This function must have at least 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "json_array_delete first argument must be a json item");
return true;
} else if (args->arg_type[1] != INT_RESULT) {
strcpy(message, "json_array_delete second argument is not an integer (index)");
strcpy(message, "First argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
......@@ -1636,22 +1746,24 @@ char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
} // endif Xchk
if (!CheckMemory(g, initid, args, 1, false, true)) {
int n;
int *x;
uint n = 1;
PJSON top;
PJAR arp;
PJVAL jvp = MakeValue(g, args, 0);
PJSON top = jvp->GetJson();
PJVAL jvp = MakeValue(g, args, 0, &top);
if (CheckPath(g, args, top, jvp, 2))
if (!(x = GetIntArgPtr(g, args, n)))
PUSH_WARNING("Missing or null array index");
else if (CheckPath(g, args, jvp->GetJson(), jvp, 1))
PUSH_WARNING(g->Message);
else if (jvp && jvp->GetValType() == TYPE_JAR) {
n = *(int*)args->args[1];
arp = jvp->GetArray();
arp->DeleteValue(n);
arp->DeleteValue(*x);
arp->InitArray(g);
str = MakeResult(g, args, top);
str = MakeResult(g, args, top, n);
} else {
PUSH_WARNING("First argument is not an array");
if (g->Mrr) *error = 1;
PUSH_WARNING("First argument target is not an array");
// if (g->Mrr) *error = 1;
} // endif jvp
} // endif CheckMemory
......@@ -1772,10 +1884,10 @@ my_bool json_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "json_object_add must have at least 2 arguments");
strcpy(message, "This function must have at least 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "json_object_add first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
......@@ -1798,10 +1910,13 @@ char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!CheckMemory(g, initid, args, 2, false, true)) {
PJOB jobp;
PJVAL jvp = MakeValue(g, args, 0);
PJSON top = jvp->GetJson();
PJVAL jvp;
PJSON jsp, top;
if (CheckPath(g, args, top, jvp, 2))
jvp = MakeValue(g, args, 0, &top);
jsp = jvp->GetJson();
if (CheckPath(g, args, jsp, jvp, 2))
PUSH_WARNING(g->Message);
else if (jvp && jvp->GetValType() == TYPE_JOB) {
jobp = jvp->GetObject();
......@@ -1810,8 +1925,8 @@ char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
jobp->SetValue(g, jvp, key);
str = MakeResult(g, args, top);
} else {
PUSH_WARNING("First argument is not an object");
if (g->Mrr) *error = 1;
PUSH_WARNING("First argument target is not an object");
// if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
} // endif CheckMemory
......@@ -1841,13 +1956,13 @@ my_bool json_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "json_object_delete must have 2 or 3 arguments");
strcpy(message, "This function must have 2 or 3 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "json_object_delete first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else if (args->arg_type[1] != STRING_RESULT) {
strcpy(message, "json_object_delete second argument must be a key string");
strcpy(message, "Second argument must be a key string");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
......@@ -1871,10 +1986,12 @@ char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!CheckMemory(g, initid, args, 1, false, true)) {
char *key;
PJOB jobp;
PJVAL jvp = MakeValue(g, args, 0);
PJSON top = jvp->GetJson();
PJSON jsp, top;
PJVAL jvp = MakeValue(g, args, 0, &top);
if (CheckPath(g, args, top, jvp, 2))
jsp = jvp->GetJson();
if (CheckPath(g, args, jsp, jvp, 2))
PUSH_WARNING(g->Message);
else if (jvp && jvp->GetValType() == TYPE_JOB) {
key = MakeKey(g, args, 1);
......@@ -1882,8 +1999,8 @@ char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
jobp->DeleteKey(key);
str = MakeResult(g, args, top);
} else {
PUSH_WARNING("First argument is not an object");
if (g->Mrr) *error = 1;
PUSH_WARNING("First argument target is not an object");
// if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
} // endif CheckMemory
......@@ -1913,10 +2030,10 @@ my_bool json_object_list_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count != 1) {
strcpy(message, "json_object_list must have 1 arguments");
strcpy(message, "This function must have 1 argument");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "json_object_list argument must be a json item");
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "Argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen);
......@@ -1932,11 +2049,21 @@ char *json_object_list(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->N) {
if (!CheckMemory(g, initid, args, 1, false)) {
char *p;
PJSON jsp;
PJVAL jvp = MakeValue(g, args, 0);
if (jvp && jvp->GetValType() == TYPE_JOB) {
PJOB jobp = jvp->GetObject();
PJAR jarp = jobp->GetKeyList(g);
if ((p = jvp->GetString())) {
if (!(jsp = ParseJson(g, p, strlen(p)))) {
PUSH_WARNING(g->Message);
return NULL;
} // endif jsp
} else
jsp = jvp->GetJson();
if (jsp->GetType() == TYPE_JOB) {
PJAR jarp = ((PJOB)jsp)->GetKeyList(g);
if (!(str = Serialize(g, jarp, NULL, 0)))
PUSH_WARNING(g->Message);
......@@ -1979,10 +2106,10 @@ my_bool json_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen, n = GetJsonGrpSize();
if (args->arg_count != 1) {
strcpy(message, "json_array_grp can only accept 1 argument");
strcpy(message, "This function can only accept 1 argument");
return true;
} else if (IsJson(args, 0) == 3) {
strcpy(message, "Json_Array_Grp does not support Jbin argument");
strcpy(message, "This function does not support Jbin arguments");
return true;
} else
CalcLen(args, false, reslen, memlen);
......@@ -2051,11 +2178,11 @@ my_bool json_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, n = GetJsonGrpSize();
if (args->arg_count != 2) {
strcpy(message, "json_object_grp can only accept 2 arguments");
if (args->arg_count != 2) {
strcpy(message, "This function requires 2 arguments (value, key)");
return true;
} else if (IsJson(args, 0) == 3) {
strcpy(message, "json_object_grp does not support Jbin arguments");
strcpy(message, "This function does not support Jbin arguments");
return true;
} else
CalcLen(args, true, reslen, memlen);
......@@ -2079,8 +2206,9 @@ void json_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PJOB objp = (PJOB)g->Activityp;
if (g->N-- > 0)
objp->SetValue(g, MakeValue(g, args, 0), MakePSZ(g, args, 1));
if (g->N-- > 0)
objp->SetValue(g, MakeValue(g, args, 0),
(args->arg_count == 1) ? MakeKey(g, args, 0) : MakePSZ(g, args, 1));
} // end of json_object_grp_add
......@@ -2123,13 +2251,13 @@ my_bool json_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "json_item_merge must have at least 2 arguments");
strcpy(message, "This function must have at least 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "json_item_merge first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else if (!IsJson(args, 1)) {
strcpy(message, "json_item_merge second argument must be a json item");
strcpy(message, "Second argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
......@@ -2203,10 +2331,10 @@ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
int n = IsJson(args, 0);
if (args->arg_count < 2) {
strcpy(message, "json_get_item must have at least 2 arguments");
strcpy(message, "This function must have at least 2 arguments");
return true;
} else if (!n && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "json_get_item first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else if (args->arg_type[1] != STRING_RESULT) {
strcpy(message, "Second argument is not a string (jpath)");
......@@ -2235,7 +2363,7 @@ char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
str = (char*)g->Xchk;
str = (char*)g->Activityp;
goto fin;
} else if (initid->const_item)
g->N = 1;
......@@ -2252,7 +2380,6 @@ char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if ((p = jvp->GetString())) {
if (!(jsp = ParseJson(g, p, strlen(p)))) {
PUSH_WARNING(g->Message);
return NULL;
} // endif jsp
......@@ -2283,7 +2410,7 @@ char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (initid->const_item)
// Keep result of constant function
g->Xchk = str;
g->Activityp = (PACTIVITY)str;
} // endif CheckMemory
......@@ -2307,20 +2434,28 @@ void json_get_item_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jsonget_string_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
unsigned long reslen, memlen, more = 1024;
int n = IsJson(args, 0);
if (args->arg_count < 2) {
strcpy(message, "jsonget_string must have at least 2 arguments");
strcpy(message, "At least 2 arguments required");
return true;
} else if (!n && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "jsonget_string first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else if (args->arg_type[1] != STRING_RESULT) {
strcpy(message, "Second argument is not a string (jpath)");
return true;
} else
CalcLen(args, false, reslen, memlen);
} else if (args->arg_count > 2) {
if (args->arg_type[2] == INT_RESULT && args->args[2])
more += (unsigned long)*(long long*)args->args[2];
else
strcpy(message, "Third argument is not an integer (memory)");
} // endif's
CalcLen(args, false, reslen, memlen);
memlen += more;
if (n == 2) {
char fn[_MAX_PATH];
......@@ -2339,11 +2474,12 @@ my_bool jsonget_string_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *)
{
int rc;
char *str = NULL;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
str = (char*)g->Xchk;
str = (char*)g->Activityp;
goto fin;
} else if (initid->const_item)
g->N = 1;
......@@ -2354,14 +2490,26 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
PJSNX jsx;
PJVAL jvp;
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
PUSH_WARNING(MSG(TOO_MANY_JUMPS));
*is_null = 1;
return NULL;
} // endif jump_level
if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
PUSH_WARNING(g->Message);
str = NULL;
goto err;
} // endif rc
if (!g->Xchk) {
jvp = MakeValue(g, args, 0);
if ((p = jvp->GetString())) {
if (!(jsp = ParseJson(g, p, strlen(p)))) {
PUSH_WARNING(g->Message);
return NULL;
goto err;
} // endif jsp
} else
......@@ -2380,8 +2528,7 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return NULL;
goto err;
} // endif SetJpath
jsx->ReadValue(g);
......@@ -2391,8 +2538,10 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (initid->const_item)
// Keep result of constant function
g->Xchk = str;
g->Activityp = (PACTIVITY)str;
err:
g->jump_level--;
} // endif CheckMemory
fin:
......@@ -2418,10 +2567,10 @@ my_bool jsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count != 2) {
strcpy(message, "jsonget_int must have 2 arguments");
strcpy(message, "This function must have 2 arguments");
return true;
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "jsonget_int first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else if (args->arg_type[1] != STRING_RESULT) {
strcpy(message, "Second argument is not a (jpath) string");
......@@ -2441,11 +2590,11 @@ long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (!g->Xchk) {
if (!g->Activityp) {
*is_null = 1;
return 0LL;
} else
return *(long long*)g->Xchk;
return *(long long*)g->Activityp;
} else if (initid->const_item)
g->N = 1;
......@@ -2502,7 +2651,7 @@ long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
// Keep result of constant function
long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
*np = n;
g->Xchk = np;
g->Activityp = (PACTIVITY)np;
} // endif const_item
return n;
......@@ -2526,10 +2675,10 @@ my_bool jsonget_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "jsonget_real must have at least 2 arguments");
strcpy(message, "At least 2 arguments required");
return true;
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "jsonget_real first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else if (args->arg_type[1] != STRING_RESULT) {
strcpy(message, "Second argument is not a (jpath) string");
......@@ -2558,11 +2707,11 @@ double jsonget_real(UDF_INIT *initid, UDF_ARGS *args,
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (!g->Xchk) {
if (!g->Activityp) {
*is_null = 1;
return 0.0;
} else
return *(double*)g->Xchk;
return *(double*)g->Activityp;
} else if (initid->const_item)
g->N = 1;
......@@ -2618,7 +2767,7 @@ double jsonget_real(UDF_INIT *initid, UDF_ARGS *args,
// Keep result of constant function
double *dp = (double*)PlugSubAlloc(g, NULL, sizeof(double));
*dp = d;
g->Xchk = dp;
g->Activityp = (PACTIVITY)dp;
} // endif const_item
return d;
......@@ -2642,10 +2791,10 @@ my_bool jsonlocate_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen, more = 1000;
if (args->arg_count < 2) {
strcpy(message, "jsonlocate must have at least 2 arguments");
strcpy(message, "At least 2 arguments required");
return true;
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "jsonlocate first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else if (args->arg_count > 2 && args->arg_type[2] != INT_RESULT) {
strcpy(message, "Third argument is not an integer (rank)");
......@@ -2672,15 +2821,15 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (g->Xchk) {
path = (char*)g->Xchk;
if (g->Activityp) {
path = (char*)g->Activityp;
*res_length = strlen(path);
return path;
} else {
*res_length = 0;
*is_null = 1;
return NULL;
} // endif Xchk
} // endif Activityp
} else if (initid->const_item)
g->N = 1;
......@@ -2737,7 +2886,7 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (initid->const_item)
// Keep result of constant function
g->Xchk = path;
g->Activityp = (PACTIVITY)path;
err:
g->jump_level--;
......@@ -2769,10 +2918,10 @@ my_bool json_locate_all_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen, more = 1000;
if (args->arg_count < 2) {
strcpy(message, "json_locate_all must have at least 2 arguments");
strcpy(message, "At least 2 arguments required");
return true;
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "json_locate_all first argument must be a json item");
strcpy(message, "First argument must be a json item");
return true;
} else if (args->arg_count > 2 && args->arg_type[2] != INT_RESULT) {
strcpy(message, "Third argument is not an integer (Depth)");
......@@ -2799,8 +2948,8 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (g->Xchk) {
path = (char*)g->Xchk;
if (g->Activityp) {
path = (char*)g->Activityp;
*res_length = strlen(path);
return path;
} else {
......@@ -2808,7 +2957,7 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
*res_length = 0;
*is_null = 1;
return NULL;
} // endif Xchk
} // endif Activityp
} else if (initid->const_item)
g->N = 1;
......@@ -2866,7 +3015,7 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (initid->const_item)
// Keep result of constant function
g->Xchk = path;
g->Activityp = (PACTIVITY)path;
err:
g->jump_level--;
......@@ -2898,34 +3047,34 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen, fl, more = 1024;
if (args->arg_count < 1 || args->arg_count > 4) {
strcpy(message, "json_file only accepts 1 to 4 arguments");
strcpy(message, "This function only accepts 1 to 4 arguments");
return true;
} else if (args->arg_type[0] != STRING_RESULT) {
strcpy(message, "json_file first argument must be a (string) file name");
return true;
} else if (args->arg_count > 1 && args->arg_type[1] != INT_RESULT) {
strcpy(message, "Second argument is not an integer (check)");
return true;
} else if (args->arg_count > 2 && args->arg_type[2] != INT_RESULT) {
strcpy(message, "Third argument is not an integer (pretty)");
} else if (!args->args[0] || args->arg_type[0] != STRING_RESULT) {
strcpy(message, "First argument must be a constant string (file name)");
return true;
} else if (args->arg_count > 3) {
if (args->arg_type[3] != INT_RESULT) {
strcpy(message, "Fourth argument is not an integer (memory)");
} // endif's args[0]
for (unsigned int i = 1; i < args->arg_count; i++) {
if (!(args->arg_type[i] == INT_RESULT || args->arg_type[i] == STRING_RESULT)) {
sprintf(message, "Argument %d is not an integer or a string (pretty or path)", i);
return true;
} else
more += (ulong)*(longlong*)args->args[2];
} // endif arg_type
} // endifs
// Take care of eventual memory argument
if (args->arg_type[i] == INT_RESULT && args->args[i])
more += (ulong)*(longlong*)args->args[i];
} // endfor i
initid->maybe_null = 1;
CalcLen(args, false, reslen, memlen);
fl = GetFileLength(args->args[0]);
reslen += fl;
if (initid->const_item)
more += fl;
if (args->arg_count > 1 && *(longlong*)args->args[1])
if (args->arg_count > 1)
more += fl * M;
memlen += more;
......@@ -2947,68 +3096,40 @@ char *json_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
PlugSubSet(g, g->Sarea, g->Sarea_Size);
fn = MakePSZ(g, args, 0);
if (args->arg_count > 1 && *(longlong*)args->args[1]) {
char *memory;
int len, pretty;
HANDLE hFile;
MEMMAP mm;
if (args->arg_count > 1) {
int len, pretty, pty = 3;
PJSON jsp;
PJVAL jvp = NULL;
pretty = (args->arg_count > 2) ? (int)*(longlong*)args->args[2] : 3;
/*****************************************************************************/
/* Create the mapping file object. */
/*****************************************************************************/
hFile = CreateFileMap(g, fn, &mm, MODE_READ, false);
if (hFile == INVALID_HANDLE_VALUE) {
DWORD rc = GetLastError();
if (!(*g->Message))
sprintf(g->Message, MSG(OPEN_MODE_ERROR), "map", (int)rc, fn);
PUSH_WARNING(g->Message);
if (g->Mrr) *error = 1;
*is_null = 1;
return NULL;
} // endif hFile
/*****************************************************************************/
/* Get the file size (assuming file is smaller than 4 GB) */
/*****************************************************************************/
len = mm.lenL;
memory = (char *)mm.memory;
if (!len) { // Empty or deleted file
CloseFileHandle(hFile);
*is_null = 1;
return NULL;
} // endif len
if (!memory) {
CloseFileHandle(hFile);
sprintf(g->Message, MSG(MAP_VIEW_ERROR), fn, GetLastError());
PUSH_WARNING(g->Message);
*is_null = 1;
return NULL;
} // endif Memory
CloseFileHandle(hFile); // Not used anymore
hFile = INVALID_HANDLE_VALUE; // For Fblock
pretty = (args->arg_type[1] == INT_RESULT) ? (int)*(longlong*)args->args[1]
: (args->arg_count > 2 && args->arg_type[2] == INT_RESULT)
? (int)*(longlong*)args->args[2] : 3;
/*******************************************************************************/
/* Parse the json file and allocate its tree structure. */
/*******************************************************************************/
g->Message[0] = 0;
if (!(jsp = ParseJson(g, memory, len, pretty))) {
if (!(jsp = ParseJsonFile(g, fn, &pty, len))) {
PUSH_WARNING(g->Message);
str = NULL;
goto fin;
} // endif jsp
CloseMemMap(memory, len);
if (pty == 3)
PUSH_WARNING("File pretty format cannot be determined");
else if (pretty != 3 && pty != pretty)
PUSH_WARNING("File pretty format doesn't match the specified pretty value");
else if (pretty == 3)
pretty = pty;
if (jsp && !(str = Serialize(g, jsp, NULL, 0)))
// Check whether a path was specified
if (CheckPath(g, args, jsp, jvp, 1)) {
PUSH_WARNING(g->Message);
str = NULL;
goto fin;
} else if (jvp)
jsp = jvp->GetJson();
if (!(str = Serialize(g, jsp, NULL, 0)))
PUSH_WARNING(g->Message);
} else
......@@ -3040,19 +3161,13 @@ my_bool jfile_make_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, more = 1024;
if (args->arg_count < 2 || args->arg_count > 3) {
strcpy(message, "jfile_make only accepts 2 or 3 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "jfile_make first argument must be a json item");
return true;
} else if (args->arg_type[1] != STRING_RESULT) {
strcpy(message, "Second argument must be a (string) file name");
if (args->arg_count < 1 || args->arg_count > 3) {
strcpy(message, "Wrong number of arguments");
return true;
} else if (args->arg_count > 2 && args->arg_type[2] != INT_RESULT) {
strcpy(message, "Third argument is not an integer (pretty)");
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "First argument must be a json item");
return true;
} // endifs
} // endif
CalcLen(args, false, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen);
......@@ -3061,22 +3176,51 @@ my_bool jfile_make_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *jfile_make(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *)
{
char *str, *fn, *msg;
int pretty;
char *p, *str, *msg, *fn = NULL;
int n, pretty = 2;
PJSON jsp;
PJVAL jvp;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
str = (char*)g->Xchk;
str = (char*)g->Activityp;
goto fin;
} else if (initid->const_item)
g->N = 1;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
if ((n = IsJson(args, 0)) == 3) {
// Get default file name and pretty
PBSON bsp = (PBSON)args->args[0];
fn = bsp->Filename;
pretty = bsp->Pretty;
} else if (n == 2)
fn = args->args[0];
if (!g->Xchk) {
jvp = MakeValue(g, args, 0);
if ((p = jvp->GetString())) {
if (!strchr("[{ \t\r\n", *p)) {
// Is this a file name?
if (!(p = GetJsonFile(g, p))) {
PUSH_WARNING(g->Message);
return NULL;
} else
fn = jvp->GetString();
} // endif p
if (!(jsp = ParseJson(g, p, strlen(p)))) {
PUSH_WARNING(g->Message);
return NULL;
} // endif jsp
jvp->SetValue(jsp);
} // endif p
if (g->Mrr) { // First argument is a constant
g->Xchk = jvp;
JsonMemSave(g);
......@@ -3085,17 +3229,27 @@ char *jfile_make(UDF_INIT *initid, UDF_ARGS *args, char *result,
} else
jvp = (PJVAL)g->Xchk;
fn = MakePSZ(g, args, 1);
pretty = (args->arg_count > 2) ? (int)*(longlong*)args->args[2] : 2;
for (uint i = 1; i < args->arg_count; i++)
switch (args->arg_type[i]) {
case STRING_RESULT:
fn = MakePSZ(g, args, i);
break;
case INT_RESULT:
pretty = (int)*(longlong*)args->args[i];
break;
} // endswitch arg_type
if ((msg = Serialize(g, jvp->GetJson(), fn, pretty)))
PUSH_WARNING(msg);
if (fn) {
if ((msg = Serialize(g, jvp->GetJson(), fn, pretty)))
PUSH_WARNING(msg);
} else
PUSH_WARNING("Missing file name");
str= fn;
if (initid->const_item)
// Keep result of constant function
g->Xchk = str;
g->Activityp = (PACTIVITY)str;
fin:
if (!str) {
......@@ -3162,18 +3316,7 @@ void jbin_array_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "jbin_array_add_values must have at least 2 arguments");
return true;
} else if (IsJson(args, 0) != 1) {
strcpy(message, "jbin_array_add_values first argument must be a json string");
return true;
} else
CalcLen(args, false, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen);
return json_array_add_values_init(initid, args, message);
} // end of jbin_array_add_values_init
char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
......@@ -3184,8 +3327,19 @@ char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false)) {
char *p;
PJSON top;
PJAR arp;
PJVAL jvp = MakeValue(g, args, 0);
PJVAL jvp = MakeValue(g, args, 0, &top);
if ((p = jvp->GetString())) {
if (!(top = ParseJson(g, p, strlen(p)))) {
PUSH_WARNING(g->Message);
return NULL;
} // endif jsp
jvp->SetValue(top);
} // endif p
if (jvp->GetValType() != TYPE_JAR) {
arp = new(g)JARRAY;
......@@ -3197,8 +3351,9 @@ char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
arp->AddValue(g, MakeValue(g, args, i));
arp->InitArray(g);
bsp = JbinAlloc(g, args, initid->max_length, arp);
bsp = JbinAlloc(g, args, initid->max_length, top);
strcat(bsp->Msg, " array");
bsp->Jsp = arp;
} else {
bsp = JbinAlloc(g, args, initid->max_length, NULL);
strncpy(bsp->Msg, g->Message, BMX);
......@@ -3222,18 +3377,7 @@ void jbin_array_add_values_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "jbin_array_add must have at least 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "jbin_array_add first argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
return JsonInit(initid, args, message, true, reslen, memlen);
return json_array_add_init(initid, args, message);
} // end of jbin_array_add_init
char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
......@@ -3252,21 +3396,14 @@ char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!CheckMemory(g, initid, args, 2, false, true)) {
int *x = NULL;
uint n = 2;
PJSON jsp;
PJVAL jvp;
PJAR arp;
jvp = MakeValue(g, args, 0);
top = jvp->GetJson();
if (args->arg_count > 2) {
if (args->arg_type[2] == INT_RESULT) {
x = (int*)PlugSubAlloc(g, NULL, sizeof(int));
*x = (int)*(longlong*)args->args[2];
n = 3;
} else if (!args->args[2])
n = 3;
} // endif count
jvp = MakeValue(g, args, 0, &top);
jsp = jvp->GetJson();
x = GetIntArgPtr(g, args, n);
if (CheckPath(g, args, top, jvp, n))
PUSH_WARNING(g->Message);
......@@ -3276,7 +3413,7 @@ char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
arp->InitArray(g);
} else {
PUSH_WARNING("First argument is not an array");
if (g->Mrr) *error = 1;
// if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
} // endif CheckMemory
......@@ -3302,21 +3439,7 @@ void jbin_array_add_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "jbin_array_delete must have at lest 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "jbin_array_delete first argument must be a json item");
return true;
} else if (args->arg_type[1] != INT_RESULT) {
strcpy(message, "jbin_array_delete second argument is not an integer (index)");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
return JsonInit(initid, args, message, true, reslen, memlen);
return json_array_delete_init(initid, args, message);
} // end of jbin_array_delete_init
char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
......@@ -3333,19 +3456,21 @@ char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
} // endif bsp
if (!CheckMemory(g, initid, args, 1, false, true)) {
int n;
int *x;
uint n = 1;
PJAR arp;
PJVAL jvp = MakeValue(g, args, 0);
PJVAL jvp = MakeValue(g, args, 0, &top);
top = jvp->GetJson();
if (CheckPath(g, args, top, jvp, 2))
if (CheckPath(g, args, top, jvp, 1))
PUSH_WARNING(g->Message);
else if (jvp && jvp->GetValType() == TYPE_JAR) {
n = *(int*)args->args[1];
arp = jvp->GetArray();
arp->DeleteValue(n);
arp->InitArray(g);
if ((x = GetIntArgPtr(g, args, n))) {
arp = jvp->GetArray();
arp->DeleteValue(*x);
arp->InitArray(g);
} else
PUSH_WARNING("Missing or null array index");
} else {
PUSH_WARNING("First argument is not an array");
if (g->Mrr) *error = 1;
......@@ -3464,18 +3589,7 @@ void jbin_object_nonull_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "jbin_object_add must have at least 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "jbin_object_add first argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
return JsonInit(initid, args, message, true, reslen, memlen);
return json_object_add_init(initid, args, message);
} // end of jbin_object_add_init
char *jbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
......@@ -3495,11 +3609,10 @@ char *jbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!CheckMemory(g, initid, args, 2, false, true)) {
char *key;
PJOB jobp;
PJVAL jvp = MakeValue(g, args, 0);
top = jvp->GetJson();
PJVAL jvp = MakeValue(g, args, 0, &top);
PJSON jsp = jvp->GetJson();
if (CheckPath(g, args, top, jvp, 2))
if (CheckPath(g, args, jsp, jvp, 2))
PUSH_WARNING(g->Message);
else if (jvp && jvp->GetValType() == TYPE_JOB) {
jobp = jvp->GetObject();
......@@ -3507,8 +3620,8 @@ char *jbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
key = MakeKey(g, args, 1);
jobp->SetValue(g, jvp, key);
} else {
PUSH_WARNING("First argument is not an object");
if (g->Mrr) *error = 1;
PUSH_WARNING("First argument target is not an object");
// if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
} // endif CheckMemory
......@@ -3534,21 +3647,7 @@ void jbin_object_add_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "jbin_object_delete must have 2 or 3 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "jbin_object_delete first argument must be a json item");
return true;
} else if (args->arg_type[1] != STRING_RESULT) {
strcpy(message, "jbin_object_delete second argument must be a key string");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
return JsonInit(initid, args, message, true, reslen, memlen);
return json_object_delete_init(initid, args, message);
} // end of jbin_object_delete_init
char *jbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
......@@ -3568,9 +3667,8 @@ char *jbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!CheckMemory(g, initid, args, 1, false, true)) {
char *key;
PJOB jobp;
PJVAL jvp = MakeValue(g, args, 0);
top = jvp->GetJson();
PJVAL jvp = MakeValue(g, args, 0, &top);
PJSON jsp = jvp->GetJson();
if (CheckPath(g, args, top, jvp, 2))
PUSH_WARNING(g->Message);
......@@ -3579,8 +3677,8 @@ char *jbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
jobp = jvp->GetObject();
jobp->DeleteKey(key);
} else {
PUSH_WARNING("First argument is not an object");
if (g->Mrr) *error = 1;
PUSH_WARNING("First argument target is not an object");
// if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
} // endif CheckMemory
......@@ -3606,18 +3704,7 @@ void jbin_object_delete_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_object_list_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
if (args->arg_count != 1) {
strcpy(message, "jbin_object_list must have 1 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "jbin_object_list argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen);
return JsonInit(initid, args, message, false, reslen, memlen);
return json_object_list_init(initid, args, message);
} // end of jbin_object_list_init
char *jbin_object_list(UDF_INIT *initid, UDF_ARGS *args, char *result,
......@@ -3629,16 +3716,25 @@ char *jbin_object_list(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, 1, false)) {
char *p;
PJSON jsp;
PJVAL jvp = MakeValue(g, args, 0);
if (jvp && jvp->GetValType() == TYPE_JOB) {
PJOB jobp = jvp->GetObject();
if ((p = jvp->GetString())) {
if (!(jsp = ParseJson(g, p, strlen(p)))) {
PUSH_WARNING(g->Message);
return NULL;
} // endif jsp
} else
jsp = jvp->GetJson();
jarp = jobp->GetKeyList(g);
if (jsp->GetType() == TYPE_JOB) {
jarp = ((PJOB)jsp)->GetKeyList(g);
} else {
PUSH_WARNING("First argument is not an object");
if (g->Mrr) *error = 1;
} // endif jvp
} // endif jsp type
} // endif CheckMemory
......@@ -3663,33 +3759,7 @@ void jbin_object_list_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
int n = IsJson(args, 0);
if (args->arg_count < 2) {
strcpy(message, "jbin_get_item must have at least 2 arguments");
return true;
} else if (!n && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "jbin_get_item first argument must be a json item");
return true;
} else if (args->arg_type[1] != STRING_RESULT) {
strcpy(message, "Second argument is not a string (jpath)");
return true;
} else
CalcLen(args, false, reslen, memlen);
if (n == 2) {
char fn[_MAX_PATH];
long fl;
memcpy(fn, args->args[0], args->lengths[0]);
fn[args->lengths[0]] = 0;
fl = GetFileLength(fn);
memlen += fl * 3;
} else if (n != 3)
memlen += args->lengths[0] * 3;
return JsonInit(initid, args, message, true, reslen, memlen);
return json_get_item_init(initid, args, message);
} // end of jbin_get_item_init
char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
......@@ -3699,7 +3769,7 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
PBSON bsp = NULL;
if (g->N) {
bsp = (PBSON)g->Xchk;
bsp = (PBSON)g->Activityp;
goto fin;
} else if (initid->const_item)
g->N = 1;
......@@ -3716,7 +3786,6 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if ((p = jvp->GetString())) {
if (!(jsp = ParseJson(g, p, strlen(p)))) {
PUSH_WARNING(g->Message);
return NULL;
} // endif jsp
......@@ -3750,7 +3819,7 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (initid->const_item)
// Keep result of constant function
g->Xchk = bsp;
g->Activityp = (PACTIVITY)bsp;
} // endif CheckMemory
......@@ -3774,21 +3843,7 @@ void jbin_get_item_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jbin_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "jbin_item_merge must have at least 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "jbin_item_merge first argument must be a json item");
return true;
} else if (!IsJson(args, 1)) {
strcpy(message, "jbin_item_merge second argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen, true);
return JsonInit(initid, args, message, true, reslen, memlen);
return json_item_merge_init(initid, args, message);
} // end of jbin_item_merge_init
char *jbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
......@@ -3806,7 +3861,7 @@ char *jbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!CheckMemory(g, initid, args, 2, false, true)) {
PJVAL jvp;
PJSON jsp[2] ={ NULL, NULL };
PJSON jsp[2] = {NULL, NULL};
for (int i = 0; i < 2; i++) {
jvp = MakeValue(g, args, i);
......@@ -3820,13 +3875,8 @@ char *jbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
} // endfor i
if (jsp[0]) {
if (jsp[0]->Merge(g, jsp[1]))
PUSH_WARNING(g->Message);
else
MakeBinResult(g, args, top, initid->max_length);
} // endif jsp
if (jsp[0] && jsp[0]->Merge(g, jsp[1]))
PUSH_WARNING(g->Message);
} // endif CheckMemory
......@@ -3853,27 +3903,31 @@ my_bool jbin_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, fl, more = 1024;
if (args->arg_count < 1 || args->arg_count > 3) {
strcpy(message, "jbin_file only accepts 1 to 3 arguments");
if (args->arg_count < 1 || args->arg_count > 4) {
strcpy(message, "This function only accepts 1 to 4 arguments");
return true;
} else if (args->arg_type[0] != STRING_RESULT || !args->args[0]) {
strcpy(message, "jbin_file first argument must be a constant string (file name)");
strcpy(message, "First argument must be a constant string (file name)");
return true;
} else if (args->arg_count > 1 && args->arg_type[1] != INT_RESULT) {
strcpy(message, "Second argument is not an integer (pretty)");
} else if (args->arg_count > 1 && args->arg_type[1] != STRING_RESULT) {
strcpy(message, "Second argument is not a string (path)");
return true;
} else if (args->arg_count > 2) {
if (args->arg_type[2] != INT_RESULT) {
strcpy(message, "Third argument is not an integer (memory)");
} else if (args->arg_count > 2 && args->arg_type[2] != INT_RESULT) {
strcpy(message, "Third argument is not an integer (pretty)");
return true;
} else if (args->arg_count > 3) {
if (args->arg_type[3] != INT_RESULT) {
strcpy(message, "Fourth argument is not an integer (memory)");
return true;
} else
more += (ulong)*(longlong*)args->args[2];
more += (ulong)*(longlong*)args->args[3];
} // endifs
initid->maybe_null = 1;
CalcLen(args, false, reslen, memlen);
fl = GetFileLength(args->args[0]);
reslen += fl;
more += fl * M;
memlen += more;
return JsonInit(initid, args, message, false, reslen, memlen);
......@@ -3882,11 +3936,10 @@ my_bool jbin_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
char *fn, *memory;
int len, pretty;
HANDLE hFile;
MEMMAP mm;
char *fn;
int pretty, len = 0, pty = 3;
PJSON jsp;
PJVAL jvp = NULL;
PGLOBAL g = (PGLOBAL)initid->ptr;
PBSON bsp = (PBSON)g->Xchk;
......@@ -3896,68 +3949,36 @@ char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
fn = MakePSZ(g, args, 0);
pretty = (args->arg_count > 1) ? (int)*(longlong*)args->args[1] : 3;
/*******************************************************************************/
/* Create the mapping file object. */
/*******************************************************************************/
hFile = CreateFileMap(g, fn, &mm, MODE_READ, false);
if (hFile == INVALID_HANDLE_VALUE) {
DWORD rc = GetLastError();
if (!(*g->Message))
sprintf(g->Message, MSG(OPEN_MODE_ERROR), "map", (int)rc, fn);
PUSH_WARNING(g->Message);
if (g->Mrr) *error = 1;
*is_null = 1;
return NULL;
} // endif hFile
/*******************************************************************************/
/* Get the file size (assuming file is smaller than 4 GB) */
/*******************************************************************************/
len = mm.lenL;
memory = (char *)mm.memory;
if (!len) { // Empty or deleted file
CloseFileHandle(hFile);
*is_null = 1;
return NULL;
} // endif len
if (!memory) {
CloseFileHandle(hFile);
sprintf(g->Message, MSG(MAP_VIEW_ERROR), fn, GetLastError());
PUSH_WARNING(g->Message);
*is_null = 1;
if (g->Mrr) *error = 1;
return NULL;
} // endif Memory
CloseFileHandle(hFile); // Not used anymore
hFile = INVALID_HANDLE_VALUE; // For Fblock
pretty = (args->arg_count > 2 && args->args[2]) ? (int)*(longlong*)args->args[2] : 3;
/*********************************************************************************/
/* Parse the json file and allocate its tree structure. */
/*********************************************************************************/
g->Message[0] = 0;
if (!(jsp = ParseJson(g, memory, len, pretty))) {
if (!(jsp = ParseJsonFile(g, fn, &pty, len))) {
PUSH_WARNING(g->Message);
if (g->Mrr) *error = 1;
} // endif jsp
*error = 1;
goto fin;
} // endif jsp
CloseMemMap(memory, len);
if (pty == 3)
PUSH_WARNING("File pretty format cannot be determined");
else if (pretty != 3 && pty != pretty)
PUSH_WARNING("File pretty format doesn't match the specified pretty value");
else if (pretty == 3)
pretty = pty;
if (jsp) {
bsp = JbinAlloc(g, args, len, jsp);
strcat(bsp->Msg, " file");
bsp->Filename = fn;
bsp->Pretty = pretty;
} else
bsp = JbinAlloc(g, args, len, jsp);
strcat(bsp->Msg, " file");
bsp->Filename = fn;
bsp->Pretty = pretty;
// Check whether a path was specified
if (CheckPath(g, args, jsp, jvp, 1)) {
PUSH_WARNING(g->Message);
bsp = NULL;
goto fin;
} else if (jvp)
bsp->Jsp = jvp->GetJsp();
if (initid->const_item)
// Keep result of constant function
......@@ -3986,10 +4007,10 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
unsigned long reslen, memlen;
if (args->arg_count != 1) {
strcpy(message, "json_serialize must have 1 argument");
strcpy(message, "This function must have 1 argument");
return true;
} else if (IsJson(args, 0) != 3) {
strcpy(message, "json_serialize argument must be a Jbin tree");
strcpy(message, "Argument must be a Jbin tree");
return true;
} else
CalcLen(args, false, reslen, memlen);
......
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=VIR BLOCK_SIZE=5;
#
# Test UDF's with constant arguments
#
SELECT JsonValue(56,3.1416,'foo',NULL);
ERROR HY000: Can't initialize function 'jsonvalue'; Cannot accept more than 1 argument
SELECT JsonValue(3.1416);
JsonValue(3.1416)
3.141600
SELECT JsonValue('foo');
JsonValue('foo')
"foo"
SELECT JsonValue(9223372036854775807);
JsonValue(9223372036854775807)
9223372036854775807
SELECT JsonValue(NULL);
JsonValue(NULL)
null
SELECT JsonValue(TRUE);
JsonValue(TRUE)
true
SELECT JsonValue(FALSE);
JsonValue(FALSE)
false
SELECT JsonValue();
JsonValue()
null
SELECT JsonValue('[11,22,33]' json_) FROM t1;
JsonValue('[11,22,33]' json_)
[11,22,33]
[11,22,33]
[11,22,33]
[11,22,33]
[11,22,33]
SELECT Json_Array();
Json_Array()
[]
SELECT Json_Object(56,3.1416,'foo',NULL);
Json_Object(56,3.1416,'foo',NULL)
{"56":56,"3.1416":3.141600,"foo":"foo","NULL":null}
SELECT Json_Object(56 qty,3.1416 price,'foo' truc, NULL garanty);
Json_Object(56 qty,3.1416 price,'foo' truc, NULL garanty)
{"qty":56,"price":3.141600,"truc":"foo","garanty":null}
SELECT Json_Array(56,3.1416,'My name is "Foo"',NULL);
Json_Array(56,3.1416,'My name is "Foo"',NULL)
[56,3.141600,"My name is \"Foo\"",null]
SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL);
Json_Array(Json_Array(56,3.1416,'foo'),NULL)
[[56,3.141600,"foo"],null]
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL)) Array;
ERROR HY000: Can't initialize function 'json_array_add'; json_array_add must have at least 2 arguments
ERROR HY000: Can't initialize function 'json_array_add'; This function must have at least 2 arguments
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL),'One more') Array;
Array
[56,3.141600,"foo",null,"One more"]
SELECT Json_Array_Add(JsonValue('one value'),'One more');
ERROR HY000: Can't initialize function 'json_array_add'; json_array_add first argument must be a json item
ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
SELECT Json_Array_Add('one value','One more');
ERROR HY000: Can't initialize function 'json_array_add'; json_array_add first argument must be a json item
ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
SELECT Json_Array_Add('one value' json_,'One more');
Json_Array_Add('one value' json_,'One more')
NULL
one value
Warnings:
Warning 1105 Error 2 opening one value
Warning 1105 Void JSON object
Warning 1105 First argument is not an array
SELECT JsonValue(56,3.1416,'foo',NULL);
ERROR HY000: Can't initialize function 'jsonvalue'; jsonvalue cannot accept more than 1 argument
SELECT JsonValue(3.1416);
JsonValue(3.1416)
3.141600
SELECT JsonValue('foo');
JsonValue('foo')
"foo"
SELECT JsonValue(NULL);
JsonValue(NULL)
null
SELECT JsonValue();
JsonValue()
null
Warning 1105 First argument target is not an array
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
Json_Array_Add('[5,3,8,7,9]' json_, 4, 0)
[4,5,3,8,7,9]
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;
Array
[5,3,4,8,7,9]
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 9);
Json_Array_Add('[5,3,8,7,9]' json_, 4, 9)
[5,3,8,7,9,4]
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
Array
[56,3.141600,"machin",null,"One more","Two more"]
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
Array
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), n) Array FROM t1;
Array
[56,3.141600,"machin",1]
[56,3.141600,"machin",2]
[56,3.141600,"machin",3]
[56,3.141600,"machin",4]
[56,3.141600,"machin",5]
SELECT Json_Array_Add_Values(Json_Array(n, 3.1416, 'machin'), n) Array FROM t1;
Array
[1,3.141600,"machin",1]
[2,3.141600,"machin",2]
[3,3.141600,"machin",3]
[4,3.141600,"machin",4]
[5,3.141600,"machin",5]
SELECT Json_Array_Add_Values('[56]', 3.1416, 'machin') Array;
Array
[56,3.141600,"machin"]
SELECT Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),0);
Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),0)
[3.141600,"My name is \"Foo\"",null]
SELECT Json_Array_Delete(Json_Object(56,3.1416,'My name is Foo',NULL),2);
Json_Array_Delete(Json_Object(56,3.1416,'My name is Foo',NULL),2)
{"56":56,"3.1416":3.141600,"My name is Foo":"My name is Foo","NULL":null}
Warnings:
Warning 1105 First argument target is not an array
SELECT Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),'2');
Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),'2')
[56,3.141600,"My name is \"Foo\"",null]
Warnings:
Warning 1105 Missing or null array index
SELECT Json_Object(56, 3.1416, 'foo', NULL);
Json_Object(56, 3.1416, 'foo', NULL)
{"56":56,"3.1416":3.141600,"foo":"foo","NULL":null}
SELECT Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty)
{"qty":56,"price":3.141600,"truc":"foo","garanty":null}
SELECT Json_Object();
Json_Object()
{}
SELECT Json_Object(Json_Array(56,3.1416,'foo'),NULL);
Json_Object(Json_Array(56,3.1416,'foo'),NULL)
{"Array(56,3.1416,'foo')":[56,3.141600,"foo"],"NULL":null}
SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL);
Json_Array(Json_Array(56,3.1416,'foo'),NULL)
[[56,3.141600,"foo"],null]
SELECT Json_Array(Json_Object(56 "qty",3.1416 "price",'foo'),NULL);
Json_Array(Json_Object(56 "qty",3.1416 "price",'foo'),NULL)
SELECT Json_Object(Json_Array(56, 3.1416, 'foo'), NULL);
Json_Object(Json_Array(56, 3.1416, 'foo'), NULL)
{"Array(56, 3.1416, 'foo')":[56,3.141600,"foo"],"NULL":null}
SELECT Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL)
[{"qty":56,"price":3.141600,"foo":"foo"},null]
SELECT Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'blue' color);
Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'blue' color)
{"qty":56,"price":3.141600,"truc":"machin","garanty":null,"color":"blue"}
SELECT Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 45.99 price);
Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 45.99 price)
{"qty":56,"price":45.990000,"truc":"machin","garanty":null}
SELECT Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'truc');
Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'truc')
{"qty":56,"price":3.141600,"garanty":null}
SELECT Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'chose');
Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'chose')
{"qty":56,"price":3.141600,"truc":"machin","garanty":null}
SELECT Json_Object_List(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty)) "Key List";
Key List
["qty","price","truc","garanty"]
SELECT Json_Object_List('{"qty":56, "price":3.1416, "truc":"machin", "garanty":null}') "Key List";
Key List
["qty","price","truc","garanty"]
#
# Test UDF's with column arguments
#
CREATE TABLE t1
CREATE TABLE t2
(
ISBN CHAR(15),
LANG CHAR(2),
......@@ -70,21 +153,20 @@ TRANSLATOR CHAR(80),
PUBLISHER CHAR(32),
DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t1;
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
Json_Array(AUTHOR, TITLE, DATEPUB)
["Jean-Christophe Bernadac","Construire une application XML",1999]
["William J. Pardi","XML en Action",1999]
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t1;
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
Json_Object(AUTHOR, TITLE, DATEPUB)
{"AUTHOR":"Jean-Christophe Bernadac","TITLE":"Construire une application XML","DATEPUB":1999}
{"AUTHOR":"William J. Pardi","TITLE":"XML en Action","DATEPUB":1999}
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t1;
ERROR HY000: Can't initialize function 'json_array_grp'; json_array_grp can only accept 1 argument
SELECT Json_Array_Grp(TITLE) FROM t1;
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t2;
ERROR HY000: Can't initialize function 'json_array_grp'; This function can only accept 1 argument
SELECT Json_Array_Grp(TITLE) FROM t2;
Json_Array_Grp(TITLE)
["Construire une application XML","XML en Action"]
DROP TABLE t1;
CREATE TABLE t1 (
CREATE TABLE t3 (
SERIALNO CHAR(5) NOT NULL,
NAME VARCHAR(12) NOT NULL FLAG=6,
SEX SMALLINT(1) NOT NULL,
......@@ -94,10 +176,10 @@ DEPARTMENT CHAr(4) NOT NULL FLAG=41,
SECRETARY CHAR(5) DEFAULT NULL FLAG=46,
SALARY DOUBLE(8,2) NOT NULL FLAG=52
) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1;
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t1 WHERE NAME = 'MERCHANT';
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
Json_Object(SERIALNO, NAME, TITLE, SALARY)
{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000}
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t1 GROUP BY DEPARTMENT;
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t3 GROUP BY DEPARTMENT;
DEPARTMENT Json_Array_Grp(NAME)
0021 ["STRONG","SHORTSIGHT"]
0318 ["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]
......@@ -105,26 +187,26 @@ DEPARTMENT Json_Array_Grp(NAME)
2452 ["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]
Warnings:
Warning 1105 Result truncated to json_grp_size values
set connect_json_grp_size=30;
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t1 GROUP BY DEPARTMENT;
SET connect_json_grp_size=30;
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
Json_Array(DEPARTMENT, Json_Array_Grp(NAME))
["0021",["STRONG","SHORTSIGHT"]]
["0318",["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]]
["0319",["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]]
["2452",["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]]
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES)
{"DEPARTMENT":"0021","NAMES":["STRONG","SHORTSIGHT"]}
{"DEPARTMENT":"0318","NAMES":["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]}
{"DEPARTMENT":"0319","NAMES":["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]}
{"DEPARTMENT":"2452","NAMES":["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]}
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES)
{"DEPARTMENT":"0021","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","TITLE":"DIRECTOR","SALARY":23000.000000},{"SERIALNO":"22222","NAME":"SHORTSIGHT","TITLE":"SECRETARY","SALARY":5500.000000}]}
{"DEPARTMENT":"0318","EMPLOYES":[{"SERIALNO":"74200","NAME":"BANCROFT","TITLE":"SALESMAN","SALARY":9600.000000},{"SERIALNO":"24888","NAME":"PLUMHEAD","TITLE":"TYPIST","SALARY":2800.000000},{"SERIALNO":"27845","NAME":"HONEY","TITLE":"SECRETARY","SALARY":4900.000000},{"SERIALNO":"73452","NAME":"TONGHO","TITLE":"ENGINEER","SALARY":6800.000000},{"SERIALNO":"74234","NAME":"WALTER","TITLE":"ENGINEER","SALARY":7400.000000},{"SERIALNO":"77777","NAME":"SHRINKY","TITLE":"ADMINISTRATOR","SALARY":7500.000000},{"SERIALNO":"70012","NAME":"WERTHER","TITLE":"DIRECTOR","SALARY":14500.000000},{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000},{"SERIALNO":"73111","NAME":"WHEELFOR","TITLE":"SALESMAN","SALARY":10030.000000}]}
{"DEPARTMENT":"0319","EMPLOYES":[{"SERIALNO":"76543","NAME":"BULLOZER","TITLE":"SALESMAN","SALARY":14800.000000},{"SERIALNO":"40567","NAME":"QUINN","TITLE":"DIRECTOR","SALARY":14000.000000},{"SERIALNO":"00137","NAME":"BROWNY","TITLE":"ENGINEER","SALARY":10500.000000},{"SERIALNO":"12345","NAME":"KITTY","TITLE":"TYPIST","SALARY":3000.450000},{"SERIALNO":"33333","NAME":"MONAPENNY","TITLE":"SECRETARY","SALARY":3800.000000},{"SERIALNO":"00023","NAME":"MARTIN","TITLE":"ENGINEER","SALARY":10000.000000},{"SERIALNO":"07654","NAME":"FUNNIGUY","TITLE":"ADMINISTRATOR","SALARY":8500.000000},{"SERIALNO":"45678","NAME":"BUGHAPPY","TITLE":"PROGRAMMER","SALARY":8500.000000},{"SERIALNO":"56789","NAME":"FODDERMAN","TITLE":"SALESMAN","SALARY":7000.000000},{"SERIALNO":"55555","NAME":"MESSIFUL","TITLE":"SECRETARY","SALARY":5000.500000},{"SERIALNO":"98765","NAME":"GOOSEPEN","TITLE":"ADMINISTRATOR","SALARY":4700.000000}]}
{"DEPARTMENT":"2452","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","TITLE":"SCIENTIST","SALARY":8000.000000},{"SERIALNO":"31416","NAME":"ORELLY","TITLE":"ENGINEER","SALARY":13400.000000},{"SERIALNO":"36666","NAME":"BIGHORN","TITLE":"SCIENTIST","SALARY":11000.000000},{"SERIALNO":"02345","NAME":"SMITH","TITLE":"ENGINEER","SALARY":9000.000000},{"SERIALNO":"11111","NAME":"CHERRY","TITLE":"SECRETARY","SALARY":4500.000000}]}
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT, TITLE;
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES)
{"DEPARTMENT":"0021","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","SALARY":23000.000000}]}
{"DEPARTMENT":"0021","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"22222","NAME":"SHORTSIGHT","SALARY":5500.000000}]}
......@@ -144,25 +226,372 @@ Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY
{"DEPARTMENT":"2452","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"31416","NAME":"ORELLY","SALARY":13400.000000},{"SERIALNO":"02345","NAME":"SMITH","SALARY":9000.000000}]}
{"DEPARTMENT":"2452","TITLE":"SCIENTIST","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","SALARY":8000.000000},{"SERIALNO":"36666","NAME":"BIGHORN","SALARY":11000.000000}]}
{"DEPARTMENT":"2452","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"11111","NAME":"CHERRY","SALARY":4500.000000}]}
SELECT Json_Object_Grp(SALARY) FROM t1;
ERROR HY000: Can't initialize function 'json_object_grp'; json_object_grp can only accept 2 arguments
SELECT Json_Object_Grp(SALARY, NAME) FROM t1;
SELECT Json_Object_Grp(SALARY) FROM t3;
ERROR HY000: Can't initialize function 'json_object_grp'; This function requires 2 arguments (value, key)
SELECT Json_Object_Grp(SALARY, NAME) FROM t3;
Json_Object_Grp(SALARY, NAME)
{"BANCROFT":9600.000000,"SMITH":9000.000000,"MERCHANT":8700.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"BIGHEAD":8000.000000,"SHRINKY":7500.000000,"WALTER":7400.000000,"FODDERMAN":7000.000000,"TONGHO":6800.000000,"SHORTSIGHT":5500.000000,"MESSIFUL":5000.500000,"HONEY":4900.000000,"GOOSEPEN":4700.000000,"CHERRY":4500.000000,"MONAPENNY":3800.000000,"KITTY":3000.450000,"PLUMHEAD":2800.000000,"STRONG":23000.000000,"BULLOZER":14800.000000,"WERTHER":14500.000000,"QUINN":14000.000000,"ORELLY":13400.000000,"BIGHORN":11000.000000,"BROWNY":10500.000000,"WHEELFOR":10030.000000,"MARTIN":10000.000000}
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES")
{"DEPARTMENT":"0021","SALARIES":{"STRONG":23000.000000,"SHORTSIGHT":5500.000000}}
{"DEPARTMENT":"0318","SALARIES":{"BANCROFT":9600.000000,"PLUMHEAD":2800.000000,"HONEY":4900.000000,"TONGHO":6800.000000,"WALTER":7400.000000,"SHRINKY":7500.000000,"WERTHER":14500.000000,"MERCHANT":8700.000000,"WHEELFOR":10030.000000}}
{"DEPARTMENT":"0319","SALARIES":{"BULLOZER":14800.000000,"QUINN":14000.000000,"BROWNY":10500.000000,"KITTY":3000.450000,"MONAPENNY":3800.000000,"MARTIN":10000.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"FODDERMAN":7000.000000,"MESSIFUL":5000.500000,"GOOSEPEN":4700.000000}}
{"DEPARTMENT":"2452","SALARIES":{"BIGHEAD":8000.000000,"ORELLY":13400.000000,"BIGHORN":11000.000000,"SMITH":9000.000000,"CHERRY":4500.000000}}
SELECT Json_Array_Grp(NAME) from t1;
SELECT Json_Array_Grp(NAME) FROM t3;
Json_Array_Grp(NAME)
["BANCROFT","SMITH","MERCHANT","FUNNIGUY","BUGHAPPY","BIGHEAD","SHRINKY","WALTER","FODDERMAN","TONGHO","SHORTSIGHT","MESSIFUL","HONEY","GOOSEPEN","CHERRY","MONAPENNY","KITTY","PLUMHEAD","STRONG","BULLOZER","WERTHER","QUINN","ORELLY","BIGHORN","BROWNY","WHEELFOR","MARTIN"]
#
# Test value getting UDF's
#
SELECT JsonGet_String(Json_Array_Grp(name),'[#]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[#]')
27
SELECT JsonGet_String(Json_Array_Grp(name),'[","]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[","]')
BANCROFT,SMITH,MERCHANT,FUNNIGUY,BUGHAPPY,BIGHEAD,SHRINKY,WALTER,FODDERMAN,TONGHO,SHORTSIGHT,MESSIFUL,HONEY,GOOSEPEN,CHERRY,MONAPENNY,KITTY,PLUMHEAD,STRONG,BULLOZER,WERTHER,QUINN,ORELLY,BIGHORN,BROWNY,WHEELFOR,MARTIN
SELECT JsonGet_String(Json_Array_Grp(name),'[>]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[>]')
WHEELFOR
SET @j1 = '[45,28,36,45,89]';
SELECT JsonGet_String(@j1,'[1]');
JsonGet_String(@j1,'[1]')
28
SELECT JsonGet_String(@j1 json_,'[3]');
JsonGet_String(@j1 json_,'[3]')
45
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'[3]');
JsonGet_String(Json_Array(45,28,36,45,89),'[3]')
45
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Array(45,28,36,45,89),'[+]') "sum";
list egal sum
45+28+36+45+89 = 243.00
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]')
36
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*');
JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*')
[36,45,89]
SELECT JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc')
machin
SET @j2 = '{"qty":56,"price":3.141600,"truc":"machin","garanty":null}';
SELECT JsonGet_String(@j2 json_,'truc');
JsonGet_String(@j2 json_,'truc')
machin
SELECT JsonGet_String(@j2,'truc');
JsonGet_String(@j2,'truc')
machin
SELECT JsonGet_String(@j2,'chose');
JsonGet_String(@j2,'chose')
NULL
SELECT JsonGet_String(NULL json_, NULL);
JsonGet_String(NULL json_, NULL)
NULL
Warnings:
Warning 1105
SELECT department, JsonGet_String(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500.00
0318 72230.00
0319 89800.95
2452 45900.00
SELECT JsonGet_Int(@j1, '[4]');
JsonGet_Int(@j1, '[4]')
89
SELECT JsonGet_Int(@j1, '[#]');
JsonGet_Int(@j1, '[#]')
5
SELECT JsonGet_Int(@j1, '[+]');
JsonGet_Int(@j1, '[+]')
243
SELECT JsonGet_Int(@j1 json_,'[3]');
JsonGet_Int(@j1 json_,'[3]')
45
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'[3]');
JsonGet_Int(Json_Array(45,28,36,45,89),'[3]')
45
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'["+"]');
JsonGet_Int(Json_Array(45,28,36,45,89),'["+"]')
45
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'[+]');
JsonGet_Int(Json_Array(45,28,36,45,89),'[+]')
243
SELECT JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]')
36
SELECT JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[0]:[1]');
JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[0]:[1]')
28
SELECT JsonGet_Int(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'qty');
JsonGet_Int(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'qty')
56
SELECT JsonGet_Int(@j2 json_,'price');
JsonGet_Int(@j2 json_,'price')
3
SELECT JsonGet_Int(@j2,'qty');
JsonGet_Int(@j2,'qty')
56
SELECT JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose');
JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose')
NULL
Warnings:
Warning 1105 Value not found
SELECT JsonGet_Int(JsonGet_String(Json_Array(Json_Array(45,28),Json_Array(36,45,89)),'[1]:*'),'[+]') sum;
sum
170
SELECT department, JsonGet_Int(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500
0318 72230
0319 89800
2452 45900
SELECT JsonGet_Real(@j1, '[2]');
JsonGet_Real(@j1, '[2]')
36.000000000000000
SELECT JsonGet_Real(@j1 json_,'[3]',2);
JsonGet_Real(@j1 json_,'[3]',2)
45.00
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[3]');
JsonGet_Real(Json_Array(45,28,36,45,89),'[3]')
45.000000000000000
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'["+"]');
JsonGet_Real(Json_Array(45,28,36,45,89),'["+"]')
45.000000000000000
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[+]');
JsonGet_Real(Json_Array(45,28,36,45,89),'[+]')
243.000000000000000
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[!]');
JsonGet_Real(Json_Array(45,28,36,45,89),'[!]')
48.600000000000000
SELECT JsonGet_Real(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
JsonGet_Real(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]')
36.000000000000000
SELECT JsonGet_Real(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'price');
JsonGet_Real(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'price')
3.141600000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_,'qty');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_,'qty')
56.000000000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price')
3.141600000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price', 4);
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price', 4)
3.1416
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose')
NULL
Warnings:
Warning 1105 Value not found
SELECT department, JsonGet_Real(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500.000000000000000
0318 72230.000000000000000
0319 89800.950000000000000
2452 45900.000000000000000
#
# Documentation examples
#
SELECT
JsonGet_Int(Json_Array(45,28,36,45,89), '[4]') "Rank",
JsonGet_Int(Json_Array(45,28,36,45,89), '[#]') "Number",
JsonGet_String(Json_Array(45,28,36,45,89), '[","]') "Concat",
JsonGet_Int(Json_Array(45,28,36,45,89), '[+]') "Sum",
JsonGet_Real(Json_Array(45,28,36,45,89), '[!]', 2) "Avg";
Rank Number Concat Sum Avg
89 5 45,28,36,45,89 243 48.60
SELECT
JsonGet_String('{"qty":7,"price":29.50,"garanty":null}','price') "String",
JsonGet_Int('{"qty":7,"price":29.50,"garanty":null}','price') "Int",
JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price') "Real";
String Int Real
29.50 29 29.500000000000000
SELECT JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price',3) "Real";
Real
29.500
#
# Testing Locate
#
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin')
truc
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56)
qty
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416)
price
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose')
NULL
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'Jack') Path;
Path
AUTHORS:[1]:FN
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'jack' ci) Path;
Path
AUTHORS:[1]:FN
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"Jack", "LN":"London"}' json_) Path;
Path
AUTHORS:[1]
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"jack", "LN":"London"}' json_) Path;
Path
NULL
SELECT JsonLocate('[45,28,36,45,89]',36);
JsonLocate('[45,28,36,45,89]',36)
[2]
SELECT JsonLocate('[45,28,36,45,89]' json_,28.0);
JsonLocate('[45,28,36,45,89]' json_,28.0)
NULL
SELECT Json_Locate_All('[45,28,36,45,89]',10);
Json_Locate_All('[45,28,36,45,89]',10)
[]
SELECT Json_Locate_All('[45,28,36,45,89]',45);
Json_Locate_All('[45,28,36,45,89]',45)
["[0]","[3]"]
SELECT Json_Locate_All('[[45,28],36,45,89]',45);
Json_Locate_All('[[45,28],36,45,89]',45)
["[0]:[0]","[2]"]
SELECT Json_Locate_All('[[45,28,45],36,45,89]',45);
Json_Locate_All('[[45,28,45],36,45,89]',45)
["[0]:[0]","[0]:[2]","[2]"]
SELECT Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'));
Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'))
["[0]:[0]","[0]:[2]","[2]"]
SELECT JsonLocate('[[45,28,45],36,45,89]',45,n) from t1;
JsonLocate('[[45,28,45],36,45,89]',45,n)
[0]:[0]
[0]:[2]
[2]
NULL
NULL
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) FROM t1;
JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']'))
[0]:[0]
[0]:[2]
[2]
NULL
NULL
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) AS `Path` FROM t1 GROUP BY n HAVING `Path` IS NOT NULL;
Path
[0]:[0]
[0]:[2]
[2]
SELECT Json_Locate_All('[45,28,[36,45,89]]',45);
Json_Locate_All('[45,28,[36,45,89]]',45)
["[0]","[2]:[1]"]
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0));
Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0))
[]
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',45.0);
Json_Locate_All('[[45,28],[36,45.0,89]]',45.0)
["[1]:[1]"]
SELECT JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_);
JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_)
[1]
SELECT JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_);
JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_)
[0]
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','45') "All paths";
All paths
[]
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_);
Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_)
["[1]:[0]"]
SELECT JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '[#]') "Nb of occurs";
Nb of occurs
2
SELECT Json_Locate_All('[[45,28],[[36,45],89]]',45,2);
Json_Locate_All('[[45,28],[[36,45],89]]',45,2)
["[0]:[0]"]
SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]');
JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]')
[0]
SELECT JsonLocate(Json_File('test/biblio.json'), 'Knab');
JsonLocate(Json_File('test/biblio.json'), 'Knab')
[0]:AUTHOR:[1]:LASTNAME
SELECT Json_Locate_All('test/biblio.json' jfile_, 'Knab');
Json_Locate_All('test/biblio.json' jfile_, 'Knab')
["[0]:AUTHOR:[1]:LASTNAME"]
#
# Testing json files
#
select Jfile_Make('[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},
{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]', 'test/fx.json', 0) AS NewFile;
NewFile
test/fx.json
SELECT Jfile_Make('test/fx.json', 1);
Jfile_Make('test/fx.json', 1)
test/fx.json
SELECT Jfile_Make('test/fx.json' jfile_);
Jfile_Make('test/fx.json' jfile_)
test/fx.json
SELECT Jfile_Make(Jbin_File('test/fx.json'), 0);
Jfile_Make(Jbin_File('test/fx.json'), 0)
test/fx.json
SELECT Json_File('test/fx.json', 1);
Json_File('test/fx.json', 1)
[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]
Warnings:
Warning 1105 File pretty format doesn't match the specified pretty value
SELECT Json_File('test/fx.json', 2);
Json_File('test/fx.json', 2)
[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]
Warnings:
Warning 1105 File pretty format doesn't match the specified pretty value
SELECT Json_File('test/fx.json', 0);
Json_File('test/fx.json', 0)
[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]
SELECT Json_File('test/fx.json', '[0]');
Json_File('test/fx.json', '[0]')
{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]}
SELECT Json_File('test/fx.json', '[?]');
Json_File('test/fx.json', '[?]')
NULL
Warnings:
Warning 1105 Invalid function specification ?
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]:*');
JsonGet_String(Json_File('test/fx.json'), '[1]:*')
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]}
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]');
JsonGet_String(Json_File('test/fx.json'), '[1]')
6 car roadster 56000 ???
SELECT JsonGet_Int(Json_File('test/fx.json'), '[1]:mileage') AS Mileage;
Mileage
56000
SELECT JsonGet_Real(Json_File('test/fx.json'), '[0]:price', 2) AS Price;
Price
5.65
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings');
Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4,6]}
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings');
Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1);
Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1)
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0);
Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0)
[6,2,4]
SELECT Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1);
Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1)
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2]}
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin);
Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin)
{"_id":7,"type":"food","item":"meat","origin":"france","ratings":[2,4]}
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size');
Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]}
Warnings:
Warning 1105 No sub-item at 'size'
SELECT Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size');
Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size')
{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":70},"ratings":[5,8,7]}
SELECT Json_Object_List(Json_File('test/fx.json', '[3]:size'));
Json_Object_List(Json_File('test/fx.json', '[3]:size'))
["W","L","H"]
DROP TABLE t1;
DROP FUNCTION Json_Array;
DROP FUNCTION Json_Array_Add;
DROP FUNCTION Json_Object;
DROP FUNCTION Json_Object_Nonull;
DROP FUNCTION JsonValue;
DROP FUNCTION Json_Array_Grp;
DROP FUNCTION Json_Object_Grp;
DROP TABLE t2;
DROP TABLE t3;
......@@ -24,12 +24,10 @@
"ISBN": "9782840825685",
"LANG": "fr",
"SUBJECT": "applications",
"AUTHOR": [
{
"FIRSTNAME": "William J.",
"LASTNAME": "Pardi"
}
],
"AUTHOR": {
"FIRSTNAME": "William J.",
"LASTNAME": "Pardi"
},
"TITLE": "XML en Action",
"TRANSLATION": "adapté de l'anglais par",
"TRANSLATOR": {
......
......@@ -11,11 +11,38 @@ if (!$HA_CONNECT_SO) {
CREATE FUNCTION json_array RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_array_add RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_array_add_values RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_array_delete RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object_nonull RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object_add RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object_delete RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object_list RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jsonvalue RETURNS STRING SONAME 'ha_connect';
CREATE AGGREGATE FUNCTION json_array_grp RETURNS STRING SONAME 'ha_connect';
CREATE AGGREGATE FUNCTION json_object_grp RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_item_merge RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_get_item RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jsonget_string RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jsonget_int RETURNS INTEGER SONAME 'ha_connect';
CREATE FUNCTION jsonget_real RETURNS REAL SONAME 'ha_connect';
CREATE FUNCTION jsonlocate RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_locate_all RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_file RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jfile_make RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_serialize RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_array RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_array_add_values RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_array_add RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_array_delete RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object_nonull RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object_add RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object_delete RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object_list RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_get_item RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_item_merge RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_file RETURNS STRING SONAME 'ha_connect';
--enable_query_log
......@@ -5,13 +5,25 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/biblio.json $MYSQLD_DATADIR/test/biblio.json
--copy_file $MTR_SUITE_DIR/std_data/employee.dat $MYSQLD_DATADIR/test/employee.dat
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=VIR BLOCK_SIZE=5;
--echo #
--echo # Test UDF's with constant arguments
--echo #
--error ER_CANT_INITIALIZE_UDF
SELECT JsonValue(56,3.1416,'foo',NULL);
SELECT JsonValue(3.1416);
SELECT JsonValue('foo');
SELECT JsonValue(9223372036854775807);
SELECT JsonValue(NULL);
SELECT JsonValue(TRUE);
SELECT JsonValue(FALSE);
SELECT JsonValue();
SELECT JsonValue('[11,22,33]' json_) FROM t1;
#
SELECT Json_Array();
SELECT Json_Object(56,3.1416,'foo',NULL);
SELECT Json_Object(56 qty,3.1416 price,'foo' truc, NULL garanty);
SELECT Json_Array(56,3.1416,'My name is "Foo"',NULL);
SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL);
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL)) Array;
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL),'One more') Array;
......@@ -20,21 +32,35 @@ SELECT Json_Array_Add(JsonValue('one value'),'One more');
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add('one value','One more');
SELECT Json_Array_Add('one value' json_,'One more');
--error ER_CANT_INITIALIZE_UDF
SELECT JsonValue(56,3.1416,'foo',NULL);
SELECT JsonValue(3.1416);
SELECT JsonValue('foo');
SELECT JsonValue(NULL);
SELECT JsonValue();
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 9);
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), n) Array FROM t1;
SELECT Json_Array_Add_Values(Json_Array(n, 3.1416, 'machin'), n) Array FROM t1;
SELECT Json_Array_Add_Values('[56]', 3.1416, 'machin') Array;
#
SELECT Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),0);
SELECT Json_Array_Delete(Json_Object(56,3.1416,'My name is Foo',NULL),2);
SELECT Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),'2');
#
SELECT Json_Object(56, 3.1416, 'foo', NULL);
SELECT Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
SELECT Json_Object();
SELECT Json_Object(Json_Array(56,3.1416,'foo'),NULL);
SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL);
SELECT Json_Array(Json_Object(56 "qty",3.1416 "price",'foo'),NULL);
SELECT Json_Object(Json_Array(56, 3.1416, 'foo'), NULL);
SELECT Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
SELECT Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'blue' color);
SELECT Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 45.99 price);
SELECT Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'truc');
SELECT Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'chose');
SELECT Json_Object_List(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty)) "Key List";
SELECT Json_Object_List('{"qty":56, "price":3.1416, "truc":"machin", "garanty":null}') "Key List";
--echo #
--echo # Test UDF's with column arguments
--echo #
CREATE TABLE t1
CREATE TABLE t2
(
ISBN CHAR(15),
LANG CHAR(2),
......@@ -47,14 +73,13 @@ CREATE TABLE t1
DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t1;
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t1;
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t1;
SELECT Json_Array_Grp(TITLE) FROM t1;
DROP TABLE t1;
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t2;
SELECT Json_Array_Grp(TITLE) FROM t2;
CREATE TABLE t1 (
CREATE TABLE t3 (
SERIALNO CHAR(5) NOT NULL,
NAME VARCHAR(12) NOT NULL FLAG=6,
SEX SMALLINT(1) NOT NULL,
......@@ -65,30 +90,156 @@ CREATE TABLE t1 (
SALARY DOUBLE(8,2) NOT NULL FLAG=52
) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1;
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t1 WHERE NAME = 'MERCHANT';
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t1 GROUP BY DEPARTMENT;
set connect_json_grp_size=30;
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT, TITLE;
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t3 GROUP BY DEPARTMENT;
SET connect_json_grp_size=30;
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Object_Grp(SALARY) FROM t1;
SELECT Json_Object_Grp(SALARY, NAME) FROM t1;
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Array_Grp(NAME) from t1;
DROP TABLE t1;
SELECT Json_Object_Grp(SALARY) FROM t3;
SELECT Json_Object_Grp(SALARY, NAME) FROM t3;
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Array_Grp(NAME) FROM t3;
DROP FUNCTION Json_Array;
DROP FUNCTION Json_Array_Add;
DROP FUNCTION Json_Object;
DROP FUNCTION Json_Object_Nonull;
DROP FUNCTION JsonValue;
DROP FUNCTION Json_Array_Grp;
DROP FUNCTION Json_Object_Grp;
--echo #
--echo # Test value getting UDF's
--echo #
SELECT JsonGet_String(Json_Array_Grp(name),'[#]') FROM t3;
SELECT JsonGet_String(Json_Array_Grp(name),'[","]') FROM t3;
SELECT JsonGet_String(Json_Array_Grp(name),'[>]') FROM t3;
SET @j1 = '[45,28,36,45,89]';
SELECT JsonGet_String(@j1,'[1]');
SELECT JsonGet_String(@j1 json_,'[3]');
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'[3]');
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Array(45,28,36,45,89),'[+]') "sum";
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*');
SELECT JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
SET @j2 = '{"qty":56,"price":3.141600,"truc":"machin","garanty":null}';
SELECT JsonGet_String(@j2 json_,'truc');
SELECT JsonGet_String(@j2,'truc');
SELECT JsonGet_String(@j2,'chose');
SELECT JsonGet_String(NULL json_, NULL);
SELECT department, JsonGet_String(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
#
SELECT JsonGet_Int(@j1, '[4]');
SELECT JsonGet_Int(@j1, '[#]');
SELECT JsonGet_Int(@j1, '[+]');
SELECT JsonGet_Int(@j1 json_,'[3]');
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'[3]');
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'["+"]');
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'[+]');
SELECT JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
SELECT JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[0]:[1]');
SELECT JsonGet_Int(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'qty');
SELECT JsonGet_Int(@j2 json_,'price');
SELECT JsonGet_Int(@j2,'qty');
SELECT JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose');
SELECT JsonGet_Int(JsonGet_String(Json_Array(Json_Array(45,28),Json_Array(36,45,89)),'[1]:*'),'[+]') sum;
SELECT department, JsonGet_Int(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
#
SELECT JsonGet_Real(@j1, '[2]');
SELECT JsonGet_Real(@j1 json_,'[3]',2);
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[3]');
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'["+"]');
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[+]');
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[!]');
SELECT JsonGet_Real(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
SELECT JsonGet_Real(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'price');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_,'qty');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price', 4);
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose');
SELECT department, JsonGet_Real(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
--echo #
--echo # Documentation examples
--echo #
SELECT
JsonGet_Int(Json_Array(45,28,36,45,89), '[4]') "Rank",
JsonGet_Int(Json_Array(45,28,36,45,89), '[#]') "Number",
JsonGet_String(Json_Array(45,28,36,45,89), '[","]') "Concat",
JsonGet_Int(Json_Array(45,28,36,45,89), '[+]') "Sum",
JsonGet_Real(Json_Array(45,28,36,45,89), '[!]', 2) "Avg";
SELECT
JsonGet_String('{"qty":7,"price":29.50,"garanty":null}','price') "String",
JsonGet_Int('{"qty":7,"price":29.50,"garanty":null}','price') "Int",
JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price') "Real";
SELECT JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price',3) "Real";
--echo #
--echo # Testing Locate
--echo #
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'Jack') Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'jack' ci) Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"Jack", "LN":"London"}' json_) Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"jack", "LN":"London"}' json_) Path;
SELECT JsonLocate('[45,28,36,45,89]',36);
SELECT JsonLocate('[45,28,36,45,89]' json_,28.0);
SELECT Json_Locate_All('[45,28,36,45,89]',10);
SELECT Json_Locate_All('[45,28,36,45,89]',45);
SELECT Json_Locate_All('[[45,28],36,45,89]',45);
SELECT Json_Locate_All('[[45,28,45],36,45,89]',45);
SELECT Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'));
SELECT JsonLocate('[[45,28,45],36,45,89]',45,n) from t1;
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) FROM t1;
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) AS `Path` FROM t1 GROUP BY n HAVING `Path` IS NOT NULL;
SELECT Json_Locate_All('[45,28,[36,45,89]]',45);
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0));
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',45.0);
SELECT JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_);
SELECT JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_);
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','45') "All paths";
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_);
SELECT JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '[#]') "Nb of occurs";
SELECT Json_Locate_All('[[45,28],[[36,45],89]]',45,2);
SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]');
SELECT JsonLocate(Json_File('test/biblio.json'), 'Knab');
SELECT Json_Locate_All('test/biblio.json' jfile_, 'Knab');
--echo #
--echo # Testing json files
--echo #
select Jfile_Make('[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},
{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]', 'test/fx.json', 0) AS NewFile;
SELECT Jfile_Make('test/fx.json', 1);
SELECT Jfile_Make('test/fx.json' jfile_);
SELECT Jfile_Make(Jbin_File('test/fx.json'), 0);
SELECT Json_File('test/fx.json', 1);
SELECT Json_File('test/fx.json', 2);
SELECT Json_File('test/fx.json', 0);
SELECT Json_File('test/fx.json', '[0]');
SELECT Json_File('test/fx.json', '[?]');
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]:*');
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]');
SELECT JsonGet_Int(Json_File('test/fx.json'), '[1]:mileage') AS Mileage;
SELECT JsonGet_Real(Json_File('test/fx.json'), '[0]:price', 2) AS Price;
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings');
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings');
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1);
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0);
SELECT Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1);
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin);
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size');
SELECT Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size');
SELECT Json_Object_List(Json_File('test/fx.json', '[3]:size'));
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
#
# Clean up
#
--source json_udf2.inc
--remove_file $MYSQLD_DATADIR/test/biblio.json
--remove_file $MYSQLD_DATADIR/test/employee.dat
--remove_file $MYSQLD_DATADIR/test/fx.json
--disable_query_log
DROP FUNCTION jsonvalue;
DROP FUNCTION json_array;
DROP FUNCTION json_array_add;
DROP FUNCTION json_array_add_values;
DROP FUNCTION json_array_delete;
DROP FUNCTION json_object;
DROP FUNCTION json_object_nonull;
DROP FUNCTION json_object_add;
DROP FUNCTION json_object_delete;
DROP FUNCTION json_object_list;
DROP FUNCTION json_array_grp;
DROP FUNCTION json_object_grp;
DROP FUNCTION json_item_merge;
DROP FUNCTION json_get_item;
DROP FUNCTION JsonGet_string;
DROP FUNCTION JsonGet_int;
DROP FUNCTION JsonGet_real;
DROP FUNCTION jsonlocate;
DROP FUNCTION json_locate_all;
DROP FUNCTION json_file;
DROP FUNCTION json_serialize;
DROP FUNCTION jfile_make;
DROP FUNCTION jbin_array;
DROP FUNCTION jbin_array_add_values;
DROP FUNCTION jbin_array_add;
DROP FUNCTION jbin_array_delete;
DROP FUNCTION jbin_object;
DROP FUNCTION jbin_object_nonull;
DROP FUNCTION jbin_object_add;
DROP FUNCTION jbin_object_delete;
DROP FUNCTION jbin_object_list;
DROP FUNCTION jbin_get_item;
DROP FUNCTION jbin_item_merge;
DROP FUNCTION jbin_file;
--enable_query_log
......@@ -659,7 +659,7 @@ int TDBJSN::ReadDB(PGLOBAL g)
if (!IsRead() && ((rc = ReadBuffer(g)) != RC_OK)) {
// Deferred reading failed
} else if (!(Row = ParseJson(g, To_Line,
strlen(To_Line), Pretty, &Comma))) {
strlen(To_Line), &Pretty, &Comma))) {
rc = (Pretty == 1 && !strcmp(To_Line, "]")) ? RC_EF : RC_FX;
} else {
Row = FindRow(g);
......@@ -1384,7 +1384,7 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (Nodes[Nod-1].Op == OP_XX) {
s = Value->GetCharValue();
if (!(jsp = ParseJson(g, s, (int)strlen(s), 0))) {
if (!(jsp = ParseJson(g, s, (int)strlen(s)))) {
strcpy(g->Message, s);
longjmp(g->jumper[g->jump_level], 666);
} // endif jsp
......@@ -1522,7 +1522,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
/* Parse the json file and allocate its tree structure. */
/*********************************************************************/
g->Message[0] = 0;
jsp = Top = ParseJson(g, memory, len, Pretty);
jsp = Top = ParseJson(g, memory, len, &Pretty);
Txfp->CloseTableFile(g, false);
Mode = mode; // Restore saved Mode
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment