summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/connect/bson.cpp15
-rw-r--r--storage/connect/bsonudf.cpp40
-rw-r--r--storage/connect/bsonudf.h3
-rw-r--r--storage/connect/json.cpp3
-rw-r--r--storage/connect/jsonudf.cpp206
-rw-r--r--storage/connect/jsonudf.h6
-rw-r--r--storage/connect/mysql-test/connect/r/json_udf.result10
-rw-r--r--storage/connect/tabbson.cpp2
-rw-r--r--storage/connect/tabjson.cpp62
-rw-r--r--storage/connect/tabjson.h5
10 files changed, 230 insertions, 122 deletions
diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp
index 7b948164cfb..92f36a4cdf2 100644
--- a/storage/connect/bson.cpp
+++ b/storage/connect/bson.cpp
@@ -1352,12 +1352,17 @@ PBVAL BJSON::NewVal(PVAL valp)
/***********************************************************************/
/* Sub-allocate and initialize a BVAL from another BVAL. */
/***********************************************************************/
-PBVAL BJSON::DupVal(PBVAL bvlp) {
- PBVAL bvp = NewVal();
+PBVAL BJSON::DupVal(PBVAL bvlp)
+{
+ 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
/***********************************************************************/
diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp
index ebaca1b3cd3..dcf072242c8 100644
--- a/storage/connect/bsonudf.cpp
+++ b/storage/connect/bsonudf.cpp
@@ -114,7 +114,7 @@ BJNX::BJNX(PGLOBAL g) : BDOC(g)
Jp = NULL;
Nodes = NULL;
Value = NULL;
- MulVal = NULL;
+ //MulVal = NULL;
Jpath = NULL;
Buf_Type = TYPE_STRING;
Long = len;
@@ -145,7 +145,7 @@ BJNX::BJNX(PGLOBAL g, PBVAL row, int type, int len, int prec, my_bool wr) : BDOC
Jp = NULL;
Nodes = NULL;
Value = AllocateValue(g, type, len, prec);
- MulVal = NULL;
+ //MulVal = NULL;
Jpath = NULL;
Buf_Type = type;
Long = len;
@@ -270,40 +270,6 @@ my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm)
return true;
} // 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;
} // end of SetArrayOptions
@@ -449,6 +415,8 @@ PBVAL BJNX::MakeJson(PGLOBAL g, PBVAL bvp, int n)
{
PBVAL vlp, jvp = bvp;
+ Jb = false;
+
if (n < Nod -1) {
if (bvp->Type == TYPE_JAR) {
int ars = GetArraySize(bvp);
diff --git a/storage/connect/bsonudf.h b/storage/connect/bsonudf.h
index bbfd1ceed80..0fe3715617e 100644
--- a/storage/connect/bsonudf.h
+++ b/storage/connect/bsonudf.h
@@ -41,7 +41,6 @@ typedef struct _jnode {
PSZ Key; // The key used for object
OPVAL Op; // Operator used for this node
PVAL CncVal; // To cont value used for OP_CNC
- PVAL Valp; // The internal array VALUE
int Rank; // The rank in array
int Rx; // Read row number
int Nx; // Next to read row number
@@ -153,7 +152,7 @@ protected:
JOUTSTR *Jp;
JNODE *Nodes; // The intermediate objects
PVAL Value;
- PVAL MulVal; // To value used by multiple column
+ //PVAL MulVal; // To value used by multiple column
char *Jpath; // The json path
int Buf_Type;
int Long;
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp
index ac5f5a122cc..f65294429db 100644
--- a/storage/connect/json.cpp
+++ b/storage/connect/json.cpp
@@ -54,6 +54,7 @@ char *GetExceptionDesc(PGLOBAL g, unsigned int e);
#endif // SE_CATCH
char *GetJsonNull(void);
+int GetDefaultPrec(void);
/***********************************************************************/
/* IsNum: check whether this string is all digits. */
@@ -1762,7 +1763,7 @@ void JVALUE::SetBigint(PGLOBAL g, long long ll)
void JVALUE::SetFloat(PGLOBAL g, double f)
{
F = f;
- Nd = 6;
+ Nd = GetDefaultPrec();
DataType = TYPE_DBL;
} // end of SetFloat
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 49a36407cec..bf6c9991800 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -70,7 +70,7 @@ JSNX::JSNX(PGLOBAL g, PJSON row, int type, int len, int prec, my_bool wr)
Jp = NULL;
Nodes = NULL;
Value = AllocateValue(g, type, len, prec);
- MulVal = NULL;
+ //MulVal = NULL;
Jpath = NULL;
Buf_Type = type;
Long = len;
@@ -196,38 +196,6 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
return true;
} // 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;
} // end of SetArrayOptions
@@ -310,7 +278,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
} // endfor i, p
Nod = i;
- MulVal = AllocateValue(g, Value);
+ //MulVal = AllocateValue(g, Value);
if (trace(1))
for (i = 0; i < Nod; i++)
@@ -322,23 +290,6 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
} // 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. */
/*********************************************************************************/
void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val)
@@ -348,6 +299,7 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val)
if (Jb) {
vp->SetValue_psz(Serialize(g, val->GetJsp(), NULL, 0));
+ Jb = false;
} else switch (val->GetValType()) {
case TYPE_DTM:
case TYPE_STRG:
@@ -393,6 +345,52 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val)
} // 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: */
/*********************************************************************************/
PJVAL JSNX::GetJson(PGLOBAL g)
@@ -435,8 +433,7 @@ PJVAL JSNX::GetRowValue(PGLOBAL g, PJSON row, int i, my_bool b)
val = new(g) JVALUE(g, Value);
return val;
} else if (Nodes[i].Op == OP_XX) {
- Jb = b;
- return new(g)JVALUE(row);
+ return MakeJson(g, row, i);
} else switch (row->GetType()) {
case TYPE_JOB:
if (!Nodes[i].Key) {
@@ -503,6 +500,88 @@ PVAL JSNX::ExpandArray(PGLOBAL g, PJAR arp, int n)
} // 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: */
/*********************************************************************************/
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;
bool err;
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;
JVALUE jval;
@@ -543,9 +623,9 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
SetJsonValue(g, vp, jvp);
continue;
} else
- SetJsonValue(g, MulVal, jvp);
+ SetJsonValue(g, mulval, jvp);
- if (!MulVal->IsNull()) {
+ if (!mulval->IsNull()) {
switch (op) {
case OP_CNC:
if (Nodes[n].CncVal) {
@@ -553,18 +633,18 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
err = vp->Compute(g, val, 1, op);
} // endif CncVal
- val[0] = MulVal;
+ val[0] = mulval;
err = vp->Compute(g, val, 1, op);
break;
// case OP_NUM:
case OP_SEP:
- val[0] = Nodes[n].Valp;
- val[1] = MulVal;
+ val[0] = vp;
+ val[1] = mulval;
err = vp->Compute(g, val, 2, OP_ADD);
break;
default:
- val[0] = Nodes[n].Valp;
- val[1] = MulVal;
+ val[0] = vp;
+ val[1] = mulval;
err = vp->Compute(g, val, 2, op);
} // endswitch Op
@@ -586,9 +666,9 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (op == OP_SEP) {
// Calculate average
- MulVal->SetValue(nv);
+ mulval->SetValue(nv);
val[0] = vp;
- val[1] = MulVal;
+ val[1] = mulval;
if (vp->Compute(g, val, 2, OP_DIV))
vp->Reset();
diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h
index 689a02ebbc5..ada0dbcd96b 100644
--- a/storage/connect/jsonudf.h
+++ b/storage/connect/jsonudf.h
@@ -44,7 +44,6 @@ typedef struct _jnode {
PSZ Key; // The key used for object
OPVAL Op; // Operator used for this node
PVAL CncVal; // To cont value used for OP_CNC
- PVAL Valp; // The internal array VALUE
int Rank; // The rank in array
int Rx; // Read row number
int Nx; // Next to read row number
@@ -334,8 +333,9 @@ protected:
my_bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm);
PVAL GetColumnValue(PGLOBAL g, PJSON row, int i);
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 MakeJson(PGLOBAL g, PJSON jsp);
+ PJVAL MakeJson(PGLOBAL g, PJSON jsp, int i);
void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val);
PJSON GetRow(PGLOBAL g);
my_bool CompareValues(PJVAL v1, PJVAL v2);
@@ -358,7 +358,7 @@ protected:
JOUTSTR *Jp;
JNODE *Nodes; // The intermediate objects
PVAL Value;
- PVAL MulVal; // To value used by multiple column
+ //PVAL MulVal; // To value used by multiple column
char *Jpath; // The json path
int Buf_Type;
int Long;
diff --git a/storage/connect/mysql-test/connect/r/json_udf.result b/storage/connect/mysql-test/connect/r/json_udf.result
index 8315fc3f3bf..e3ee84d9084 100644
--- a/storage/connect/mysql-test/connect/r/json_udf.result
+++ b/storage/connect/mysql-test/connect/r/json_udf.result
@@ -322,7 +322,7 @@ JsonGet_String(Json_Make_Array(45,28,36,45,89),'3')
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";
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');
JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.0')
36
@@ -349,10 +349,10 @@ Warnings:
Warning 1105
SELECT department, JsonGet_String(Json_Make_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
+0021 28500.000000
+0318 72230.000000
+0319 89800.950000
+2452 45900.000000
SELECT JsonGet_Int(@j1, '4');
JsonGet_Int(@j1, '4')
89
diff --git a/storage/connect/tabbson.cpp b/storage/connect/tabbson.cpp
index db63b8e78db..bbc2c54c80f 100644
--- a/storage/connect/tabbson.cpp
+++ b/storage/connect/tabbson.cpp
@@ -881,7 +881,7 @@ PBVAL BCUTIL::GetRowValue(PGLOBAL g, PBVAL row, int i)
} // endfor i
return bvp;
-} // end of GetColumnValue
+} // end of GetRowValue
/***********************************************************************/
/* GetColumnValue: */
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index fb5a64c7d55..96aa5db683a 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -1610,7 +1610,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
/***********************************************************************/
/* 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()) {
strcpy(g->Message, "Cannot make Json for a numeric column");
@@ -1621,6 +1621,7 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
} // endif Warned
Value->Reset();
+ return Value;
#if 0
} else if (Value->GetType() == TYPE_BIN) {
if ((unsigned)Value->GetClen() >= sizeof(BSON)) {
@@ -1634,13 +1635,66 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
Value->SetValue_char(NULL, 0);
} // endif Clen
#endif // 0
- } else
- Value->SetValue_psz(Serialize(g, jsp, NULL, 0));
+ } else if (n < Nod - 1) {
+ 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;
} // 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. */
/***********************************************************************/
void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL jvp)
@@ -1740,7 +1794,7 @@ PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i)
Value->SetValue(row->GetType() == TYPE_JAR ? ((PJAR)row)->size() : 1);
return(Value);
} else if (Nodes[i].Op == OP_XX) {
- return MakeJson(G, row);
+ return MakeJson(G, row, i);
} else switch (row->GetType()) {
case TYPE_JOB:
if (!Nodes[i].Key) {
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index b47dc9b0665..147bef484a6 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -230,8 +230,9 @@ public:
PVAL GetColumnValue(PGLOBAL g, PJSON row, int i);
PVAL ExpandArray(PGLOBAL g, PJAR arp, int n);
PVAL CalculateArray(PGLOBAL g, PJAR arp, int n);
- PVAL MakeJson(PGLOBAL g, PJSON jsp);
- void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val);
+ PVAL MakeJson(PGLOBAL g, PJSON jsp, int n);
+ PJVAL GetRowValue(PGLOBAL g, PJSON row, int i);
+ void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val);
PJSON GetRow(PGLOBAL g);
// Default constructor not to be used