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