mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- Adding the JSON table type
added: storage/connect/json.cpp storage/connect/json.h storage/connect/mysql-test/connect/r/json.result storage/connect/mysql-test/connect/std_data/biblio.jsn storage/connect/mysql-test/connect/std_data/expense.jsn storage/connect/mysql-test/connect/std_data/mulexp3.jsn storage/connect/mysql-test/connect/std_data/mulexp4.jsn storage/connect/mysql-test/connect/std_data/mulexp5.jsn storage/connect/mysql-test/connect/t/json.test storage/connect/tabjson.cpp storage/connect/tabjson.h modified: storage/connect/CMakeLists.txt storage/connect/engmsg.h storage/connect/filamtxt.h storage/connect/ha_connect.cc storage/connect/msgid.h storage/connect/mycat.cc storage/connect/plgdbsem.h storage/connect/tabdos.cpp storage/connect/value.cpp storage/connect/value.h
This commit is contained in:
@@ -21,18 +21,18 @@ ha_connect.cc connect.cc user_connect.cc mycat.cc
|
||||
fmdlex.c osutil.c plugutil.c rcmsg.c rcmsg.h
|
||||
array.cpp blkfil.cpp colblk.cpp csort.cpp
|
||||
filamap.cpp filamdbf.cpp filamfix.cpp filamtxt.cpp filamvct.cpp filamzip.cpp
|
||||
filter.cpp maputil.cpp myutil.cpp plgdbutl.cpp reldef.cpp tabcol.cpp
|
||||
tabdos.cpp tabfix.cpp tabfmt.cpp table.cpp tabmul.cpp taboccur.cpp
|
||||
filter.cpp json.cpp maputil.cpp myutil.cpp plgdbutl.cpp reldef.cpp tabcol.cpp
|
||||
tabdos.cpp tabfix.cpp tabfmt.cpp tabjson.cpp table.cpp tabmul.cpp taboccur.cpp
|
||||
tabpivot.cpp tabsys.cpp tabtbl.cpp tabutil.cpp tabvct.cpp tabvir.cpp
|
||||
tabxcl.cpp valblk.cpp value.cpp xindex.cpp xobject.cpp
|
||||
|
||||
array.h blkfil.h block.h catalog.h checklvl.h colblk.h connect.h csort.h
|
||||
engmsg.h filamap.h filamdbf.h filamfix.h filamtxt.h filamvct.h filamzip.h
|
||||
filter.h global.h ha_connect.h inihandl.h maputil.h msgid.h mycat.h myutil.h
|
||||
os.h osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h resource.h tabcol.h
|
||||
tabdos.h tabfix.h tabfmt.h tabmul.h taboccur.h tabpivot.h tabsys.h
|
||||
tabtbl.h tabutil.h tabvct.h tabvir.h tabxcl.h user_connect.h valblk.h value.h
|
||||
xindex.h xobject.h xtable.h)
|
||||
filter.h global.h ha_connect.h inihandl.h json.h maputil.h msgid.h mycat.h
|
||||
myutil.h os.h osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h resource.h
|
||||
tabcol.h tabdos.h tabfix.h tabfmt.h tabjson.h tabmul.h taboccur.h tabpivot.h
|
||||
tabsys.h tabtbl.h tabutil.h tabvct.h tabvir.h tabxcl.h user_connect.h
|
||||
valblk.h value.h xindex.h xobject.h xtable.h)
|
||||
|
||||
#
|
||||
# Definitions that are shared for all OSes
|
||||
|
@@ -103,6 +103,10 @@
|
||||
#define MSG_FILE_MAP_ERROR "CreateFileMapping %s error rc=%d"
|
||||
#define MSG_FILE_OPEN_YET "File %s already open"
|
||||
#define MSG_FILE_UNFOUND "File %s not found"
|
||||
#define MSG_FIX_OVFLW_ADD "Fixed Overflow on add"
|
||||
#define MSG_FIX_OVFLW_TIMES "Fixed Overflow on times"
|
||||
#define MSG_FIX_UNFLW_ADD "Fixed Underflow on add"
|
||||
#define MSG_FIX_UNFLW_TIMES "Fixed Underflow on times"
|
||||
#define MSG_FLD_TOO_LNG_FOR "Field %d too long for %s line %d of %s"
|
||||
#define MSG_FLT_BAD_RESULT "Float inexact result"
|
||||
#define MSG_FLT_DENORMAL_OP "Float denormal operand"
|
||||
@@ -318,3 +322,4 @@
|
||||
#define MSG_XPATH_CNTX_ERR "Unable to create new XPath context"
|
||||
#define MSG_XPATH_EVAL_ERR "Unable to evaluate xpath location '%s'"
|
||||
#define MSG_XPATH_NOT_SUPP "Unsupported Xpath for column %s"
|
||||
#define MSG_ZERO_DIVIDE "Zero divide in expression"
|
||||
|
@@ -26,6 +26,7 @@ class DllExport TXTFAM : public BLOCK {
|
||||
friend class TDBCSV;
|
||||
friend class TDBFIX;
|
||||
friend class TDBVCT;
|
||||
friend class TDBJSON;
|
||||
friend class DOSCOL;
|
||||
friend class BINCOL;
|
||||
friend class VCTCOL;
|
||||
|
@@ -170,8 +170,8 @@
|
||||
#define SZWMIN 4194304 // Minimum work area size 4M
|
||||
|
||||
extern "C" {
|
||||
char version[]= "Version 1.03.0005 January 13, 2015";
|
||||
char compver[]= "Version 1.03.0005 " __DATE__ " " __TIME__;
|
||||
char version[]= "Version 1.03.0006 January 13, 2015";
|
||||
char compver[]= "Version 1.03.0006 " __DATE__ " " __TIME__;
|
||||
|
||||
#if defined(WIN32)
|
||||
char slash= '\\';
|
||||
@@ -3834,7 +3834,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn)
|
||||
case TAB_XML:
|
||||
case TAB_INI:
|
||||
case TAB_VEC:
|
||||
// case TAB_JSON:
|
||||
case TAB_JSON:
|
||||
if (options->filename && *options->filename) {
|
||||
char *s, path[FN_REFLEN], dbpath[FN_REFLEN];
|
||||
#if defined(WIN32)
|
||||
|
1055
storage/connect/json.cpp
Normal file
1055
storage/connect/json.cpp
Normal file
File diff suppressed because it is too large
Load Diff
240
storage/connect/json.h
Normal file
240
storage/connect/json.h
Normal file
@@ -0,0 +1,240 @@
|
||||
/**************** json H Declares Source Code File (.H) ****************/
|
||||
/* Name: json.h Version 1.0 */
|
||||
/* */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
|
||||
/* */
|
||||
/* This file contains the JSON classes declares. */
|
||||
/***********************************************************************/
|
||||
#include "value.h"
|
||||
|
||||
#if defined(_DEBUG)
|
||||
#define X assert(false);
|
||||
#else
|
||||
#define X
|
||||
#endif
|
||||
|
||||
enum JTYP {TYPE_JSON = 12, TYPE_JAR, TYPE_JOB, TYPE_JVAL};
|
||||
|
||||
class JOUT;
|
||||
class JSON;
|
||||
class JMAP;
|
||||
class JVALUE;
|
||||
class JOBJECT;
|
||||
class JARRAY;
|
||||
|
||||
typedef class JPAIR *PJPR;
|
||||
typedef class JSON *PJSON;
|
||||
typedef class JVALUE *PJVAL;
|
||||
typedef class JOBJECT *PJOB;
|
||||
typedef class JARRAY *PJAR;
|
||||
|
||||
typedef struct {
|
||||
char *str;
|
||||
int len;
|
||||
} STRG, *PSG;
|
||||
|
||||
PJSON ParseJson(PGLOBAL g, char *s, int n, int prty, bool *b = NULL);
|
||||
PJAR ParseArray(PGLOBAL g, int& i, STRG& src);
|
||||
PJOB ParseObject(PGLOBAL g, int& i, STRG& src);
|
||||
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src);
|
||||
char *ParseString(PGLOBAL g, int& i, STRG& src);
|
||||
PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src);
|
||||
PSZ Serialize(PGLOBAL g, PJSON jsp, FILE *fs, int pretty);
|
||||
bool SerializeArray(JOUT *js, PJAR jarp, bool b);
|
||||
bool SerializeObject(JOUT *js, PJOB jobp);
|
||||
bool SerializeValue(JOUT *js, PJVAL jvp);
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class JOUT. Used by Serialize. */
|
||||
/***********************************************************************/
|
||||
class JOUT : public BLOCK {
|
||||
public:
|
||||
JOUT(PGLOBAL gp) : BLOCK() {g = gp;}
|
||||
|
||||
virtual bool Write(char *s) = 0;
|
||||
virtual bool Write(char c) = 0;
|
||||
virtual bool Escape(char *s) = 0;
|
||||
|
||||
// Member
|
||||
PGLOBAL g;
|
||||
}; // end of class JOUT
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class JOUTSTR. Used to Serialize to a string. */
|
||||
/***********************************************************************/
|
||||
class JOUTSTR : public JOUT {
|
||||
public:
|
||||
JOUTSTR(PGLOBAL g);
|
||||
|
||||
virtual bool Write(char *s);
|
||||
virtual bool Write(char c);
|
||||
virtual bool Escape(char *s);
|
||||
|
||||
// Member
|
||||
char *Strp; // The serialized string
|
||||
size_t N; // Position of next char
|
||||
size_t Max; // String max size
|
||||
}; // end of class JOUTSTR
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class JOUTFILE. Used to Serialize to a file. */
|
||||
/***********************************************************************/
|
||||
class JOUTFILE : public JOUT {
|
||||
public:
|
||||
JOUTFILE(PGLOBAL g, FILE *str) : JOUT(g) {Stream = str;}
|
||||
|
||||
virtual bool Write(char *s);
|
||||
virtual bool Write(char c);
|
||||
virtual bool Escape(char *s);
|
||||
|
||||
// Member
|
||||
FILE *Stream;
|
||||
}; // end of class JOUTFILE
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class JOUTPRT. Used to Serialize to a pretty file. */
|
||||
/***********************************************************************/
|
||||
class JOUTPRT : public JOUTFILE {
|
||||
public:
|
||||
JOUTPRT(PGLOBAL g, FILE *str) : JOUTFILE(g, str) {M = 0; B = false;}
|
||||
|
||||
virtual bool Write(char *s);
|
||||
virtual bool Write(char c);
|
||||
|
||||
// Member
|
||||
int M;
|
||||
bool B;
|
||||
}; // end of class JOUTPRT
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class PAIR. The pairs of a json Object. */
|
||||
/***********************************************************************/
|
||||
class JPAIR : public BLOCK {
|
||||
friend class JOBJECT;
|
||||
friend PJOB ParseObject(PGLOBAL, int&, STRG&);
|
||||
friend bool SerializeObject(JOUT *, PJOB);
|
||||
public:
|
||||
JPAIR(PSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;}
|
||||
|
||||
protected:
|
||||
PSZ Key; // This pair key name
|
||||
PJVAL Val; // To the value of the pair
|
||||
PJPR Next; // To the next pair
|
||||
}; // end of class JPAIR
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class JSON. The base class for all other json classes. */
|
||||
/***********************************************************************/
|
||||
class JSON : public BLOCK {
|
||||
public:
|
||||
JSON(void) {Size = 0;}
|
||||
|
||||
int size(void) {return Size;}
|
||||
virtual void Clear(void) {Size = 0;}
|
||||
virtual JTYP GetType(void) {return TYPE_JSON;}
|
||||
virtual JTYP GetValType(void) {X return TYPE_JSON;}
|
||||
virtual void InitArray(PGLOBAL g) {X}
|
||||
virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL) {X return NULL;}
|
||||
virtual PJPR AddPair(PGLOBAL g, PSZ key) {X return NULL;}
|
||||
virtual PJVAL GetValue(const char *key) {X return NULL;}
|
||||
virtual PJOB GetObject(void) {X return NULL;}
|
||||
virtual PJAR GetArray(void) {X return NULL;}
|
||||
virtual PJVAL GetValue(int i) {X return NULL;}
|
||||
virtual PVAL GetValue(void) {X return NULL;}
|
||||
virtual PJSON GetJson(void) {X return NULL;}
|
||||
virtual int GetInteger(void) {X return 0;}
|
||||
virtual double GetFloat() {X return 0.0;}
|
||||
virtual PSZ GetString() {X return NULL;}
|
||||
virtual PSZ GetText(PGLOBAL g) {X return NULL;}
|
||||
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i) {X return true;}
|
||||
virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key) {X}
|
||||
virtual void SetValue(PVAL valp) {X}
|
||||
virtual void SetValue(PJSON jsp) {X}
|
||||
virtual bool DeleteValue(int i) {X return true;}
|
||||
|
||||
protected:
|
||||
int Size;
|
||||
}; // end of class JSON
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class JOBJECT: contains a list of value pairs. */
|
||||
/***********************************************************************/
|
||||
class JOBJECT : public JSON {
|
||||
friend PJOB ParseObject(PGLOBAL, int&, STRG&);
|
||||
friend bool SerializeObject(JOUT *, PJOB);
|
||||
public:
|
||||
JOBJECT(void) : JSON() {First = Last = NULL;}
|
||||
|
||||
virtual void Clear(void) {First = Last = NULL; Size = 0;}
|
||||
virtual JTYP GetType(void) {return TYPE_JOB;}
|
||||
virtual PJPR AddPair(PGLOBAL g, PSZ key);
|
||||
virtual PJOB GetObject(void) {return this;}
|
||||
virtual PJVAL GetValue(const char* key);
|
||||
virtual PSZ GetText(PGLOBAL g);
|
||||
virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key);
|
||||
|
||||
protected:
|
||||
PJPR First;
|
||||
PJPR Last;
|
||||
}; // end of class JOBJECT
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class JARRAY. */
|
||||
/***********************************************************************/
|
||||
class JARRAY : public JSON {
|
||||
friend PJAR ParseArray(PGLOBAL, int&, STRG&);
|
||||
public:
|
||||
JARRAY(void) : JSON() {Alloc = 0; First = Last = NULL; Mvals = NULL;}
|
||||
|
||||
virtual void Clear(void) {First = Last = NULL; Size = 0;}
|
||||
virtual JTYP GetType(void) {return TYPE_JAR;}
|
||||
virtual PJAR GetArray(void) {return this;}
|
||||
virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL);
|
||||
virtual void InitArray(PGLOBAL g);
|
||||
virtual PJVAL GetValue(int i);
|
||||
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i);
|
||||
virtual bool DeleteValue(int n);
|
||||
|
||||
protected:
|
||||
// Members
|
||||
int Alloc; // The Mvals allocated size
|
||||
PJVAL First; // Used when constructing
|
||||
PJVAL Last; // Last constructed value
|
||||
PJVAL *Mvals; // Allocated when finished
|
||||
}; // end of class JARRAY
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class JVALUE. */
|
||||
/***********************************************************************/
|
||||
class JVALUE : public JSON {
|
||||
friend class JARRAY;
|
||||
friend PJVAL ParseValue(PGLOBAL, int&, STRG&);
|
||||
friend bool SerializeValue(JOUT *, PJVAL);
|
||||
public:
|
||||
JVALUE(void) : JSON()
|
||||
{Jsp = NULL; Value = NULL; Next = NULL; Del = false;}
|
||||
JVALUE(PJSON jsp) : JSON()
|
||||
{Jsp = jsp; Value = NULL; Next = NULL; Del = false;}
|
||||
JVALUE(PGLOBAL g, PVAL valp);
|
||||
|
||||
virtual void Clear(void)
|
||||
{Jsp = NULL; Value = NULL; Next = NULL; Del = false; Size = 0;}
|
||||
virtual JTYP GetType(void) {return TYPE_JVAL;}
|
||||
virtual JTYP GetValType(void);
|
||||
virtual PJOB GetObject(void);
|
||||
virtual PJAR GetArray(void);
|
||||
virtual PVAL GetValue(void) {return Value;}
|
||||
virtual PJSON GetJson(void) {return (Jsp ? Jsp : this);}
|
||||
virtual int GetInteger(void);
|
||||
virtual double GetFloat(void);
|
||||
virtual PSZ GetString(void);
|
||||
virtual void SetValue(PVAL valp) {Value = valp;}
|
||||
virtual void SetValue(PJSON jsp) {Jsp = jsp;}
|
||||
|
||||
protected:
|
||||
PJSON Jsp; // To the json value
|
||||
PVAL Value; // The numeric value
|
||||
PJVAL Next; // Next value in array
|
||||
bool Del; // True when deleted
|
||||
}; // end of class JVALUE
|
||||
|
@@ -318,3 +318,8 @@
|
||||
#define MSG_XPATH_CNTX_ERR 517
|
||||
#define MSG_XPATH_EVAL_ERR 518
|
||||
#define MSG_XPATH_NOT_SUPP 519
|
||||
#define MSG_ZERO_DIVIDE 520
|
||||
#define MSG_FIX_OVFLW_ADD 521
|
||||
#define MSG_FIX_OVFLW_TIMES 522
|
||||
#define MSG_FIX_UNFLW_ADD 523
|
||||
#define MSG_FIX_UNFLW_TIMES 524
|
||||
|
@@ -89,7 +89,7 @@
|
||||
#include "tabpivot.h"
|
||||
#endif // PIVOT_SUPPORT
|
||||
#include "tabvir.h"
|
||||
//#include "tabjson.h"
|
||||
#include "tabjson.h"
|
||||
#include "ha_connect.h"
|
||||
#include "mycat.h"
|
||||
|
||||
@@ -140,7 +140,7 @@ TABTYPE GetTypeID(const char *type)
|
||||
: (!stricmp(type, "PIVOT")) ? TAB_PIVOT
|
||||
#endif
|
||||
: (!stricmp(type, "VIR")) ? TAB_VIR
|
||||
// : (!stricmp(type, "JSON")) ? TAB_JSON
|
||||
: (!stricmp(type, "JSON")) ? TAB_JSON
|
||||
: (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
|
||||
} // end of GetTypeID
|
||||
|
||||
@@ -161,7 +161,7 @@ bool IsFileType(TABTYPE type)
|
||||
case TAB_XML:
|
||||
case TAB_INI:
|
||||
case TAB_VEC:
|
||||
// case TAB_JSON:
|
||||
case TAB_JSON:
|
||||
isfile= true;
|
||||
break;
|
||||
default:
|
||||
@@ -254,6 +254,7 @@ bool IsTypeIndexable(TABTYPE type)
|
||||
case TAB_BIN:
|
||||
case TAB_VEC:
|
||||
case TAB_DBF:
|
||||
case TAB_JSON:
|
||||
idx= true;
|
||||
break;
|
||||
default:
|
||||
@@ -279,6 +280,7 @@ int GetIndexType(TABTYPE type)
|
||||
case TAB_BIN:
|
||||
case TAB_VEC:
|
||||
case TAB_DBF:
|
||||
case TAB_JSON:
|
||||
xtyp= 1;
|
||||
break;
|
||||
case TAB_MYSQL:
|
||||
@@ -542,7 +544,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
|
||||
case TAB_PIVOT: tdp= new(g) PIVOTDEF; break;
|
||||
#endif // PIVOT_SUPPORT
|
||||
case TAB_VIR: tdp= new(g) VIRDEF; break;
|
||||
// case TAB_JSON: tdp= new(g) JSONDEF; break;
|
||||
case TAB_JSON: tdp= new(g) JSONDEF; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
|
||||
} // endswitch
|
||||
|
439
storage/connect/mysql-test/connect/r/json.result
Normal file
439
storage/connect/mysql-test/connect/r/json.result
Normal file
@@ -0,0 +1,439 @@
|
||||
#
|
||||
# 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=JSON FILE_NAME='biblio.jsn';
|
||||
SELECT * FROM t1;
|
||||
ISBN LANG SUBJECT AUTHOR TITLE TRANSLATION TRANSLATOR PUBLISHER DATEPUB
|
||||
9782212090819 fr applications Jean-Christophe Bernadac 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
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Testing Jpath. Get the number of authors
|
||||
#
|
||||
CREATE TABLE t1
|
||||
(
|
||||
ISBN CHAR(15),
|
||||
Language CHAR(2) FIELD_FORMAT='LANG',
|
||||
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
|
||||
Authors INT(2) FIELD_FORMAT='AUTHOR:[#]',
|
||||
Title CHAR(32) FIELD_FORMAT='TITLE',
|
||||
Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
|
||||
Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
|
||||
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
|
||||
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
|
||||
Year int(4) FIELD_FORMAT='DATEPUB'
|
||||
)
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.jsn';
|
||||
SELECT * FROM t1;
|
||||
ISBN Language Subject Authors Title Translation Translator Publisher Location Year
|
||||
9782212090819 fr applications 2 Construire une application XML Eyrolles Paris 1999
|
||||
9782840825685 fr applications 1 XML en Action adapt<70> 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) FIELD_FORMAT='LANG',
|
||||
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
|
||||
AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[" and "]:FIRSTNAME',
|
||||
AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[" and "]:LASTNAME',
|
||||
Title CHAR(32) FIELD_FORMAT='TITLE',
|
||||
Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
|
||||
Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
|
||||
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
|
||||
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
|
||||
Year int(4) FIELD_FORMAT='DATEPUB'
|
||||
)
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.jsn';
|
||||
SELECT * FROM t1;
|
||||
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
|
||||
9782212090819 fr applications Jean-Christophe and Fran<61>ois Bernadac and 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
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Testing expanding authors
|
||||
#
|
||||
CREATE TABLE t1
|
||||
(
|
||||
ISBN CHAR(15),
|
||||
Language CHAR(2) FIELD_FORMAT='LANG',
|
||||
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
|
||||
AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
|
||||
AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
|
||||
Title CHAR(32) FIELD_FORMAT='TITLE',
|
||||
Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
|
||||
Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
|
||||
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
|
||||
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
|
||||
Year int(4) FIELD_FORMAT='DATEPUB'
|
||||
)
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.jsn';
|
||||
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 Fran<61>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
|
||||
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
|
||||
#
|
||||
# To add an author a new table must be created
|
||||
#
|
||||
CREATE TABLE t2 (
|
||||
FIRSTNAME CHAR(32),
|
||||
LASTNAME CHAR(32))
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.jsn' OPTION_LIST='Object=[2]: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 Eyrolles Paris 1999
|
||||
9782212090819 fr applications Philippe 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 Charles Dickens XML en Action adapt<70> 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.jsn';
|
||||
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<70> de l'anglais par",
|
||||
"TRANSLATOR": {
|
||||
"FIRSTNAME": "James",
|
||||
"LASTNAME": "Guerin"
|
||||
},
|
||||
"PUBLISHER": {
|
||||
"NAME": "Microsoft Press",
|
||||
"PLACE": "Paris"
|
||||
},
|
||||
"DATEPUB": 1999
|
||||
}
|
||||
]
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# A file with 2 arrays
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
WHO CHAR(12),
|
||||
WEEK INT(2) FIELD_FORMAT='WEEK:[X]:NUMBER',
|
||||
WHAT CHAR(32) FIELD_FORMAT='WEEK::EXPENSE:["+"]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK::EXPENSE:[+]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
|
||||
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;
|
||||
#
|
||||
# Cannot be fully expanded
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
WHO CHAR(12),
|
||||
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';
|
||||
SELECT * FROM t1;
|
||||
ERROR HY000: Got error 174 'Cannot expand more than one array' from CONNECT
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Expand expense in 3 one week tables
|
||||
#
|
||||
CREATE TABLE t2 (
|
||||
WHO CHAR(12),
|
||||
WEEK INT(2) FIELD_FORMAT='WEEK:[1]:NUMBER',
|
||||
WHAT CHAR(32) FIELD_FORMAT='WEEK:[1]:EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[1]:EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
|
||||
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) FIELD_FORMAT='WEEK:[2]:NUMBER',
|
||||
WHAT CHAR(32) FIELD_FORMAT='WEEK:[2]:EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[2]:EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
|
||||
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) FIELD_FORMAT='WEEK:[3]:NUMBER',
|
||||
WHAT CHAR(32) FIELD_FORMAT='WEEK:[3]:EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[3]:EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
|
||||
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) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp3.jsn';
|
||||
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) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp4.jsn';
|
||||
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) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp5.jsn';
|
||||
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) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp*.jsn' MULTIPLE=1;
|
||||
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;
|
||||
#
|
||||
# Or also a partition JSON table
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
WHO CHAR(12),
|
||||
WEEK INT(2),
|
||||
WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp%s.jsn';
|
||||
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;
|
45
storage/connect/mysql-test/connect/std_data/biblio.jsn
Normal file
45
storage/connect/mysql-test/connect/std_data/biblio.jsn
Normal file
@@ -0,0 +1,45 @@
|
||||
[
|
||||
{
|
||||
"ISBN": "9782212090819",
|
||||
"LANG": "fr",
|
||||
"SUBJECT": "applications",
|
||||
"AUTHOR": [
|
||||
{
|
||||
"FIRSTNAME": "Jean-Christophe",
|
||||
"LASTNAME": "Bernadac"
|
||||
},
|
||||
{
|
||||
"FIRSTNAME": "Fran<61>ois",
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"TITLE": "XML en Action",
|
||||
"TRANSLATION": "adapt<70> de l'anglais par",
|
||||
"TRANSLATOR": {
|
||||
"FIRSTNAME": "James",
|
||||
"LASTNAME": "Guerin"
|
||||
},
|
||||
"PUBLISHER": {
|
||||
"NAME": "Microsoft Press",
|
||||
"PLACE": "Paris"
|
||||
},
|
||||
"DATEPUB": 1999
|
||||
}
|
||||
]
|
158
storage/connect/mysql-test/connect/std_data/expense.jsn
Normal file
158
storage/connect/mysql-test/connect/std_data/expense.jsn
Normal file
@@ -0,0 +1,158 @@
|
||||
[
|
||||
{
|
||||
"WHO": "Joe",
|
||||
"WEEK": [
|
||||
{
|
||||
"NUMBER": 3,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 18.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 12.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 19.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Car",
|
||||
"AMOUNT": 20.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"NUMBER": 4,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 19.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 16.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 17.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 17.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 14.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"NUMBER": 5,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 14.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 12.00
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"WHO": "Beth",
|
||||
"WEEK": [
|
||||
{
|
||||
"NUMBER": 3,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 16.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"NUMBER": 4,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 17.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 15.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"NUMBER": 5,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 12.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 20.00
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"WHO": "Janet",
|
||||
"WEEK": [
|
||||
{
|
||||
"NUMBER": 3,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Car",
|
||||
"AMOUNT": 19.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 18.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 18.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"NUMBER": 4,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Car",
|
||||
"AMOUNT": 17.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"NUMBER": 5,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 14.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Car",
|
||||
"AMOUNT": 12.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 19.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 12.00
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
52
storage/connect/mysql-test/connect/std_data/mulexp3.jsn
Normal file
52
storage/connect/mysql-test/connect/std_data/mulexp3.jsn
Normal file
@@ -0,0 +1,52 @@
|
||||
[
|
||||
{
|
||||
"WHO": "Joe",
|
||||
"WEEK": 3,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 18.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 12.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 19.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Car",
|
||||
"AMOUNT": 20.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"WHO": "Beth",
|
||||
"WEEK": 3,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 16.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"WHO": "Janet",
|
||||
"WEEK": 3,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Car",
|
||||
"AMOUNT": 19.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 18.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 18.00
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
52
storage/connect/mysql-test/connect/std_data/mulexp4.jsn
Normal file
52
storage/connect/mysql-test/connect/std_data/mulexp4.jsn
Normal file
@@ -0,0 +1,52 @@
|
||||
[
|
||||
{
|
||||
"WHO": "Joe",
|
||||
"WEEK": 4,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 19.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 16.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 17.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 17.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 14.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"WHO": "Beth",
|
||||
"WEEK": 4,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 17.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 15.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"WHO": "Janet",
|
||||
"WEEK": 4,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Car",
|
||||
"AMOUNT": 17.00
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
52
storage/connect/mysql-test/connect/std_data/mulexp5.jsn
Normal file
52
storage/connect/mysql-test/connect/std_data/mulexp5.jsn
Normal file
@@ -0,0 +1,52 @@
|
||||
[
|
||||
{
|
||||
"WHO": "Joe",
|
||||
"WEEK": 5,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 14.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 12.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"WHO": "Beth",
|
||||
"WEEK": 5,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 12.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 20.00
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"WHO": "Janet",
|
||||
"WEEK": 5,
|
||||
"EXPENSE": [
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 14.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Car",
|
||||
"AMOUNT": 12.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Beer",
|
||||
"AMOUNT": 19.00
|
||||
},
|
||||
{
|
||||
"WHAT": "Food",
|
||||
"AMOUNT": 12.00
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
247
storage/connect/mysql-test/connect/t/json.test
Normal file
247
storage/connect/mysql-test/connect/t/json.test
Normal file
@@ -0,0 +1,247 @@
|
||||
--source include/not_embedded.inc
|
||||
--source include/have_partition.inc
|
||||
|
||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||
|
||||
--copy_file $MTR_SUITE_DIR/std_data/biblio.jsn $MYSQLD_DATADIR/test/biblio.jsn
|
||||
--copy_file $MTR_SUITE_DIR/std_data/expense.jsn $MYSQLD_DATADIR/test/expense.jsn
|
||||
--copy_file $MTR_SUITE_DIR/std_data/mulexp3.jsn $MYSQLD_DATADIR/test/mulexp3.jsn
|
||||
--copy_file $MTR_SUITE_DIR/std_data/mulexp4.jsn $MYSQLD_DATADIR/test/mulexp4.jsn
|
||||
--copy_file $MTR_SUITE_DIR/std_data/mulexp5.jsn $MYSQLD_DATADIR/test/mulexp5.jsn
|
||||
|
||||
--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=JSON FILE_NAME='biblio.jsn';
|
||||
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) FIELD_FORMAT='LANG',
|
||||
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
|
||||
Authors INT(2) FIELD_FORMAT='AUTHOR:[#]',
|
||||
Title CHAR(32) FIELD_FORMAT='TITLE',
|
||||
Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
|
||||
Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
|
||||
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
|
||||
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
|
||||
Year int(4) FIELD_FORMAT='DATEPUB'
|
||||
)
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.jsn';
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Concatenates the authors
|
||||
--echo #
|
||||
CREATE TABLE t1
|
||||
(
|
||||
ISBN CHAR(15),
|
||||
Language CHAR(2) FIELD_FORMAT='LANG',
|
||||
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
|
||||
AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[" and "]:FIRSTNAME',
|
||||
AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[" and "]:LASTNAME',
|
||||
Title CHAR(32) FIELD_FORMAT='TITLE',
|
||||
Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
|
||||
Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
|
||||
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
|
||||
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
|
||||
Year int(4) FIELD_FORMAT='DATEPUB'
|
||||
)
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.jsn';
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Testing expanding authors
|
||||
--echo #
|
||||
CREATE TABLE t1
|
||||
(
|
||||
ISBN CHAR(15),
|
||||
Language CHAR(2) FIELD_FORMAT='LANG',
|
||||
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
|
||||
AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
|
||||
AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
|
||||
Title CHAR(32) FIELD_FORMAT='TITLE',
|
||||
Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
|
||||
Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
|
||||
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
|
||||
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
|
||||
Year int(4) FIELD_FORMAT='DATEPUB'
|
||||
)
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.jsn';
|
||||
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=JSON FILE_NAME='biblio.jsn' OPTION_LIST='Object=[2]: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.jsn';
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # A file with 2 arrays
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
WHO CHAR(12),
|
||||
WEEK INT(2) FIELD_FORMAT='WEEK:[X]:NUMBER',
|
||||
WHAT CHAR(32) FIELD_FORMAT='WEEK::EXPENSE:["+"]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK::EXPENSE:[+]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Cannot be fully expanded
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
WHO CHAR(12),
|
||||
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
|
||||
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) FIELD_FORMAT='WEEK:[1]:NUMBER',
|
||||
WHAT CHAR(32) FIELD_FORMAT='WEEK:[1]:EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[1]:EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
|
||||
SELECT * FROM t2;
|
||||
|
||||
CREATE TABLE t3 (
|
||||
WHO CHAR(12),
|
||||
WEEK INT(2) FIELD_FORMAT='WEEK:[2]:NUMBER',
|
||||
WHAT CHAR(32) FIELD_FORMAT='WEEK:[2]:EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[2]:EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
|
||||
SELECT * FROM t3;
|
||||
|
||||
CREATE TABLE t4 (
|
||||
WHO CHAR(12),
|
||||
WEEK INT(2) FIELD_FORMAT='WEEK:[3]:NUMBER',
|
||||
WHAT CHAR(32) FIELD_FORMAT='WEEK:[3]:EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[3]:EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
|
||||
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) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp3.jsn';
|
||||
SELECT * FROM t2;
|
||||
|
||||
CREATE TABLE t3 (
|
||||
WHO CHAR(12),
|
||||
WEEK INT(2),
|
||||
WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp4.jsn';
|
||||
SELECT * FROM t3;
|
||||
|
||||
CREATE TABLE t4 (
|
||||
WHO CHAR(12),
|
||||
WEEK INT(2),
|
||||
WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp5.jsn';
|
||||
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) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp*.jsn' MULTIPLE=1;
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Or also a partition JSON table
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
WHO CHAR(12),
|
||||
WEEK INT(2),
|
||||
WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
|
||||
AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
|
||||
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp%s.jsn';
|
||||
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.jsn
|
||||
--remove_file $MYSQLD_DATADIR/test/expense.jsn
|
||||
--remove_file $MYSQLD_DATADIR/test/mulexp3.jsn
|
||||
--remove_file $MYSQLD_DATADIR/test/mulexp4.jsn
|
||||
--remove_file $MYSQLD_DATADIR/test/mulexp5.jsn
|
@@ -74,11 +74,10 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
|
||||
TAB_PLG = 20, /* PLG NIY */
|
||||
TAB_PIVOT = 21, /* PIVOT table */
|
||||
TAB_VIR = 22, /* Virtual tables */
|
||||
// TAB_JSON = 23, /* JSON tables */
|
||||
// TAB_JSN = 24, /* Semi-json tables */
|
||||
TAB_JCT = 25, /* Junction tables NIY */
|
||||
TAB_DMY = 26, /* DMY Dummy tables NIY */
|
||||
TAB_NIY = 27}; /* Table not implemented yet */
|
||||
TAB_JSON = 23, /* JSON tables */
|
||||
TAB_JCT = 24, /* Junction tables NIY */
|
||||
TAB_DMY = 25, /* DMY Dummy tables NIY */
|
||||
TAB_NIY = 26}; /* Table not implemented yet */
|
||||
|
||||
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
|
||||
TYPE_AM_ROWID = 1, /* ROWID type (special column) */
|
||||
@@ -123,6 +122,8 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
|
||||
TYPE_AM_BLK = 131, /* BLK access method type no */
|
||||
TYPE_AM_ZIP = 132, /* ZIP access method type no */
|
||||
TYPE_AM_ZLIB = 133, /* ZLIB access method type no */
|
||||
TYPE_AM_JSON = 134, /* JSON access method type no */
|
||||
TYPE_AM_JSN = 135, /* JSN access method type no */
|
||||
TYPE_AM_MAC = 137, /* MAC table access method type */
|
||||
TYPE_AM_WMI = 139, /* WMI table access method type */
|
||||
TYPE_AM_XCL = 140, /* SYS column access method type */
|
||||
|
@@ -2211,7 +2211,8 @@ int TDBDOS::WriteDB(PGLOBAL g)
|
||||
htrc("DOS WriteDB: R%d Mode=%d \n", Tdb_No, Mode);
|
||||
|
||||
// Make the line to write
|
||||
(void)PrepareWriting(g);
|
||||
if (PrepareWriting(g))
|
||||
return true;
|
||||
|
||||
if (trace > 1)
|
||||
htrc("Write: line is='%s'\n", To_Line);
|
||||
|
1327
storage/connect/tabjson.cpp
Normal file
1327
storage/connect/tabjson.cpp
Normal file
File diff suppressed because it is too large
Load Diff
197
storage/connect/tabjson.h
Normal file
197
storage/connect/tabjson.h
Normal file
@@ -0,0 +1,197 @@
|
||||
/*************** tabjson H Declares Source Code File (.H) **************/
|
||||
/* Name: tabjson.h Version 1.0 */
|
||||
/* */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
|
||||
/* */
|
||||
/* This file contains the JSON classes declares. */
|
||||
/***********************************************************************/
|
||||
#include "osutil.h"
|
||||
#include "block.h"
|
||||
#include "colblk.h"
|
||||
#include "json.h"
|
||||
|
||||
enum JMODE {MODE_OBJECT, MODE_ARRAY, MODE_VALUE};
|
||||
|
||||
typedef class JSONDEF *PJDEF;
|
||||
typedef class TDBJSON *PJTDB;
|
||||
typedef class JSONCOL *PJCOL;
|
||||
|
||||
class TDBJSN;
|
||||
|
||||
/***********************************************************************/
|
||||
/* The JSON tree node. Can be an Object or an Array. */
|
||||
/***********************************************************************/
|
||||
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
|
||||
int Rank; // The rank in array
|
||||
} JNODE, *PJNODE;
|
||||
|
||||
/***********************************************************************/
|
||||
/* JSON table. */
|
||||
/***********************************************************************/
|
||||
class JSONDEF : public DOSDEF { /* Table description */
|
||||
friend class TDBJSON;
|
||||
friend class TDBJSN;
|
||||
public:
|
||||
// Constructor
|
||||
JSONDEF(void);
|
||||
|
||||
// Implementation
|
||||
virtual const char *GetType(void) {return "JSON";}
|
||||
|
||||
// Methods
|
||||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||
virtual PTDB GetTable(PGLOBAL g, MODE m);
|
||||
|
||||
protected:
|
||||
// Members
|
||||
JMODE Jmode; /* MODE_OBJECT by default */
|
||||
char *Objname; /* Name of first level object */
|
||||
char *Xcol; /* Name of expandable column */
|
||||
int Limit; /* Limit of multiple values */
|
||||
int Pretty; /* Depends on file structure */
|
||||
bool Strict; /* Strict syntax checking */
|
||||
}; // end of JSONDEF
|
||||
|
||||
/* -------------------------- TDBJSN class --------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
/* This is the JSN Access Method class declaration. */
|
||||
/* The table is a DOS file, each record being a JSON object. */
|
||||
/***********************************************************************/
|
||||
class TDBJSN : public TDBDOS {
|
||||
friend class JSONCOL;
|
||||
public:
|
||||
// Constructor
|
||||
TDBJSN(PJDEF tdp, PTXF txfp);
|
||||
TDBJSN(TDBJSN *tdbp);
|
||||
|
||||
// Implementation
|
||||
virtual AMT GetAmType(void) {return TYPE_AM_JSN;}
|
||||
virtual bool SkipHeader(PGLOBAL g);
|
||||
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJSN(this);}
|
||||
|
||||
// Methods
|
||||
virtual PTDB CopyOne(PTABS t);
|
||||
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
|
||||
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL colp);
|
||||
virtual int RowNumber(PGLOBAL g, BOOL b = FALSE)
|
||||
{return (b) ? N : Fpos + 1;}
|
||||
|
||||
// Database routines
|
||||
virtual int Cardinality(PGLOBAL g);
|
||||
virtual int GetMaxSize(PGLOBAL g);
|
||||
virtual bool OpenDB(PGLOBAL g);
|
||||
virtual bool PrepareWriting(PGLOBAL g);
|
||||
virtual int ReadDB(PGLOBAL g);
|
||||
|
||||
protected:
|
||||
// Members
|
||||
PJSON Row; // The current row
|
||||
PJCOL Colp; // The multiple column
|
||||
JMODE Jmode; // MODE_OBJECT by default
|
||||
char *Xcol; // Name of expandable column
|
||||
int Fpos; // The current row index
|
||||
int Spos; // DELETE start index
|
||||
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 SameRow; // Same row nb
|
||||
int Xval; // Index of expandable array
|
||||
}; // end of class TDBJSN
|
||||
|
||||
/* -------------------------- JSONCOL class -------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class JSONCOL: JSON access method column descriptor. */
|
||||
/***********************************************************************/
|
||||
class JSONCOL : public DOSCOL {
|
||||
friend class TDBJSN;
|
||||
friend class TDBJSON;
|
||||
public:
|
||||
// Constructors
|
||||
JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i);
|
||||
JSONCOL(JSONCOL *colp, PTDB tdbp); // Constructor used in copy process
|
||||
|
||||
// Implementation
|
||||
virtual int GetAmType(void) {return Tjp->GetAmType();}
|
||||
|
||||
// Methods
|
||||
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
|
||||
bool ParseJpath(PGLOBAL g);
|
||||
virtual void ReadColumn(PGLOBAL g);
|
||||
virtual void WriteColumn(PGLOBAL g);
|
||||
|
||||
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);
|
||||
void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n);
|
||||
|
||||
// Default constructor not to be used
|
||||
JSONCOL(void) {}
|
||||
|
||||
// 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
|
||||
int Nod; // The number of intermediate objects
|
||||
int Ival; // Index of multiple values
|
||||
int Nx; // The last read sub-row
|
||||
bool Xpd; // True for expandable column
|
||||
bool Parsed; // True when parsed
|
||||
}; // end of class JSONCOL
|
||||
|
||||
/* -------------------------- TDBJSON class -------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
/* This is the JSON Access Method class declaration. */
|
||||
/***********************************************************************/
|
||||
class TDBJSON : public TDBJSN {
|
||||
friend class JSONCOL;
|
||||
public:
|
||||
// Constructor
|
||||
TDBJSON(PJDEF tdp, PTXF txfp);
|
||||
TDBJSON(PJTDB tdbp);
|
||||
|
||||
// Implementation
|
||||
virtual AMT GetAmType(void) {return TYPE_AM_JSON;}
|
||||
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJSON(this);}
|
||||
|
||||
// Methods
|
||||
virtual PTDB CopyOne(PTABS t);
|
||||
|
||||
// Database routines
|
||||
virtual int Cardinality(PGLOBAL g);
|
||||
virtual int GetMaxSize(PGLOBAL g);
|
||||
virtual void ResetSize(void);
|
||||
virtual int GetRecpos(void) {return Fpos;}
|
||||
virtual bool OpenDB(PGLOBAL g);
|
||||
virtual int ReadDB(PGLOBAL g);
|
||||
virtual bool PrepareWriting(PGLOBAL g) {return false;}
|
||||
virtual int WriteDB(PGLOBAL g);
|
||||
virtual int DeleteDB(PGLOBAL g, int irc);
|
||||
virtual void CloseDB(PGLOBAL g);
|
||||
|
||||
// Optimization routines
|
||||
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
|
||||
|
||||
protected:
|
||||
int MakeNewDoc(PGLOBAL g);
|
||||
int MakeDocument(PGLOBAL g);
|
||||
|
||||
// Members
|
||||
PJSON Top; // The file JSON tree
|
||||
PJAR Doc; // The document array
|
||||
char *Objname; // The table object name
|
||||
int Multiple; // 0: No 1: DIR 2: Section 3: filelist
|
||||
bool Done; // True when document parsing is done
|
||||
bool Changed; // After Update, Insert or Delete
|
||||
}; // end of class TDBJSON
|
@@ -67,6 +67,22 @@
|
||||
|
||||
#define FOURYEARS 126230400 // Four years in seconds (1 leap)
|
||||
|
||||
#define MAXUINT8 ((UINT8)~((UINT8)0))
|
||||
#define MAXINT8 ((INT8)(MAXUINT8 >> 1))
|
||||
#define MININT8 ((INT8)~MAXINT8)
|
||||
|
||||
#define MAXUINT16 ((UINT16)~((UINT16)0))
|
||||
#define MAXINT16 ((INT16)(MAXUINT16 >> 1))
|
||||
#define MININT16 ((INT16)~MAXINT16)
|
||||
|
||||
#define MAXUINT32 ((UINT32)~((UINT32)0))
|
||||
#define MAXINT32 ((INT32)(MAXUINT32 >> 1))
|
||||
#define MININT32 ((INT32)~MAXINT32)
|
||||
|
||||
#define MAXUINT64 ((UINT64)~((UINT64)0))
|
||||
#define MAXINT64 ((INT64)(MAXUINT64 >> 1))
|
||||
#define MININT64 ((INT64)~MAXINT64)
|
||||
|
||||
/***********************************************************************/
|
||||
/* Initialize the DTVAL static member. */
|
||||
/***********************************************************************/
|
||||
@@ -434,6 +450,7 @@ PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype, int uns)
|
||||
{
|
||||
PSZ p, sp;
|
||||
bool un = (uns < 0) ? false : (uns > 0) ? true : valp->IsUnsigned();
|
||||
PVAL vp;
|
||||
|
||||
if (newtype == TYPE_VOID) // Means allocate a value of the same type
|
||||
newtype = valp->GetType();
|
||||
@@ -445,53 +462,55 @@ PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype, int uns)
|
||||
if ((sp = valp->GetCharString(p)) != p)
|
||||
strcpy (p, sp);
|
||||
|
||||
valp = new(g) TYPVAL<PSZ>(g, p, valp->GetValLen(), valp->GetValPrec());
|
||||
vp = new(g) TYPVAL<PSZ>(g, p, valp->GetValLen(), valp->GetValPrec());
|
||||
break;
|
||||
case TYPE_SHORT:
|
||||
if (un)
|
||||
valp = new(g) TYPVAL<ushort>(valp->GetUShortValue(),
|
||||
TYPE_SHORT, 0, true);
|
||||
vp = new(g) TYPVAL<ushort>(valp->GetUShortValue(),
|
||||
TYPE_SHORT, 0, true);
|
||||
else
|
||||
valp = new(g) TYPVAL<short>(valp->GetShortValue(), TYPE_SHORT);
|
||||
vp = new(g) TYPVAL<short>(valp->GetShortValue(), TYPE_SHORT);
|
||||
|
||||
break;
|
||||
case TYPE_INT:
|
||||
if (un)
|
||||
valp = new(g) TYPVAL<uint>(valp->GetUIntValue(), TYPE_INT, 0, true);
|
||||
vp = new(g) TYPVAL<uint>(valp->GetUIntValue(), TYPE_INT, 0, true);
|
||||
else
|
||||
valp = new(g) TYPVAL<int>(valp->GetIntValue(), TYPE_INT);
|
||||
vp = new(g) TYPVAL<int>(valp->GetIntValue(), TYPE_INT);
|
||||
|
||||
break;
|
||||
case TYPE_BIGINT:
|
||||
if (un)
|
||||
valp = new(g) TYPVAL<ulonglong>(valp->GetUBigintValue(),
|
||||
TYPE_BIGINT, 0, true);
|
||||
vp = new(g) TYPVAL<ulonglong>(valp->GetUBigintValue(),
|
||||
TYPE_BIGINT, 0, true);
|
||||
else
|
||||
valp = new(g) TYPVAL<longlong>(valp->GetBigintValue(), TYPE_BIGINT);
|
||||
vp = new(g) TYPVAL<longlong>(valp->GetBigintValue(), TYPE_BIGINT);
|
||||
|
||||
break;
|
||||
case TYPE_DATE:
|
||||
valp = new(g) DTVAL(g, valp->GetIntValue());
|
||||
vp = new(g) DTVAL(g, valp->GetIntValue());
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
valp = new(g) TYPVAL<double>(valp->GetFloatValue(), TYPE_DOUBLE,
|
||||
(uns) ? uns : valp->GetValPrec());
|
||||
vp = new(g) TYPVAL<double>(valp->GetFloatValue(), TYPE_DOUBLE,
|
||||
(uns) ? uns : valp->GetValPrec());
|
||||
break;
|
||||
case TYPE_TINY:
|
||||
if (un)
|
||||
valp = new(g) TYPVAL<uchar>(valp->GetUTinyValue(),
|
||||
vp = new(g) TYPVAL<uchar>(valp->GetUTinyValue(),
|
||||
TYPE_TINY, 0, true);
|
||||
else
|
||||
valp = new(g) TYPVAL<char>(valp->GetTinyValue(), TYPE_TINY);
|
||||
vp = new(g) TYPVAL<char>(valp->GetTinyValue(), TYPE_TINY);
|
||||
|
||||
break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(BAD_VALUE_TYPE), newtype);
|
||||
return NULL;
|
||||
} // endswitch type
|
||||
|
||||
valp->SetGlobal(g);
|
||||
return valp;
|
||||
|
||||
vp->SetNullable(valp->GetNullable());
|
||||
vp->SetNull(valp->IsNull());
|
||||
vp->SetGlobal(g);
|
||||
return vp;
|
||||
} // end of AllocateValue
|
||||
|
||||
/* -------------------------- Class VALUE ---------------------------- */
|
||||
@@ -939,7 +958,6 @@ int TYPVAL<TYPE>::CompareValue(PVAL vp)
|
||||
return (Tval > n) ? 1 : (Tval < n) ? (-1) : 0;
|
||||
} // end of CompareValue
|
||||
|
||||
#if 0
|
||||
/***********************************************************************/
|
||||
/* Return max type value if b is true, else min type value. */
|
||||
/***********************************************************************/
|
||||
@@ -1004,7 +1022,7 @@ TYPE TYPVAL<TYPE>::SafeAdd(TYPE n1, TYPE n2)
|
||||
template <>
|
||||
inline double TYPVAL<double>::SafeAdd(double n1, double n2)
|
||||
{
|
||||
assert(false); return 0;
|
||||
return n1 + n2;
|
||||
} // end of SafeAdd
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -1032,9 +1050,8 @@ TYPE TYPVAL<TYPE>::SafeMult(TYPE n1, TYPE n2)
|
||||
template <>
|
||||
inline double TYPVAL<double>::SafeMult(double n1, double n2)
|
||||
{
|
||||
assert(false); return 0;
|
||||
return n1 * n2;
|
||||
} // end of SafeMult
|
||||
#endif // 0
|
||||
|
||||
/***********************************************************************/
|
||||
/* Compute defined functions for the type. */
|
||||
@@ -1052,12 +1069,18 @@ bool TYPVAL<TYPE>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||
|
||||
switch (op) {
|
||||
case OP_ADD:
|
||||
// Tval = SafeAdd(val[0], val[1]);
|
||||
Tval = val[0] + val[1];
|
||||
Tval = SafeAdd(val[0], val[1]);
|
||||
break;
|
||||
case OP_MULT:
|
||||
// Tval = SafeMult(val[0], val[1]);
|
||||
Tval = val[0] * val[1];
|
||||
Tval = SafeMult(val[0], val[1]);
|
||||
break;
|
||||
case OP_DIV:
|
||||
if (!val[1]) {
|
||||
strcpy(g->Message, MSG(ZERO_DIVIDE));
|
||||
return true;
|
||||
} // endif
|
||||
|
||||
Tval = val[0] / val[1];
|
||||
break;
|
||||
default:
|
||||
rc = Compall(g, vp, np, op);
|
||||
@@ -1067,7 +1090,6 @@ bool TYPVAL<TYPE>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||
return rc;
|
||||
} // end of Compute
|
||||
|
||||
#if 0
|
||||
template <>
|
||||
bool TYPVAL<double>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||
{
|
||||
@@ -1092,7 +1114,6 @@ bool TYPVAL<double>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||
|
||||
return rc;
|
||||
} // end of Compute
|
||||
#endif // 0
|
||||
|
||||
/***********************************************************************/
|
||||
/* Compute a function for all types. */
|
||||
@@ -1106,6 +1127,18 @@ bool TYPVAL<TYPE>::Compall(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||
val[i] = GetTypedValue(vp[i]);
|
||||
|
||||
switch (op) {
|
||||
case OP_DIV:
|
||||
if (val[0]) {
|
||||
if (!val[1]) {
|
||||
strcpy(g->Message, MSG(ZERO_DIVIDE));
|
||||
return true;
|
||||
} // endif
|
||||
|
||||
Tval = val[0] / val[1];
|
||||
} else
|
||||
Tval = 0;
|
||||
|
||||
break;
|
||||
case OP_MIN:
|
||||
Tval = MY_MIN(val[0], val[1]);
|
||||
break;
|
||||
|
@@ -190,9 +190,9 @@ class DllExport TYPVAL : public VALUE {
|
||||
virtual void Print(PGLOBAL g, char *, uint);
|
||||
|
||||
protected:
|
||||
//static TYPE MinMaxVal(bool b);
|
||||
// TYPE SafeAdd(TYPE n1, TYPE n2);
|
||||
// TYPE SafeMult(TYPE n1, TYPE n2);
|
||||
static TYPE MinMaxVal(bool b);
|
||||
TYPE SafeAdd(TYPE n1, TYPE n2);
|
||||
TYPE SafeMult(TYPE n1, TYPE n2);
|
||||
bool Compall(PGLOBAL g, PVAL *vp, int np, OPVAL op);
|
||||
|
||||
// Default constructor not to be used
|
||||
|
Reference in New Issue
Block a user