Commit fd1ca70b authored by Olivier Bertrand's avatar Olivier Bertrand

- Enhance JSON tables handling.

modified:
  storage/connect/json.cpp
  storage/connect/json.h
  storage/connect/mysql-test/connect/r/json.result
  storage/connect/mysql-test/connect/t/json.test
  storage/connect/tabjson.cpp
  storage/connect/tabjson.h

- Avoid crash when a partition table name pattern is ill formed
  (such as using place holder %i instead of %s)
modified:
  storage/connect/ha_connect.cc
parent 9a2dc7df
......@@ -997,8 +997,12 @@ char *ha_connect::GetRealString(const char *s)
char *sv;
if (IsPartitioned() && s) {
sv= (char*)PlugSubAlloc(xp->g, NULL, strlen(s) + strlen(partname));
// sv= (char*)PlugSubAlloc(xp->g, NULL, strlen(s) + strlen(partname));
// With wrong string pattern, the size of the constructed string
// can be more than strlen(s) + strlen(partname)
sv= (char*)PlugSubAlloc(xp->g, NULL, 0);
sprintf(sv, s, partname);
PlugSubAlloc(xp->g, NULL, strlen(sv) + 1);
} else
sv= (char*)s;
......
......@@ -576,9 +576,9 @@ bool SerializeObject(JOUT *js, PJOB jobp)
else if (js->WriteChr(','))
return true;
if (js->WriteChr('\"') ||
if (js->WriteChr('"') ||
js->WriteStr(pair->Key) ||
js->WriteChr('\"') ||
js->WriteChr('"') ||
js->WriteChr(':') ||
SerializeValue(js, pair->Val))
return true;
......@@ -725,13 +725,13 @@ bool JOUTFILE::Escape(const char *s)
for (unsigned int i = 0; i < strlen(s); i++)
switch (s[i]) {
case '"': fputs("\\\"", Stream); break;
case '\\': fputs("\\\\", Stream); break;
case '\t': fputs("\\t", Stream); break;
case '\n': fputs("\\n", Stream); break;
case '\r': fputs("\\r", Stream); break;
case '\b': fputs("\\b", Stream); break;
case '\f': fputs("\\f", Stream); break;
case '\\': fputs("\\\\", Stream); break;
case '"': fputs("\\\"", Stream); break;
default:
fputc(s[i], Stream);
break;
......
......@@ -18,7 +18,8 @@ enum JTYP {TYPE_STRG = 1,
TYPE_BOOL = 4,
TYPE_INTG = 7,
TYPE_JSON = 12,
TYPE_JAR, TYPE_JOB,
TYPE_JAR,
TYPE_JOB,
TYPE_JVAL};
class JOUT;
......
......@@ -89,8 +89,8 @@ ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher L
UPDATE t1 SET AuthorFN = 'Philippe' WHERE AuthorLN = 'Knab';
SELECT * FROM t1 WHERE ISBN = '9782212090819';
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications Jean-Christophe Bernadac Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications Philippe Knab Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications Philippe Bernadac Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications Franois Knab Construire une application XML Eyrolles Paris 1999
#
# To add an author a new table must be created
#
......@@ -104,8 +104,8 @@ William J. Pardi
INSERT INTO t2 VALUES('Charles','Dickens');
SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications Jean-Christophe Bernadac Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications Philippe Knab Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications Philippe Bernadac Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications Franois Knab Construire une application XML Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
9782840825685 fr applications Charles Dickens XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1;
......@@ -127,11 +127,11 @@ line
"SUBJECT": "applications",
"AUTHOR": [
{
"FIRSTNAME": "Jean-Christophe",
"FIRSTNAME": "Philippe",
"LASTNAME": "Bernadac"
},
{
"FIRSTNAME": "Philippe",
"FIRSTNAME": "Franois",
"LASTNAME": "Knab"
}
],
......@@ -192,7 +192,7 @@ Janet 4 Car 17.00
Janet 5 Beer+Car+Beer+Food 57.00
DROP TABLE t1;
#
# Cannot be fully expanded
# Now it can be fully expanded
#
CREATE TABLE t1 (
WHO CHAR(12),
......@@ -201,7 +201,31 @@ WHAT CHAR(32) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:WHAT',
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
SELECT * FROM t1;
ERROR HY000: Got error 174 'Cannot expand more than one array' from CONNECT
WHO WEEK WHAT AMOUNT
Joe 3 Beer 18.00
Joe 3 Food 12.00
Joe 3 Food 19.00
Joe 3 Car 20.00
Joe 4 Beer 19.00
Joe 4 Beer 16.00
Joe 4 Food 17.00
Joe 4 Food 17.00
Joe 4 Beer 14.00
Joe 5 Beer 14.00
Joe 5 Food 12.00
Beth 3 Beer 16.00
Beth 4 Food 17.00
Beth 4 Beer 15.00
Beth 5 Food 12.00
Beth 5 Beer 20.00
Janet 3 Car 19.00
Janet 3 Food 18.00
Janet 3 Beer 18.00
Janet 4 Car 17.00
Janet 5 Beer 14.00
Janet 5 Car 12.00
Janet 5 Beer 19.00
Janet 5 Food 12.00
DROP TABLE t1;
#
# Expand expense in 3 one week tables
......
......@@ -128,7 +128,7 @@ SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Cannot be fully expanded
--echo # Now it can be fully expanded
--echo #
CREATE TABLE t1 (
WHO CHAR(12),
......@@ -136,7 +136,7 @@ WEEK INT(2) FIELD_FORMAT='WEEK:[X]:NUMBER',
WHAT CHAR(32) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:WHAT',
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
--error ER_GET_ERRMSG
#--error ER_GET_ERRMSG
SELECT * FROM t1;
DROP TABLE t1;
......
......@@ -119,12 +119,12 @@ TDBJSN::TDBJSN(PJDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
Fpos = -1;
Spos = N = 0;
Limit = tdp->Limit;
NextSame = 0;
SameRow = 0;
Xval = -1;
Pretty = tdp->Pretty;
Strict = tdp->Strict;
NextSame = false;
Comma = false;
SameRow = 0;
Xval = -1;
} // end of TDBJSN standard constructor
TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp)
......@@ -137,12 +137,12 @@ TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp)
Spos = tdbp->Spos;
N = tdbp->N;
Limit = tdbp->Limit;
Pretty = tdbp->Pretty;
Strict = tdbp->Strict;
NextSame = tdbp->NextSame;
Comma = tdbp->Comma;
SameRow = tdbp->SameRow;
Xval = tdbp->Xval;
Pretty = tdbp->Pretty;
Strict = tdbp->Strict;
Comma = tdbp->Comma;
} // end of TDBJSN copy constructor
// Used for update
......@@ -221,14 +221,9 @@ bool TDBJSN::OpenDB(PGLOBAL g)
/*******************************************************************/
/* Table already open replace it at its beginning. */
/*******************************************************************/
for (PJCOL cp = (PJCOL)Columns; cp; cp = (PJCOL)cp->GetNext()) {
cp->Nx = 0;
cp->Arp = NULL;
} // endfor cp
Fpos= -1;
Spos = 0;
NextSame = false;
NextSame = 0;
SameRow = 0;
} else {
/*******************************************************************/
......@@ -292,7 +287,8 @@ int TDBJSN::ReadDB(PGLOBAL g)
N++;
if (NextSame) {
SameRow++;
SameRow = NextSame;
NextSame = 0;
return RC_OK;
} else if ((rc = TDBDOS::ReadDB(g)) == RC_OK)
if (!IsRead() && ((rc = ReadBuffer(g)) != RC_OK)) {
......@@ -333,21 +329,20 @@ int TDBJSN::ReadDB(PGLOBAL g)
} // end of PrepareWriting
/* ----------------------------- JSNCOL ------------------------------- */
/* ---------------------------- JSONCOL ------------------------------ */
/***********************************************************************/
/* JSNCOL public constructor. */
/* JSONCOL public constructor. */
/***********************************************************************/
JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
: DOSCOL(g, cdp, tdbp, cprec, i, "DOS")
{
Tjp = (TDBJSN *)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
Arp = NULL;
Jpath = cdp->GetFmt();
MulVal = NULL;
Nodes = NULL;
Nod = Nx =0;
Ival = -1;
Nod = 0;
Xnod = -1;
Xpd = false;
Parsed = false;
} // end of JSONCOL constructor
......@@ -359,13 +354,11 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
JSONCOL::JSONCOL(JSONCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
{
Tjp = col1->Tjp;
Arp = col1->Arp;
Jpath = col1->Jpath;
MulVal = col1->MulVal;
Nodes = col1->Nodes;
Nod = col1->Nod;
Ival = col1->Ival;
Nx = col1->Nx;
Xnod = col1->Xnod;
Xpd = col1->Xpd;
Parsed = col1->Parsed;
} // end of JSONCOL copy constructor
......@@ -387,17 +380,16 @@ bool JSONCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
} // end of SetBuffer
/***********************************************************************/
/* Analyse array processing options. */
/* Check whether this object is expanded. */
/***********************************************************************/
bool JSONCOL::CheckExpand(PGLOBAL g, int i, PSZ nm, bool b)
{
if (Tjp->Xcol && nm && !strcmp(nm, Tjp->Xcol) &&
(Tjp->Xval < 0 || Tjp->Xval == i)) {
if ((Tjp->Xcol && nm && !strcmp(nm, Tjp->Xcol) &&
(Tjp->Xval < 0 || Tjp->Xval == i)) || Xpd) {
Xpd = true; // Expandable object
Nodes[i].Op = OP_XX;
Tjp->Xval = i;
} else if (b) {
strcpy(g->Message, "Cannot expand more than one array");
strcpy(g->Message, "Cannot expand more than one branch");
return true;
} // endif Xcol
......@@ -490,6 +482,38 @@ bool JSONCOL::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);
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
......@@ -507,8 +531,7 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
if (Parsed)
return false; // Already done
if (InitValue(g))
else if (InitValue(g))
return true;
else if (!Jpath)
Jpath = Name;
......@@ -552,47 +575,223 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
{
if (val) {
if (Nodes[n].Op == OP_NUM)
vp->SetValue(1);
else {
again:
switch (val->GetValType()) {
case TYPE_STRG:
case TYPE_INTG:
case TYPE_DBL:
vp->SetValue_pval(val->GetValue());
break;
case TYPE_BOOL:
if (vp->IsTypeNum())
vp->SetValue(val->GetInteger() ? 1 : 0);
else
vp->SetValue_psz((PSZ)(val->GetInteger() ? "true" : "false"));
switch (val->GetValType()) {
case TYPE_STRG:
case TYPE_INTG:
case TYPE_DBL:
vp->SetValue_pval(val->GetValue());
break;
case TYPE_BOOL:
if (vp->IsTypeNum())
vp->SetValue(val->GetInteger() ? 1 : 0);
else
vp->SetValue_psz((PSZ)(val->GetInteger() ? "true" : "false"));
break;
case TYPE_JAR:
SetJsonValue(g, vp, val->GetArray()->GetValue(0), n);
break;
case TYPE_JOB:
// if (!vp->IsTypeNum() || !Strict) {
vp->SetValue_psz(val->GetObject()->GetText(g));
break;
case TYPE_JAR:
val = val->GetArray()->GetValue(0);
goto again;
case TYPE_JOB:
if (!vp->IsTypeNum()) {
vp->SetValue_psz(val->GetObject()->GetText(g));
break;
} // endif Type
// } // endif Type
default:
vp->Reset();
} // endswitch Type
} // endelse
default:
vp->Reset();
} // endswitch Type
} else
vp->Reset();
} // end of SetJsonValue
/***********************************************************************/
/* ReadColumn: */
/***********************************************************************/
void JSONCOL::ReadColumn(PGLOBAL g)
{
if (!Tjp->SameRow || Xnod >= Tjp->SameRow)
Value->SetValue_pval(GetColumnValue(g, Tjp->Row, 0));
} // end of ReadColumn
/***********************************************************************/
/* GetColumnValue: */
/***********************************************************************/
PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i)
{
int n = Nod - 1;
int nextsame = 0;
bool expd = false;
PJAR arp;
PJVAL val = NULL;
//for (; i < Nod-1 && row; i++) {
for (; i < Nod && row; i++) {
if (Nodes[i].Op == OP_NUM) {
Value->SetValue(row->GetType() == TYPE_JAR ? row->size() : 1);
return(Value);
} else switch (row->GetType()) {
case TYPE_JOB:
if (!Nodes[i].Key) {
// Expected Array was not there
if (i < Nod-1)
continue;
else
val = new(g) JVALUE(row);
} else
val = ((PJOB)row)->GetValue(Nodes[i].Key);
break;
case TYPE_JAR:
arp = (PJAR)row;
if (!Nodes[i].Key) {
if (Nodes[i].Op != OP_NULL) {
if (Nodes[i].Rank) {
val = arp->GetValue(Nodes[i].Rank - 1);
} else if (Nodes[i].Op == OP_XX) {
return ExpandArray(g, arp, i);
} else
return CalculateArray(g, arp, i);
} else
val = NULL;
} else if (i < Nod-1) {
strcpy(g->Message, "Unexpected array");
val = NULL; // Not an expected array
} else
val = arp->GetValue(0);
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
SetJsonValue(g, Value, val, n);
return Value;
} // end of GetColumnValue
/***********************************************************************/
/* ExpandArray: */
/***********************************************************************/
PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
{
int ars;
PJVAL jvp;
JVALUE jval;
ars = MY_MIN(Tjp->Limit, arp->size());
jvp = arp->GetValue(Nodes[n].Nx);
if (n < Nod - 1 && jvp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvp->GetJson(), n + 1));
jvp = &jval;
} // endif n
if (n >= Tjp->NextSame) {
if (++Nodes[n].Nx == ars) {
Nodes[n].Nx = 0;
Xnod = 0;
} else
Xnod = n;
Tjp->NextSame = Xnod;
} // endif NextSame
SetJsonValue(g, Value, jvp, n);
return Value;
} // end of ExpandArray
/***********************************************************************/
/* CalculateArray: */
/***********************************************************************/
PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
{
int i, ars;
bool err;
OPVAL op = Nodes[n].Op;
PVAL val[2], vp = Nodes[n].Valp;
PJVAL jvp;
JVALUE jval;
vp->Reset();
ars = MY_MIN(Tjp->Limit, arp->size());
for (i = 0; i < ars; i++) {
jvp = arp->GetValue(i);
if (n < Nod - 1 && jvp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvp->GetJson(), n + 1));
jvp = &jval;
} // endif n
if (!i) {
SetJsonValue(g, vp, jvp, n);
continue;
} else
SetJsonValue(g, MulVal, jvp, n);
if (!MulVal->IsZero()) {
switch (op) {
case OP_CNC:
if (Nodes[n].CncVal) {
val[0] = Nodes[n].CncVal;
err = vp->Compute(g, val, 1, op);
} // endif CncVal
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;
err = vp->Compute(g, val, 2, OP_ADD);
break;
default:
val[0] = Nodes[n].Valp;
val[1] = MulVal;
err = vp->Compute(g, val, 2, op);
} // endswitch Op
if (err)
vp->Reset();
} // endif Zero
} // endfor i
if (op == OP_SEP) {
// Calculate average
MulVal->SetValue(ars);
val[0] = vp;
val[1] = MulVal;
if (vp->Compute(g, val, 2, OP_DIV))
vp->Reset();
} // endif Op
return vp;
} // end of CalculateArray
/***********************************************************************/
/* GetRow: Get the object containing this column. */
/***********************************************************************/
PJSON JSONCOL::GetRow(PGLOBAL g, int mode)
PJSON JSONCOL::GetRow(PGLOBAL g)
{
PJVAL val;
PJAR arp;
......@@ -610,23 +809,15 @@ PJSON JSONCOL::GetRow(PGLOBAL g, int mode)
case TYPE_JAR:
if (!Nodes[i].Key) {
if (Nodes[i].Op != OP_NULL) {
Ival = i;
arp = (PJAR)row;
if (mode < 2) // First pass
Arp = arp;
if (Nodes[i].Op != OP_XX) {
if (Nodes[i].Rank)
val = arp->GetValue(Nodes[i].Rank - 1);
else
val = arp->GetValue(arp == Arp ? Nx : 0);
} else
val = arp->GetValue(Tjp->SameRow);
} else
val = NULL;
if (Nodes[i].Rank)
val = arp->GetValue(Nodes[i].Rank - 1);
else
val = arp->GetValue(Nodes[i].Nx);
} else
val = NULL;
} else {
strcpy(g->Message, "Unexpected array");
......@@ -644,7 +835,7 @@ PJSON JSONCOL::GetRow(PGLOBAL g, int mode)
if (val) {
row = val->GetJson();
} else if (mode == 1) { // mode write
} else {
// Construct missing objects
for (i++; row && i < Nod; i++) {
if (!Nodes[i].Key) {
......@@ -668,139 +859,13 @@ PJSON JSONCOL::GetRow(PGLOBAL g, int mode)
} // endfor i
break;
} else
row = NULL;
} // endelse
} // endfor i
return row;
} // end of GetRow
/***********************************************************************/
/* ReadColumn: */
/***********************************************************************/
void JSONCOL::ReadColumn(PGLOBAL g)
{
int mode = 0, n = Nod - 1;
PJSON row;
PJVAL val = NULL;
evenmore:
row = GetRow(g, mode);
more:
if (row) switch (row->GetType()) {
case TYPE_JOB:
if (Nodes[n].Key)
val = row->GetValue(Nodes[n].Key);
else
val = new(g) JVALUE(row);
break;
case TYPE_JAR:
// Multiple column ?
if (Nodes[n].Op != OP_NULL) {
Arp = (PJAR)row;
val = Arp->GetValue(Nodes[n].Rank > 0 ?
Nodes[n].Rank - 1 :
Nodes[n].Op == OP_XX ? Tjp->SameRow : Nx);
Ival = n;
} else
val = NULL;
break;
case TYPE_JVAL:
val = (PJVAL)row;
break;
default:
sprintf(g->Message, "Wrong return value type %d", row->GetType());
Value->Reset();
return;
} // endswitch Type
if (!Nx /*|| (Xpd)*/)
SetJsonValue(g, Value, val, n);
if (Arp) {
// Multiple column
int ars = (Nodes[Ival].Rank > 0) ? 1 : MY_MIN(Tjp->Limit, Arp->size());
if (Nodes[Ival].Op == OP_XX) {
if (ars > Tjp->SameRow + 1)
Tjp->NextSame = true; // More to come
else {
Tjp->NextSame = false;
Arp = NULL;
} // endelse
} else {
if (Nx && val) {
SetJsonValue(g, MulVal, val, Ival);
if (!MulVal->IsZero()) {
PVAL val[2];
bool err;
switch (Nodes[Ival].Op) {
case OP_CNC:
if (Nodes[Ival].CncVal) {
val[0] = Nodes[Ival].CncVal;
err = Value->Compute(g, val, 1, Nodes[Ival].Op);
} // endif CncVal
val[0] = MulVal;
err = Value->Compute(g, val, 1, Nodes[Ival].Op);
break;
case OP_NUM:
case OP_SEP:
val[0] = Value;
val[1] = MulVal;
err = Value->Compute(g, val, 2, OP_ADD);
break;
default:
val[0] = Value;
val[1] = MulVal;
err = Value->Compute(g, val, 2, Nodes[Ival].Op);
} // endswitch Op
if (err)
Value->Reset();
} // endif Zero
} // endif Nx
if (ars > ++Nx) {
if (Ival != n) {
mode = 2;
goto evenmore;
} else
goto more;
} else {
if (Nodes[Ival].Op == OP_SEP) {
// Calculate average
PVAL val[2];
MulVal->SetValue(ars);
val[0] = Value;
val[1] = MulVal;
if (Value->Compute(g, val, 2, OP_DIV))
Value->Reset();
} // endif Op
Arp = NULL;
Nx = 0;
} // endif ars
} // endif Op
} // endif Arp
} // end of ReadColumn
/***********************************************************************/
/* WriteColumn: */
/***********************************************************************/
......@@ -821,7 +886,7 @@ void JSONCOL::WriteColumn(PGLOBAL g)
PJOB objp = NULL;
PJAR arp = NULL;
PJVAL jvp = NULL;
PJSON row = GetRow(g, 1);
PJSON row = GetRow(g);
JTYP type = row->GetType();
switch (row->GetType()) {
......@@ -1176,11 +1241,6 @@ bool TDBJSON::OpenDB(PGLOBAL g)
/*******************************************************************/
/* Table already open replace it at its beginning. */
/*******************************************************************/
for (PJCOL cp = (PJCOL)Columns; cp; cp = (PJCOL)cp->GetNext()) {
cp->Nx = 0;
cp->Arp = NULL;
} // endfor cp
Fpos= -1;
Spos = 0;
NextSame = false;
......@@ -1218,7 +1278,8 @@ int TDBJSON::ReadDB(PGLOBAL g)
N++;
if (NextSame) {
SameRow++;
SameRow = NextSame;
NextSame = false;
rc = RC_OK;
} else if (++Fpos < (signed)Doc->size()) {
Row = Doc->GetValue(Fpos);
......
......@@ -15,6 +15,7 @@ enum JMODE {MODE_OBJECT, MODE_ARRAY, MODE_VALUE};
typedef class JSONDEF *PJDEF;
typedef class TDBJSON *PJTDB;
typedef class JSONCOL *PJCOL;
typedef class JARLST *PJARS;
class TDBJSN;
......@@ -25,7 +26,9 @@ 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 Nx; // Same row number
} JNODE, *PJNODE;
/***********************************************************************/
......@@ -98,11 +101,11 @@ class TDBJSN : public TDBDOS {
int N; // The current Rownum
int Limit; // Limit of multiple values
int Pretty; // Depends on file structure
bool Strict; // Strict syntax checking
bool NextSame; // Same next row
bool Comma; // Row has final comma
int NextSame; // Same next row
int SameRow; // Same row nb
int Xval; // Index of expandable array
bool Strict; // Strict syntax checking
bool Comma; // Row has final comma
}; // end of class TDBJSN
/* -------------------------- JSONCOL class -------------------------- */
......@@ -130,8 +133,11 @@ class JSONCOL : public DOSCOL {
protected:
bool CheckExpand(PGLOBAL g, int i, PSZ nm, bool b);
bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm);
PJSON GetRow(PGLOBAL g, int mode);
PVAL GetColumnValue(PGLOBAL g, PJSON row, int i);
PVAL ExpandArray(PGLOBAL g, PJAR arp, int n);
PVAL CalculateArray(PGLOBAL g, PJAR arp, int n);
void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n);
PJSON GetRow(PGLOBAL g);
// Default constructor not to be used
JSONCOL(void) {}
......@@ -139,12 +145,10 @@ class JSONCOL : public DOSCOL {
// Members
TDBJSN *Tjp; // To the JSN table block
PVAL MulVal; // To value used by multiple column
PJAR Arp; // The intermediate array
char *Jpath; // The json path
JNODE *Nodes ; // The intermediate objects
JNODE *Nodes; // The intermediate objects
int Nod; // The number of intermediate objects
int Ival; // Index of multiple values
int Nx; // The last read sub-row
int Xnod; // Index of multiple values
bool Xpd; // True for expandable column
bool Parsed; // True when parsed
}; // end of class JSONCOL
......
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