Commit ceacffbb authored by Olivier Bertrand's avatar Olivier Bertrand

- Fix pretty=2 Tabjson bug on INSERT.

  Occuring when inserting more than one line in one statement.
  modified:   storage/connect/json.cpp

- Fix a wrong if statement
  modified:   storage/connect/tabjson.cpp

- Continue BSON implementation
  modified:   storage/connect/bson.cpp
  modified:   storage/connect/bson.h
  modified:   storage/connect/filamtxt.cpp
  modified:   storage/connect/filamtxt.h
  modified:   storage/connect/tabbson.cpp
  modified:   storage/connect/tabbson.h

- No need anymore
  deleted:    storage/connect/mysql-test/connect/r/bson.result
  deleted:    storage/connect/mysql-test/connect/t/bson.test
parent aa10789f
......@@ -872,7 +872,18 @@ void BJSON::SubSet(bool b)
} // end of SubSet
/* ------------------------ Bobject functions ------------------------ */
/*********************************************************************************/
/* Set the beginning of suballocations. */
/*********************************************************************************/
void BJSON::MemSet(size_t size)
{
PPOOLHEADER pph = (PPOOLHEADER)G->Sarea;
pph->To_Free = size + sizeof(POOLHEADER);
pph->FreeBlk = G->Sarea_Size - pph->To_Free;
} // end of MemSet
/* ------------------------ Bobject functions ------------------------ */
/***********************************************************************/
/* Sub-allocate and initialize a BPAIR. */
......@@ -1187,18 +1198,17 @@ void BJSON::MergeArray(PBVAL bap1, PBVAL bap2)
void BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n)
{
CheckType(bap, TYPE_JAR);
int i = 0;
PBVAL bvp = NULL, pvp = NULL;
if (bap->To_Val) {
for (int i = 0; bvp = GetArray(bap); i++, bvp = GetNext(bvp))
if (bap->To_Val)
for (bvp = GetArray(bap); bvp; i++, bvp = GetNext(bvp))
if (i == n) {
SetValueVal(bvp, nvp);
return;
} else
pvp = bvp;
} // endif bap
if (!bvp)
AddArrayValue(bap, MOF(nvp));
......@@ -1264,7 +1274,8 @@ void BJSON::DeleteValue(PBVAL bap, int n)
bap->Nd--;
break;
} // endif i
} else
pvp = bvp;
} // end of DeleteValue
......@@ -1587,17 +1598,17 @@ PBVAL BJSON::SetValue(PBVAL vlp, PVAL valp)
} else switch (valp->GetType()) {
case TYPE_DATE:
if (((DTVAL*)valp)->IsFormatted())
vlp->To_Val = MOF(PlugDup(G, valp->GetCharValue()));
vlp->To_Val = DupStr(valp->GetCharValue());
else {
char buf[32];
vlp->To_Val = MOF(PlugDup(G, valp->GetCharString(buf)));
vlp->To_Val = DupStr(valp->GetCharString(buf));
} // endif Formatted
vlp->Type = TYPE_DTM;
break;
case TYPE_STRING:
vlp->To_Val = MOF(PlugDup(G, valp->GetCharValue()));
vlp->To_Val = DupStr(valp->GetCharValue());
vlp->Type = TYPE_STRG;
break;
case TYPE_DOUBLE:
......@@ -1608,7 +1619,7 @@ PBVAL BJSON::SetValue(PBVAL vlp, PVAL valp)
vlp->F = (float)valp->GetFloatValue();
vlp->Type = TYPE_FLOAT;
} else {
double *dp = (double*)PlugSubAlloc(G, NULL, sizeof(double));
double *dp = (double*)BsonSubAlloc(sizeof(double));
*dp = valp->GetFloatValue();
vlp->To_Val = MOF(dp);
......@@ -1629,7 +1640,7 @@ PBVAL BJSON::SetValue(PBVAL vlp, PVAL valp)
vlp->N = valp->GetIntValue();
vlp->Type = TYPE_INTG;
} else {
longlong* llp = (longlong*)PlugSubAlloc(G, NULL, sizeof(longlong));
longlong* llp = (longlong*)BsonSubAlloc(sizeof(longlong));
*llp = valp->GetBigintValue();
vlp->To_Val = MOF(llp);
......
......@@ -76,6 +76,7 @@ class BJSON : public BLOCK {
void* GetBase(void) { return Base; }
void SubSet(bool b = false);
void MemSave(void) {G->Saved_Size = ((PPOOLHEADER)G->Sarea)->To_Free;}
void MemSet(size_t size);
void GetMsg(PGLOBAL g) { if (g != G) strcpy(g->Message, G->Message); }
// SubAlloc functions
......
......@@ -805,8 +805,8 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
Placed = false;
if (trace(2))
htrc(" About to read: stream=%p To_Buf=%p Buflen=%d\n",
Stream, To_Buf, Buflen);
htrc(" About to read: stream=%p To_Buf=%p Buflen=%d Fpos=%d\n",
Stream, To_Buf, Buflen, Fpos);
if (fgets(To_Buf, Buflen, Stream)) {
p = To_Buf + strlen(To_Buf) - 1;
......@@ -1665,6 +1665,7 @@ void BLKFAM::Rewind(void)
/* --------------------------- Class BINFAM -------------------------- */
#if 0
/***********************************************************************/
/* BIN GetFileLength: returns file size in number of bytes. */
/***********************************************************************/
......@@ -1692,7 +1693,6 @@ int BINFAM::Cardinality(PGLOBAL g)
return (g) ? -1 : 0;
} // end of Cardinality
#if 0
/***********************************************************************/
/* OpenTableFile: Open a DOS/UNIX table file using C standard I/Os. */
/***********************************************************************/
......@@ -1747,11 +1747,29 @@ bool BINFAM::AllocateBuffer(PGLOBAL g)
// Lrecl is Ok
Buflen = Lrecl;
// Buffer will be allocated separately
if (mode == MODE_ANY) {
xtrc(1, "SubAllocating a buffer of %d bytes\n", Buflen);
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
} else if (UseTemp || mode == MODE_DELETE) {
// Have a big buffer to move lines
Dbflen = Buflen * DOS_BUFF_LEN;
DelBuf = PlugSubAlloc(g, NULL, Dbflen);
} // endif mode
return false;
#if 0
MODE mode = Tdbp->GetMode();
// Lrecl is Ok
Dbflen = Buflen = Lrecl;
if (trace(1))
htrc("SubAllocating a buffer of %d bytes\n", Buflen);
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
DelBuf = To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
return false;
#endif // 0
} // end of AllocateBuffer
#if 0
......@@ -1830,8 +1848,8 @@ int BINFAM::ReadBuffer(PGLOBAL g)
} else
Placed = false;
xtrc(2, " About to read: bstream=%p To_Buf=%p Buflen=%d\n",
Stream, To_Buf, Buflen);
xtrc(2, " About to read: bstream=%p To_Buf=%p Buflen=%d Fpos=%d\n",
Stream, To_Buf, Buflen, Fpos);
// Read the prefix giving the row length
if (!fread(&Recsize, sizeof(size_t), 1, Stream)) {
......@@ -1848,7 +1866,6 @@ int BINFAM::ReadBuffer(PGLOBAL g)
if (fread(To_Buf, Recsize, 1, Stream)) {
xtrc(2, " Read: To_Buf=%p Recsize=%zd\n", To_Buf, Recsize);
// memcpy(Tdbp->GetLine(), To_Buf, Recsize);
num_read++;
rc = RC_OK;
} else if (feof(Stream)) {
......@@ -1876,6 +1893,50 @@ int BINFAM::WriteBuffer(PGLOBAL g)
int curpos = 0;
bool moved = true;
// T_Stream is the temporary stream or the table file stream itself
if (!T_Stream) {
if (UseTemp && Tdbp->GetMode() == MODE_UPDATE) {
if (OpenTempFile(g))
return RC_FX;
} else
T_Stream = Stream;
} // endif T_Stream
if (Tdbp->GetMode() == MODE_UPDATE) {
/*******************************************************************/
/* Here we simply rewrite a record on itself. There are two cases */
/* were another method should be used, a/ when Update apply to */
/* the whole file, b/ when updating the last field of a variable */
/* length file. The method could be to rewrite a new file, then */
/* to erase the old one and rename the new updated file. */
/*******************************************************************/
curpos = ftell(Stream);
if (trace(1))
htrc("Last : %d cur: %d\n", Fpos, curpos);
if (UseTemp) {
/*****************************************************************/
/* We are using a temporary file. */
/* Before writing the updated record, we must eventually copy */
/* all the intermediate records that have not been updated. */
/*****************************************************************/
if (MoveIntermediateLines(g, &moved))
return RC_FX;
Spos = curpos; // New start position
} else
// Update is directly written back into the file,
// with this (fast) method, record size cannot change.
if (fseek(Stream, Fpos, SEEK_SET)) {
sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
return RC_FX;
} // endif
} // endif mode
/*********************************************************************/
/* Prepare writing the line. */
/*********************************************************************/
......@@ -1884,17 +1945,23 @@ int BINFAM::WriteBuffer(PGLOBAL g)
/*********************************************************************/
/* Now start the writing process. */
/*********************************************************************/
if (fwrite(&Recsize, sizeof(size_t), 1, Stream) != 1) {
if (fwrite(&Recsize, sizeof(size_t), 1, T_Stream) != 1) {
sprintf(g->Message, "Error %d writing prefix to %s",
errno, To_File);
return RC_FX;
} else if (fwrite(To_Buf, Recsize, 1, Stream) != 1) {
} else if (fwrite(To_Buf, Recsize, 1, T_Stream) != 1) {
sprintf(g->Message, "Error %d writing %zd bytes to %s",
errno, Recsize, To_File);
return RC_FX;
} // endif fwrite
xtrc(1, "write done\n");
if (Tdbp->GetMode() == MODE_UPDATE && moved)
if (fseek(Stream, curpos, SEEK_SET)) {
sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno));
return RC_FX;
} // endif
xtrc(1, "Binary write done\n");
return RC_OK;
} // end of WriteBuffer
......@@ -2023,7 +2090,6 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_OK; // All is correct
} // end of DeleteRecords
#endif // 0
/***********************************************************************/
/* Table file close routine for DOS access method. */
......@@ -2049,4 +2115,4 @@ void BINFAM::Rewind(void)
Rows = 0;
OldBlk = CurBlk = -1;
} // end of Rewind
#endif // 0
......@@ -229,20 +229,20 @@ class DllExport BINFAM : public DOSFAM {
// Methods
//virtual void Reset(void) {TXTFAM::Reset();}
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g);
//virtual int GetFileLength(PGLOBAL g);
//virtual int Cardinality(PGLOBAL g);
virtual int MaxBlkSize(PGLOBAL g, int s) {return s;}
virtual bool AllocateBuffer(PGLOBAL g);
//virtual int GetRowID(void);
//virtual bool RecordPos(PGLOBAL g);
//virtual bool SetPos(PGLOBAL g, int recpos);
virtual int SkipRecord(PGLOBAL g, bool header) {return 0;}
virtual int SkipRecord(PGLOBAL g, bool header) {return RC_OK;}
//virtual bool OpenTableFile(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g);
//virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void);
//virtual void CloseTableFile(PGLOBAL g, bool abort);
//virtual void Rewind(void);
//protected:
//virtual int InitDelete(PGLOBAL g, int fpos, int spos);
......
......@@ -1665,7 +1665,7 @@ void JVALUE::SetValue(PGLOBAL g, PVAL valp)
} else switch (valp->GetType()) {
case TYPE_DATE:
if (((DTVAL*)valp)->IsFormatted())
Strp = valp->GetCharValue();
Strp = PlugDup(g, valp->GetCharValue());
else {
char buf[32];
......@@ -1675,7 +1675,7 @@ void JVALUE::SetValue(PGLOBAL g, PVAL valp)
DataType = TYPE_DTM;
break;
case TYPE_STRING:
Strp = valp->GetCharValue();
Strp = PlugDup(g, valp->GetCharValue());
DataType = TYPE_STRG;
break;
case TYPE_DOUBLE:
......
#
# Testing doc samples
#
CREATE TABLE t1
(
ISBN CHAR(15),
LANG CHAR(2),
SUBJECT CHAR(32),
AUTHOR CHAR(64),
TITLE CHAR(32),
TRANSLATION CHAR(32),
TRANSLATOR CHAR(80),
PUBLISHER CHAR(32),
DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json';
SELECT * FROM t1;
ISBN LANG SUBJECT AUTHOR TITLE TRANSLATION TRANSLATOR PUBLISHER DATEPUB
9782212090819 fr applications Jean-Christophe Bernadac, Franois Knab Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1;
#
# Testing Jpath. Get the number of authors
#
CREATE TABLE t1
(
ISBN CHAR(15),
Language CHAR(2) JPATH='$.LANG',
Subject CHAR(32) JPATH='$.SUBJECT',
Authors INT(2) JPATH='$.AUTHOR[#]',
Title CHAR(32) JPATH='$.TITLE',
Translation CHAR(32) JPATH='$.TRANSLATION',
Translator CHAR(80) JPATH='$.TRANSLATOR',
Publisher CHAR(20) JPATH='$.PUBLISHER.NAME',
Location CHAR(16) JPATH='$.PUBLISHER.PLACE',
Year int(4) JPATH='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json';
SELECT * FROM t1;
ISBN Language Subject Authors Title Translation Translator Publisher Location Year
9782212090819 fr applications 2 Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications 1 XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1;
#
# Concatenates the authors
#
CREATE TABLE t1
(
ISBN CHAR(15),
Language CHAR(2) JPATH='$.LANG',
Subject CHAR(32) JPATH='$.SUBJECT',
AuthorFN CHAR(128) JPATH='$.AUTHOR[" and "].FIRSTNAME',
AuthorLN CHAR(128) JPATH='$.AUTHOR[" and "].LASTNAME',
Title CHAR(32) JPATH='$.TITLE',
Translation CHAR(32) JPATH='$.TRANSLATION',
Translator CHAR(80) JPATH='$.TRANSLATOR',
Publisher CHAR(20) JPATH='$.PUBLISHER.NAME',
Location CHAR(16) JPATH='$.PUBLISHER.PLACE',
Year int(4) JPATH='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json';
SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications Jean-Christophe and Franois Bernadac and Knab Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1;
#
# Testing expanding authors
#
CREATE TABLE t1
(
ISBN CHAR(15),
Language CHAR(2) JPATH='$.LANG',
Subject CHAR(32) JPATH='$.SUBJECT',
AuthorFN CHAR(128) JPATH='$.AUTHOR[*].FIRSTNAME',
AuthorLN CHAR(128) JPATH='$.AUTHOR[*].LASTNAME',
Title CHAR(32) JPATH='$.TITLE',
Translation CHAR(32) JPATH='$.TRANSLATION',
Translator CHAR(80) JPATH='$.TRANSLATOR',
Publisher CHAR(20) JPATH='$.PUBLISHER.NAME',
Location CHAR(16) JPATH='$.PUBLISHER.PLACE',
Year int(4) JPATH='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json';
SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications Jean-Christophe Bernadac Construire une application XML NULL NULL Eyrolles Paris 1999
9782212090819 fr applications Franois Knab Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
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 NULL NULL Eyrolles Paris 1999
9782212090819 fr applications Philippe Knab Construire une application XML NULL NULL Eyrolles Paris 1999
#
# To add an author a new table must be created
#
CREATE TABLE t2 (
FIRSTNAME CHAR(32),
LASTNAME CHAR(32))
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json' OPTION_LIST='Object=$[1].AUTHOR';
SELECT * FROM t2;
FIRSTNAME LASTNAME
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 NULL NULL Eyrolles Paris 1999
9782212090819 fr applications Philippe Knab Construire une application XML NULL NULL 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;
DROP TABLE t2;
#
# Check the biblio file has the good format
#
CREATE TABLE t1
(
line char(255)
)
ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='biblio.json';
SELECT * FROM t1;
line
[
{
"ISBN": "9782212090819",
"LANG": "fr",
"SUBJECT": "applications",
"AUTHOR": [
{
"FIRSTNAME": "Jean-Christophe",
"LASTNAME": "Bernadac"
},
{
"FIRSTNAME": "Philippe",
"LASTNAME": "Knab"
}
],
"TITLE": "Construire une application XML",
"PUBLISHER": {
"NAME": "Eyrolles",
"PLACE": "Paris"
},
"DATEPUB": 1999
},
{
"ISBN": "9782840825685",
"LANG": "fr",
"SUBJECT": "applications",
"AUTHOR": [
{
"FIRSTNAME": "William J.",
"LASTNAME": "Pardi"
},
{
"FIRSTNAME": "Charles",
"LASTNAME": "Dickens"
}
],
"TITLE": "XML en Action",
"TRANSLATION": "adapt de l'anglais par",
"TRANSLATOR": {
"FIRSTNAME": "James",
"LASTNAME": "Guerin"
},
"PUBLISHER": {
"NAME": "Microsoft Press",
"PLACE": "Paris"
},
"DATEPUB": 1999
}
]
DROP TABLE t1;
#
# Testing a pretty=0 file
#
CREATE TABLE t1
(
ISBN CHAR(15) NOT NULL,
Language CHAR(2) JPATH='$.LANG',
Subject CHAR(32) JPATH='$.SUBJECT',
AuthorFN CHAR(128) JPATH='$.AUTHOR[*].FIRSTNAME',
AuthorLN CHAR(128) JPATH='$.AUTHOR[*].LASTNAME',
Title CHAR(32) JPATH='$.TITLE',
Translation CHAR(32) JPATH='$.TRANSLATED.PREFIX',
TranslatorFN CHAR(80) JPATH='$.TRANSLATED.TRANSLATOR.FIRSTNAME',
TranslatorLN CHAR(80) JPATH='$.TRANSLATED.TRANSLATOR.LASTNAME',
Publisher CHAR(20) JPATH='$.PUBLISHER.NAME',
Location CHAR(16) JPATH='$.PUBLISHER.PLACE',
Year int(4) JPATH='$.DATEPUB',
INDEX IX(ISBN)
)
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='bib0.json' LRECL=320 OPTION_LIST='Pretty=0';
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 IX 1 ISBN A NULL NULL NULL XINDEX
SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation TranslatorFN TranslatorLN Publisher Location Year
9782212090819 fr applications Jean-Michel Bernadac Construire une application XML NULL NULL NULL Eyrolles Paris 1999
9782212090819 fr applications Franois Knab Construire une application XML NULL NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 2001
DESCRIBE SELECT * FROM t1 WHERE ISBN = '9782212090819';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref IX IX 15 const 1 Using where
UPDATE t1 SET AuthorFN = 'Philippe' WHERE ISBN = '9782212090819';
ERROR HY000: Got error 122 'Cannot write expanded column when Pretty is not 2' from CONNECT
DROP TABLE t1;
#
# A file with 2 arrays
#
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[*].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[].EXPENSE["+"].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[].EXPENSE[+].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t1;
WHO WEEK WHAT AMOUNT
Joe 3 Beer+Food+Food+Car 69.00
Joe 4 Beer+Beer+Food+Food+Beer 83.00
Joe 5 Beer+Food 26.00
Beth 3 Beer 16.00
Beth 4 Food+Beer 32.00
Beth 5 Food+Beer 32.00
Janet 3 Car+Food+Beer 55.00
Janet 4 Car 17.00
Janet 5 Beer+Car+Beer+Food 57.00
DROP TABLE t1;
#
# Now it can be fully expanded
#
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[*].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[*].EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[*].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t1;
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;
#
# A table showing many calculated results
#
CREATE TABLE t1 (
WHO CHAR(12) NOT NULL,
WEEKS CHAR(12) NOT NULL JPATH='$.WEEK[", "].NUMBER',
SUMS CHAR(64) NOT NULL JPATH='$.WEEK["+"].EXPENSE[+].AMOUNT',
SUM DOUBLE(8,2) NOT NULL JPATH='$.WEEK[+].EXPENSE[+].AMOUNT',
AVGS CHAR(64) NOT NULL JPATH='$.WEEK["+"].EXPENSE[!].AMOUNT',
SUMAVG DOUBLE(8,2) NOT NULL JPATH='$.WEEK[+].EXPENSE[!].AMOUNT',
AVGSUM DOUBLE(8,2) NOT NULL JPATH='$.WEEK[!].EXPENSE[+].AMOUNT',
AVGAVG DOUBLE(8,2) NOT NULL JPATH='$.WEEK[!].EXPENSE[!].AMOUNT',
AVERAGE DOUBLE(8,2) NOT NULL JPATH='$.WEEK[!].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t1;
WHO WEEKS SUMS SUM AVGS SUMAVG AVGSUM AVGAVG AVERAGE
Joe 3, 4, 5 69.00+83.00+26.00 178.00 17.25+16.60+13.00 46.85 59.33 15.62 16.18
Beth 3, 4, 5 16.00+32.00+32.00 80.00 16.00+16.00+16.00 48.00 26.67 16.00 16.00
Janet 3, 4, 5 55.00+17.00+57.00 129.00 18.33+17.00+14.25 49.58 43.00 16.53 16.12
DROP TABLE t1;
#
# Expand expense in 3 one week tables
#
CREATE TABLE t2 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[0].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[0].EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[0].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t2;
WHO WEEK WHAT AMOUNT
Joe 3 Beer 18.00
Joe 3 Food 12.00
Joe 3 Food 19.00
Joe 3 Car 20.00
Beth 3 Beer 16.00
Janet 3 Car 19.00
Janet 3 Food 18.00
Janet 3 Beer 18.00
CREATE TABLE t3 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[1].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[1].EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[1].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t3;
WHO WEEK WHAT AMOUNT
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
Beth 4 Food 17.00
Beth 4 Beer 15.00
Janet 4 Car 17.00
CREATE TABLE t4 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[2].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[2].EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[2].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t4;
WHO WEEK WHAT AMOUNT
Joe 5 Beer 14.00
Joe 5 Food 12.00
Beth 5 Food 12.00
Beth 5 Beer 20.00
Janet 5 Beer 14.00
Janet 5 Car 12.00
Janet 5 Beer 19.00
Janet 5 Food 12.00
#
# The expanded table is made as a TBL table
#
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32),
AMOUNT DOUBLE(8,2))
ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t2,t3,t4';
SELECT * FROM t1;
WHO WEEK WHAT AMOUNT
Joe 3 Beer 18.00
Joe 3 Food 12.00
Joe 3 Food 19.00
Joe 3 Car 20.00
Beth 3 Beer 16.00
Janet 3 Car 19.00
Janet 3 Food 18.00
Janet 3 Beer 18.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
Beth 4 Food 17.00
Beth 4 Beer 15.00
Janet 4 Car 17.00
Joe 5 Beer 14.00
Joe 5 Food 12.00
Beth 5 Food 12.00
Beth 5 Beer 20.00
Janet 5 Beer 14.00
Janet 5 Car 12.00
Janet 5 Beer 19.00
Janet 5 Food 12.00
DROP TABLE t1, t2, t3, t4;
#
# Three partial JSON tables
#
CREATE TABLE t2 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp3.json';
SELECT * FROM t2;
WHO WEEK WHAT AMOUNT
Joe 3 Beer 18.00
Joe 3 Food 12.00
Joe 3 Food 19.00
Joe 3 Car 20.00
Beth 3 Beer 16.00
Janet 3 Car 19.00
Janet 3 Food 18.00
Janet 3 Beer 18.00
CREATE TABLE t3 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp4.json';
SELECT * FROM t3;
WHO WEEK WHAT AMOUNT
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
Beth 4 Food 17.00
Beth 4 Beer 15.00
Janet 4 Car 17.00
CREATE TABLE t4 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp5.json';
SELECT * FROM t4;
WHO WEEK WHAT AMOUNT
Joe 5 Beer 14.00
Joe 5 Food 12.00
Beth 5 Food 12.00
Beth 5 Beer 20.00
Janet 5 Beer 14.00
Janet 5 Car 12.00
Janet 5 Beer 19.00
Janet 5 Food 12.00
#
# The complete table can be a multiple JSON table
#
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp*.json' MULTIPLE=1;
SELECT * FROM t1 ORDER BY WHO, WEEK, WHAT, AMOUNT;
WHO WEEK WHAT AMOUNT
Beth 3 Beer 16.00
Beth 4 Beer 15.00
Beth 4 Food 17.00
Beth 5 Beer 20.00
Beth 5 Food 12.00
Janet 3 Beer 18.00
Janet 3 Car 19.00
Janet 3 Food 18.00
Janet 4 Car 17.00
Janet 5 Beer 14.00
Janet 5 Beer 19.00
Janet 5 Car 12.00
Janet 5 Food 12.00
Joe 3 Beer 18.00
Joe 3 Car 20.00
Joe 3 Food 12.00
Joe 3 Food 19.00
Joe 4 Beer 14.00
Joe 4 Beer 16.00
Joe 4 Beer 19.00
Joe 4 Food 17.00
Joe 4 Food 17.00
Joe 5 Beer 14.00
Joe 5 Food 12.00
DROP TABLE t1;
#
# Or also a partition JSON table
#
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp%s.json';
ALTER TABLE t1
PARTITION BY LIST COLUMNS(WEEK) (
PARTITION `3` VALUES IN(3),
PARTITION `4` VALUES IN(4),
PARTITION `5` VALUES IN(5));
Warnings:
Warning 1105 Data repartition in 3 is unchecked
Warning 1105 Data repartition in 4 is unchecked
Warning 1105 Data repartition in 5 is unchecked
SHOW WARNINGS;
Level Code Message
Warning 1105 Data repartition in 3 is unchecked
Warning 1105 Data repartition in 4 is unchecked
Warning 1105 Data repartition in 5 is unchecked
SELECT * FROM t1;
WHO WEEK WHAT AMOUNT
Joe 3 Beer 18.00
Joe 3 Food 12.00
Joe 3 Food 19.00
Joe 3 Car 20.00
Beth 3 Beer 16.00
Janet 3 Car 19.00
Janet 3 Food 18.00
Janet 3 Beer 18.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
Beth 4 Food 17.00
Beth 4 Beer 15.00
Janet 4 Car 17.00
Joe 5 Beer 14.00
Joe 5 Food 12.00
Beth 5 Food 12.00
Beth 5 Beer 20.00
Janet 5 Beer 14.00
Janet 5 Car 12.00
Janet 5 Beer 19.00
Janet 5 Food 12.00
SELECT * FROM t1 WHERE WEEK = 4;
WHO WEEK WHAT AMOUNT
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
Beth 4 Food 17.00
Beth 4 Beer 15.00
Janet 4 Car 17.00
DROP TABLE t1, t2, t3, t4;
--source include/not_embedded.inc
--source include/have_partition.inc
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/biblio.json $MYSQLD_DATADIR/test/biblio.json
--copy_file $MTR_SUITE_DIR/std_data/bib0.json $MYSQLD_DATADIR/test/bib0.json
--copy_file $MTR_SUITE_DIR/std_data/expense.json $MYSQLD_DATADIR/test/expense.json
--copy_file $MTR_SUITE_DIR/std_data/mulexp3.json $MYSQLD_DATADIR/test/mulexp3.json
--copy_file $MTR_SUITE_DIR/std_data/mulexp4.json $MYSQLD_DATADIR/test/mulexp4.json
--copy_file $MTR_SUITE_DIR/std_data/mulexp5.json $MYSQLD_DATADIR/test/mulexp5.json
--echo #
--echo # Testing doc samples
--echo #
CREATE TABLE t1
(
ISBN CHAR(15),
LANG CHAR(2),
SUBJECT CHAR(32),
AUTHOR CHAR(64),
TITLE CHAR(32),
TRANSLATION CHAR(32),
TRANSLATOR CHAR(80),
PUBLISHER CHAR(32),
DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json';
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing Jpath. Get the number of authors
--echo #
CREATE TABLE t1
(
ISBN CHAR(15),
Language CHAR(2) JPATH='$.LANG',
Subject CHAR(32) JPATH='$.SUBJECT',
Authors INT(2) JPATH='$.AUTHOR[#]',
Title CHAR(32) JPATH='$.TITLE',
Translation CHAR(32) JPATH='$.TRANSLATION',
Translator CHAR(80) JPATH='$.TRANSLATOR',
Publisher CHAR(20) JPATH='$.PUBLISHER.NAME',
Location CHAR(16) JPATH='$.PUBLISHER.PLACE',
Year int(4) JPATH='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json';
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Concatenates the authors
--echo #
CREATE TABLE t1
(
ISBN CHAR(15),
Language CHAR(2) JPATH='$.LANG',
Subject CHAR(32) JPATH='$.SUBJECT',
AuthorFN CHAR(128) JPATH='$.AUTHOR[" and "].FIRSTNAME',
AuthorLN CHAR(128) JPATH='$.AUTHOR[" and "].LASTNAME',
Title CHAR(32) JPATH='$.TITLE',
Translation CHAR(32) JPATH='$.TRANSLATION',
Translator CHAR(80) JPATH='$.TRANSLATOR',
Publisher CHAR(20) JPATH='$.PUBLISHER.NAME',
Location CHAR(16) JPATH='$.PUBLISHER.PLACE',
Year int(4) JPATH='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json';
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing expanding authors
--echo #
CREATE TABLE t1
(
ISBN CHAR(15),
Language CHAR(2) JPATH='$.LANG',
Subject CHAR(32) JPATH='$.SUBJECT',
AuthorFN CHAR(128) JPATH='$.AUTHOR[*].FIRSTNAME',
AuthorLN CHAR(128) JPATH='$.AUTHOR[*].LASTNAME',
Title CHAR(32) JPATH='$.TITLE',
Translation CHAR(32) JPATH='$.TRANSLATION',
Translator CHAR(80) JPATH='$.TRANSLATOR',
Publisher CHAR(20) JPATH='$.PUBLISHER.NAME',
Location CHAR(16) JPATH='$.PUBLISHER.PLACE',
Year int(4) JPATH='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json';
SELECT * FROM t1;
UPDATE t1 SET AuthorFN = 'Philippe' WHERE AuthorLN = 'Knab';
SELECT * FROM t1 WHERE ISBN = '9782212090819';
--echo #
--echo # To add an author a new table must be created
--echo #
CREATE TABLE t2 (
FIRSTNAME CHAR(32),
LASTNAME CHAR(32))
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='biblio.json' OPTION_LIST='Object=$[1].AUTHOR';
SELECT * FROM t2;
INSERT INTO t2 VALUES('Charles','Dickens');
SELECT * FROM t1;
DROP TABLE t1;
DROP TABLE t2;
--echo #
--echo # Check the biblio file has the good format
--echo #
CREATE TABLE t1
(
line char(255)
)
ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='biblio.json';
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing a pretty=0 file
--echo #
CREATE TABLE t1
(
ISBN CHAR(15) NOT NULL,
Language CHAR(2) JPATH='$.LANG',
Subject CHAR(32) JPATH='$.SUBJECT',
AuthorFN CHAR(128) JPATH='$.AUTHOR[*].FIRSTNAME',
AuthorLN CHAR(128) JPATH='$.AUTHOR[*].LASTNAME',
Title CHAR(32) JPATH='$.TITLE',
Translation CHAR(32) JPATH='$.TRANSLATED.PREFIX',
TranslatorFN CHAR(80) JPATH='$.TRANSLATED.TRANSLATOR.FIRSTNAME',
TranslatorLN CHAR(80) JPATH='$.TRANSLATED.TRANSLATOR.LASTNAME',
Publisher CHAR(20) JPATH='$.PUBLISHER.NAME',
Location CHAR(16) JPATH='$.PUBLISHER.PLACE',
Year int(4) JPATH='$.DATEPUB',
INDEX IX(ISBN)
)
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='bib0.json' LRECL=320 OPTION_LIST='Pretty=0';
SHOW INDEX FROM t1;
SELECT * FROM t1;
DESCRIBE SELECT * FROM t1 WHERE ISBN = '9782212090819';
--error ER_GET_ERRMSG
UPDATE t1 SET AuthorFN = 'Philippe' WHERE ISBN = '9782212090819';
DROP TABLE t1;
--echo #
--echo # A file with 2 arrays
--echo #
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[*].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[].EXPENSE["+"].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[].EXPENSE[+].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Now it can be fully expanded
--echo #
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[*].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[*].EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[*].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
#--error ER_GET_ERRMSG
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # A table showing many calculated results
--echo #
CREATE TABLE t1 (
WHO CHAR(12) NOT NULL,
WEEKS CHAR(12) NOT NULL JPATH='$.WEEK[", "].NUMBER',
SUMS CHAR(64) NOT NULL JPATH='$.WEEK["+"].EXPENSE[+].AMOUNT',
SUM DOUBLE(8,2) NOT NULL JPATH='$.WEEK[+].EXPENSE[+].AMOUNT',
AVGS CHAR(64) NOT NULL JPATH='$.WEEK["+"].EXPENSE[!].AMOUNT',
SUMAVG DOUBLE(8,2) NOT NULL JPATH='$.WEEK[+].EXPENSE[!].AMOUNT',
AVGSUM DOUBLE(8,2) NOT NULL JPATH='$.WEEK[!].EXPENSE[+].AMOUNT',
AVGAVG DOUBLE(8,2) NOT NULL JPATH='$.WEEK[!].EXPENSE[!].AMOUNT',
AVERAGE DOUBLE(8,2) NOT NULL JPATH='$.WEEK[!].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Expand expense in 3 one week tables
--echo #
CREATE TABLE t2 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[0].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[0].EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[0].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t2;
CREATE TABLE t3 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[1].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[1].EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[1].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t3;
CREATE TABLE t4 (
WHO CHAR(12),
WEEK INT(2) JPATH='$.WEEK[2].NUMBER',
WHAT CHAR(32) JPATH='$.WEEK[2].EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.WEEK[2].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='expense.json';
SELECT * FROM t4;
--echo #
--echo # The expanded table is made as a TBL table
--echo #
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32),
AMOUNT DOUBLE(8,2))
ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t2,t3,t4';
SELECT * FROM t1;
DROP TABLE t1, t2, t3, t4;
--echo #
--echo # Three partial JSON tables
--echo #
CREATE TABLE t2 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp3.json';
SELECT * FROM t2;
CREATE TABLE t3 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp4.json';
SELECT * FROM t3;
CREATE TABLE t4 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp5.json';
SELECT * FROM t4;
--echo #
--echo # The complete table can be a multiple JSON table
--echo #
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp*.json' MULTIPLE=1;
SELECT * FROM t1 ORDER BY WHO, WEEK, WHAT, AMOUNT;
DROP TABLE t1;
--echo #
--echo # Or also a partition JSON table
--echo #
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
WHAT CHAR(32) JPATH='$.EXPENSE[*].WHAT',
AMOUNT DOUBLE(8,2) JPATH='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=BSON FILE_NAME='mulexp%s.json';
ALTER TABLE t1
PARTITION BY LIST COLUMNS(WEEK) (
PARTITION `3` VALUES IN(3),
PARTITION `4` VALUES IN(4),
PARTITION `5` VALUES IN(5));
SHOW WARNINGS;
SELECT * FROM t1;
SELECT * FROM t1 WHERE WEEK = 4;
DROP TABLE t1, t2, t3, t4;
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/biblio.json
--remove_file $MYSQLD_DATADIR/test/bib0.dnx
--remove_file $MYSQLD_DATADIR/test/bib0.json
--remove_file $MYSQLD_DATADIR/test/expense.json
--remove_file $MYSQLD_DATADIR/test/mulexp3.json
--remove_file $MYSQLD_DATADIR/test/mulexp4.json
--remove_file $MYSQLD_DATADIR/test/mulexp5.json
......@@ -634,29 +634,28 @@ PBVAL BTUTIL::ParseLine(PGLOBAL g, int *pretty, bool *comma)
/***********************************************************************/
/* Make the top tree from the object path. */
/***********************************************************************/
PBVAL BTUTIL::MakeTopTree(PGLOBAL g, PBVAL jsp)
PBVAL BTUTIL::MakeTopTree(PGLOBAL g, int type)
{
PBVAL top = NULL;
PBVAL top = NULL, val = NULL;
if (Tp->Objname) {
if (!Tp->Val) {
// Parse and allocate Objname item(s)
if (!Tp->Row) {
// Parse and allocate Objpath item(s)
char* p;
char* objpath = PlugDup(g, Tp->Objname);
char *objpath = PlugDup(g, Tp->Objname);
int i;
PBVAL objp = NULL;
PBVAL arp = NULL;
PBVAL val = NULL;
for (; objpath; objpath = p) {
if ((p = strchr(objpath, Tp->Sep)))
*p++ = 0;
if (*objpath != '[' && !IsNum(objpath)) {
// objp = new(g) JOBJECT;
objp = NewVal(TYPE_JOB);
if (!top)
top = NewVal(TYPE_JOB);
top = objp;
if (val)
SetValueObj(val, objp);
......@@ -687,12 +686,12 @@ PBVAL BTUTIL::MakeTopTree(PGLOBAL g, PBVAL jsp)
} // endfor p
Tp->Val = val;
} // endif Val
SetValueVal(Tp->Val, jsp);
Tp->Row = val;
Tp->Row->Type = type;
} else
top = jsp;
top = Tp->Row = NewVal(type);
return top;
} // end of MakeTopTree
......@@ -1270,7 +1269,6 @@ TDBBSN::TDBBSN(PGLOBAL g, PBDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
Bp = new(g) BTUTIL(tdp->G, this);
Top = NULL;
Row = NULL;
Val = NULL;
Colp = NULL;
if (tdp) {
......@@ -1306,7 +1304,6 @@ TDBBSN::TDBBSN(TDBBSN* tdbp) : TDBDOS(NULL, tdbp)
Bp = tdbp->Bp;
Top = tdbp->Top;
Row = tdbp->Row;
Val = tdbp->Val;
Colp = tdbp->Colp;
Jmode = tdbp->Jmode;
Objname = tdbp->Objname;
......@@ -1413,11 +1410,6 @@ bool TDBBSN::OpenDB(PGLOBAL g)
{
TUSE use = Use;
if (Pretty < 0 && Mode == MODE_UPDATE) {
sprintf(g->Message, "Mode %d NIY for Bjson", Mode);
return true;
} // endif Mode
if (Use == USE_OPEN) {
/*******************************************************************/
/* Table already open replace it at its beginning. ??? */
......@@ -1437,19 +1429,20 @@ bool TDBBSN::OpenDB(PGLOBAL g)
return false;
if (Pretty < 0) {
/*******************************************************************/
/*********************************************************************/
/* Binary BJSON table. */
/*******************************************************************/
/*********************************************************************/
xtrc(1, "JSN OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
this, Tdb_No, Use, Mode);
/*********************************************************************/
/* Lrecl is Ok. */
/*********************************************************************/
// Lrecl is Ok
size_t linelen = Lrecl;
MODE mode = Mode;
// Buffer must be set to G->Sarea
// Buffer must be allocated in G->Sarea
Mode = MODE_ANY;
Txfp->AllocateBuffer(Bp->G);
Mode = mode;
if (Mode == MODE_INSERT)
Bp->SubSet(true);
......@@ -1465,23 +1458,25 @@ bool TDBBSN::OpenDB(PGLOBAL g)
/* First opening. */
/***********************************************************************/
if (Mode == MODE_INSERT) {
int type;
switch (Jmode) {
case MODE_OBJECT: Row = Bp->NewVal(TYPE_JOB); break;
case MODE_ARRAY: Row = Bp->NewVal(TYPE_JAR); break;
case MODE_VALUE: Row = Bp->NewVal(TYPE_JVAL); break;
case MODE_OBJECT: type = TYPE_JOB; break;
case MODE_ARRAY: type = TYPE_JAR; break;
case MODE_VALUE: type = TYPE_JVAL; break;
default:
sprintf(g->Message, "Invalid Jmode %d", Jmode);
return true;
} // endswitch Jmode
Top = Bp->MakeTopTree(g, type);
Bp->MemSave();
} // endif Mode
if (Xcol)
To_Filter = NULL; // Imcompatible
To_Filter = NULL; // Not compatible
return false;
} // end of OpenDB
/***********************************************************************/
......@@ -1534,6 +1529,7 @@ int TDBBSN::ReadDB(PGLOBAL g)
Bp->SubSet();
if ((Row = Bp->ParseLine(g, &Pretty, &Comma))) {
Top = Row;
Row = Bp->FindRow(g);
SameRow = 0;
Fpos++;
......@@ -1545,10 +1541,9 @@ int TDBBSN::ReadDB(PGLOBAL g)
} else
rc = RC_EF;
} else {
// Here we get a movable Json binary tree
Bp->SubSet(); // Perhaps Useful when updating
Row = (PBVAL)To_Line;
} else { // Here we get a movable Json binary tree
Bp->MemSet(((BINFAM*)Txfp)->Recsize); // Useful when updating
Row = Top = (PBVAL)To_Line;
Row = Bp->FindRow(g);
SameRow = 0;
Fpos++;
......@@ -1569,8 +1564,8 @@ bool TDBBSN::PrepareWriting(PGLOBAL g)
if (Pretty >= 0) {
PSZ s;
if (!(Top = Bp->MakeTopTree(g, Row)))
return true;
// if (!(Top = Bp->MakeTopTree(g, Row->Type)))
// return true;
if ((s = Bp->SerialVal(g, Top, Pretty))) {
if (Comma)
......@@ -2030,6 +2025,25 @@ void BSONCOL::WriteColumn(PGLOBAL g)
throw 666;
} // endif jsp
switch (row->Type) {
case TYPE_JAR:
if (Nod > 1 && Nodes[Nod - 2].Op == OP_EQ)
Cp->SetArrayValue(row, jsp, Nodes[Nod - 2].Rank);
else
Cp->AddArrayValue(row, jsp);
break;
case TYPE_JOB:
if (Nod > 1 && Nodes[Nod - 2].Key)
Cp->SetKeyValue(row, jsp, Nodes[Nod - 2].Key);
break;
case TYPE_JVAL:
default:
Cp->SetValueVal(row, jsp);
} // endswitch Type
break;
} else
jsp = Cp->NewVal(Value);
......@@ -2103,9 +2117,10 @@ int TDBBSON::MakeNewDoc(PGLOBAL g)
// Create a void table that will be populated
Docp = Bp->NewVal(TYPE_JAR);
if (!(Top = Bp->MakeTopTree(g, Docp)))
if (!(Top = Bp->MakeTopTree(g, TYPE_JAR)))
return RC_FX;
Docp = Row;
Done = true;
return RC_OK;
} // end of MakeNewDoc
......
......@@ -111,7 +111,7 @@ class BTUTIL : public BDOC {
// Utility functions
PBVAL FindRow(PGLOBAL g);
PBVAL ParseLine(PGLOBAL g, int *pretty, bool *comma);
PBVAL MakeTopTree(PGLOBAL g, PBVAL jsp);
PBVAL MakeTopTree(PGLOBAL g, int type);
PSZ SerialVal(PGLOBAL g, PBVAL top, int pretty);
protected:
......@@ -199,7 +199,6 @@ class DllExport TDBBSN : public TDBDOS {
PBTUT Bp; // The BSUTIL handling class
PBVAL Top; // The top JSON tree
PBVAL Row; // The current row
PBVAL Val; // The value of the current row
PBSCOL Colp; // The multiple column
JMODE Jmode; // MODE_OBJECT by default
PCSZ Objname; // The table object name
......
......@@ -1925,7 +1925,7 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
PJSON nwr, row = Tjp->Row;
for (int i = 0; i < Nod && row; i++) {
if (Nodes[i+1].Op == OP_XX)
if (i < Nod-1 && Nodes[i+1].Op == OP_XX)
break;
else switch (row->GetType()) {
case TYPE_JOB:
......
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