Commit 801a6d50 authored by Olivier Bertrand's avatar Olivier Bertrand

- Add new JPATH features

  modified:   storage/connect/bson.cpp
  modified:   storage/connect/bsonudf.cpp
  modified:   storage/connect/bsonudf.h
  modified:   storage/connect/json.cpp
  modified:   storage/connect/jsonudf.cpp
  modified:   storage/connect/jsonudf.h
  modified:   storage/connect/mysql-test/connect/r/json_udf.result
  modified:   storage/connect/tabbson.cpp
  modified:   storage/connect/tabjson.cpp
  modified:   storage/connect/tabjson.h
parent d788225b
...@@ -1352,12 +1352,17 @@ PBVAL BJSON::NewVal(PVAL valp) ...@@ -1352,12 +1352,17 @@ PBVAL BJSON::NewVal(PVAL valp)
/***********************************************************************/ /***********************************************************************/
/* Sub-allocate and initialize a BVAL from another BVAL. */ /* Sub-allocate and initialize a BVAL from another BVAL. */
/***********************************************************************/ /***********************************************************************/
PBVAL BJSON::DupVal(PBVAL bvlp) { PBVAL BJSON::DupVal(PBVAL bvlp)
PBVAL bvp = NewVal(); {
if (bvlp) {
PBVAL bvp = NewVal();
*bvp = *bvlp;
bvp->Next = 0;
return bvp;
} else
return NULL;
*bvp = *bvlp;
bvp->Next = 0;
return bvp;
} // end of DupVal } // end of DupVal
/***********************************************************************/ /***********************************************************************/
......
...@@ -114,7 +114,7 @@ BJNX::BJNX(PGLOBAL g) : BDOC(g) ...@@ -114,7 +114,7 @@ BJNX::BJNX(PGLOBAL g) : BDOC(g)
Jp = NULL; Jp = NULL;
Nodes = NULL; Nodes = NULL;
Value = NULL; Value = NULL;
MulVal = NULL; //MulVal = NULL;
Jpath = NULL; Jpath = NULL;
Buf_Type = TYPE_STRING; Buf_Type = TYPE_STRING;
Long = len; Long = len;
...@@ -145,7 +145,7 @@ BJNX::BJNX(PGLOBAL g, PBVAL row, int type, int len, int prec, my_bool wr) : BDOC ...@@ -145,7 +145,7 @@ BJNX::BJNX(PGLOBAL g, PBVAL row, int type, int len, int prec, my_bool wr) : BDOC
Jp = NULL; Jp = NULL;
Nodes = NULL; Nodes = NULL;
Value = AllocateValue(g, type, len, prec); Value = AllocateValue(g, type, len, prec);
MulVal = NULL; //MulVal = NULL;
Jpath = NULL; Jpath = NULL;
Buf_Type = type; Buf_Type = type;
Long = len; Long = len;
...@@ -270,40 +270,6 @@ my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm) ...@@ -270,40 +270,6 @@ my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm)
return true; return true;
} // endif's } // endif's
#if 0
// For calculated arrays, a local Value must be used
switch (jnp->Op) {
case OP_NUM:
jnp->Valp = AllocateValue(g, TYPE_INT);
break;
case OP_ADD:
case OP_MULT:
case OP_SEP:
if (!IsTypeChar(Buf_Type))
jnp->Valp = AllocateValue(g, Buf_Type, 0, GetPrecision());
else
jnp->Valp = AllocateValue(g, TYPE_DOUBLE, 0, 2);
break;
case OP_MIN:
case OP_MAX:
jnp->Valp = AllocateValue(g, Buf_Type, Long, GetPrecision());
break;
case OP_CNC:
if (IsTypeChar(Buf_Type))
jnp->Valp = AllocateValue(g, TYPE_STRING, Long, GetPrecision());
else
jnp->Valp = AllocateValue(g, TYPE_STRING, 512);
break;
default:
break;
} // endswitch Op
if (jnp->Valp)
MulVal = AllocateValue(g, jnp->Valp);
#endif // 0
return false; return false;
} // end of SetArrayOptions } // end of SetArrayOptions
...@@ -449,6 +415,8 @@ PBVAL BJNX::MakeJson(PGLOBAL g, PBVAL bvp, int n) ...@@ -449,6 +415,8 @@ PBVAL BJNX::MakeJson(PGLOBAL g, PBVAL bvp, int n)
{ {
PBVAL vlp, jvp = bvp; PBVAL vlp, jvp = bvp;
Jb = false;
if (n < Nod -1) { if (n < Nod -1) {
if (bvp->Type == TYPE_JAR) { if (bvp->Type == TYPE_JAR) {
int ars = GetArraySize(bvp); int ars = GetArraySize(bvp);
......
...@@ -41,7 +41,6 @@ typedef struct _jnode { ...@@ -41,7 +41,6 @@ typedef struct _jnode {
PSZ Key; // The key used for object PSZ Key; // The key used for object
OPVAL Op; // Operator used for this node OPVAL Op; // Operator used for this node
PVAL CncVal; // To cont value used for OP_CNC PVAL CncVal; // To cont value used for OP_CNC
PVAL Valp; // The internal array VALUE
int Rank; // The rank in array int Rank; // The rank in array
int Rx; // Read row number int Rx; // Read row number
int Nx; // Next to read row number int Nx; // Next to read row number
...@@ -153,7 +152,7 @@ class BJNX : public BDOC { ...@@ -153,7 +152,7 @@ class BJNX : public BDOC {
JOUTSTR *Jp; JOUTSTR *Jp;
JNODE *Nodes; // The intermediate objects JNODE *Nodes; // The intermediate objects
PVAL Value; PVAL Value;
PVAL MulVal; // To value used by multiple column //PVAL MulVal; // To value used by multiple column
char *Jpath; // The json path char *Jpath; // The json path
int Buf_Type; int Buf_Type;
int Long; int Long;
......
...@@ -54,6 +54,7 @@ char *GetExceptionDesc(PGLOBAL g, unsigned int e); ...@@ -54,6 +54,7 @@ char *GetExceptionDesc(PGLOBAL g, unsigned int e);
#endif // SE_CATCH #endif // SE_CATCH
char *GetJsonNull(void); char *GetJsonNull(void);
int GetDefaultPrec(void);
/***********************************************************************/ /***********************************************************************/
/* IsNum: check whether this string is all digits. */ /* IsNum: check whether this string is all digits. */
...@@ -1762,7 +1763,7 @@ void JVALUE::SetBigint(PGLOBAL g, long long ll) ...@@ -1762,7 +1763,7 @@ void JVALUE::SetBigint(PGLOBAL g, long long ll)
void JVALUE::SetFloat(PGLOBAL g, double f) void JVALUE::SetFloat(PGLOBAL g, double f)
{ {
F = f; F = f;
Nd = 6; Nd = GetDefaultPrec();
DataType = TYPE_DBL; DataType = TYPE_DBL;
} // end of SetFloat } // end of SetFloat
......
...@@ -70,7 +70,7 @@ JSNX::JSNX(PGLOBAL g, PJSON row, int type, int len, int prec, my_bool wr) ...@@ -70,7 +70,7 @@ JSNX::JSNX(PGLOBAL g, PJSON row, int type, int len, int prec, my_bool wr)
Jp = NULL; Jp = NULL;
Nodes = NULL; Nodes = NULL;
Value = AllocateValue(g, type, len, prec); Value = AllocateValue(g, type, len, prec);
MulVal = NULL; //MulVal = NULL;
Jpath = NULL; Jpath = NULL;
Buf_Type = type; Buf_Type = type;
Long = len; Long = len;
...@@ -196,38 +196,6 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm) ...@@ -196,38 +196,6 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
return true; return true;
} // endif's } // endif's
// For calculated arrays, a local Value must be used
switch (jnp->Op) {
case OP_NUM:
jnp->Valp = AllocateValue(g, TYPE_INT);
break;
case OP_ADD:
case OP_MULT:
case OP_SEP:
if (!IsTypeChar(Buf_Type))
jnp->Valp = AllocateValue(g, Buf_Type, 0, GetPrecision());
else
jnp->Valp = AllocateValue(g, TYPE_DOUBLE, 0, 2);
break;
case OP_MIN:
case OP_MAX:
jnp->Valp = AllocateValue(g, Buf_Type, Long, GetPrecision());
break;
case OP_CNC:
if (IsTypeChar(Buf_Type))
jnp->Valp = AllocateValue(g, TYPE_STRING, Long, GetPrecision());
else
jnp->Valp = AllocateValue(g, TYPE_STRING, 512);
break;
default:
break;
} // endswitch Op
if (jnp->Valp)
MulVal = AllocateValue(g, jnp->Valp);
return false; return false;
} // end of SetArrayOptions } // end of SetArrayOptions
...@@ -310,7 +278,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g) ...@@ -310,7 +278,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
} // endfor i, p } // endfor i, p
Nod = i; Nod = i;
MulVal = AllocateValue(g, Value); //MulVal = AllocateValue(g, Value);
if (trace(1)) if (trace(1))
for (i = 0; i < Nod; i++) for (i = 0; i < Nod; i++)
...@@ -321,23 +289,6 @@ my_bool JSNX::ParseJpath(PGLOBAL g) ...@@ -321,23 +289,6 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
return false; return false;
} // end of ParseJpath } // end of ParseJpath
/*********************************************************************************/
/* MakeJson: Serialize the json item and set value to it. */
/*********************************************************************************/
PVAL JSNX::MakeJson(PGLOBAL g, PJSON jsp)
{
if (Value->IsTypeNum()) {
strcpy(g->Message, "Cannot make Json for a numeric value");
Value->Reset();
} else if (jsp->GetType() != TYPE_JAR && jsp->GetType() != TYPE_JOB) {
strcpy(g->Message, "Target is not an array or object");
Value->Reset();
} else
Value->SetValue_psz(Serialize(g, jsp, NULL, 0));
return Value;
} // end of MakeJson
/*********************************************************************************/ /*********************************************************************************/
/* SetValue: Set a value from a JVALUE contains. */ /* SetValue: Set a value from a JVALUE contains. */
/*********************************************************************************/ /*********************************************************************************/
...@@ -348,6 +299,7 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val) ...@@ -348,6 +299,7 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val)
if (Jb) { if (Jb) {
vp->SetValue_psz(Serialize(g, val->GetJsp(), NULL, 0)); vp->SetValue_psz(Serialize(g, val->GetJsp(), NULL, 0));
Jb = false;
} else switch (val->GetValType()) { } else switch (val->GetValType()) {
case TYPE_DTM: case TYPE_DTM:
case TYPE_STRG: case TYPE_STRG:
...@@ -392,6 +344,52 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val) ...@@ -392,6 +344,52 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val)
} // end of SetJsonValue } // end of SetJsonValue
/*********************************************************************************/
/* MakeJson: Serialize the json item and set value to it. */
/*********************************************************************************/
PJVAL JSNX::MakeJson(PGLOBAL g, PJSON jsp, int n)
{
Jb = false;
if (Value->IsTypeNum()) {
strcpy(g->Message, "Cannot make Json for a numeric value");
return NULL;
} else if (jsp->GetType() != TYPE_JAR && jsp->GetType() != TYPE_JOB) {
strcpy(g->Message, "Target is not an array or object");
return NULL;
} else if (n < Nod -1) {
if (jsp->GetType() == TYPE_JAR) {
int ars = jsp->GetSize(false);
PJNODE jnp = &Nodes[n];
PJAR jarp = new(g) JARRAY;
jnp->Op = OP_EQ;
for (jnp->Rank = 0; jnp->Rank < ars; jnp->Rank++)
jarp->AddArrayValue(g, GetRowValue(g, jsp, n));
jarp->InitArray(g);
jnp->Op = OP_XX;
jnp->Rank = 0;
jsp = jarp;
} else if(jsp->GetType() == TYPE_JOB) {
PJSON jp;
PJOB jobp = new(g) JOBJECT;
for (PJPR prp = ((PJOB)jsp)->GetFirst(); prp; prp = prp->Next) {
jp = (prp->Val->DataType == TYPE_JSON) ? prp->Val->Jsp : prp->Val;
jobp->SetKeyValue(g, GetRowValue(g, jp, n + 1), prp->Key);
} // endfor prp
jsp = jobp;
} // endif Type
} // endif
Jb = true;
return new(g) JVALUE(jsp);
} // end of MakeJson
/*********************************************************************************/ /*********************************************************************************/
/* GetJson: */ /* GetJson: */
/*********************************************************************************/ /*********************************************************************************/
...@@ -435,8 +433,7 @@ PJVAL JSNX::GetRowValue(PGLOBAL g, PJSON row, int i, my_bool b) ...@@ -435,8 +433,7 @@ PJVAL JSNX::GetRowValue(PGLOBAL g, PJSON row, int i, my_bool b)
val = new(g) JVALUE(g, Value); val = new(g) JVALUE(g, Value);
return val; return val;
} else if (Nodes[i].Op == OP_XX) { } else if (Nodes[i].Op == OP_XX) {
Jb = b; return MakeJson(g, row, i);
return new(g)JVALUE(row);
} else switch (row->GetType()) { } else switch (row->GetType()) {
case TYPE_JOB: case TYPE_JOB:
if (!Nodes[i].Key) { if (!Nodes[i].Key) {
...@@ -502,6 +499,88 @@ PVAL JSNX::ExpandArray(PGLOBAL g, PJAR arp, int n) ...@@ -502,6 +499,88 @@ PVAL JSNX::ExpandArray(PGLOBAL g, PJAR arp, int n)
return NULL; return NULL;
} // end of ExpandArray } // end of ExpandArray
/*********************************************************************************/
/* Get the value used for calculating the array. */
/*********************************************************************************/
PVAL JSNX::GetCalcValue(PGLOBAL g, PJAR jap, int n)
{
// For calculated arrays, a local Value must be used
int lng = 0;
short type, prec = 0;
bool b = n < Nod - 1;
PVAL valp;
PJVAL vlp, vp;
OPVAL op = Nodes[n].Op;
switch (op) {
case OP_NUM:
type = TYPE_INT;
break;
case OP_ADD:
case OP_MULT:
if (!IsTypeNum(Buf_Type)) {
type = TYPE_INT;
prec = 0;
for (vlp = jap->GetArrayValue(0); vlp; vlp = vlp->Next) {
vp = (b && vlp->GetJsp()) ? GetRowValue(g, vlp, n + 1) : vlp;
switch (vp->DataType) {
case TYPE_BINT:
if (type == TYPE_INT)
type = TYPE_BIGINT;
break;
case TYPE_DBL:
case TYPE_FLOAT:
type = TYPE_DOUBLE;
prec = MY_MAX(prec, vp->Nd);
break;
default:
break;
} // endswitch Type
} // endfor vlp
} else {
type = Buf_Type;
prec = GetPrecision();
} // endif Buf_Type
break;
case OP_SEP:
if (IsTypeChar(Buf_Type)) {
type = TYPE_DOUBLE;
prec = 2;
} else {
type = Buf_Type;
prec = GetPrecision();
} // endif Buf_Type
break;
case OP_MIN:
case OP_MAX:
type = Buf_Type;
lng = Long;
prec = GetPrecision();
break;
case OP_CNC:
type = TYPE_STRING;
if (IsTypeChar(Buf_Type)) {
lng = (Long) ? Long : 512;
prec = GetPrecision();
} else
lng = 512;
break;
default:
break;
} // endswitch Op
return valp = AllocateValue(g, type, lng, prec);
} // end of GetCalcValue
/*********************************************************************************/ /*********************************************************************************/
/* CalculateArray: */ /* CalculateArray: */
/*********************************************************************************/ /*********************************************************************************/
...@@ -510,7 +589,8 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n) ...@@ -510,7 +589,8 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
int i, ars = arp->size(), nv = 0; int i, ars = arp->size(), nv = 0;
bool err; bool err;
OPVAL op = Nodes[n].Op; OPVAL op = Nodes[n].Op;
PVAL val[2], vp = Nodes[n].Valp; PVAL val[2], vp = GetCalcValue(g, arp, n);
PVAL mulval = AllocateValue(g, vp);
PJVAL jvrp, jvp; PJVAL jvrp, jvp;
JVALUE jval; JVALUE jval;
...@@ -543,9 +623,9 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n) ...@@ -543,9 +623,9 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
SetJsonValue(g, vp, jvp); SetJsonValue(g, vp, jvp);
continue; continue;
} else } else
SetJsonValue(g, MulVal, jvp); SetJsonValue(g, mulval, jvp);
if (!MulVal->IsNull()) { if (!mulval->IsNull()) {
switch (op) { switch (op) {
case OP_CNC: case OP_CNC:
if (Nodes[n].CncVal) { if (Nodes[n].CncVal) {
...@@ -553,18 +633,18 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n) ...@@ -553,18 +633,18 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
err = vp->Compute(g, val, 1, op); err = vp->Compute(g, val, 1, op);
} // endif CncVal } // endif CncVal
val[0] = MulVal; val[0] = mulval;
err = vp->Compute(g, val, 1, op); err = vp->Compute(g, val, 1, op);
break; break;
// case OP_NUM: // case OP_NUM:
case OP_SEP: case OP_SEP:
val[0] = Nodes[n].Valp; val[0] = vp;
val[1] = MulVal; val[1] = mulval;
err = vp->Compute(g, val, 2, OP_ADD); err = vp->Compute(g, val, 2, OP_ADD);
break; break;
default: default:
val[0] = Nodes[n].Valp; val[0] = vp;
val[1] = MulVal; val[1] = mulval;
err = vp->Compute(g, val, 2, op); err = vp->Compute(g, val, 2, op);
} // endswitch Op } // endswitch Op
...@@ -586,9 +666,9 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n) ...@@ -586,9 +666,9 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (op == OP_SEP) { if (op == OP_SEP) {
// Calculate average // Calculate average
MulVal->SetValue(nv); mulval->SetValue(nv);
val[0] = vp; val[0] = vp;
val[1] = MulVal; val[1] = mulval;
if (vp->Compute(g, val, 2, OP_DIV)) if (vp->Compute(g, val, 2, OP_DIV))
vp->Reset(); vp->Reset();
......
...@@ -44,7 +44,6 @@ typedef struct _jnode { ...@@ -44,7 +44,6 @@ typedef struct _jnode {
PSZ Key; // The key used for object PSZ Key; // The key used for object
OPVAL Op; // Operator used for this node OPVAL Op; // Operator used for this node
PVAL CncVal; // To cont value used for OP_CNC PVAL CncVal; // To cont value used for OP_CNC
PVAL Valp; // The internal array VALUE
int Rank; // The rank in array int Rank; // The rank in array
int Rx; // Read row number int Rx; // Read row number
int Nx; // Next to read row number int Nx; // Next to read row number
...@@ -334,8 +333,9 @@ class JSNX : public BLOCK { ...@@ -334,8 +333,9 @@ class JSNX : public BLOCK {
my_bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm); my_bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm);
PVAL GetColumnValue(PGLOBAL g, PJSON row, int i); PVAL GetColumnValue(PGLOBAL g, PJSON row, int i);
PVAL ExpandArray(PGLOBAL g, PJAR arp, int n); PVAL ExpandArray(PGLOBAL g, PJAR arp, int n);
PVAL GetCalcValue(PGLOBAL g, PJAR bap, int n);
PVAL CalculateArray(PGLOBAL g, PJAR arp, int n); PVAL CalculateArray(PGLOBAL g, PJAR arp, int n);
PVAL MakeJson(PGLOBAL g, PJSON jsp); PJVAL MakeJson(PGLOBAL g, PJSON jsp, int i);
void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val); void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val);
PJSON GetRow(PGLOBAL g); PJSON GetRow(PGLOBAL g);
my_bool CompareValues(PJVAL v1, PJVAL v2); my_bool CompareValues(PJVAL v1, PJVAL v2);
...@@ -358,7 +358,7 @@ class JSNX : public BLOCK { ...@@ -358,7 +358,7 @@ class JSNX : public BLOCK {
JOUTSTR *Jp; JOUTSTR *Jp;
JNODE *Nodes; // The intermediate objects JNODE *Nodes; // The intermediate objects
PVAL Value; PVAL Value;
PVAL MulVal; // To value used by multiple column //PVAL MulVal; // To value used by multiple column
char *Jpath; // The json path char *Jpath; // The json path
int Buf_Type; int Buf_Type;
int Long; int Long;
......
...@@ -322,7 +322,7 @@ JsonGet_String(Json_Make_Array(45,28,36,45,89),'3') ...@@ -322,7 +322,7 @@ JsonGet_String(Json_Make_Array(45,28,36,45,89),'3')
45 45
SELECT JsonGet_String(Json_Make_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Make_Array(45,28,36,45,89),'[+]') "sum"; SELECT JsonGet_String(Json_Make_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Make_Array(45,28,36,45,89),'[+]') "sum";
list egal sum list egal sum
45+28+36+45+89 = 243.00 45+28+36+45+89 = 243
SELECT JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.0'); SELECT JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.0');
JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.0') JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.0')
36 36
...@@ -349,10 +349,10 @@ Warnings: ...@@ -349,10 +349,10 @@ Warnings:
Warning 1105 Warning 1105
SELECT department, JsonGet_String(Json_Make_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries.[+]') Sumsal FROM t3 GROUP BY department; SELECT department, JsonGet_String(Json_Make_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries.[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal department Sumsal
0021 28500.00 0021 28500.000000
0318 72230.00 0318 72230.000000
0319 89800.95 0319 89800.950000
2452 45900.00 2452 45900.000000
SELECT JsonGet_Int(@j1, '4'); SELECT JsonGet_Int(@j1, '4');
JsonGet_Int(@j1, '4') JsonGet_Int(@j1, '4')
89 89
......
...@@ -881,7 +881,7 @@ PBVAL BCUTIL::GetRowValue(PGLOBAL g, PBVAL row, int i) ...@@ -881,7 +881,7 @@ PBVAL BCUTIL::GetRowValue(PGLOBAL g, PBVAL row, int i)
} // endfor i } // endfor i
return bvp; return bvp;
} // end of GetColumnValue } // end of GetRowValue
/***********************************************************************/ /***********************************************************************/
/* GetColumnValue: */ /* GetColumnValue: */
......
...@@ -1610,7 +1610,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -1610,7 +1610,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
/***********************************************************************/ /***********************************************************************/
/* MakeJson: Serialize the json item and set value to it. */ /* MakeJson: Serialize the json item and set value to it. */
/***********************************************************************/ /***********************************************************************/
PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp) PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp, int n)
{ {
if (Value->IsTypeNum()) { if (Value->IsTypeNum()) {
strcpy(g->Message, "Cannot make Json for a numeric column"); strcpy(g->Message, "Cannot make Json for a numeric column");
...@@ -1621,6 +1621,7 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp) ...@@ -1621,6 +1621,7 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
} // endif Warned } // endif Warned
Value->Reset(); Value->Reset();
return Value;
#if 0 #if 0
} else if (Value->GetType() == TYPE_BIN) { } else if (Value->GetType() == TYPE_BIN) {
if ((unsigned)Value->GetClen() >= sizeof(BSON)) { if ((unsigned)Value->GetClen() >= sizeof(BSON)) {
...@@ -1634,12 +1635,65 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp) ...@@ -1634,12 +1635,65 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
Value->SetValue_char(NULL, 0); Value->SetValue_char(NULL, 0);
} // endif Clen } // endif Clen
#endif // 0 #endif // 0
} else } else if (n < Nod - 1) {
Value->SetValue_psz(Serialize(g, jsp, NULL, 0)); if (jsp->GetType() == TYPE_JAR) {
int ars = jsp->GetSize(false);
PJNODE jnp = &Nodes[n];
PJAR jvp = new(g) JARRAY;
for (jnp->Rank = 0; jnp->Rank < ars; jnp->Rank++)
jvp->AddArrayValue(g, GetRowValue(g, jsp, n));
jnp->Rank = 0;
jvp->InitArray(g);
jsp = jvp;
} else if (jsp->Type == TYPE_JOB) {
PJOB jvp = new(g) JOBJECT;
for (PJPR prp = ((PJOB)jsp)->GetFirst(); prp; prp = prp->Next)
jvp->SetKeyValue(g, GetRowValue(g, prp->Val, n + 1), prp->Key);
jsp = jvp;
} // endif Type
} // endif
Value->SetValue_psz(Serialize(g, jsp, NULL, 0));
return Value; return Value;
} // end of MakeJson } // end of MakeJson
/***********************************************************************/
/* GetRowValue: */
/***********************************************************************/
PJVAL JSONCOL::GetRowValue(PGLOBAL g, PJSON row, int i)
{
int n = Nod - 1;
PJVAL val = NULL;
for (; i < Nod && row; i++) {
switch (row->GetType()) {
case TYPE_JOB:
val = (Nodes[i].Key) ? ((PJOB)row)->GetKeyValue(Nodes[i].Key) : NULL;
break;
case TYPE_JAR:
val = ((PJAR)row)->GetArrayValue(Nodes[i].Rank);
break;
case TYPE_JVAL:
val = (PJVAL)row;
break;
default:
sprintf(g->Message, "Invalid row JSON type %d", row->GetType());
val = NULL;
} // endswitch Type
if (i < Nod-1)
row = (val) ? val->GetJson() : NULL;
} // endfor i
return val;
} // end of GetRowValue
/***********************************************************************/ /***********************************************************************/
/* SetValue: Set a value from a JVALUE contains. */ /* SetValue: Set a value from a JVALUE contains. */
/***********************************************************************/ /***********************************************************************/
...@@ -1740,7 +1794,7 @@ PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i) ...@@ -1740,7 +1794,7 @@ PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i)
Value->SetValue(row->GetType() == TYPE_JAR ? ((PJAR)row)->size() : 1); Value->SetValue(row->GetType() == TYPE_JAR ? ((PJAR)row)->size() : 1);
return(Value); return(Value);
} else if (Nodes[i].Op == OP_XX) { } else if (Nodes[i].Op == OP_XX) {
return MakeJson(G, row); return MakeJson(G, row, i);
} else switch (row->GetType()) { } else switch (row->GetType()) {
case TYPE_JOB: case TYPE_JOB:
if (!Nodes[i].Key) { if (!Nodes[i].Key) {
......
...@@ -230,8 +230,9 @@ class DllExport JSONCOL : public DOSCOL { ...@@ -230,8 +230,9 @@ class DllExport JSONCOL : public DOSCOL {
PVAL GetColumnValue(PGLOBAL g, PJSON row, int i); PVAL GetColumnValue(PGLOBAL g, PJSON row, int i);
PVAL ExpandArray(PGLOBAL g, PJAR arp, int n); PVAL ExpandArray(PGLOBAL g, PJAR arp, int n);
PVAL CalculateArray(PGLOBAL g, PJAR arp, int n); PVAL CalculateArray(PGLOBAL g, PJAR arp, int n);
PVAL MakeJson(PGLOBAL g, PJSON jsp); PVAL MakeJson(PGLOBAL g, PJSON jsp, int n);
void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val); PJVAL GetRowValue(PGLOBAL g, PJSON row, int i);
void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val);
PJSON GetRow(PGLOBAL g); PJSON GetRow(PGLOBAL g);
// Default constructor not to be used // Default constructor not to be used
......
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