Commit dc3a693b authored by Olivier Bertrand's avatar Olivier Bertrand

- Inline MakePtr and MakeOff with OFFSET as size_t

  Also add a new member Saved_Size in the Global structure.
  modified:   storage/connect/global.h
  modified:   storage/connect/plugutil.cpp
  modified:   storage/connect/user_connect.cc
  modified:   storage/connect/jsonudf.cpp

- Add session variables json_all_path and default_depth
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/mongo.cpp
  modified:   storage/connect/tabjson.cpp
  modified:   storage/connect/tabxml.cpp

- ADD column options JPATH and XPATH
  Work as FIELD_FORMAT but are more readable
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/ha_connect.h
  modified:   storage/connect/mysql-test/connect/r/json_java_2.result
  modified:   storage/connect/mysql-test/connect/r/json_java_3.result
  modified:   storage/connect/mysql-test/connect/r/json_mongo_c.result

- Handle negative numbes in the option list
  modified:   storage/connect/ha_connect.cc

- Fix Json parse that could crash the server.
  Was because it could use THROW out of the TRY block.
  Also handle all error by THROW.
  It is now done by a new class JSON.
  modified:   storage/connect/json.cpp
  modified:   storage/connect/json.h

- Add a new UDF function jfile_translate.
  It translate a Json file to pretty = 0.
  Fast because it does not a real parse of the file.
  modified:   storage/connect/jsonudf.cpp
  modified:   storage/connect/jsonudf.h

- Add a now options JSIZE and STRINGIFY to Json tables.
  STRINGIFY makes Objects or Arrays to be returned by their
  json representation instead of by their concatenated values.
  JSIZE allows to specify the LRECL (was 256) defaults to 1024.
  Also fix a bug about locating the sub-table by its path.
  modified:   storage/connect/tabjson.cpp
  modified:   storage/connect/tabjson.h
parent 5d2ddef2
...@@ -89,14 +89,10 @@ extern "C" { ...@@ -89,14 +89,10 @@ extern "C" {
#define PAT_LOG "log" #define PAT_LOG "log"
#if defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX) #if defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX)
/*********************************************************************/ // printf does not accept null pointer for %s target
/* printf does not accept null pointer for %s target. */
/*********************************************************************/
#define SVP(S) ((S) ? S : "<null>") #define SVP(S) ((S) ? S : "<null>")
#else #else
/*********************************************************************/ // printf accepts null pointer for %s target
/* printf accepts null pointer for %s target. */
/*********************************************************************/
#define SVP(S) S #define SVP(S) S
#endif #endif
...@@ -112,9 +108,6 @@ extern "C" { ...@@ -112,9 +108,6 @@ extern "C" {
/***********************************************************************/ /***********************************************************************/
#include "os.h" #include "os.h"
typedef size_t OFFSET;
typedef char NAME[9];
typedef struct { typedef struct {
ushort Length; ushort Length;
char String[2]; char String[2];
...@@ -127,6 +120,7 @@ typedef struct _global *PGLOBAL; ...@@ -127,6 +120,7 @@ typedef struct _global *PGLOBAL;
typedef struct _globplg *PGS; typedef struct _globplg *PGS;
typedef struct _activity *PACTIVITY; typedef struct _activity *PACTIVITY;
typedef struct _parm *PPARM; typedef struct _parm *PPARM;
typedef char NAME[9];
/***********************************************************************/ /***********************************************************************/
/* Segment Sub-Allocation block structure declares. */ /* Segment Sub-Allocation block structure declares. */
...@@ -135,7 +129,7 @@ typedef struct _parm *PPARM; ...@@ -135,7 +129,7 @@ typedef struct _parm *PPARM;
/* restore them if needed. This scheme implies that no SubFree be used */ /* restore them if needed. This scheme implies that no SubFree be used */
/***********************************************************************/ /***********************************************************************/
typedef struct { /* Plug Area SubAlloc header */ typedef struct { /* Plug Area SubAlloc header */
OFFSET To_Free; /* Offset of next free block */ size_t To_Free; /* Offset of next free block */
size_t FreeBlk; /* Size of remaining free memory */ size_t FreeBlk; /* Size of remaining free memory */
} POOLHEADER, *PPOOLHEADER; } POOLHEADER, *PPOOLHEADER;
...@@ -190,9 +184,10 @@ typedef struct _global { /* Global structure */ ...@@ -190,9 +184,10 @@ typedef struct _global { /* Global structure */
void *Sarea; /* Points to work area */ void *Sarea; /* Points to work area */
size_t Sarea_Size; /* Work area size */ size_t Sarea_Size; /* Work area size */
PACTIVITY Activityp; PACTIVITY Activityp;
char Message[MAX_STR]; char Message[MAX_STR]; /* Message (result, error, trace) */
ulong More; /* Used by jsonudf */ ulong More; /* Used by jsonudf */
int Createas; /* To pass multi to ext tables */ size_t Saved_Size; /* Saved work area to_free */
bool Createas; /* To pass multi to ext tables */
void *Xchk; /* indexes in create/alter */ void *Xchk; /* indexes in create/alter */
short Alchecked; /* Checked for ALTER */ short Alchecked; /* Checked for ALTER */
short Mrr; /* True when doing mrr */ short Mrr; /* True when doing mrr */
...@@ -222,7 +217,6 @@ DllExport void FreeSarea(PGLOBAL); ...@@ -222,7 +217,6 @@ DllExport void FreeSarea(PGLOBAL);
DllExport BOOL PlugSubSet(void *, size_t); DllExport BOOL PlugSubSet(void *, size_t);
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t); DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
DllExport char *PlugDup(PGLOBAL g, const char *str); DllExport char *PlugDup(PGLOBAL g, const char *str);
DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...); DllExport void htrc(char const *fmt, ...);
DllExport void xtrc(uint, char const* fmt, ...); DllExport void xtrc(uint, char const* fmt, ...);
DllExport uint GetTraceValue(void); DllExport uint GetTraceValue(void);
...@@ -232,8 +226,24 @@ DllExport uint GetTraceValue(void); ...@@ -232,8 +226,24 @@ DllExport uint GetTraceValue(void);
#endif #endif
/***********************************************************************/ /***********************************************************************/
/* Non exported routine declarations. */ /* Inline routine definitions. */
/***********************************************************************/
/***********************************************************************/
/* This routine makes a pointer from an offset to a memory pointer. */
/***********************************************************************/
inline void* MakePtr(void* memp, size_t offset) {
// return ((offset == 0) ? NULL : &((char*)memp)[offset]);
return (!offset) ? NULL : (char *)memp + offset;
} /* end of MakePtr */
/***********************************************************************/
/* This routine makes an offset from a pointer new format. */
/***********************************************************************/ /***********************************************************************/
//void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw inline size_t MakeOff(void* memp, void* ptr) {
#if defined(_DEBUG)
assert(ptr > memp);
#endif // _DEBUG
return ((!ptr) ? 0 : (size_t)((char*)ptr - (size_t)memp));
} /* end of MakeOff */
/*-------------------------- End of Global.H --------------------------*/ /*-------------------------- End of Global.H --------------------------*/
...@@ -170,7 +170,7 @@ ...@@ -170,7 +170,7 @@
#define JSONMAX 10 // JSON Default max grp size #define JSONMAX 10 // JSON Default max grp size
extern "C" { extern "C" {
char version[]= "Version 1.07.0002 October 03, 2020"; char version[]= "Version 1.07.0002 October 18, 2020";
#if defined(__WIN__) #if defined(__WIN__)
char compver[]= "Version 1.07.0002 " __DATE__ " " __TIME__; char compver[]= "Version 1.07.0002 " __DATE__ " " __TIME__;
char slash= '\\'; char slash= '\\';
...@@ -251,6 +251,7 @@ bool ExactInfo(void); ...@@ -251,6 +251,7 @@ bool ExactInfo(void);
USETEMP UseTemp(void); USETEMP UseTemp(void);
int GetConvSize(void); int GetConvSize(void);
TYPCONV GetTypeConv(void); TYPCONV GetTypeConv(void);
bool JsonAllPath(void);
char *GetJsonNull(void); char *GetJsonNull(void);
uint GetJsonGrpSize(void); uint GetJsonGrpSize(void);
char *GetJavaWrapper(void); char *GetJavaWrapper(void);
...@@ -394,6 +395,11 @@ static MYSQL_THDVAR_ENUM( ...@@ -394,6 +395,11 @@ static MYSQL_THDVAR_ENUM(
1, // def (yes) 1, // def (yes)
&xconv_typelib); // typelib &xconv_typelib); // typelib
// Adding JPATH to all Json table columns
static MYSQL_THDVAR_BOOL(json_all_path, PLUGIN_VAR_RQCMDARG,
"Adding JPATH to all Json table columns",
NULL, NULL, 0); // NO by default
// Null representation for JSON values // Null representation for JSON values
static MYSQL_THDVAR_STR(json_null, static MYSQL_THDVAR_STR(json_null,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
...@@ -401,6 +407,12 @@ static MYSQL_THDVAR_STR(json_null, ...@@ -401,6 +407,12 @@ static MYSQL_THDVAR_STR(json_null,
// check_json_null, update_json_null, // check_json_null, update_json_null,
NULL, NULL, "<null>"); NULL, NULL, "<null>");
// Default Json, XML or Mongo depth
static MYSQL_THDVAR_INT(default_depth,
PLUGIN_VAR_RQCMDARG,
"Default depth used by Json, XML and Mongo discovery",
NULL, NULL, 0, -1, 16, 1);
// Estimate max number of rows for JSON aggregate functions // Estimate max number of rows for JSON aggregate functions
static MYSQL_THDVAR_UINT(json_grp_size, static MYSQL_THDVAR_UINT(json_grp_size,
PLUGIN_VAR_RQCMDARG, // opt PLUGIN_VAR_RQCMDARG, // opt
...@@ -462,11 +474,13 @@ uint GetTraceValue(void) ...@@ -462,11 +474,13 @@ uint GetTraceValue(void)
{return (uint)(connect_hton ? THDVAR(current_thd, xtrace) : 0);} {return (uint)(connect_hton ? THDVAR(current_thd, xtrace) : 0);}
bool ExactInfo(void) {return THDVAR(current_thd, exact_info);} bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
static bool CondPushEnabled(void) {return THDVAR(current_thd, cond_push);} static bool CondPushEnabled(void) {return THDVAR(current_thd, cond_push);}
bool JsonAllPath(void) {return THDVAR(current_thd, json_all_path);}
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);} USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
int GetConvSize(void) {return THDVAR(current_thd, conv_size);} int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);} TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
char *GetJsonNull(void) char *GetJsonNull(void)
{return connect_hton ? THDVAR(current_thd, json_null) : NULL;} {return connect_hton ? THDVAR(current_thd, json_null) : NULL;}
int GetDefaultDepth(void) {return THDVAR(current_thd, default_depth);}
uint GetJsonGrpSize(void) uint GetJsonGrpSize(void)
{return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;} {return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;}
size_t GetWorkSize(void) {return (size_t)THDVAR(current_thd, work_size);} size_t GetWorkSize(void) {return (size_t)THDVAR(current_thd, work_size);}
...@@ -630,6 +644,8 @@ ha_create_table_option connect_field_option_list[]= ...@@ -630,6 +644,8 @@ ha_create_table_option connect_field_option_list[]=
HA_FOPTION_NUMBER("FIELD_LENGTH", fldlen, 0, 0, INT_MAX32, 1), HA_FOPTION_NUMBER("FIELD_LENGTH", fldlen, 0, 0, INT_MAX32, 1),
HA_FOPTION_STRING("DATE_FORMAT", dateformat), HA_FOPTION_STRING("DATE_FORMAT", dateformat),
HA_FOPTION_STRING("FIELD_FORMAT", fieldformat), HA_FOPTION_STRING("FIELD_FORMAT", fieldformat),
HA_FOPTION_STRING("JPATH", jsonpath),
HA_FOPTION_STRING("XPATH", xmlpath),
HA_FOPTION_STRING("SPECIAL", special), HA_FOPTION_STRING("SPECIAL", special),
HA_FOPTION_ENUM("DISTRIB", opt, "scattered,clustered,sorted", 0), HA_FOPTION_ENUM("DISTRIB", opt, "scattered,clustered,sorted", 0),
HA_FOPTION_END HA_FOPTION_END
...@@ -1322,9 +1338,10 @@ int GetIntegerTableOption(PGLOBAL g, PTOS options, PCSZ opname, int idef) ...@@ -1322,9 +1338,10 @@ int GetIntegerTableOption(PGLOBAL g, PTOS options, PCSZ opname, int idef)
if ((ulonglong) opval == (ulonglong)NO_IVAL) { if ((ulonglong) opval == (ulonglong)NO_IVAL) {
PCSZ pv; PCSZ pv;
if ((pv= GetListOption(g, opname, options->oplist))) if ((pv = GetListOption(g, opname, options->oplist))) {
opval= CharToNumber((char*)pv, strlen(pv), ULONGLONG_MAX, true); // opval = CharToNumber((char*)pv, strlen(pv), ULONGLONG_MAX, false);
else return atoi(pv);
} else
return idef; return idef;
} // endif opval } // endif opval
...@@ -1576,7 +1593,8 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) ...@@ -1576,7 +1593,8 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Offset= (int)fop->offset; pcf->Offset= (int)fop->offset;
pcf->Freq= (int)fop->freq; pcf->Freq= (int)fop->freq;
pcf->Datefmt= (char*)fop->dateformat; pcf->Datefmt= (char*)fop->dateformat;
pcf->Fieldfmt= (char*)fop->fieldformat; pcf->Fieldfmt = fop->fieldformat ? (char*)fop->fieldformat
: fop->jsonpath ? (char*)fop->jsonpath : (char*)fop->xmlpath;
} else { } else {
pcf->Offset= -1; pcf->Offset= -1;
pcf->Freq= 0; pcf->Freq= 0;
...@@ -4984,7 +5002,7 @@ int ha_connect::check_stmt(PGLOBAL g, MODE newmode, bool cras) ...@@ -4984,7 +5002,7 @@ int ha_connect::check_stmt(PGLOBAL g, MODE newmode, bool cras)
} // endif CheckCleanup } // endif CheckCleanup
if (cras) if (cras)
g->Createas= 1; // To tell external tables of a multi-table command g->Createas= true; // To tell external tables of a multi-table command
if (trace(1)) if (trace(1))
htrc("Calling CntCheckDB db=%s cras=%d\n", GetDBName(NULL), cras); htrc("Calling CntCheckDB db=%s cras=%d\n", GetDBName(NULL), cras);
...@@ -5334,95 +5352,99 @@ static char *encode(PGLOBAL g, const char *cnm) ...@@ -5334,95 +5352,99 @@ static char *encode(PGLOBAL g, const char *cnm)
@return @return
Return 0 if ok Return 0 if ok
*/ */
static bool add_field(String *sql, const char *field_name, int typ, int len, static bool add_field(String* sql, TABTYPE ttp, const char* field_name, int typ,
int dec, char *key, uint tm, const char *rem, char *dft, int len, int dec, char* key, uint tm, const char* rem,
char *xtra, char *fmt, int flag, bool dbf, char v) char* dft, char* xtra, char* fmt, int flag, bool dbf, char v) {
{
#if defined(DEVELOPMENT) #if defined(DEVELOPMENT)
// Some client programs regard CHAR(36) as GUID // Some client programs regard CHAR(36) as GUID
char var= (len > 255 || len == 36) ? 'V' : v; char var = (len > 255 || len == 36) ? 'V' : v;
#else #else
char var = (len > 255) ? 'V' : v; char var = (len > 255) ? 'V' : v;
#endif #endif
bool q, error= false; bool q, error = false;
const char *type= PLGtoMYSQLtype(typ, dbf, var); const char* type = PLGtoMYSQLtype(typ, dbf, var);
error|= sql->append('`'); error |= sql->append('`');
error|= sql->append(field_name); error |= sql->append(field_name);
error|= sql->append("` "); error |= sql->append("` ");
error|= sql->append(type); error |= sql->append(type);
if (typ == TYPE_STRING || if (typ == TYPE_STRING ||
(len && typ != TYPE_DATE && (typ != TYPE_DOUBLE || dec >= 0))) { (len && typ != TYPE_DATE && (typ != TYPE_DOUBLE || dec >= 0))) {
error|= sql->append('('); error |= sql->append('(');
error|= sql->append_ulonglong(len); error |= sql->append_ulonglong(len);
if (typ == TYPE_DOUBLE) { if (typ == TYPE_DOUBLE) {
error|= sql->append(','); error |= sql->append(',');
// dec must be < len and < 31 // dec must be < len and < 31
error|= sql->append_ulonglong(MY_MIN(dec, (MY_MIN(len, 31) - 1))); error |= sql->append_ulonglong(MY_MIN(dec, (MY_MIN(len, 31) - 1)));
} else if (dec > 0 && !strcmp(type, "DECIMAL")) { } else if (dec > 0 && !strcmp(type, "DECIMAL")) {
error|= sql->append(','); error |= sql->append(',');
// dec must be < len // dec must be < len
error|= sql->append_ulonglong(MY_MIN(dec, len - 1)); error |= sql->append_ulonglong(MY_MIN(dec, len - 1));
} // endif dec } // endif dec
error|= sql->append(')'); error |= sql->append(')');
} // endif len } // endif len
if (v == 'U') if (v == 'U')
error|= sql->append(" UNSIGNED"); error |= sql->append(" UNSIGNED");
else if (v == 'Z') else if (v == 'Z')
error|= sql->append(" ZEROFILL"); error |= sql->append(" ZEROFILL");
if (key && *key) { if (key && *key) {
error|= sql->append(" "); error |= sql->append(" ");
error|= sql->append(key); error |= sql->append(key);
} // endif key } // endif key
if (tm) if (tm)
error|= sql->append(STRING_WITH_LEN(" NOT NULL"), system_charset_info); error |= sql->append(STRING_WITH_LEN(" NOT NULL"), system_charset_info);
if (dft && *dft) { if (dft && *dft) {
error|= sql->append(" DEFAULT "); error |= sql->append(" DEFAULT ");
if (typ == TYPE_DATE) if (typ == TYPE_DATE)
q= (strspn(dft, "0123456789 -:/") == strlen(dft)); q = (strspn(dft, "0123456789 -:/") == strlen(dft));
else else
q= !IsTypeNum(typ); q = !IsTypeNum(typ);
if (q) { if (q) {
error|= sql->append("'"); error |= sql->append("'");
error|= sql->append_for_single_quote(dft, strlen(dft)); error |= sql->append_for_single_quote(dft, strlen(dft));
error|= sql->append("'"); error |= sql->append("'");
} else } else
error|= sql->append(dft); error |= sql->append(dft);
} // endif dft } // endif dft
if (xtra && *xtra) { if (xtra && *xtra) {
error|= sql->append(" "); error |= sql->append(" ");
error|= sql->append(xtra); error |= sql->append(xtra);
} // endif rem } // endif rem
if (rem && *rem) { if (rem && *rem) {
error|= sql->append(" COMMENT '"); error |= sql->append(" COMMENT '");
error|= sql->append_for_single_quote(rem, strlen(rem)); error |= sql->append_for_single_quote(rem, strlen(rem));
error|= sql->append("'"); error |= sql->append("'");
} // endif rem } // endif rem
if (fmt && *fmt) { if (fmt && *fmt) {
error|= sql->append(" FIELD_FORMAT='"); switch (ttp) {
error|= sql->append_for_single_quote(fmt, strlen(fmt)); case TAB_JSON: error |= sql->append(" JPATH='"); break;
error|= sql->append("'"); case TAB_XML: error |= sql->append(" XPATH='"); break;
default: error |= sql->append(" FIELD_FORMAT='");
} // endswitch ttp
error |= sql->append_for_single_quote(fmt, strlen(fmt));
error |= sql->append("'");
} // endif flag } // endif flag
if (flag) { if (flag) {
error|= sql->append(" FLAG="); error |= sql->append(" FLAG=");
error|= sql->append_ulonglong(flag); error |= sql->append_ulonglong(flag);
} // endif flag } // endif flag
error|= sql->append(','); error |= sql->append(',');
return error; return error;
} // end of add_field } // end of add_field
...@@ -6045,7 +6067,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -6045,7 +6067,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
len= 256; // STRBLK's have 0 length len= 256; // STRBLK's have 0 length
// Now add the field // Now add the field
if (add_field(&sql, cnm, typ, len, dec, NULL, tm, if (add_field(&sql, ttp, cnm, typ, len, dec, NULL, tm,
NULL, NULL, NULL, NULL, flg, dbf, v)) NULL, NULL, NULL, NULL, flg, dbf, v))
rc= HA_ERR_OUT_OF_MEM; rc= HA_ERR_OUT_OF_MEM;
} // endfor crp } // endfor crp
...@@ -6239,7 +6261,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -6239,7 +6261,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
prec= 0; prec= 0;
// Now add the field // Now add the field
if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra, if (add_field(&sql, ttp, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
fmt, flg, dbf, v)) fmt, flg, dbf, v))
rc= HA_ERR_OUT_OF_MEM; rc= HA_ERR_OUT_OF_MEM;
} // endfor i } // endfor i
...@@ -7362,6 +7384,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= { ...@@ -7362,6 +7384,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(errmsg_dir_path), MYSQL_SYSVAR(errmsg_dir_path),
#endif // XMSG #endif // XMSG
MYSQL_SYSVAR(json_null), MYSQL_SYSVAR(json_null),
MYSQL_SYSVAR(json_all_path),
MYSQL_SYSVAR(default_depth),
MYSQL_SYSVAR(json_grp_size), MYSQL_SYSVAR(json_grp_size),
#if defined(JAVA_SUPPORT) #if defined(JAVA_SUPPORT)
MYSQL_SYSVAR(jvm_path), MYSQL_SYSVAR(jvm_path),
......
...@@ -104,6 +104,8 @@ struct ha_field_option_struct ...@@ -104,6 +104,8 @@ struct ha_field_option_struct
uint opt; uint opt;
const char *dateformat; const char *dateformat;
const char *fieldformat; const char *fieldformat;
const char* jsonpath;
const char* xmlpath;
char *special; char *special;
}; };
......
This diff is collapsed.
...@@ -69,12 +69,7 @@ PBSON JbinAlloc(PGLOBAL g, UDF_ARGS* args, ulong len, PJSON jsp); ...@@ -69,12 +69,7 @@ PBSON JbinAlloc(PGLOBAL g, UDF_ARGS* args, ulong len, PJSON jsp);
char *NextChr(PSZ s, char sep); char *NextChr(PSZ s, char sep);
char *GetJsonNull(void); char *GetJsonNull(void);
PJSON ParseJson(PGLOBAL g, char *s, int n, int *prty = NULL, bool *b = NULL); PJSON ParseJson(PGLOBAL g, char* s, int n, int* prty = NULL, bool* b = NULL);
PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty);
PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty);
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty);
char *ParseString(PGLOBAL g, int& i, STRG& src);
PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src);
PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty); PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty);
bool SerializeArray(JOUT *js, PJAR jarp, bool b); bool SerializeArray(JOUT *js, PJAR jarp, bool b);
bool SerializeObject(JOUT *js, PJOB jobp); bool SerializeObject(JOUT *js, PJOB jobp);
...@@ -152,7 +147,7 @@ class JOUTPRT : public JOUTFILE { ...@@ -152,7 +147,7 @@ class JOUTPRT : public JOUTFILE {
class JPAIR : public BLOCK { class JPAIR : public BLOCK {
friend class JOBJECT; friend class JOBJECT;
friend class JSNX; friend class JSNX;
friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*); friend class JSON;
friend bool SerializeObject(JOUT *, PJOB); friend bool SerializeObject(JOUT *, PJOB);
public: public:
JPAIR(PCSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;} JPAIR(PCSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;}
...@@ -171,8 +166,9 @@ class JPAIR : public BLOCK { ...@@ -171,8 +166,9 @@ class JPAIR : public BLOCK {
/* Class JSON. The base class for all other json classes. */ /* Class JSON. The base class for all other json classes. */
/***********************************************************************/ /***********************************************************************/
class JSON : public BLOCK { class JSON : public BLOCK {
friend PJSON ParseJson(PGLOBAL, char*, int, int*, bool*);
public: public:
JSON(void) {Size = 0;} JSON(void) : s(NULL), len(0), pty(NULL) {Size = 0;}
int size(void) {return Size;} int size(void) {return Size;}
virtual int GetSize(bool b) {return Size;} virtual int GetSize(bool b) {return Size;}
...@@ -209,14 +205,27 @@ class JSON : public BLOCK { ...@@ -209,14 +205,27 @@ class JSON : public BLOCK {
virtual bool IsNull(void) {X return true;} virtual bool IsNull(void) {X return true;}
protected: protected:
PJAR ParseArray(PGLOBAL g, int& i);
PJOB ParseObject(PGLOBAL g, int& i);
PJVAL ParseValue(PGLOBAL g, int& i);
char *ParseString(PGLOBAL g, int& i);
PVAL ParseNumeric(PGLOBAL g, int& i);
PJAR ParseAsArray(PGLOBAL g, int& i, int pretty, int *ptyp);
// Members
int Size; int Size;
// Only used when parsing
private:
char *s;
int len;
bool *pty;
}; // end of class JSON }; // end of class JSON
/***********************************************************************/ /***********************************************************************/
/* Class JOBJECT: contains a list of value pairs. */ /* Class JOBJECT: contains a list of value pairs. */
/***********************************************************************/ /***********************************************************************/
class JOBJECT : public JSON { class JOBJECT : public JSON {
friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeObject(JOUT *, PJOB); friend bool SerializeObject(JOUT *, PJOB);
friend class JSNX; friend class JSNX;
public: public:
...@@ -282,8 +291,8 @@ class JVALUE : public JSON { ...@@ -282,8 +291,8 @@ class JVALUE : public JSON {
friend class JARRAY; friend class JARRAY;
friend class JSNX; friend class JSNX;
friend class JSONCOL; friend class JSONCOL;
friend PJVAL ParseValue(PGLOBAL, int&, STRG&, bool*); friend class JSON;
friend bool SerializeValue(JOUT *, PJVAL); friend bool SerializeValue(JOUT*, PJVAL);
public: public:
JVALUE(void) : JSON() {Clear();} JVALUE(void) : JSON() {Clear();}
JVALUE(PJSON jsp); JVALUE(PJSON jsp);
......
This diff is collapsed.
...@@ -235,6 +235,10 @@ extern "C" { ...@@ -235,6 +235,10 @@ extern "C" {
DllExport char *json_serialize(UDF_EXEC_ARGS); DllExport char *json_serialize(UDF_EXEC_ARGS);
DllExport void json_serialize_deinit(UDF_INIT*); DllExport void json_serialize_deinit(UDF_INIT*);
DllExport my_bool jfile_convert_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char* jfile_convert(UDF_EXEC_ARGS);
DllExport void jfile_convert_deinit(UDF_INIT*);
DllExport my_bool envar_init(UDF_INIT*, UDF_ARGS*, char*); DllExport my_bool envar_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *envar(UDF_EXEC_ARGS); DllExport char *envar(UDF_EXEC_ARGS);
...@@ -324,3 +328,38 @@ class JSNX : public BLOCK { ...@@ -324,3 +328,38 @@ class JSNX : public BLOCK {
my_bool Wr; // Write mode my_bool Wr; // Write mode
my_bool Jb; // Must return json item my_bool Jb; // Must return json item
}; // end of class JSNX }; // end of class JSNX
/*********************************************************************************/
/* Class JUP: used by jfile_convert to make a json file pretty = 0. */
/*********************************************************************************/
class JUP : public BLOCK {
public:
// Constructor
JUP(PGLOBAL g);
// Implementation
void AddBuff(char c) {
if (k < recl)
buff[k++] = c;
else
throw "Record size is too small";
} // end of AddBuff
// Methods
char *UnprettyJsonFile(PGLOBAL g, char* fn, char* outfn, int lrecl);
bool unPretty(PGLOBAL g, int lrecl);
void CopyObject(PGLOBAL g);
void CopyArray(PGLOBAL g);
void CopyValue(PGLOBAL g);
void CopyString(PGLOBAL g);
void CopyNumeric(PGLOBAL g);
// Members
FILE* fs;
char* s;
char* buff;
int len;
int recl;
int i, k;
}; // end of class JUP
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s); bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s);
bool IsNum(PSZ s); bool IsNum(PSZ s);
int GetDefaultDepth(void);
/***********************************************************************/ /***********************************************************************/
/* Make selector json representation for Mongo tables. */ /* Make selector json representation for Mongo tables. */
...@@ -248,15 +249,10 @@ MGODISC::MGODISC(PGLOBAL g, int *lg) { ...@@ -248,15 +249,10 @@ MGODISC::MGODISC(PGLOBAL g, int *lg) {
/***********************************************************************/ /***********************************************************************/
int MGODISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt) int MGODISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt)
{ {
PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
PMGODEF tdp; PMGODEF tdp;
if (level = GetStringTableOption(g, topt, "Depth", level)) { lvl = GetIntegerTableOption(g, topt, "Level", GetDefaultDepth());
lvl = atoi(level); lvl = GetIntegerTableOption(g, topt, "Depth", lvl);
lvl = (lvl > 16) ? 16 : lvl;
} else
lvl = 0;
all = GetBooleanTableOption(g, topt, "Fullarray", false); all = GetBooleanTableOption(g, topt, "Fullarray", false);
/*********************************************************************/ /*********************************************************************/
......
...@@ -20,12 +20,12 @@ SELECT * from t1; ...@@ -20,12 +20,12 @@ SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath
_id 1 CHAR 24 24 0 0 _id _id 1 CHAR 24 24 0 0 _id
address_building 1 CHAR 10 10 0 0 address.building address_building 1 CHAR 10 10 0 0 address.building
address_coord 1 CHAR 256 256 0 1 address.coord address_coord 1 CHAR 1024 1024 0 1 address.coord
address_street 1 CHAR 38 38 0 0 address.street address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0 borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0 cuisine 1 CHAR 64 64 0 0
grades_date 1 CHAR 256 256 0 1 grades.0.date grades_date 1 CHAR 1024 1024 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score grades_score 5 BIGINT 2 2 0 1 grades.0.score
name 1 CHAR 98 98 0 0 name 1 CHAR 98 98 0 0
...@@ -64,16 +64,16 @@ OPTION_LIST='Level=1,Driver=Java,Version=2' CONNECTION='mongodb://localhost:2701 ...@@ -64,16 +64,16 @@ OPTION_LIST='Level=1,Driver=Java,Version=2' CONNECTION='mongodb://localhost:2701
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id', `_id` char(24) NOT NULL `JPATH`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(10) NOT NULL `JPATH`='address.building',
`address_coord` varchar(256) DEFAULT NULL `FIELD_FORMAT`='address.coord', `address_coord` varchar(1024) DEFAULT NULL `JPATH`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(38) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL, `cuisine` char(64) NOT NULL,
`grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date', `grades_date` varchar(1024) DEFAULT NULL `JPATH`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade', `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score', `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL, `name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8' `LRECL`=4096 ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8' `LRECL`=4096
...@@ -251,15 +251,15 @@ OPTION_LIST='Driver=Java,level=2,version=2'; ...@@ -251,15 +251,15 @@ OPTION_LIST='Driver=Java,level=2,version=2';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id', `_id` char(24) NOT NULL `JPATH`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(10) NOT NULL `JPATH`='address.building',
`address_coord` double(18,16) DEFAULT NULL `FIELD_FORMAT`='address.coord.0', `address_coord` double(18,16) DEFAULT NULL `JPATH`='address.coord.0',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(38) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`grades_date` char(24) DEFAULT NULL `FIELD_FORMAT`='grades.0.date', `grades_date` char(24) DEFAULT NULL `JPATH`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade', `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score', `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL, `name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=2' `LRECL`=4096 ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=2' `LRECL`=4096
......
...@@ -20,12 +20,12 @@ SELECT * from t1; ...@@ -20,12 +20,12 @@ SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath
_id 1 CHAR 24 24 0 0 _id _id 1 CHAR 24 24 0 0 _id
address_building 1 CHAR 10 10 0 0 address.building address_building 1 CHAR 10 10 0 0 address.building
address_coord 1 CHAR 256 256 0 1 address.coord address_coord 1 CHAR 1024 1024 0 1 address.coord
address_street 1 CHAR 38 38 0 0 address.street address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0 borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0 cuisine 1 CHAR 64 64 0 0
grades_date 1 CHAR 256 256 0 1 grades.0.date grades_date 1 CHAR 1024 1024 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score grades_score 5 BIGINT 2 2 0 1 grades.0.score
name 1 CHAR 98 98 0 0 name 1 CHAR 98 98 0 0
...@@ -64,16 +64,16 @@ OPTION_LIST='Level=1,Driver=Java,Version=3' CONNECTION='mongodb://localhost:2701 ...@@ -64,16 +64,16 @@ OPTION_LIST='Level=1,Driver=Java,Version=3' CONNECTION='mongodb://localhost:2701
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id', `_id` char(24) NOT NULL `JPATH`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(10) NOT NULL `JPATH`='address.building',
`address_coord` varchar(256) DEFAULT NULL `FIELD_FORMAT`='address.coord', `address_coord` varchar(1024) DEFAULT NULL `JPATH`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(38) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL, `cuisine` char(64) NOT NULL,
`grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date', `grades_date` varchar(1024) DEFAULT NULL `JPATH`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade', `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score', `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL, `name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8' `LRECL`=4096 ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8' `LRECL`=4096
...@@ -251,15 +251,15 @@ OPTION_LIST='Driver=Java,level=2,version=3'; ...@@ -251,15 +251,15 @@ OPTION_LIST='Driver=Java,level=2,version=3';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id', `_id` char(24) NOT NULL `JPATH`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(10) NOT NULL `JPATH`='address.building',
`address_coord` double(18,16) DEFAULT NULL `FIELD_FORMAT`='address.coord.0', `address_coord` double(18,16) DEFAULT NULL `JPATH`='address.coord.0',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(38) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`grades_date` bigint(13) DEFAULT NULL `FIELD_FORMAT`='grades.0.date', `grades_date` bigint(13) DEFAULT NULL `JPATH`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade', `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score', `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL, `name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=3' `LRECL`=4096 ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=3' `LRECL`=4096
......
...@@ -20,12 +20,12 @@ SELECT * from t1; ...@@ -20,12 +20,12 @@ SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath
_id 1 CHAR 24 24 0 0 _id _id 1 CHAR 24 24 0 0 _id
address_building 1 CHAR 10 10 0 0 address.building address_building 1 CHAR 10 10 0 0 address.building
address_coord 1 CHAR 256 256 0 1 address.coord address_coord 1 CHAR 1024 1024 0 1 address.coord
address_street 1 CHAR 38 38 0 0 address.street address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0 borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0 cuisine 1 CHAR 64 64 0 0
grades_date 1 CHAR 256 256 0 1 grades.0.date grades_date 1 CHAR 1024 1024 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score grades_score 5 BIGINT 2 2 0 1 grades.0.score
name 1 CHAR 98 98 0 0 name 1 CHAR 98 98 0 0
...@@ -64,16 +64,16 @@ OPTION_LIST='Level=1,Driver=C,Version=0' CONNECTION='mongodb://localhost:27017' ...@@ -64,16 +64,16 @@ OPTION_LIST='Level=1,Driver=C,Version=0' CONNECTION='mongodb://localhost:27017'
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id', `_id` char(24) NOT NULL `JPATH`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(10) NOT NULL `JPATH`='address.building',
`address_coord` varchar(256) DEFAULT NULL `FIELD_FORMAT`='address.coord', `address_coord` varchar(1024) DEFAULT NULL `JPATH`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(38) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL, `cuisine` char(64) NOT NULL,
`grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date', `grades_date` varchar(1024) DEFAULT NULL `JPATH`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade', `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score', `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL, `name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=C,Version=0' `DATA_CHARSET`='utf8' `LRECL`=1024 ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=C,Version=0' `DATA_CHARSET`='utf8' `LRECL`=1024
...@@ -251,15 +251,15 @@ OPTION_LIST='Driver=C,level=2,version=0'; ...@@ -251,15 +251,15 @@ OPTION_LIST='Driver=C,level=2,version=0';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id', `_id` char(24) NOT NULL `JPATH`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(10) NOT NULL `JPATH`='address.building',
`address_coord` double(23,20) DEFAULT NULL `FIELD_FORMAT`='address.coord.0', `address_coord` double(23,20) DEFAULT NULL `JPATH`='address.coord.0',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(38) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`grades_date` bigint(13) DEFAULT NULL `FIELD_FORMAT`='grades.0.date', `grades_date` bigint(13) DEFAULT NULL `JPATH`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade', `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score', `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL, `name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"projection":{"cuisine":0}}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=C,level=2,version=0' `LRECL`=1024 ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"projection":{"cuisine":0}}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=C,level=2,version=0' `LRECL`=1024
......
...@@ -158,13 +158,14 @@ PGLOBAL PlugInit(LPCSTR Language, size_t worksize) ...@@ -158,13 +158,14 @@ PGLOBAL PlugInit(LPCSTR Language, size_t worksize)
} // end try/catch } // end try/catch
g->Sarea = NULL; g->Sarea = NULL;
g->Createas = 0; g->Createas = false;
g->Alchecked = 0; g->Alchecked = 0;
g->Mrr = 0; g->Mrr = 0;
g->Activityp = NULL; g->Activityp = NULL;
g->Xchk = NULL; g->Xchk = NULL;
g->N = 0; g->N = 0;
g->More = 0; g->More = 0;
g->Saved_Size = 0;
strcpy(g->Message, ""); strcpy(g->Message, "");
/*******************************************************************/ /*******************************************************************/
...@@ -528,7 +529,7 @@ BOOL PlugSubSet(void *memp, size_t size) ...@@ -528,7 +529,7 @@ BOOL PlugSubSet(void *memp, size_t size)
{ {
PPOOLHEADER pph = (PPOOLHEADER)memp; PPOOLHEADER pph = (PPOOLHEADER)memp;
pph->To_Free = (OFFSET)sizeof(POOLHEADER); pph->To_Free = (size_t)sizeof(POOLHEADER);
pph->FreeBlk = size - pph->To_Free; pph->FreeBlk = size - pph->To_Free;
return FALSE; return FALSE;
} /* end of PlugSubSet */ } /* end of PlugSubSet */
...@@ -580,7 +581,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) ...@@ -580,7 +581,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
/* Do the suballocation the simplest way. */ /* Do the suballocation the simplest way. */
/*********************************************************************/ /*********************************************************************/
memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */ memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */
pph->To_Free += (OFFSET)size; /* New offset of pool free block */ pph->To_Free += size; /* New offset of pool free block */
pph->FreeBlk -= size; /* New size of pool free block */ pph->FreeBlk -= size; /* New size of pool free block */
if (trace(16)) if (trace(16))
...@@ -605,40 +606,4 @@ char *PlugDup(PGLOBAL g, const char *str) ...@@ -605,40 +606,4 @@ char *PlugDup(PGLOBAL g, const char *str)
} // end of PlugDup } // end of PlugDup
#if 0
/***********************************************************************/
/* This routine suballocate a copy of the passed string. */
/***********************************************************************/
char *PlugDup(PGLOBAL g, const char *str)
{
char *buf;
size_t len;
if (str && (len = strlen(str))) {
buf = (char*)PlugSubAlloc(g, NULL, len + 1);
strcpy(buf, str);
} else
buf = NULL;
return(buf);
} /* end of PlugDup */
#endif // 0
/***********************************************************************/
/* This routine makes a pointer from an offset to a memory pointer. */
/***********************************************************************/
void *MakePtr(void *memp, OFFSET offset)
{
return ((offset == 0) ? NULL : &((char *)memp)[offset]);
} /* end of MakePtr */
/***********************************************************************/
/* This routine makes an offset from a pointer new format. */
/***********************************************************************/
#if 0
OFFSET MakeOff(void *memp, void *ptr)
{
return ((!ptr) ? 0 : (OFFSET)((char *)ptr - (char *)memp));
} /* end of MakeOff */
#endif
/*--------------------- End of PLUGUTIL program -----------------------*/ /*--------------------- End of PLUGUTIL program -----------------------*/
...@@ -52,19 +52,10 @@ ...@@ -52,19 +52,10 @@
/* External functions. */ /* External functions. */
/***********************************************************************/ /***********************************************************************/
USETEMP UseTemp(void); USETEMP UseTemp(void);
bool JsonAllPath(void);
int GetDefaultDepth(void);
char *GetJsonNull(void); char *GetJsonNull(void);
//typedef struct _jncol {
// struct _jncol *Next;
// char *Name;
// char *Fmt;
// int Type;
// int Len;
// int Scale;
// bool Cbn;
// bool Found;
//} JCOL, *PJCL;
/***********************************************************************/ /***********************************************************************/
/* JSONColumns: construct the result blocks containing the description */ /* JSONColumns: construct the result blocks containing the description */
/* of all the columns of a table contained inside a JSON file. */ /* of all the columns of a table contained inside a JSON file. */
...@@ -167,23 +158,20 @@ JSONDISC::JSONDISC(PGLOBAL g, uint *lg) ...@@ -167,23 +158,20 @@ JSONDISC::JSONDISC(PGLOBAL g, uint *lg)
jsp = NULL; jsp = NULL;
row = NULL; row = NULL;
sep = NULL; sep = NULL;
i = n = bf = ncol = lvl = 0; i = n = bf = ncol = lvl = sz = 0;
all = false; all = strfy = false;
} // end of JSONDISC constructor } // end of JSONDISC constructor
int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
{ {
char filename[_MAX_PATH]; char filename[_MAX_PATH];
bool mgo = (GetTypeID(topt->type) == TAB_MONGO); bool mgo = (GetTypeID(topt->type) == TAB_MONGO);
PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
if ((level = GetStringTableOption(g, topt, "Depth", level))) {
lvl = atoi(level);
lvl = (lvl > 16) ? 16 : lvl;
} else
lvl = 0;
lvl = GetIntegerTableOption(g, topt, "Level", GetDefaultDepth());
lvl = GetIntegerTableOption(g, topt, "Depth", lvl);
sep = GetStringTableOption(g, topt, "Separator", "."); sep = GetStringTableOption(g, topt, "Separator", ".");
sz = GetIntegerTableOption(g, topt, "Jsize", 1024);
strfy = GetBooleanTableOption(g, topt, "Stringify", false);
/*********************************************************************/ /*********************************************************************/
/* Open the input file. */ /* Open the input file. */
...@@ -306,7 +294,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) ...@@ -306,7 +294,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
// Allocate the parse work memory // Allocate the parse work memory
PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL)); PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
memset(G, 0, sizeof(GLOBAL)); memset(G, 0, sizeof(GLOBAL));
G->Sarea_Size = tdp->Lrecl * 10; G->Sarea_Size = (size_t)tdp->Lrecl * 10;
G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size); G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
PlugSubSet(G->Sarea, G->Sarea_Size); PlugSubSet(G->Sarea, G->Sarea_Size);
G->jump_level = 0; G->jump_level = 0;
...@@ -403,6 +391,9 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j) ...@@ -403,6 +391,9 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
PJAR jar; PJAR jar;
if ((valp = jvp ? jvp->GetValue() : NULL)) { if ((valp = jvp ? jvp->GetValue() : NULL)) {
if (JsonAllPath() && !fmt[bf])
strcat(fmt, colname);
jcol.Type = valp->GetType(); jcol.Type = valp->GetType();
jcol.Len = valp->GetValLen(); jcol.Len = valp->GetValLen();
jcol.Scale = valp->GetValPrec(); jcol.Scale = valp->GetValPrec();
...@@ -482,8 +473,16 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j) ...@@ -482,8 +473,16 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
} // endswitch Type } // endswitch Type
} else if (lvl >= 0) { } else if (lvl >= 0) {
if (strfy) {
if (!fmt[bf])
strcat(fmt, colname);
strcat(fmt, ".*");
} else if (JsonAllPath() && !fmt[bf])
strcat(fmt, colname);
jcol.Type = TYPE_STRING; jcol.Type = TYPE_STRING;
jcol.Len = 256; jcol.Len = sz;
jcol.Scale = 0; jcol.Scale = 0;
jcol.Cbn = true; jcol.Cbn = true;
} else } else
...@@ -2040,7 +2039,7 @@ int TDBJSON::MakeDocument(PGLOBAL g) ...@@ -2040,7 +2039,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
if ((objpath = PlugDup(g, Objname))) { if ((objpath = PlugDup(g, Objname))) {
if (*objpath == '$') objpath++; if (*objpath == '$') objpath++;
if (*objpath == '.') objpath++; if (*objpath == '.') objpath++;
p1 = p2 = NULL; p1 = (*objpath == '[') ? objpath++ : NULL;
/*********************************************************************/ /*********************************************************************/
/* Find the table in the tree structure. */ /* Find the table in the tree structure. */
......
...@@ -68,8 +68,8 @@ class JSONDISC : public BLOCK { ...@@ -68,8 +68,8 @@ class JSONDISC : public BLOCK {
PCSZ sep; PCSZ sep;
char colname[65], fmt[129], buf[16]; char colname[65], fmt[129], buf[16];
uint *length; uint *length;
int i, n, bf, ncol, lvl; int i, n, bf, ncol, lvl, sz;
bool all; bool all, strfy;
}; // end of JSONDISC }; // end of JSONDISC
/***********************************************************************/ /***********************************************************************/
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
/* ------------- */ /* ------------- */
/* Version 3.0 */ /* Version 3.0 */
/* */ /* */
/* Author Olivier BERTRAND 2007 - 2017 */ /* Author Olivier BERTRAND 2007 - 2020 */
/* */ /* */
/* This program are the XML tables classes using MS-DOM or libxml2. */ /* This program are the XML tables classes using MS-DOM or libxml2. */
/***********************************************************************/ /***********************************************************************/
...@@ -62,6 +62,8 @@ extern "C" char version[]; ...@@ -62,6 +62,8 @@ extern "C" char version[];
#define TYPE_UNKNOWN 12 /* Must be greater than other types */ #define TYPE_UNKNOWN 12 /* Must be greater than other types */
#define XLEN(M) sizeof(M) - strlen(M) - 1 /* To avoid overflow*/ #define XLEN(M) sizeof(M) - strlen(M) - 1 /* To avoid overflow*/
int GetDefaultDepth(void);
/***********************************************************************/ /***********************************************************************/
/* Class and structure used by XMLColumns. */ /* Class and structure used by XMLColumns. */
/***********************************************************************/ /***********************************************************************/
...@@ -149,7 +151,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) ...@@ -149,7 +151,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
strcpy(g->Message, MSG(MISSING_FNAME)); strcpy(g->Message, MSG(MISSING_FNAME));
return NULL; return NULL;
} else { } else {
lvl = GetIntegerTableOption(g, topt, "Level", 0); lvl = GetIntegerTableOption(g, topt, "Level", GetDefaultDepth());
lvl = GetIntegerTableOption(g, topt, "Depth", lvl); lvl = GetIntegerTableOption(g, topt, "Depth", lvl);
lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl; lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl;
} // endif fn } // endif fn
......
...@@ -158,16 +158,16 @@ bool user_connect::CheckCleanup(bool force) ...@@ -158,16 +158,16 @@ bool user_connect::CheckCleanup(bool force)
{ {
if (thdp->query_id > last_query_id || force) { if (thdp->query_id > last_query_id || force) {
size_t worksize = GetWorkSize(); size_t worksize = GetWorkSize();
size_t size = g->Sarea_Size;
PlugCleanup(g, true); PlugCleanup(g, true);
if (size != worksize) { if (worksize != g->Sarea_Size) {
FreeSarea(g); FreeSarea(g);
g->Saved_Size = g->Sarea_Size;
// Check whether the work area could be allocated // Check whether the work area could be allocated
if (AllocSarea(g, worksize)) { if (AllocSarea(g, worksize)) {
AllocSarea(g, size); AllocSarea(g, g->Saved_Size);
SetWorkSize(g->Sarea_Size); // Was too big SetWorkSize(g->Sarea_Size); // Was too big
} // endif sarea } // endif sarea
...@@ -175,10 +175,11 @@ bool user_connect::CheckCleanup(bool force) ...@@ -175,10 +175,11 @@ bool user_connect::CheckCleanup(bool force)
PlugSubSet(g->Sarea, g->Sarea_Size); PlugSubSet(g->Sarea, g->Sarea_Size);
g->Xchk = NULL; g->Xchk = NULL;
g->Createas = 0; g->Createas = false;
g->Alchecked = 0; g->Alchecked = 0;
g->Mrr = 0; g->Mrr = 0;
g->More = 0; g->More = 0;
g->Saved_Size = 0;
last_query_id= thdp->query_id; last_query_id= thdp->query_id;
if (trace(65) && !force) if (trace(65) && !force)
......
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