summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2017-07-18 13:16:55 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2017-07-18 13:16:55 +0200
commitf590296c28ec54007692181e010d7064c1071ff2 (patch)
tree8ca5932a93f59bb60abfb0928ef483e96ed999d6
parenta9d32010d0ba36cc9b9d7fb58eeace687bb13f7a (diff)
downloadmariadb-git-f590296c28ec54007692181e010d7064c1071ff2.tar.gz
-- Finalize work on MongoDB access
Implement discovery for the MongoDB Java Driver Create classes to minimize code and avoid dupicates Rearrange and rename implied files modified: storage/connect/CMakeLists.txt renamed: storage/connect/mongofam.cpp -> storage/connect/cmgfam.cpp renamed: storage/connect/mongofam.h -> storage/connect/cmgfam.h modified: storage/connect/cmgoconn.h modified: storage/connect/javaconn.h modified: storage/connect/jdbconn.cpp modified: storage/connect/jmgoconn.cpp modified: storage/connect/jmgoconn.h modified: storage/connect/mongo.cpp modified: storage/connect/mongo.h renamed: storage/connect/tabmgo.cpp -> storage/connect/tabcmg.cpp renamed: storage/connect/tabmgo.h -> storage/connect/tabcmg.h modified: storage/connect/tabjmg.cpp modified: storage/connect/tabjmg.h modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h -- Trace Sarea allocation and freeing modified: storage/connect/connect.cc modified: storage/connect/plugutil.cpp modified: storage/connect/user_connect.cc -- Null Json values where not mark as null in JSNX::SetJsonValue This was added in TYPE_NULL (declared as TYPE_VOID) modified: storage/connect/json.cpp modified: storage/connect/json.h modified: storage/connect/jsonudf.cpp -- Null JValues are ignored in JSNX::CalculateArray Also done in tabjson.cpp for JSONCOL::CalculateArray modified: storage/connect/json.h modified: storage/connect/jsonudf.cpp modified: storage/connect/tabjson.cpp -- Null JSON values now represented by connect_json_null session variable modified: storage/connect/json.cpp modified: storage/connect/json.h modified: storage/connect/jsonudf.cpp modified: storage/connect/tabjson.cpp -- JVALUE has size = 1 modified: storage/connect/json.h -- Fix by vuvova because Debian compilation failure. modified: storage/connect/value.cpp
-rw-r--r--storage/connect/CMakeLists.txt4
-rw-r--r--storage/connect/cmgfam.cpp (renamed from storage/connect/mongofam.cpp)58
-rw-r--r--storage/connect/cmgfam.h (renamed from storage/connect/mongofam.h)18
-rw-r--r--storage/connect/cmgoconn.h8
-rw-r--r--storage/connect/connect.cc11
-rw-r--r--storage/connect/global.h42
-rw-r--r--storage/connect/ha_connect.cc31
-rw-r--r--storage/connect/javaconn.h1
-rw-r--r--storage/connect/jdbconn.cpp2
-rw-r--r--storage/connect/jmgoconn.cpp16
-rw-r--r--storage/connect/jmgoconn.h27
-rw-r--r--storage/connect/json.cpp94
-rw-r--r--storage/connect/json.h25
-rw-r--r--storage/connect/jsonudf.cpp270
-rw-r--r--storage/connect/jsonudf.h12
-rw-r--r--storage/connect/mongo.cpp259
-rw-r--r--storage/connect/mongo.h32
-rw-r--r--storage/connect/plugutil.cpp102
-rw-r--r--storage/connect/tabcmg.cpp (renamed from storage/connect/tabmgo.cpp)302
-rw-r--r--storage/connect/tabcmg.h (renamed from storage/connect/tabmgo.h)49
-rw-r--r--storage/connect/tabjmg.cpp129
-rw-r--r--storage/connect/tabjmg.h27
-rw-r--r--storage/connect/tabjson.cpp36
-rw-r--r--storage/connect/tabjson.h6
-rw-r--r--storage/connect/user_connect.cc15
-rw-r--r--storage/connect/value.cpp5
26 files changed, 994 insertions, 587 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 248764879ed..9b0f555ad48 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -316,8 +316,8 @@ ENDIF(CONNECT_WITH_ZIP)
# INCLUDE_DIRECTORIES(${MONGO_INCLUDE_DIR})
# SET(MONGO_LIBRARY ${MONGO_LIBRARIES})
# SET(CONNECT_SOURCES ${CONNECT_SOURCES}
-# cmgoconn.cpp mongofam.cpp tabmgo.cpp
-# cmgoconn.h mongofam.h tabmgo.h)
+# cmgoconn.cpp cmgfam.cpp tabcmg.cpp
+# cmgoconn.h cmgfam.h tabcmg.h)
# IF (NOT JAVA_FOUND AND JNI_FOUND)
# SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongo.cpp mongo.h)
# ENDIF (NOT JAVA_FOUND AND JNI_FOUND)
diff --git a/storage/connect/mongofam.cpp b/storage/connect/cmgfam.cpp
index e40ed422d06..579b5b919a7 100644
--- a/storage/connect/mongofam.cpp
+++ b/storage/connect/cmgfam.cpp
@@ -1,7 +1,7 @@
-/************ MONGO FAM C++ Program Source Code File (.CPP) ************/
-/* PROGRAM NAME: mongofam.cpp */
+/************** CMGFAM C++ Program Source Code File (.CPP) *************/
+/* PROGRAM NAME: cmgfam.cpp */
/* ------------- */
-/* Version 1.3 */
+/* Version 1.4 */
/* */
/* COPYRIGHT: */
/* ---------- */
@@ -30,18 +30,18 @@
#include "filamtxt.h"
#include "tabdos.h"
#include "tabjson.h"
-#include "mongofam.h"
+#include "cmgfam.h"
#if defined(UNIX) || defined(UNIV_LINUX)
#include "osutil.h"
#endif
-/* --------------------------- Class MGOFAM -------------------------- */
+/* --------------------------- Class CMGFAM -------------------------- */
/***********************************************************************/
/* Constructors. */
/***********************************************************************/
-MGOFAM::MGOFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
+CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
{
Cmgp = NULL;
Pcg.Tdbp = NULL;
@@ -66,20 +66,20 @@ MGOFAM::MGOFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
Mode = MODE_ANY;
Done = false;
Lrecl = tdp->Lrecl + tdp->Ending;
-} // end of MGOFAM standard constructor
+} // end of CMGFAM standard constructor
- MGOFAM::MGOFAM(PMGOFAM tdfp) : DOSFAM(tdfp)
+ CMGFAM::CMGFAM(PCMGFAM tdfp) : DOSFAM(tdfp)
{
Pcg = tdfp->Pcg;
To_Fbt = tdfp->To_Fbt;
Mode = tdfp->Mode;
Done = tdfp->Done;
- } // end of MGOFAM copy constructor
+ } // end of CMGFAM copy constructor
/***********************************************************************/
/* Reset: reset position values at the beginning of file. */
/***********************************************************************/
-void MGOFAM::Reset(void)
+void CMGFAM::Reset(void)
{
TXTFAM::Reset();
Fpos = Tpos = Spos = 0;
@@ -88,7 +88,7 @@ void MGOFAM::Reset(void)
/***********************************************************************/
/* MGO GetFileLength: returns file size in number of bytes. */
/***********************************************************************/
-int MGOFAM::GetFileLength(PGLOBAL g)
+int CMGFAM::GetFileLength(PGLOBAL g)
{
return 0;
} // end of GetFileLength
@@ -98,7 +98,7 @@ int MGOFAM::GetFileLength(PGLOBAL g)
/* This function can be called with a null argument to test the */
/* availability of Cardinality implementation (1 yes, 0 no). */
/***********************************************************************/
-int MGOFAM::Cardinality(PGLOBAL g)
+int CMGFAM::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
@@ -109,7 +109,7 @@ int MGOFAM::Cardinality(PGLOBAL g)
/***********************************************************************/
/* Note: This function is not really implemented yet. */
/***********************************************************************/
-int MGOFAM::MaxBlkSize(PGLOBAL, int s)
+int CMGFAM::MaxBlkSize(PGLOBAL, int s)
{
return s;
} // end of MaxBlkSize
@@ -117,7 +117,7 @@ int MGOFAM::MaxBlkSize(PGLOBAL, int s)
/***********************************************************************/
/* Init: initialize MongoDB processing. */
/***********************************************************************/
-bool MGOFAM::Init(PGLOBAL g)
+bool CMGFAM::Init(PGLOBAL g)
{
if (Done)
return false;
@@ -141,7 +141,7 @@ bool MGOFAM::Init(PGLOBAL g)
/***********************************************************************/
/* OpenTableFile: Open a MongoDB table. */
/***********************************************************************/
-bool MGOFAM::OpenTableFile(PGLOBAL g)
+bool CMGFAM::OpenTableFile(PGLOBAL g)
{
Mode = Tdbp->GetMode();
@@ -165,7 +165,7 @@ bool MGOFAM::OpenTableFile(PGLOBAL g)
/***********************************************************************/
/* GetRowID: return the RowID of last read record. */
/***********************************************************************/
-int MGOFAM::GetRowID(void)
+int CMGFAM::GetRowID(void)
{
return Rows;
} // end of GetRowID
@@ -173,7 +173,7 @@ int MGOFAM::GetRowID(void)
/***********************************************************************/
/* GetPos: return the position of last read record. */
/***********************************************************************/
-int MGOFAM::GetPos(void)
+int CMGFAM::GetPos(void)
{
return Fpos;
} // end of GetPos
@@ -181,7 +181,7 @@ int MGOFAM::GetPos(void)
/***********************************************************************/
/* GetNextPos: return the position of next record. */
/***********************************************************************/
-int MGOFAM::GetNextPos(void)
+int CMGFAM::GetNextPos(void)
{
return Fpos; // TODO
} // end of GetNextPos
@@ -189,7 +189,7 @@ int MGOFAM::GetNextPos(void)
/***********************************************************************/
/* SetPos: Replace the table at the specified position. */
/***********************************************************************/
-bool MGOFAM::SetPos(PGLOBAL g, int pos)
+bool CMGFAM::SetPos(PGLOBAL g, int pos)
{
Fpos = pos;
Placed = true;
@@ -199,25 +199,25 @@ bool MGOFAM::SetPos(PGLOBAL g, int pos)
/***********************************************************************/
/* Record file position in case of UPDATE or DELETE. */
/***********************************************************************/
-bool MGOFAM::RecordPos(PGLOBAL g)
+bool CMGFAM::RecordPos(PGLOBAL g)
{
- strcpy(g->Message, "MGOFAM::RecordPos NIY");
+ strcpy(g->Message, "CMGFAM::RecordPos NIY");
return true;
} // end of RecordPos
/***********************************************************************/
/* Initialize Fpos and the current position for indexed DELETE. */
/***********************************************************************/
-int MGOFAM::InitDelete(PGLOBAL g, int fpos, int spos)
+int CMGFAM::InitDelete(PGLOBAL g, int fpos, int spos)
{
- strcpy(g->Message, "MGOFAM::InitDelete NIY");
+ strcpy(g->Message, "CMGFAM::InitDelete NIY");
return RC_FX;
} // end of InitDelete
/***********************************************************************/
/* Skip one record in file. */
/***********************************************************************/
-int MGOFAM::SkipRecord(PGLOBAL g, bool header)
+int CMGFAM::SkipRecord(PGLOBAL g, bool header)
{
return RC_OK; // Dummy
} // end of SkipRecord
@@ -225,7 +225,7 @@ int MGOFAM::SkipRecord(PGLOBAL g, bool header)
/***********************************************************************/
/* ReadBuffer: Get next document from a collection. */
/***********************************************************************/
-int MGOFAM::ReadBuffer(PGLOBAL g)
+int CMGFAM::ReadBuffer(PGLOBAL g)
{
int rc = Cmgp->ReadNext(g);
@@ -239,7 +239,7 @@ int MGOFAM::ReadBuffer(PGLOBAL g)
/***********************************************************************/
/* WriteBuffer: File write routine for MGO access method. */
/***********************************************************************/
-int MGOFAM::WriteBuffer(PGLOBAL g)
+int CMGFAM::WriteBuffer(PGLOBAL g)
{
return Cmgp->Write(g);
} // end of WriteBuffer
@@ -247,7 +247,7 @@ int MGOFAM::WriteBuffer(PGLOBAL g)
/***********************************************************************/
/* Data Base delete line routine for MGO and BLK access methods. */
/***********************************************************************/
-int MGOFAM::DeleteRecords(PGLOBAL g, int irc)
+int CMGFAM::DeleteRecords(PGLOBAL g, int irc)
{
return (irc == RC_OK) ? WriteBuffer(g) : RC_OK;
} // end of DeleteRecords
@@ -255,7 +255,7 @@ int MGOFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/
/* Table file close routine for MGO access method. */
/***********************************************************************/
-void MGOFAM::CloseTableFile(PGLOBAL g, bool)
+void CMGFAM::CloseTableFile(PGLOBAL g, bool)
{
Cmgp->Close();
Done = false;
@@ -264,7 +264,7 @@ void MGOFAM::CloseTableFile(PGLOBAL g, bool)
/***********************************************************************/
/* Rewind routine for MGO access method. */
/***********************************************************************/
-void MGOFAM::Rewind(void)
+void CMGFAM::Rewind(void)
{
Cmgp->Rewind();
} // end of Rewind
diff --git a/storage/connect/mongofam.h b/storage/connect/cmgfam.h
index 99cc6128ffd..7571f5c5309 100644
--- a/storage/connect/mongofam.h
+++ b/storage/connect/cmgfam.h
@@ -1,5 +1,5 @@
-/************** MongoFam H Declares Source Code File (.H) **************/
-/* Name: mongofam.h Version 1.4 */
+/*************** CMGFam H Declares Source Code File (.H) ***************/
+/* Name: cmgfam.h Version 1.5 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
@@ -8,19 +8,19 @@
#include "cmgoconn.h"
typedef class TXTFAM *PTXF;
-typedef class MGOFAM *PMGOFAM;
+typedef class CMGFAM *PCMGFAM;
typedef class MGODEF *PMGODEF;
-typedef class TDBMGO *PTDBMGO;
+typedef class TDBCMG *PTDBCMG;
/***********************************************************************/
/* This is the MongoDB Access Method class declaration. */
/***********************************************************************/
-class DllExport MGOFAM : public DOSFAM {
+class DllExport CMGFAM : public DOSFAM {
friend void mongo_init(bool);
public:
// Constructor
- MGOFAM(PJDEF tdp);
- MGOFAM(PMGOFAM txfp);
+ CMGFAM(PJDEF tdp);
+ CMGFAM(PCMGFAM txfp);
// Implementation
virtual AMT GetAmType(void) { return TYPE_AM_MGO; }
@@ -28,7 +28,7 @@ public:
virtual int GetPos(void);
virtual int GetNextPos(void);
void SetTdbp(PTDBDOS tdbp) { Tdbp = tdbp; }
- virtual PTXF Duplicate(PGLOBAL g) { return (PTXF)new(g) MGOFAM(this); }
+ virtual PTXF Duplicate(PGLOBAL g) { return (PTXF)new(g) CMGFAM(this); }
void SetLrecl(int lrecl) { Lrecl = lrecl; }
// Methods
@@ -61,5 +61,5 @@ protected:
PFBLOCK To_Fbt; // Pointer to temp file block
MODE Mode;
bool Done; // Init done
-}; // end of class MGOFAM
+}; // end of class CMGFAM
diff --git a/storage/connect/cmgoconn.h b/storage/connect/cmgoconn.h
index 9e1361039ab..47275f54381 100644
--- a/storage/connect/cmgoconn.h
+++ b/storage/connect/cmgoconn.h
@@ -10,7 +10,7 @@
#include <mongoc.h>
// C connection to a MongoDB data source
-class TDBMGO;
+class TDBCMG;
class MGOCOL;
/***********************************************************************/
@@ -18,7 +18,7 @@ class MGOCOL;
/***********************************************************************/
typedef class INCOL *PINCOL;
typedef class MGODEF *PMGODEF;
-typedef class TDBMGO *PTDBMGO;
+typedef class TDBCMG *PTDBCMG;
typedef class MGOCOL *PMGOCOL;
typedef struct mongo_parms {
@@ -63,8 +63,8 @@ public:
/* CMgoConn class. */
/***********************************************************************/
class CMgoConn : public BLOCK {
- friend class TDBMGO;
- friend class MGODISC;
+ friend class TDBCMG;
+ friend class CMGDISC;
public:
// Constructor
CMgoConn(PGLOBAL g, PCPARM pcg);
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 08d35b05932..8f06a710ef2 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -80,7 +80,7 @@ PGLOBAL CntExit(PGLOBAL g)
/* CntEndDB: DB termination semantic routine. */
/***********************************************************************/
void CntEndDB(PGLOBAL g)
- {
+{
PDBUSER dbuserp= PlgGetUser(g);
if (dbuserp) {
@@ -88,9 +88,14 @@ void CntEndDB(PGLOBAL g)
delete dbuserp->Catalog;
free(dbuserp);
- } // endif dbuserp
- } // end of CntEndDB
+ if (trace)
+ htrc("CntEndDB: Freeing Dup\n");
+
+ g->Activityp->Aptr = NULL;
+ } // endif dbuserp
+
+} // end of CntEndDB
/***********************************************************************/
/* CntCheckDB: Initialize a DB application session. */
diff --git a/storage/connect/global.h b/storage/connect/global.h
index cb756494efc..de7a9fb3c03 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -58,31 +58,10 @@
/* Miscellaneous Constants */
/***********************************************************************/
#define NO_IVAL -95684275 /* Used by GetIntegerOption */
-#define VMLANG 370 /* Size of olf VM lang blocks */
#define MAX_JUMP 24 /* Maximum jump level number */
#define MAX_STR 4160 /* Maximum message length */
-#define STR_SIZE 501 /* Length of char strings. */
-#define STD_INPUT 0 /* Standard language input */
-#define STD_OUTPUT 1 /* Standard language output */
-#define ERROR_OUTPUT 2 /* Error message output */
-#define DEBUG_OUTPUT 3 /* Debug info output */
-#define PROMPT_OUTPUT 4 /* Prompt message output */
-#define COPY_OUTPUT 5 /* Copy of language input */
-#define STD_MSG 6 /* System message file */
-#define DEBUG_MSG 7 /* Debug message file */
-#define DUMMY 0 /* Dummy file index in Ldm block */
-#define STDIN 1 /* stdin file index in Ldm block */
-#define STDOUT 2 /* stdout file index in Ldm block */
-#define STDERR 3 /* stderr file index in Ldm block */
-#define STDEBUG 4 /* debug file index in Ldm block */
-#define STDPRN 5 /* stdprn file index in Ldm block */
-#define STDFREE 6 /* Free file index in Ldm block */
-#define TYPE_SEM -2 /* Returned semantic function */
-#define TYPE_DFONC -2 /* Indirect sem ref in FPARM */
#define TYPE_VOID -1
-#define TYPE_SBPAR -1 /* Phrase reference in FPARM */
-#define TYPE_SEMX 0 /* Initial semantic function type? */
#define TYPE_ERROR 0
#define TYPE_STRING 1
#define TYPE_DOUBLE 2
@@ -96,22 +75,6 @@
#define TYPE_BIN 10
#define TYPE_PCHAR 11
-#if defined(OS32)
- #define SYS_STAMP "OS32"
-#elif defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX)
- #define SYS_STAMP "UNIX"
-#elif defined(OS16)
- #define SYS_STAMP "OS16"
-#elif defined(DOSR)
- #define SYS_STAMP "DOSR"
-#elif defined(WIN)
- #define SYS_STAMP "WIN1"
-#elif defined(__WIN__)
- #define SYS_STAMP "WIN2"
-#else
- #define SYS_STAMP "XXXX"
-#endif
-
#if defined(__cplusplus)
extern "C" {
#endif
@@ -119,11 +82,6 @@ extern "C" {
/***********************************************************************/
/* Static variables */
/***********************************************************************/
-#if defined(STORAGE)
- char sys_stamp[5] = SYS_STAMP;
-#else
- extern char sys_stamp[];
-#endif
/***********************************************************************/
/* File-Selection Indicators */
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index b0a37ea445a..fc23d320c83 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -210,9 +210,9 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
PQRYRES VirColumns(PGLOBAL g, bool info);
PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info);
-#if defined(MONGO_SUPPORT)
+#if defined(JDBC_SUPPORT) || defined(MONGO_SUPPORT)
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ url, PTOS topt, bool info);
-#endif // MONGO_SUPPORT
+#endif // JDBC_SUPPORT || MONGO_SUPPORT
int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v);
void PushWarning(PGLOBAL g, THD *thd, int level);
bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, PCSZ host, PCSZ db,
@@ -223,6 +223,7 @@ void mongo_init(bool);
USETEMP UseTemp(void);
int GetConvSize(void);
TYPCONV GetTypeConv(void);
+char *GetJsonNull(void);
uint GetJsonGrpSize(void);
char *GetJavaWrapper(void);
uint GetWorkSize(void);
@@ -332,6 +333,13 @@ static MYSQL_THDVAR_ENUM(
0, // def (no)
&xconv_typelib); // typelib
+// Null representation for JSON values
+static MYSQL_THDVAR_STR(json_null,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+ "Representation of Json null values",
+ // check_json_null, update_json_null,
+ NULL, NULL, "<null>");
+
// Estimate max number of rows for JSON aggregate functions
static MYSQL_THDVAR_UINT(json_grp_size,
PLUGIN_VAR_RQCMDARG, // opt
@@ -343,7 +351,7 @@ static MYSQL_THDVAR_UINT(json_grp_size,
static MYSQL_THDVAR_STR(java_wrapper,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
"Java wrapper class name",
- // check_class_path, update_class_path,
+ // check_java_wrapper, update_java_wrapper,
NULL, NULL, "wrappers/JdbcInterface");
#endif // JDBC_SUPPORT
@@ -383,6 +391,8 @@ bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
+char *GetJsonNull(void)
+ {return connect_hton ? THDVAR(current_thd, json_null) : NULL;}
uint GetJsonGrpSize(void)
{return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;}
uint GetWorkSize(void) {return THDVAR(current_thd, work_size);}
@@ -5761,25 +5771,13 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if !defined(MONGO_SUPPORT)
driver = "JAVA";
- // strcpy(g->Message, "No column discovery for Java MONGO tables yet");
- // Temporarily use the JSONColumns function
- qrp = JSONColumns(g, db, url, topt, fnc == FNC_COL);
#elif !defined(JDBC_SUPPORT)
driver = "C";
- qrp = MGOColumns(g, db, url, topt, fnc == FNC_COL);
#else // MONGO_SUPPORT && JDBC_SUPPORT
if (!driver)
driver = "C";
-
- if (toupper(*driver) == 'C') {
- qrp = MGOColumns(g, db, url, topt, fnc == FNC_COL);
- } else {
- // strcpy(g->Message, "No column discovery for Java MONGO tables yet");
- // Temporarily use the JSONColumns function
- qrp = JSONColumns(g, db, url, topt, fnc == FNC_COL);
- } // endif driver
-
#endif // MONGO_SUPPORT && JDBC_SUPPORT
+ qrp = MGOColumns(g, db, url, topt, fnc == FNC_COL);
break;
#endif // MONGO_SUPPORT || JDBC_SUPPORT
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
@@ -7137,6 +7135,7 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
#if defined(XMSG)
MYSQL_SYSVAR(errmsg_dir_path),
#endif // XMSG
+ MYSQL_SYSVAR(json_null),
MYSQL_SYSVAR(json_grp_size),
#if defined(JDBC_SUPPORT)
MYSQL_SYSVAR(jvm_path),
diff --git a/storage/connect/javaconn.h b/storage/connect/javaconn.h
index fba633945f0..565c4ac2607 100644
--- a/storage/connect/javaconn.h
+++ b/storage/connect/javaconn.h
@@ -63,6 +63,7 @@ class JAVAConn;
/***********************************************************************/
class JAVAConn : public BLOCK {
friend class TDBJMG;
+ friend class JMGDISC;
private:
JAVAConn(); // Standard (unused) constructor
diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp
index dbfd1b0e24d..e0524392082 100644
--- a/storage/connect/jdbconn.cpp
+++ b/storage/connect/jdbconn.cpp
@@ -1226,7 +1226,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
case 5: crp->Name = "Nullable"; break;
} // endswitch i
- // Build the java string array
+ // Build the java int array
jintArray val = env->NewIntArray(4);
if (val == nullptr) {
diff --git a/storage/connect/jmgoconn.cpp b/storage/connect/jmgoconn.cpp
index cb0729ed1f7..a51127c80a0 100644
--- a/storage/connect/jmgoconn.cpp
+++ b/storage/connect/jmgoconn.cpp
@@ -110,8 +110,8 @@ JMgoConn::JMgoConn(PGLOBAL g, PCSZ collname, PCSZ wrapper)
deleteid = gcollid = countid = rewindid = nullptr;
DiscFunc = "MongoDisconnect";
Fpc = NULL;
- m_Version = 0;
m_Fetch = 0;
+ m_Ncol = 0;
m_Version = 0;
} // end of JMgoConn
@@ -122,13 +122,13 @@ void JMgoConn::AddJars(PSTRG jpop, char sep)
{
#if defined(DEVELOPMENT)
if (m_Version == 2) {
- //jpop->Append(sep);
- //jpop->Append("C:/Eclipse/workspace/MongoWrap2/bin");
+ jpop->Append(sep);
+ jpop->Append("C:/Eclipse/workspace/MongoWrap2/bin");
jpop->Append(sep);
jpop->Append("C:/mongo-java-driver/mongo-java-driver-2.13.3.jar");
} else {
- //jpop->Append(sep);
- //jpop->Append("C:/Eclipse/workspace/MongoWrap3/bin");
+ jpop->Append(sep);
+ jpop->Append("C:/Eclipse/workspace/MongoWrap3/bin");
jpop->Append(sep);
jpop->Append("C:/mongo-java-driver/mongo-java-driver-3.4.2.jar");
} // endif m_Version
@@ -495,13 +495,15 @@ int JMgoConn::Fetch(int pos)
//else
// m_Fetch++;
- m_Rows += (int)rc;
+ m_Ncol = (int)rc;
+ rc = MY_MIN(rc, 1);
+ m_Rows += rc;
} else
sprintf(g->Message, "Fetch: %s", Msg);
//} // endif pos
- return (int)rc;
+ return rc;
} // end of Fetch
/***********************************************************************/
diff --git a/storage/connect/jmgoconn.h b/storage/connect/jmgoconn.h
index 8e8577efe97..8ee7985d760 100644
--- a/storage/connect/jmgoconn.h
+++ b/storage/connect/jmgoconn.h
@@ -19,31 +19,6 @@ typedef class MGODEF *PMGODEF;
typedef class TDBJMG *PTDBJMG;
typedef class JMGCOL *PJMGCOL;
-#if 0
-/***********************************************************************/
-/* Class used to get the columns of a mongo collection. */
-/***********************************************************************/
-class MGODISC : public BLOCK {
-public:
- // Constructor
- MGODISC(PGLOBAL g, int *lg);
-
- // Functions
- int GetColumns(PGLOBAL g, char *db, PTOS topt);
- bool FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
- char *pcn, char *pfmt, int i, int k, bool b);
-
- // Members
- BCOL bcol;
- PBCOL bcp, fbcp, pbcp;
- PMGODEF tdp;
- TDBJMG *tmgp;
- int *length;
- int n, k, lvl;
- bool all;
-}; // end of MGODISC
-#endif // 0
-
typedef struct JKCOL {
JKCOL *Next;
PJNCOL Jncolp;
@@ -73,6 +48,7 @@ public:
/***********************************************************************/
class JMgoConn : public JAVAConn {
friend class TDBJMG;
+ friend class JMGDISC;
//friend class TDBXJDC;
//friend PQRYRES GetColumnInfo(PGLOBAL, char*&, char *, int, PVBLK&);
private:
@@ -132,5 +108,6 @@ protected:
jmethodID deleteid; // The CollDelete method ID
PJNCOL Fpc; // To JNCOL classes
int m_Fetch;
+ int m_Ncol;
int m_Version; // Java driver version (2 or 3)
}; // end of JMgoConn class definition
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp
index 44758e7b0ad..da94d4e227c 100644
--- a/storage/connect/json.cpp
+++ b/storage/connect/json.cpp
@@ -1,5 +1,5 @@
/*************** json CPP Declares Source Code File (.H) ***************/
-/* Name: json.cpp Version 1.3 */
+/* Name: json.cpp Version 1.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
/* */
@@ -53,6 +53,8 @@ void trans_func(unsigned int u, _EXCEPTION_POINTERS* pExp)
char *GetExceptionDesc(PGLOBAL g, unsigned int e);
#endif // SE_CATCH
+char *GetJsonNull(void);
+
/***********************************************************************/
/* IsNum: check whether this string is all digits. */
/***********************************************************************/
@@ -537,7 +539,7 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
if (!has_e)
goto err;
- // passthru
+ // fall through
case '-':
if (found_digit)
goto err;
@@ -827,7 +829,7 @@ bool JOUTSTR::Escape(const char *s)
case '\r':
case '\b':
case '\f': WriteChr('\\');
- // passthru
+ // fall through
default:
WriteChr(s[i]);
break;
@@ -964,6 +966,25 @@ return false;
/* -------------------------- Class JOBJECT -------------------------- */
/***********************************************************************/
+/* Return the number of pairs in this object. */
+/***********************************************************************/
+int JOBJECT::GetSize(bool b)
+{
+ if (b) {
+ // Return only non null pairs
+ int n = 0;
+
+ for (PJPR jpp = First; jpp; jpp = jpp->Next)
+ if (jpp->Val && !jpp->Val->IsNull())
+ n++;
+
+ return n;
+ } else
+ return Size;
+
+} // end of GetSize
+
+/***********************************************************************/
/* Add a new pair to an Object. */
/***********************************************************************/
PJPR JOBJECT::AddPair(PGLOBAL g, PCSZ key)
@@ -1046,7 +1067,7 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSZ text)
PlugSubAlloc(g, NULL, strlen(text) + 1);
return text + n;
-} // end of GetValue;
+} // end of GetText;
/***********************************************************************/
/* Merge two objects. */
@@ -1087,7 +1108,7 @@ void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PCSZ key)
} // end of SetValue
/***********************************************************************/
-/* Delete a value corresponding to the given key. */
+/* Delete a value corresponding to the given key. */
/***********************************************************************/
void JOBJECT::DeleteKey(PCSZ key)
{
@@ -1118,6 +1139,25 @@ bool JOBJECT::IsNull(void)
/* -------------------------- Class JARRAY --------------------------- */
/***********************************************************************/
+/* Return the number of values in this object. */
+/***********************************************************************/
+int JARRAY::GetSize(bool b)
+{
+ if (b) {
+ // Return only non null values
+ int n = 0;
+
+ for (PJVAL jvp = First; jvp; jvp = jvp->Next)
+ if (!jvp->IsNull())
+ n++;
+
+ return n;
+ } else
+ return Size;
+
+} // end of GetSize
+
+/***********************************************************************/
/* Make the array of values from the values list. */
/***********************************************************************/
void JARRAY::InitArray(PGLOBAL g)
@@ -1226,17 +1266,41 @@ bool JARRAY::SetValue(PGLOBAL g, PJVAL jvp, int n)
} // end of SetValue
/***********************************************************************/
+/* Return the text corresponding to all values. */
+/***********************************************************************/
+PSZ JARRAY::GetText(PGLOBAL g, PSZ text)
+{
+ int n;
+ PJVAL jp;
+
+ if (!text) {
+ text = (char*)PlugSubAlloc(g, NULL, 0);
+ text[0] = 0;
+ n = 1;
+ } else
+ n = 0;
+
+ for (jp = First; jp; jp = jp->Next)
+ jp->GetText(g, text);
+
+ if (n)
+ PlugSubAlloc(g, NULL, strlen(text) + 1);
+
+ return text + n;
+} // end of GetText;
+
+/***********************************************************************/
/* Delete a Value from the Arrays Value list. */
/***********************************************************************/
bool JARRAY::DeleteValue(int n)
{
- PJVAL jvp = GetValue(n);
+ PJVAL jvp = GetValue(n);
- if (jvp) {
- jvp->Del = true;
- return false;
- } else
- return true;
+ if (jvp) {
+ jvp->Del = true;
+ return false;
+ } else
+ return true;
} // end of DeleteValue
@@ -1286,7 +1350,7 @@ JTYP JVALUE::GetValType(void)
else if (Value)
return (JTYP)Value->GetType();
else
- return (JTYP)TYPE_VOID;
+ return TYPE_NULL;
} // end of GetValType
@@ -1350,7 +1414,7 @@ PSZ JVALUE::GetString(void)
/***********************************************************************/
PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
{
- if (Jsp && Jsp->GetType() == TYPE_JOB)
+ if (Jsp)
return Jsp->GetText(g, text);
char buf[32];
@@ -1358,8 +1422,8 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
if (s)
strcat(strcat(text, " "), s);
- else
- strcat(text, " <null>");
+ else if (GetJsonNull())
+ strcat(strcat(text, " "), GetJsonNull());
return text;
} // end of GetText
diff --git a/storage/connect/json.h b/storage/connect/json.h
index 685c1dddcf2..daed055435b 100644
--- a/storage/connect/json.h
+++ b/storage/connect/json.h
@@ -13,7 +13,8 @@
#define X
#endif
-enum JTYP {TYPE_STRG = TYPE_STRING,
+enum JTYP {TYPE_NULL = TYPE_VOID,
+ TYPE_STRG = TYPE_STRING,
TYPE_DBL = TYPE_DOUBLE,
TYPE_BOOL = TYPE_TINY,
TYPE_BINT = TYPE_BIGINT,
@@ -146,6 +147,7 @@ class JSON : public BLOCK {
JSON(void) {Size = 0;}
int size(void) {return Size;}
+ virtual int GetSize(bool b) {return Size;}
virtual void Clear(void) {Size = 0;}
virtual JTYP GetType(void) {return TYPE_JSON;}
virtual JTYP GetValType(void) {X return TYPE_JSON;}
@@ -193,10 +195,11 @@ class JOBJECT : public JSON {
using JSON::GetValue;
using JSON::SetValue;
- virtual void Clear(void) {First = Last = NULL; Size = 0;}
+ virtual void Clear(void) {First = Last = NULL; Size = 0;}
virtual JTYP GetType(void) {return TYPE_JOB;}
virtual PJPR GetFirst(void) {return First;}
- virtual PJPR AddPair(PGLOBAL g, PCSZ key);
+ virtual int GetSize(bool b);
+ virtual PJPR AddPair(PGLOBAL g, PCSZ key);
virtual PJOB GetObject(void) {return this;}
virtual PJVAL GetValue(const char* key);
virtual PJAR GetKeyList(PGLOBAL g);
@@ -222,11 +225,13 @@ class JARRAY : public JSON {
using JSON::GetValue;
using JSON::SetValue;
virtual void Clear(void) {First = Last = NULL; Size = 0;}
- virtual JTYP GetType(void) {return TYPE_JAR;}
+ virtual JTYP GetType(void) {return TYPE_JAR;}
virtual PJAR GetArray(void) {return this;}
- PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL);
+ virtual int GetSize(bool b);
+ PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL);
virtual void InitArray(PGLOBAL g);
virtual PJVAL GetValue(int i);
+ virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual bool Merge(PGLOBAL g, PJSON jsp);
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i);
virtual bool DeleteValue(int n);
@@ -246,20 +251,20 @@ class JARRAY : public JSON {
class JVALUE : public JSON {
friend class JARRAY;
friend class JSNX;
+ friend class JSONCOL;
friend PJVAL ParseValue(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeValue(JOUT *, PJVAL);
public:
- JVALUE(void) : JSON()
- {Jsp = NULL; Value = NULL; Next = NULL; Del = false;}
+ JVALUE(void) : JSON() {Clear();}
JVALUE(PJSON jsp) : JSON()
- {Jsp = jsp; Value = NULL; Next = NULL; Del = false;}
- JVALUE(PGLOBAL g, PVAL valp);
+ {Jsp = jsp; Value = NULL; Next = NULL; Del = false; Size = 1;}
+ JVALUE(PGLOBAL g, PVAL valp);
JVALUE(PGLOBAL g, PCSZ strp);
using JSON::GetValue;
using JSON::SetValue;
virtual void Clear(void)
- {Jsp = NULL; Value = NULL; Next = NULL; Del = false; Size = 0;}
+ {Jsp = NULL; Value = NULL; Next = NULL; Del = false; Size = 1;}
virtual JTYP GetType(void) {return TYPE_JVAL;}
virtual JTYP GetValType(void);
virtual PJOB GetObject(void);
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 124e5bdc6ad..eb98510c702 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -1,5 +1,5 @@
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
-/* PROGRAM NAME: jsonudf Version 1.5 */
+/* PROGRAM NAME: jsonudf Version 1.6 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
@@ -29,6 +29,7 @@
bool IsNum(PSZ s);
char *NextChr(PSZ s, char sep);
+char *GetJsonNull(void);
uint GetJsonGrpSize(void);
static int IsJson(UDF_ARGS *args, uint i);
static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
@@ -347,11 +348,13 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
SetJsonValue(g, vp, val->GetArray()->GetValue(0), n);
break;
case TYPE_JOB:
- // if (!vp->IsTypeNum() || !Strict) {
+// if (!vp->IsTypeNum() || !Strict) {
vp->SetValue_psz(val->GetObject()->GetText(g, NULL));
break;
- // } // endif Type
+// } // endif Type
+ case TYPE_NULL:
+ vp->SetNull(true);
default:
vp->Reset();
} // endswitch Type
@@ -488,15 +491,16 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
JVALUE jval;
vp->Reset();
-//ars = MY_MIN(Tjp->Limit, arp->size());
ars = arp->size();
for (i = 0; i < ars; i++) {
jvrp = arp->GetValue(i);
-// do {
- if (n < Nod - 1 && jvrp->GetJson()) {
-// Tjp->NextSame = nextsame;
+ if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) {
+ if (jvrp->IsNull()) {
+ jvrp->Value = AllocateValue(g, GetJsonNull(), TYPE_STRING);
+ jvp = jvrp;
+ } else if (n < Nod - 1 && jvrp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvrp->GetJson(), n + 1));
jvp = &jval;
} else
@@ -510,25 +514,25 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (!MulVal->IsZero()) {
switch (op) {
- case OP_CNC:
- if (Nodes[n].CncVal) {
- val[0] = Nodes[n].CncVal;
- err = vp->Compute(g, val, 1, op);
- } // endif CncVal
+ case OP_CNC:
+ if (Nodes[n].CncVal) {
+ val[0] = Nodes[n].CncVal;
+ err = vp->Compute(g, val, 1, op);
+ } // endif CncVal
- val[0] = MulVal;
- err = vp->Compute(g, val, 1, op);
- break;
- // case OP_NUM:
- case OP_SEP:
- val[0] = Nodes[n].Valp;
- val[1] = MulVal;
- err = vp->Compute(g, val, 2, OP_ADD);
- break;
- default:
- val[0] = Nodes[n].Valp;
- val[1] = MulVal;
- err = vp->Compute(g, val, 2, op);
+ val[0] = MulVal;
+ err = vp->Compute(g, val, 1, op);
+ break;
+// case OP_NUM:
+ case OP_SEP:
+ val[0] = Nodes[n].Valp;
+ val[1] = MulVal;
+ err = vp->Compute(g, val, 2, OP_ADD);
+ break;
+ default:
+ val[0] = Nodes[n].Valp;
+ val[1] = MulVal;
+ err = vp->Compute(g, val, 2, op);
} // endswitch Op
if (err)
@@ -536,7 +540,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
} // endif Zero
-// } while (Tjp->NextSame > nextsame);
+ } // endif jvrp
} // endfor i
@@ -1100,6 +1104,7 @@ inline void JsonMemSave(PGLOBAL g)
/*********************************************************************************/
inline void JsonFreeMem(PGLOBAL g)
{
+ g->Activityp = NULL;
PlugExit(g);
} /* end of JsonFreeMem */
@@ -1111,7 +1116,7 @@ static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
unsigned long reslen, unsigned long memlen,
unsigned long more = 0)
{
- PGLOBAL g = PlugInit(NULL, memlen + more);
+ PGLOBAL g = PlugInit(NULL, memlen + more + 500); // +500 to avoid CheckMem
if (!g) {
strcpy(message, "Allocation error");
@@ -1471,6 +1476,9 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
ml += g->More;
if (ml > g->Sarea_Size) {
+ if (trace)
+ htrc("Freeing Sarea size=%d\n", g->Sarea_Size);
+
free(g->Sarea);
if (!(g->Sarea = PlugAllocMem(g, ml))) {
@@ -1814,7 +1822,7 @@ char *json_make_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
return str;
} // end of json_make_array
-void json_array_deinit(UDF_INIT* initid)
+void json_make_array_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of json_make_array_deinit
@@ -2098,6 +2106,206 @@ void json_array_delete_deinit(UDF_INIT* initid)
} // end of json_array_delete_deinit
/*********************************************************************************/
+/* Sum big integer values from a Json array. */
+/*********************************************************************************/
+my_bool jsonsum_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen, more;
+
+ if (args->arg_count != 1) {
+ strcpy(message, "This function must have 1 argument");
+ return true;
+ } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "First argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ // TODO: calculate this
+ more = (IsJson(args, 0) != 3) ? 1000 : 0;
+
+ return JsonInit(initid, args, message, true, reslen, memlen, more);
+} // end of jsonsum_int_init
+
+long long jsonsum_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
+{
+ long long n = 0LL;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ if (g->N) {
+ if (!g->Activityp) {
+ *is_null = 1;
+ return 0LL;
+ } else
+ return *(long long*)g->Activityp;
+
+ } else if (initid->const_item)
+ g->N = 1;
+
+ if (!CheckMemory(g, initid, args, 1, false, false, true)) {
+ PJVAL jvp = MakeValue(g, args, 0);
+
+ if (jvp && jvp->GetValType() == TYPE_JAR) {
+ PJAR arp = jvp->GetArray();
+
+ for (int i = 0; i < arp->size(); i++)
+ n += arp->GetValue(i)->GetBigint();
+
+ } else {
+ PUSH_WARNING("First argument target is not an array");
+ } // endif jvp
+
+ } else {
+ *error = 1;
+ n = -1LL;
+ } // end of CheckMemory
+
+ if (g->N) {
+ // Keep result of constant function
+ long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } // endif const_item
+
+ return n;
+} // end of jsonsum_int
+
+void jsonsum_int_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of jsonsum_int_deinit
+
+/*********************************************************************************/
+/* Sum big integer values from a Json array. */
+/*********************************************************************************/
+my_bool jsonsum_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen, more;
+
+ if (args->arg_count != 1) {
+ strcpy(message, "This function must have 1 argument");
+ return true;
+ } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "First argument must be a json item");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ // TODO: calculate this
+ more = (IsJson(args, 0) != 3) ? 1000 : 0;
+
+ return JsonInit(initid, args, message, true, reslen, memlen, more);
+} // end of jsonsum_real_init
+
+double jsonsum_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
+{
+ double n = 0.0;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ if (g->N) {
+ if (!g->Activityp) {
+ *is_null = 1;
+ return 0.0;
+ } else
+ return *(double*)g->Activityp;
+
+ } else if (initid->const_item)
+ g->N = 1;
+
+ if (!CheckMemory(g, initid, args, 1, false, false, true)) {
+ PJVAL jvp = MakeValue(g, args, 0);
+
+ if (jvp && jvp->GetValType() == TYPE_JAR) {
+ PJAR arp = jvp->GetArray();
+
+ for (int i = 0; i < arp->size(); i++)
+ n += arp->GetValue(i)->GetFloat();
+
+ } else {
+ PUSH_WARNING("First argument target is not an array");
+ } // endif jvp
+
+ } else {
+ *error = 1;
+ n = -1.0;
+ } // end of CheckMemory
+
+ if (g->N) {
+ // Keep result of constant function
+ double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } // endif const_item
+
+ return n;
+} // end of jsonsum_real
+
+void jsonsum_real_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of jsonsum_real_deinit
+
+/*********************************************************************************/
+/* Returns the average of big integer values from a Json array. */
+/*********************************************************************************/
+my_bool jsonavg_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ return jsonsum_real_init(initid, args, message);
+} // end of jsonavg_real_init
+
+double jsonavg_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
+{
+ double n = 0.0;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ if (g->N) {
+ if (!g->Activityp) {
+ *is_null = 1;
+ return 0.0;
+ } else
+ return *(double*)g->Activityp;
+
+ } else if (initid->const_item)
+ g->N = 1;
+
+ if (!CheckMemory(g, initid, args, 1, false, false, true)) {
+ PJVAL jvp = MakeValue(g, args, 0);
+
+ if (jvp && jvp->GetValType() == TYPE_JAR) {
+ PJAR arp = jvp->GetArray();
+
+ if (arp->size()) {
+ for (int i = 0; i < arp->size(); i++)
+ n += arp->GetValue(i)->GetFloat();
+
+ n /= arp->size();
+ } // endif size
+
+ } else {
+ PUSH_WARNING("First argument target is not an array");
+ } // endif jvp
+
+ } else {
+ *error = 1;
+ n = -1.0;
+ } // end of CheckMemory
+
+ if (g->N) {
+ // Keep result of constant function
+ double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } // endif const_item
+
+ return n;
+} // end of jsonavg_real
+
+void jsonavg_real_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of jsonavg_real_deinit
+
+/*********************************************************************************/
/* Make a Json Object containing all the parameters. */
/*********************************************************************************/
my_bool json_make_object_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
@@ -2990,6 +3198,7 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
+
PUSH_WARNING(g->Message);
str = NULL;
} catch (const char *msg) {
@@ -3039,7 +3248,7 @@ my_bool jsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} // end of jsonget_int_init
long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
- char *is_null, char *error)
+ char *is_null, char *error)
{
char *p, *path;
long long n;
@@ -3330,6 +3539,7 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
+
PUSH_WARNING(g->Message);
*error = 1;
path = NULL;
@@ -3454,6 +3664,7 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
+
PUSH_WARNING(g->Message);
*error = 1;
path = NULL;
@@ -3728,6 +3939,7 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
+
PUSH_WARNING(g->Message);
str = NULL;
} catch (const char *msg) {
diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h
index 53fa555ee08..cd3b9768f7a 100644
--- a/storage/connect/jsonudf.h
+++ b/storage/connect/jsonudf.h
@@ -53,6 +53,18 @@ extern "C" {
DllExport char *json_array_delete(UDF_EXEC_ARGS);
DllExport void json_array_delete_deinit(UDF_INIT*);
+ DllExport my_bool jsonsum_int_init(UDF_INIT*, UDF_ARGS*, char*);
+ DllExport long long jsonsum_int(UDF_INIT*, UDF_ARGS*, char*, char*);
+ DllExport void jsonsum_int_deinit(UDF_INIT*);
+
+ DllExport my_bool jsonsum_real_init(UDF_INIT*, UDF_ARGS*, char*);
+ DllExport double jsonsum_real(UDF_INIT*, UDF_ARGS*, char*, char*);
+ DllExport void jsonsum_real_deinit(UDF_INIT*);
+
+ DllExport my_bool jsonavg_real_init(UDF_INIT*, UDF_ARGS*, char*);
+ DllExport double jsonavg_real(UDF_INIT*, UDF_ARGS*, char*, char*);
+ DllExport void jsonavg_real_deinit(UDF_INIT*);
+
DllExport my_bool json_make_object_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_make_object(UDF_EXEC_ARGS);
DllExport void json_make_object_deinit(UDF_INIT*);
diff --git a/storage/connect/mongo.cpp b/storage/connect/mongo.cpp
index 07b8beb8ce7..55c26dae9f3 100644
--- a/storage/connect/mongo.cpp
+++ b/storage/connect/mongo.cpp
@@ -19,11 +19,265 @@
#include "xtable.h"
#include "tabext.h"
#if defined(MONGO_SUPPORT)
-#include "tabmgo.h"
+#include "tabcmg.h"
#endif // MONGO_SUPPORT
#if defined(JDBC_SUPPORT)
#include "tabjmg.h"
#endif // JDBC_SUPPORT
+#include "resource.h"
+
+/***********************************************************************/
+/* This should be an option. */
+/***********************************************************************/
+#define MAXCOL 200 /* Default max column nb in result */
+#define TYPE_UNKNOWN 12 /* Must be greater than other types */
+
+bool IsNum(PSZ s);
+
+/***********************************************************************/
+/* MGOColumns: construct the result blocks containing the description */
+/* of all the columns of a document contained inside MongoDB. */
+/***********************************************************************/
+PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info)
+{
+ static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
+ TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
+ static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
+ FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
+ unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
+ int ncol = sizeof(buftyp) / sizeof(int);
+ int i, n = 0;
+//PCSZ drv;
+ PBCOL bcp;
+ MGODISC *cmgd;
+ PQRYRES qrp;
+ PCOLRES crp;
+
+ if (info) {
+ length[0] = 128;
+ length[7] = 256;
+ goto skipit;
+ } // endif info
+
+ /*********************************************************************/
+ /* Open MongoDB. */
+ /*********************************************************************/
+# if !defined(JDBC_SUPPORT)
+ cmgd = new(g) CMGDISC(g, (int*)length);
+#elif !defined(MONGO_SUPPORT)
+ cmgd = new(g) JMGDISC(g, (int*)length);
+#else
+ drv = GetStringTableOption(g, topt, "Driver", "C");
+
+ if (toupper(*drv) == 'C')
+ cmgd = new(g) CMGDISC(g, (int*)length);
+ else
+ cmgd = new(g) JMGDISC(g, (int*)length);
+#endif
+
+ if ((n = cmgd->GetColumns(g, db, uri, topt)) < 0)
+ goto err;
+
+skipit:
+ if (trace)
+ htrc("MGOColumns: n=%d len=%d\n", n, length[0]);
+
+ /*********************************************************************/
+ /* Allocate the structures used to refer to the result set. */
+ /*********************************************************************/
+ qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
+ buftyp, fldtyp, length, false, false);
+
+ crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
+ crp->Name = "Nullable";
+ crp->Next->Name = "Bpath";
+
+ if (info || !qrp)
+ return qrp;
+
+ qrp->Nblin = n;
+
+ /*********************************************************************/
+ /* Now get the results into blocks. */
+ /*********************************************************************/
+ for (i = 0, bcp = cmgd->fbcp; bcp; i++, bcp = bcp->Next) {
+ if (bcp->Type == TYPE_UNKNOWN) // Void column
+ bcp->Type = TYPE_STRING;
+
+ crp = qrp->Colresp; // Column Name
+ crp->Kdata->SetValue(bcp->Name, i);
+ crp = crp->Next; // Data Type
+ crp->Kdata->SetValue(bcp->Type, i);
+ crp = crp->Next; // Type Name
+ crp->Kdata->SetValue(GetTypeName(bcp->Type), i);
+ crp = crp->Next; // Precision
+ crp->Kdata->SetValue(bcp->Len, i);
+ crp = crp->Next; // Length
+ crp->Kdata->SetValue(bcp->Len, i);
+ crp = crp->Next; // Scale (precision)
+ crp->Kdata->SetValue(bcp->Scale, i);
+ crp = crp->Next; // Nullable
+ crp->Kdata->SetValue(bcp->Cbn ? 1 : 0, i);
+ crp = crp->Next; // Field format
+
+ if (crp->Kdata)
+ crp->Kdata->SetValue(bcp->Fmt, i);
+
+ } // endfor i
+
+ /*********************************************************************/
+ /* Return the result pointer. */
+ /*********************************************************************/
+ return qrp;
+
+err:
+ if (cmgd->tmgp)
+ cmgd->tmgp->CloseDB(g);
+
+ return NULL;
+} // end of MGOColumns
+
+/***********************************************************************/
+/* Class used to get the columns of a mongo collection. */
+/***********************************************************************/
+MGODISC::MGODISC(PGLOBAL g, int *lg) {
+ length = lg;
+ fbcp = NULL;
+ pbcp = NULL;
+ tmgp = NULL;
+ drv = NULL;
+ i = ncol = lvl = 0;
+ all = false;
+} // end of MGODISC constructor
+
+/***********************************************************************/
+/* Class used to get the columns of a mongo collection. */
+/***********************************************************************/
+int MGODISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt)
+{
+ PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
+ PMGODEF tdp;
+
+ if (level) {
+ lvl = atoi(level);
+ lvl = (lvl > 16) ? 16 : lvl;
+ } else
+ lvl = 0;
+
+ all = GetBooleanTableOption(g, topt, "Fullarray", false);
+
+ /*********************************************************************/
+ /* Open the MongoDB collection. */
+ /*********************************************************************/
+ tdp = new(g) MGODEF;
+ tdp->Uri = uri;
+ tdp->Driver = drv;
+ tdp->Tabname = GetStringTableOption(g, topt, "Name", NULL);
+ tdp->Tabname = GetStringTableOption(g, topt, "Tabname", tdp->Tabname);
+ tdp->Tabschema = GetStringTableOption(g, topt, "Dbname", db);
+ tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
+ tdp->Colist = GetStringTableOption(g, topt, "Colist", "all");
+ tdp->Filter = GetStringTableOption(g, topt, "Filter", NULL);
+ tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
+ tdp->Version = GetIntegerTableOption(g, topt, "Version", 3);
+ tdp->Wrapname = (PSZ)GetStringTableOption(g, topt, "Wrapper",
+ (tdp->Version == 2) ? "Mongo2Interface" : "Mongo3Interface");
+
+ if (trace)
+ htrc("Uri %s coll=%s db=%s colist=%s filter=%s lvl=%d\n",
+ tdp->Uri, tdp->Tabname, tdp->Tabschema, tdp->Colist, tdp->Filter, lvl);
+
+ tmgp = tdp->GetTable(g, MODE_READ);
+ tmgp->SetMode(MODE_READ);
+
+ if (tmgp->OpenDB(g))
+ return -1;
+
+ bcol.Next = NULL;
+ bcol.Name = bcol.Fmt = NULL;
+ bcol.Type = TYPE_UNKNOWN;
+ bcol.Len = bcol.Scale = 0;
+ bcol.Found = true;
+ bcol.Cbn = false;
+
+ if (Init(g))
+ return -1;
+
+ /*********************************************************************/
+ /* Analyse the BSON tree and define columns. */
+ /*********************************************************************/
+ for (i = 1; ; i++) {
+ switch (tmgp->ReadDB(g)) {
+ case RC_EF:
+ return ncol;
+ case RC_FX:
+ return -1;
+ default:
+ GetDoc();
+ } // endswitch ReadDB
+
+ if (Find(g))
+ return -1;
+
+ // Missing columns can be null
+ for (bcp = fbcp; bcp; bcp = bcp->Next) {
+ bcp->Cbn |= !bcp->Found;
+ bcp->Found = false;
+ } // endfor bcp
+
+ } // endfor i
+
+ return ncol;
+} // end of GetColumns
+
+/***********************************************************************/
+/* Add a new column in the column list. */
+/***********************************************************************/
+void MGODISC::AddColumn(PGLOBAL g, PCSZ colname, PCSZ fmt, int k)
+{
+ // Check whether this column was already found
+ for (bcp = fbcp; bcp; bcp = bcp->Next)
+ if (!strcmp(colname, bcp->Name))
+ break;
+
+ if (bcp) {
+ if (bcp->Type != bcol.Type)
+ bcp->Type = TYPE_STRING;
+
+ if (k && *fmt && (!bcp->Fmt || strlen(bcp->Fmt) < strlen(fmt))) {
+ bcp->Fmt = PlugDup(g, fmt);
+ length[7] = MY_MAX(length[7], strlen(fmt));
+ } // endif *fmt
+
+ bcp->Len = MY_MAX(bcp->Len, bcol.Len);
+ bcp->Scale = MY_MAX(bcp->Scale, bcol.Scale);
+ bcp->Cbn |= bcol.Cbn;
+ bcp->Found = true;
+ } else {
+ // New column
+ bcp = (PBCOL)PlugSubAlloc(g, NULL, sizeof(BCOL));
+ *bcp = bcol;
+ bcp->Cbn |= (i > 1);
+ bcp->Name = PlugDup(g, colname);
+ length[0] = MY_MAX(length[0], strlen(colname));
+
+ if (k) {
+ bcp->Fmt = PlugDup(g, fmt);
+ length[7] = MY_MAX(length[7], strlen(fmt));
+ } else
+ bcp->Fmt = NULL;
+
+ if (pbcp) {
+ bcp->Next = pbcp->Next;
+ pbcp->Next = bcp;
+ } else
+ fbcp = bcp;
+
+ ncol++;
+ } // endif jcp
+
+ pbcp = bcp;
+} // end of AddColumn
/* -------------------------- Class MGODEF --------------------------- */
@@ -91,7 +345,7 @@ PTDB MGODEF::GetTable(PGLOBAL g, MODE m)
#if defined(MONGO_SUPPORT)
if (Driver && toupper(*Driver) == 'C')
- return new(g) TDBMGO(this);
+ return new(g) TDBCMG(this);
#endif // MONGO_SUPPORT
#if defined(JDBC_SUPPORT)
return new(g) TDBJMG(this);
@@ -100,4 +354,3 @@ PTDB MGODEF::GetTable(PGLOBAL g, MODE m)
return NULL;
#endif // !JDBC_SUPPORT
} // end of GetTable
-
diff --git a/storage/connect/mongo.h b/storage/connect/mongo.h
index 26d83b38bbc..af69226ea8b 100644
--- a/storage/connect/mongo.h
+++ b/storage/connect/mongo.h
@@ -26,14 +26,42 @@ typedef struct _bncol {
} BCOL, *PBCOL;
/***********************************************************************/
+/* Class used to get the columns of a mongo collection. */
+/***********************************************************************/
+class MGODISC : public BLOCK {
+public:
+ // Constructor
+ MGODISC(PGLOBAL g, int *lg);
+
+ // Methods
+ virtual bool Init(PGLOBAL g) { return false; }
+ virtual void GetDoc(void) {}
+ virtual bool Find(PGLOBAL g) = 0;
+
+ // Functions
+ int GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt);
+ void AddColumn(PGLOBAL g, PCSZ colname, PCSZ fmt, int k);
+
+ // Members
+ BCOL bcol;
+ PBCOL bcp, fbcp, pbcp;
+ PMGODEF tdp;
+ PTDB tmgp;
+ PCSZ drv;
+ int *length;
+ int i, ncol, lvl;
+ bool all;
+}; // end of MGODISC
+
+/***********************************************************************/
/* MongoDB table. */
/***********************************************************************/
class DllExport MGODEF : public EXTDEF { /* Table description */
- friend class TDBMGO;
+ friend class TDBCMG;
friend class TDBJMG;
friend class TDBGOL;
friend class TDBJGL;
- friend class MGOFAM;
+ friend class CMGFAM;
friend class MGODISC;
friend PQRYRES MGOColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index f0822526b98..e4bfd825932 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -2,11 +2,11 @@
/* */
/* PROGRAM NAME: PLUGUTIL */
/* ------------- */
-/* Version 2.9 */
+/* Version 3.0 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1993-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 1993-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -76,6 +76,7 @@
#include "osutil.h"
#include "global.h"
+#include "plgdbsem.h"
#if defined(NEWMSG)
#include "rcmsg.h"
#endif // NEWMSG
@@ -132,12 +133,12 @@ void htrc(char const *fmt, ...)
/* Return value is the pointer to the Global structure. */
/***********************************************************************/
PGLOBAL PlugInit(LPCSTR Language, uint worksize)
- {
- PGLOBAL g;
+{
+ PGLOBAL g;
- if (trace > 1)
- htrc("PlugInit: Language='%s'\n",
- ((!Language) ? "Null" : (char*)Language));
+ if (trace > 1)
+ htrc("PlugInit: Language='%s'\n",
+ ((!Language) ? "Null" : (char*)Language));
try {
g = new GLOBAL;
@@ -146,53 +147,54 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
return NULL;
} // end try/catch
- //if (!(g = (PGLOBAL)malloc(sizeof(GLOBAL)))) {
- // fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
- // return NULL;
- // } else {
- g->Sarea = NULL;
- g->Createas = 0;
- g->Alchecked = 0;
- g->Mrr = 0;
- g->Activityp = NULL;
- g->Xchk = NULL;
- g->N = 0;
- g->More = 0;
- strcpy(g->Message, "");
-
- /*******************************************************************/
- /* Allocate the main work segment. */
- /*******************************************************************/
- if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) {
- char errmsg[MAX_STR];
- sprintf(errmsg, MSG(WORK_AREA), g->Message);
- strcpy(g->Message, errmsg);
- g->Sarea_Size = 0;
- } else
- g->Sarea_Size = worksize;
-
- //} /* endif g */
-
- g->jump_level = -1; /* New setting to allow recursive call of Plug */
- return(g);
- } /* end of PlugInit */
+ g->Sarea = NULL;
+ g->Createas = 0;
+ g->Alchecked = 0;
+ g->Mrr = 0;
+ g->Activityp = NULL;
+ g->Xchk = NULL;
+ g->N = 0;
+ g->More = 0;
+ strcpy(g->Message, "");
+
+ /*******************************************************************/
+ /* Allocate the main work segment. */
+ /*******************************************************************/
+ if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) {
+ char errmsg[MAX_STR];
+ sprintf(errmsg, MSG(WORK_AREA), g->Message);
+ strcpy(g->Message, errmsg);
+ g->Sarea_Size = 0;
+ } else
+ g->Sarea_Size = worksize;
+
+ g->jump_level = -1; /* New setting to allow recursive call of Plug */
+ return(g);
+} /* end of PlugInit */
/***********************************************************************/
/* PlugExit: Terminate Plug operations. */
/***********************************************************************/
int PlugExit(PGLOBAL g)
- {
- int rc = 0;
+{
+ if (g) {
+ PDBUSER dup = PlgGetUser(g);
+
+ if (dup)
+ free(dup);
+
+ if (g->Sarea) {
+ if (trace)
+ htrc("Freeing Sarea size=%d\n", g->Sarea_Size);
- if (!g)
- return rc;
+ free(g->Sarea);
+ } // endif Sarea
- if (g->Sarea)
- free(g->Sarea);
+ delete g;
+ } // endif g
- delete g;
- return rc;
- } /* end of PlugExit */
+ return 0;
+} // end of PlugExit
/***********************************************************************/
/* Remove the file type from a file name. */
@@ -456,7 +458,7 @@ short GetLineLength(PGLOBAL g)
/* Program for memory allocation of work and language areas. */
/***********************************************************************/
void *PlugAllocMem(PGLOBAL g, uint size)
- {
+{
void *areap; /* Pointer to allocated area */
/*********************************************************************/
@@ -465,16 +467,16 @@ void *PlugAllocMem(PGLOBAL g, uint size)
if (!(areap = malloc(size)))
sprintf(g->Message, MSG(MALLOC_ERROR), "malloc");
- if (trace > 1) {
+ if (trace) {
if (areap)
htrc("Memory of %u allocated at %p\n", size, areap);
else
htrc("PlugAllocMem: %s\n", g->Message);
- } // endif trace
+ } // endif trace
return (areap);
- } /* end of PlugAllocMem */
+} // end of PlugAllocMem
/***********************************************************************/
/* Program for SubSet initialization of memory pools. */
diff --git a/storage/connect/tabmgo.cpp b/storage/connect/tabcmg.cpp
index 810785ede80..23ae5219719 100644
--- a/storage/connect/tabmgo.cpp
+++ b/storage/connect/tabcmg.cpp
@@ -1,7 +1,7 @@
-/************** tabmgo C++ Program Source Code File (.CPP) *************/
-/* PROGRAM NAME: tabmgo Version 1.0 */
+/************** tabcmg C++ Program Source Code File (.CPP) *************/
+/* PROGRAM NAME: tabcmg Version 1.1 */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
-/* This program are the MongoDB class DB execution routines. */
+/* This program are the C MongoDB class DB execution routines. */
/***********************************************************************/
/***********************************************************************/
@@ -22,214 +22,40 @@
#include "maputil.h"
#include "filamtxt.h"
#include "tabext.h"
-#include "tabmgo.h"
+#include "tabcmg.h"
#include "tabmul.h"
-#include "checklvl.h"
-#include "resource.h"
-#include "mycat.h" // for FNC_COL
#include "filter.h"
-/***********************************************************************/
-/* This should be an option. */
-/***********************************************************************/
-#define MAXCOL 200 /* Default max column nb in result */
-#define TYPE_UNKNOWN 12 /* Must be greater than other types */
-
-bool IsNum(PSZ s);
+/* -------------------------- Class CMGDISC -------------------------- */
/***********************************************************************/
-/* MGOColumns: construct the result blocks containing the description */
-/* of all the columns of a document contained inside MongoDB. */
+/* Get document. */
/***********************************************************************/
-PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info)
+void CMGDISC::GetDoc(void)
{
- static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
- TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
- static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
- FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
- unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
- int ncol = sizeof(buftyp) / sizeof(int);
- int i, n = 0;
- PBCOL bcp;
- MGODISC *mgd;
- PQRYRES qrp;
- PCOLRES crp;
-
- if (info) {
- length[0] = 128;
- length[7] = 256;
- goto skipit;
- } // endif info
-
- /*********************************************************************/
- /* Open MongoDB. */
- /*********************************************************************/
- mgd = new(g) MGODISC(g, (int*)length);
-
- if ((n = mgd->GetColumns(g, db, uri, topt)) < 0)
- goto err;
-
-skipit:
- if (trace)
- htrc("MGOColumns: n=%d len=%d\n", n, length[0]);
-
- /*********************************************************************/
- /* Allocate the structures used to refer to the result set. */
- /*********************************************************************/
- qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
- buftyp, fldtyp, length, false, false);
-
- crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
- crp->Name = "Nullable";
- crp->Next->Name = "Bpath";
-
- if (info || !qrp)
- return qrp;
-
- qrp->Nblin = n;
-
- /*********************************************************************/
- /* Now get the results into blocks. */
- /*********************************************************************/
- for (i = 0, bcp = mgd->fbcp; bcp; i++, bcp = bcp->Next) {
- if (bcp->Type == TYPE_UNKNOWN) // Void column
- bcp->Type = TYPE_STRING;
-
- crp = qrp->Colresp; // Column Name
- crp->Kdata->SetValue(bcp->Name, i);
- crp = crp->Next; // Data Type
- crp->Kdata->SetValue(bcp->Type, i);
- crp = crp->Next; // Type Name
- crp->Kdata->SetValue(GetTypeName(bcp->Type), i);
- crp = crp->Next; // Precision
- crp->Kdata->SetValue(bcp->Len, i);
- crp = crp->Next; // Length
- crp->Kdata->SetValue(bcp->Len, i);
- crp = crp->Next; // Scale (precision)
- crp->Kdata->SetValue(bcp->Scale, i);
- crp = crp->Next; // Nullable
- crp->Kdata->SetValue(bcp->Cbn ? 1 : 0, i);
- crp = crp->Next; // Field format
-
- if (crp->Kdata)
- crp->Kdata->SetValue(bcp->Fmt, i);
-
- } // endfor i
-
- /*********************************************************************/
- /* Return the result pointer. */
- /*********************************************************************/
- return qrp;
-
-err:
- if (mgd->tmgp)
- mgd->tmgp->CloseDB(g);
-
- return NULL;
-} // end of MGOColumns
+ doc = ((TDBCMG*)tmgp)->Cmgp->Document;
+} // end of GetDoc
/***********************************************************************/
-/* Class used to get the columns of a mongo collection. */
+/* Analyse passed document. */
/***********************************************************************/
-// Constructor
-MGODISC::MGODISC(PGLOBAL g, int *lg) {
- length = lg;
- fbcp = NULL;
- pbcp = NULL;
- tmgp = NULL;
- n = k = lvl = 0;
- all = false;
-} // end of MGODISC constructor
+//bool CMGDISC::Find(PGLOBAL g, int i, int k, bool b)
+bool CMGDISC::Find(PGLOBAL g)
+{
+ return FindInDoc(g, &iter, doc, NULL, NULL, 0, false);
+} // end of Find
/***********************************************************************/
-/* Class used to get the columns of a mongo collection. */
+/* Analyse passed document. */
/***********************************************************************/
-int MGODISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt)
-{
- PCSZ level;
- bson_iter_t iter;
- const bson_t *doc;
- PMGODEF tdp;
- TDBMGO *tmgp = NULL;
-
- level = GetStringTableOption(g, topt, "Level", NULL);
-
- if (level) {
- lvl = atoi(level);
- lvl = (lvl > 16) ? 16 : lvl;
- } else
- lvl = 0;
-
- all = GetBooleanTableOption(g, topt, "Fullarray", false);
-
- /*********************************************************************/
- /* Open the MongoDB collection. */
- /*********************************************************************/
- tdp = new(g) MGODEF;
- tdp->Uri = uri;
- tdp->Tabname = GetStringTableOption(g, topt, "Name", NULL);
- tdp->Tabname = GetStringTableOption(g, topt, "Tabname", tdp->Tabname);
- tdp->Tabschema = GetStringTableOption(g, topt, "Dbname", db);
- tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
- tdp->Colist = GetStringTableOption(g, topt, "Colist", "all");
- tdp->Filter = GetStringTableOption(g, topt, "Filter", NULL);
- tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
-
- if (trace)
- htrc("Uri %s coll=%s db=%s colist=%s filter=%s lvl=%d\n",
- tdp->Uri, tdp->Tabname, tdp->Tabschema, tdp->Colist, tdp->Filter, lvl);
-
- tmgp = new(g) TDBMGO(tdp);
- tmgp->SetMode(MODE_READ);
-
- if (tmgp->OpenDB(g))
- return -1;
-
- bcol.Next = NULL;
- bcol.Name = bcol.Fmt = NULL;
- bcol.Type = TYPE_UNKNOWN;
- bcol.Len = bcol.Scale = 0;
- bcol.Found = true;
- bcol.Cbn = false;
-
- /*********************************************************************/
- /* Analyse the BSON tree and define columns. */
- /*********************************************************************/
- for (int i = 1; ; i++) {
- switch (tmgp->ReadDB(g)) {
- case RC_EF:
- return n;
- case RC_FX:
- return -1;
- default:
- doc = tmgp->Cmgp->Document;
- } // endswitch ReadDB
-
- if (FindInDoc(g, &iter, doc, NULL, NULL, i, k, false))
- return -1;
-
- // Missing columns can be null
- for (bcp = fbcp; bcp; bcp = bcp->Next) {
- bcp->Cbn |= !bcp->Found;
- bcp->Found = false;
- } // endfor bcp
-
- } // endfor i
-
- return n;
-} // end of GetColumns
-
-/*********************************************************************/
-/* Analyse passed document. */
-/*********************************************************************/
-bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
- char *pcn, char *pfmt, int i, int k, bool b)
+bool CMGDISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
+ char *pcn, char *pfmt, int k, bool b)
{
if (!doc || bson_iter_init(iter, doc)) {
const char *key;
char colname[65];
char fmt[129];
- bool newcol;
+ bool newcol;
while (bson_iter_next(iter)) {
key = bson_iter_key(iter);
@@ -286,7 +112,7 @@ bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
bson_iter_t child;
if (bson_iter_recurse(iter, &child))
- if (FindInDoc(g, &child, NULL, colname, fmt, i, k + 1, false))
+ if (FindInDoc(g, &child, NULL, colname, fmt, k + 1, false))
return true;
newcol = false;
@@ -307,7 +133,7 @@ bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
bson_iter_array(iter, &len, &data);
arr = bson_new_from_data(data, len);
- if (FindInDoc(g, &itar, arr, colname, fmt, i, k + 1, !all))
+ if (FindInDoc(g, &itar, arr, colname, fmt, k + 1, !all))
return true;
newcol = false;
@@ -315,50 +141,8 @@ bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
} // endif's
- if (newcol) {
- // Check whether this column was already found
- for (bcp = fbcp; bcp; bcp = bcp->Next)
- if (!strcmp(colname, bcp->Name))
- break;
-
- if (bcp) {
- if (bcp->Type != bcol.Type)
- bcp->Type = TYPE_STRING;
-
- if (k && *fmt && (!bcp->Fmt || strlen(bcp->Fmt) < strlen(fmt))) {
- bcp->Fmt = PlugDup(g, fmt);
- length[7] = MY_MAX(length[7], strlen(fmt));
- } // endif *fmt
-
- bcp->Len = MY_MAX(bcp->Len, bcol.Len);
- bcp->Scale = MY_MAX(bcp->Scale, bcol.Scale);
- bcp->Cbn |= bcol.Cbn;
- bcp->Found = true;
- } else {
- // New column
- bcp = (PBCOL)PlugSubAlloc(g, NULL, sizeof(BCOL));
- *bcp = bcol;
- bcp->Cbn |= (i > 1);
- bcp->Name = PlugDup(g, colname);
- length[0] = MY_MAX(length[0], strlen(colname));
-
- if (k) {
- bcp->Fmt = PlugDup(g, fmt);
- length[7] = MY_MAX(length[7], strlen(fmt));
- } else
- bcp->Fmt = NULL;
-
- if (pbcp) {
- bcp->Next = pbcp->Next;
- pbcp->Next = bcp;
- } else
- fbcp = bcp;
-
- n++;
- } // endif jcp
-
- pbcp = bcp;
- } // endif newcol
+ if (newcol)
+ AddColumn(g, colname, fmt, k);
if (b)
break; // Test only first element of arrays
@@ -370,12 +154,12 @@ bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
return false;
} // end of FindInDoc
-/* --------------------------- Class TDBMGO -------------------------- */
+/* --------------------------- Class TDBCMG -------------------------- */
/***********************************************************************/
-/* Implementation of the TDBMGO class. */
+/* Implementation of the TDBCMG class. */
/***********************************************************************/
-TDBMGO::TDBMGO(MGODEF *tdp) : TDBEXT(tdp)
+TDBCMG::TDBCMG(MGODEF *tdp) : TDBEXT(tdp)
{
Cmgp = NULL;
Cnd = NULL;
@@ -402,9 +186,9 @@ TDBMGO::TDBMGO(MGODEF *tdp) : TDBEXT(tdp)
Fpos = -1;
N = 0;
Done = false;
-} // end of TDBMGO standard constructor
+} // end of TDBCMG standard constructor
-TDBMGO::TDBMGO(TDBMGO *tdbp) : TDBEXT(tdbp)
+TDBCMG::TDBCMG(TDBCMG *tdbp) : TDBEXT(tdbp)
{
Cmgp = tdbp->Cmgp;
Cnd = tdbp->Cnd;
@@ -413,16 +197,16 @@ TDBMGO::TDBMGO(TDBMGO *tdbp) : TDBEXT(tdbp)
Fpos = tdbp->Fpos;
N = tdbp->N;
Done = tdbp->Done;
-} // end of TDBMGO copy constructor
+} // end of TDBCMG copy constructor
// Used for update
-PTDB TDBMGO::Clone(PTABS t)
+PTDB TDBCMG::Clone(PTABS t)
{
PTDB tp;
PMGOCOL cp1, cp2;
PGLOBAL g = t->G;
- tp = new(g) TDBMGO(this);
+ tp = new(g) TDBCMG(this);
for (cp1 = (PMGOCOL)Columns; cp1; cp1 = (PMGOCOL)cp1->GetNext())
if (!cp1->IsSpecial()) {
@@ -436,7 +220,7 @@ PTDB TDBMGO::Clone(PTABS t)
/***********************************************************************/
/* Allocate JSN column description block. */
/***********************************************************************/
-PCOL TDBMGO::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
+PCOL TDBCMG::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
PMGOCOL colp = new(g) MGOCOL(g, cdp, this, cprec, n);
@@ -446,7 +230,7 @@ PCOL TDBMGO::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/***********************************************************************/
/* InsertSpecialColumn: Put a special column ahead of the column list.*/
/***********************************************************************/
-PCOL TDBMGO::InsertSpecialColumn(PCOL colp)
+PCOL TDBCMG::InsertSpecialColumn(PCOL colp)
{
if (!colp->IsSpecial())
return NULL;
@@ -459,7 +243,7 @@ PCOL TDBMGO::InsertSpecialColumn(PCOL colp)
/***********************************************************************/
/* Init: initialize MongoDB processing. */
/***********************************************************************/
-bool TDBMGO::Init(PGLOBAL g)
+bool TDBCMG::Init(PGLOBAL g)
{
if (Done)
return false;
@@ -482,7 +266,7 @@ bool TDBMGO::Init(PGLOBAL g)
/***********************************************************************/
/* MONGO Cardinality: returns table size in number of rows. */
/***********************************************************************/
-int TDBMGO::Cardinality(PGLOBAL g)
+int TDBCMG::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
@@ -495,7 +279,7 @@ int TDBMGO::Cardinality(PGLOBAL g)
/***********************************************************************/
/* MONGO GetMaxSize: returns collection size estimate. */
/***********************************************************************/
-int TDBMGO::GetMaxSize(PGLOBAL g)
+int TDBCMG::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0)
MaxSize = Cardinality(g);
@@ -506,7 +290,7 @@ int TDBMGO::GetMaxSize(PGLOBAL g)
/***********************************************************************/
/* OpenDB: Data Base open routine for MONGO access method. */
/***********************************************************************/
-bool TDBMGO::OpenDB(PGLOBAL g)
+bool TDBCMG::OpenDB(PGLOBAL g)
{
if (Use == USE_OPEN) {
/*******************************************************************/
@@ -540,7 +324,7 @@ bool TDBMGO::OpenDB(PGLOBAL g)
/***********************************************************************/
/* Data Base indexed read routine for ODBC access method. */
/***********************************************************************/
-bool TDBMGO::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
+bool TDBCMG::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
{
strcpy(g->Message, "MONGO tables are not indexable");
return true;
@@ -549,7 +333,7 @@ bool TDBMGO::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
/***********************************************************************/
/* ReadDB: Get next document from a collection. */
/***********************************************************************/
-int TDBMGO::ReadDB(PGLOBAL g)
+int TDBCMG::ReadDB(PGLOBAL g)
{
return Cmgp->ReadNext(g);
} // end of ReadDB
@@ -557,7 +341,7 @@ int TDBMGO::ReadDB(PGLOBAL g)
/***********************************************************************/
/* WriteDB: Data Base write routine for MGO access method. */
/***********************************************************************/
-int TDBMGO::WriteDB(PGLOBAL g)
+int TDBCMG::WriteDB(PGLOBAL g)
{
return Cmgp->Write(g);
} // end of WriteDB
@@ -565,7 +349,7 @@ int TDBMGO::WriteDB(PGLOBAL g)
/***********************************************************************/
/* Data Base delete line routine for MGO access method. */
/***********************************************************************/
-int TDBMGO::DeleteDB(PGLOBAL g, int irc)
+int TDBCMG::DeleteDB(PGLOBAL g, int irc)
{
return (irc == RC_OK) ? WriteDB(g) : RC_OK;
} // end of DeleteDB
@@ -573,7 +357,7 @@ int TDBMGO::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
/* Table close routine for MONGO tables. */
/***********************************************************************/
-void TDBMGO::CloseDB(PGLOBAL g)
+void TDBCMG::CloseDB(PGLOBAL g)
{
Cmgp->Close();
Done = false;
@@ -587,7 +371,7 @@ void TDBMGO::CloseDB(PGLOBAL g)
MGOCOL::MGOCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
: EXTCOL(cdp, tdbp, cprec, i, "MGO")
{
- Tmgp = (PTDBMGO)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
+ Tmgp = (PTDBCMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName();
} // end of MGOCOL constructor
diff --git a/storage/connect/tabmgo.h b/storage/connect/tabcmg.h
index 9a4e537eadf..260f2def8a2 100644
--- a/storage/connect/tabmgo.h
+++ b/storage/connect/tabcmg.h
@@ -1,5 +1,5 @@
-/**************** tabmgo H Declares Source Code File (.H) **************/
-/* Name: tabmgo.h Version 1.1 */
+/**************** tabcmg H Declares Source Code File (.H) **************/
+/* Name: tabcmg.h Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
@@ -11,45 +11,46 @@
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
-class MGODISC : public BLOCK {
+class CMGDISC : public MGODISC {
public:
// Constructor
- MGODISC(PGLOBAL g, int *lg);
+ CMGDISC(PGLOBAL g, int *lg) : MGODISC(g, lg) { drv = "C"; }
- // Functions
- int GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt);
+ // Methods
+ virtual void GetDoc(void);
+//virtual bool Find(PGLOBAL g, int i, int k, bool b);
+ virtual bool Find(PGLOBAL g);
+
+ // BSON Function
+//bool FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
+// char *pcn, char *pfmt, int i, int k, bool b);
bool FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
- char *pcn, char *pfmt, int i, int k, bool b);
+ char *pcn, char *pfmt, int k, bool b);
// Members
- BCOL bcol;
- PBCOL bcp, fbcp, pbcp;
- PMGODEF tdp;
- TDBMGO *tmgp;
- int *length;
- int n, k, lvl;
- bool all;
-}; // end of MGODISC
+ bson_iter_t iter;
+ const bson_t *doc;
+}; // end of CMGDISC
-/* -------------------------- TDBMGO class --------------------------- */
+/* -------------------------- TDBCMG class --------------------------- */
/***********************************************************************/
/* This is the MongoDB Table Type class declaration. */
/* The table is a collection, each record being a document. */
/***********************************************************************/
-class DllExport TDBMGO : public TDBEXT {
+class DllExport TDBCMG : public TDBEXT {
friend class MGOCOL;
friend class MGODEF;
- friend class MGODISC;
+ friend class CMGDISC;
friend PQRYRES MGOColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
// Constructor
- TDBMGO(MGODEF *tdp);
- TDBMGO(TDBMGO *tdbp);
+ TDBCMG(MGODEF *tdp);
+ TDBCMG(TDBCMG *tdbp);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_MGO;}
- virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMGO(this);}
+ virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBCMG(this);}
// Methods
virtual PTDB Clone(PTABS t);
@@ -78,7 +79,7 @@ protected:
int N; // The current Rownum
int B; // Array index base
bool Done; // Init done
-}; // end of class TDBMGO
+}; // end of class TDBCMG
/* --------------------------- MGOCOL class -------------------------- */
@@ -86,7 +87,7 @@ protected:
/* Class MGOCOL: MongoDB access method column descriptor. */
/***********************************************************************/
class DllExport MGOCOL : public EXTCOL {
- friend class TDBMGO;
+ friend class TDBCMG;
friend class FILTER;
public:
// Constructors
@@ -106,7 +107,7 @@ protected:
MGOCOL(void) {}
// Members
- TDBMGO *Tmgp; // To the MGO table block
+ TDBCMG *Tmgp; // To the MGO table block
char *Jpath; // The json path
}; // end of class MGOCOL
diff --git a/storage/connect/tabjmg.cpp b/storage/connect/tabjmg.cpp
index bf147e76cc0..76a6c3aff6c 100644
--- a/storage/connect/tabjmg.cpp
+++ b/storage/connect/tabjmg.cpp
@@ -27,13 +27,108 @@
#include "mycat.h" // for FNC_COL
#include "filter.h"
+PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info);
+
+/* -------------------------- Class JMGDISC -------------------------- */
+
/***********************************************************************/
-/* This should be an option. */
+/* Initialyze. */
/***********************************************************************/
-#define MAXCOL 200 /* Default max column nb in result */
-#define TYPE_UNKNOWN 12 /* Must be greater than other types */
+bool JMGDISC::Init(PGLOBAL g)
+{
+ if (!(Jcp = ((TDBJMG*)tmgp)->Jcp)) {
+ strcpy(g->Message, "Init: Jcp is NULL");
+ return true;
+ } else if (Jcp->gmID(g, columnid, "ColumnDesc",
+ "(Ljava/lang/Object;I[II)Ljava/lang/Object;"))
+ return true;
+ else if (Jcp->gmID(g, bvnameid, "ColDescName", "()Ljava/lang/String;"))
+ return true;
+
+ return false;
+} // end of Init
+
+/***********************************************************************/
+/* Analyse passed document. */
+/***********************************************************************/
+bool JMGDISC::Find(PGLOBAL g)
+{
+ return ColDesc(g, nullptr, NULL, NULL, Jcp->m_Ncol, 0);
+} // end of Find
+
+/***********************************************************************/
+/* Analyse passed document. */
+/***********************************************************************/
+bool JMGDISC::ColDesc(PGLOBAL g, jobject obj, char *pcn, char *pfmt,
+ int ncol, int k)
+{
+ const char *key;
+ char colname[65];
+ char fmt[129];
+ bool rc = true;
+ jint *n = nullptr;
+ jstring jkey;
+ jobject jres;
+
+ // Build the java int array
+ jintArray val = Jcp->env->NewIntArray(5);
+
+ if (val == nullptr) {
+ strcpy(g->Message, "Cannot allocate jint array");
+ return true;
+ } else if (!ncol)
+ n = Jcp->env->GetIntArrayElements(val, 0);
+
+ for (int i = 0; i < ncol; i++) {
+ jres = Jcp->env->CallObjectMethod(Jcp->job, columnid, obj, i, val, lvl - k);
+ n = Jcp->env->GetIntArrayElements(val, 0);
+
+ if (Jcp->Check(n[0])) {
+ sprintf(g->Message, "ColDesc: %s", Jcp->Msg);
+ goto err;
+ } else if (!n[0])
+ continue;
+
+ jkey = (jstring)Jcp->env->CallObjectMethod(Jcp->job, bvnameid);
+ key = Jcp->env->GetStringUTFChars(jkey, (jboolean)false);
+
+ if (pcn) {
+ strncpy(colname, pcn, 64);
+ colname[64] = 0;
+ strncat(strncat(colname, "_", 65), key, 65);
+ } else
+ strcpy(colname, key);
+
+ if (pfmt) {
+ strncpy(fmt, pfmt, 128);
+ fmt[128] = 0;
+ strncat(strncat(fmt, ".", 129), key, 129);
+ } else
+ strcpy(fmt, key);
-PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
+ if (!jres) {
+ bcol.Type = n[0];
+ bcol.Len = n[1];
+ bcol.Scale = n[2];
+ bcol.Cbn = n[3];
+ AddColumn(g, colname, fmt, k);
+ } else {
+ if (n[0] == 2 && !all)
+ n[4] = MY_MIN(n[4], 1);
+
+ if (ColDesc(g, jres, colname, fmt, n[4], k + 1))
+ goto err;
+
+ } // endif jres
+
+ } // endfor i
+
+ rc = false;
+
+ err:
+ Jcp->env->ReleaseIntArrayElements(val, n, 0);
+ return rc;
+} // end of ColDesc
/* --------------------------- Class TDBJMG -------------------------- */
@@ -82,16 +177,6 @@ TDBJMG::TDBJMG(PMGODEF tdp) : TDBEXT(tdp)
TDBJMG::TDBJMG(TDBJMG *tdbp) : TDBEXT(tdbp)
{
Uri = tdbp->Uri;
-//Pool = tdbp->Pool;
-//Client = tdbp->Client;
-//Database = NULL;
-//Collection = tdbp->Collection;
-//Cursor = tdbp->Cursor;
-//Query = tdbp->Query;
-//Opts = tdbp->Opts;
-//Fpc = tdbp->Fpc;
-//Cnd = tdbp->Cnd;
-//Uristr = tdbp->Uristr;
Db_name = tdbp->Db_name;;
Coll_name = tdbp->Coll_name;
Options = tdbp->Options;
@@ -126,11 +211,7 @@ PTDB TDBJMG::Clone(PTABS t)
/***********************************************************************/
PCOL TDBJMG::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
- PJMGCOL colp = new(g) JMGCOL(g, cdp, this, cprec, n);
-
-//colp->Mbuf = (char*)PlugSubAlloc(g, NULL, colp->Long + 1);
- return colp;
- //return (colp->ParseJpath(g)) ? NULL : colp;
+ return new(g) JMGCOL(g, cdp, this, cprec, n);
} // end of MakeCol
/***********************************************************************/
@@ -497,12 +578,12 @@ TDBJGL::TDBJGL(PMGODEF tdp) : TDBCAT(tdp)
Db = tdp->GetTabschema();
} // end of TDBJCL constructor
- /***********************************************************************/
- /* GetResult: Get the list the JSON file columns. */
- /***********************************************************************/
+/***********************************************************************/
+/* GetResult: Get the list the MongoDB collection columns. */
+/***********************************************************************/
PQRYRES TDBJGL::GetResult(PGLOBAL g)
{
- return JSONColumns(g, Db, Uri, Topt, false);
+ return MGOColumns(g, Db, Uri, Topt, false);
} // end of GetResult
- /* -------------------------- End of mongo --------------------------- */
+/* -------------------------- End of mongo --------------------------- */
diff --git a/storage/connect/tabjmg.h b/storage/connect/tabjmg.h
index 323fc0bba48..bf16060a92d 100644
--- a/storage/connect/tabjmg.h
+++ b/storage/connect/tabjmg.h
@@ -9,6 +9,31 @@
#include "jmgoconn.h"
#include "jdbccat.h"
+/***********************************************************************/
+/* Class used to get the columns of a mongo collection. */
+/***********************************************************************/
+class JMGDISC : public MGODISC {
+public:
+ // Constructor
+ JMGDISC(PGLOBAL g, int *lg) : MGODISC(g, lg)
+ { drv = "Java"; Jcp = NULL; columnid = nullptr; }
+
+ // Methods
+ virtual bool Init(PGLOBAL g);
+ virtual void GetDoc(void) {}
+ virtual bool Find(PGLOBAL g);
+
+protected:
+ // Function
+ bool ColDesc(PGLOBAL g, jobject obj, char *pcn, char *pfmt,
+ int ncol, int k);
+
+ // Members
+ JMgoConn *Jcp; // Points to a Mongo connection class
+ jmethodID columnid; // The ColumnDesc method ID
+ jmethodID bvnameid; // The ColDescName method ID
+}; // end of JMGDISC
+
/* -------------------------- TDBJMG class --------------------------- */
/***********************************************************************/
@@ -18,7 +43,7 @@
class DllExport TDBJMG : public TDBEXT {
friend class JMGCOL;
friend class MGODEF;
- friend class MGODISC;
+ friend class JMGDISC;
friend class JAVAConn;
friend PQRYRES MGOColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 2deb3e845c3..b22c69b6948 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -1,5 +1,5 @@
/************* tabjson C++ Program Source Code File (.CPP) *************/
-/* PROGRAM NAME: tabjson Version 1.4 */
+/* PROGRAM NAME: tabjson Version 1.5 */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
/* This program are the JSON class DB execution routines. */
/***********************************************************************/
@@ -35,7 +35,7 @@
#include "jmgfam.h"
#endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
-#include "mongofam.h"
+#include "cmgfam.h"
#endif // MONGO_SUPPORT
#include "tabmul.h"
#include "checklvl.h"
@@ -47,7 +47,6 @@
/***********************************************************************/
#define MAXCOL 200 /* Default max column nb in result */
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
-#define USE_G 1 /* Use recoverable memory if 1 */
/***********************************************************************/
/* External functions. */
@@ -55,6 +54,7 @@
USETEMP UseTemp(void);
bool IsNum(PSZ s);
char *NextChr(PSZ s, char sep);
+char *GetJsonNull(void);
typedef struct _jncol {
struct _jncol *Next;
@@ -199,12 +199,12 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
} else if (tdp->Uri) {
#if defined(MONGO_SUPPORT) || defined(JDBC_SUPPORT)
#if !defined(JDBC_SUPPORT)
- tjnp = new(g) TDBJSN(tdp, new(g) MGOFAM(tdp));
+ tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
#elif !defined(MONGO_SUPPORT)
tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
#else
if (tdp->Driver && toupper(*tdp->Driver) == 'C')
- tjnp = new(g) TDBJSN(tdp, new(g) MGOFAM(tdp));
+ tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
else
tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
#endif
@@ -217,7 +217,6 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
tjnp->SetMode(MODE_READ);
-#if USE_G
// Allocate the parse work memory
PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
memset(G, 0, sizeof(GLOBAL));
@@ -226,9 +225,6 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
PlugSubSet(G, G->Sarea, G->Sarea_Size);
G->jump_level = 0;
tjnp->SetG(G);
-#else
- tjnp->SetG(g);
-#endif
if (tjnp->OpenDB(g))
return NULL;
@@ -560,12 +556,12 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
if (Uri) {
#if defined(MONGO_SUPPORT) || defined(JDBC_SUPPORT)
#if !defined(JDBC_SUPPORT)
- txfp = new(g) MGOFAM(this);
+ txfp = new(g) CMGFAM(this);
#elif !defined(MONGO_SUPPORT)
txfp = new(g) JMGFAM(this);
#else
if (Driver && toupper(*Driver) == 'C')
- txfp = new(g) MGOFAM(this);
+ txfp = new(g) CMGFAM(this);
else
txfp = new(g) JMGFAM(this);
#endif
@@ -602,7 +598,6 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
// Txfp must be set for TDBDOS
tdbp = new(g) TDBJSN(this, txfp);
-#if USE_G
if (Lrecl) {
// Allocate the parse work memory
PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
@@ -616,9 +611,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
strcpy(g->Message, "LRECL is not defined");
return NULL;
} // endif Lrecl
-#else
- ((TDBJSN*)tdbp)->G = g;
-#endif
+
} else {
if (Zipped) {
#if defined(ZIP_SUPPORT)
@@ -903,10 +896,8 @@ int TDBJSN::ReadDB(PGLOBAL g)
// Deferred reading failed
return rc;
-#if USE_G
// Recover the memory used for parsing
PlugSubSet(G, G->Sarea, G->Sarea_Size);
-#endif
if ((Row = ParseJson(G, To_Line, strlen(To_Line), &Pretty, &Comma))) {
Row = FindRow(g);
@@ -915,9 +906,7 @@ int TDBJSN::ReadDB(PGLOBAL g)
M = 1;
rc = RC_OK;
} else if (Pretty != 1 || strcmp(To_Line, "]")) {
-#if USE_G
strcpy(g->Message, G->Message);
-#endif
rc = RC_FX;
} else
rc = RC_EF;
@@ -1030,9 +1019,7 @@ int TDBJSN::WriteDB(PGLOBAL g)
{
int rc = TDBDOS::WriteDB(g);
-#if USE_G
PlugSubSet(G, G->Sarea, G->Sarea_Size);
-#endif
Row->Clear();
return rc;
} // end of WriteDB
@@ -1586,8 +1573,11 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
for (i = 0; i < ars; i++) {
jvrp = arp->GetValue(i);
- do {
- if (n < Nod - 1 && jvrp->GetJson()) {
+ if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) do {
+ if (jvrp->IsNull()) {
+ jvrp->Value = AllocateValue(g, GetJsonNull(), TYPE_STRING);
+ jvp = jvrp;
+ } else if (n < Nod - 1 && jvrp->GetJson()) {
Tjp->NextSame = nextsame;
jval.SetValue(GetColumnValue(g, jvrp->GetJson(), n + 1));
jvp = &jval;
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index 6cdd2993e1f..3ccc43f198d 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -40,7 +40,7 @@ class DllExport JSONDEF : public DOSDEF { /* Table description */
friend class JMGFAM;
#endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
- friend class MGOFAM;
+ friend class CMGFAM;
#endif // MONGO_SUPPORT
friend PQRYRES JSONColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
@@ -93,7 +93,7 @@ class DllExport TDBJSN : public TDBDOS {
friend class JMGFAM;
#endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
- friend class MGOFAM;
+ friend class CMGFAM;
#endif // MONGO_SUPPORT
public:
// Constructor
@@ -163,7 +163,7 @@ class DllExport JSONCOL : public DOSCOL {
friend class JMGFAM;
#endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
- friend class MGOFAM;
+ friend class CMGFAM;
#endif // MONGO_SUPPORT
public:
// Constructors
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index 32119c34900..623c5c466c4 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -111,7 +111,10 @@ bool user_connect::user_init()
int rc= PlugExit(g);
g= NULL;
- free(dup);
+
+ if (dup)
+ free(dup);
+
return true;
} // endif g->
@@ -152,10 +155,14 @@ bool user_connect::CheckCleanup(bool force)
PlugCleanup(g, true);
if (g->Sarea_Size != worksize) {
- if (g->Sarea)
- free(g->Sarea);
+ if (g->Sarea) {
+ if (trace)
+ htrc("CheckCleanup: Free Sarea %d\n", g->Sarea_Size);
+
+ free(g->Sarea);
+ } // endif Size
- // Check whether the work area size was changed
+ // Check whether the work area could be allocated
if (!(g->Sarea = PlugAllocMem(g, worksize))) {
g->Sarea = PlugAllocMem(g, g->Sarea_Size);
SetWorkSize(g->Sarea_Size); // Was too big
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 236c8eaba1b..4ea838b0940 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -119,6 +119,7 @@ ulonglong CharToNumber(const char *p, int n, ulonglong maxval,
if (minus) *minus = true;
} // endif Unsigned
+ // Fall through
case '+':
p++;
break;
@@ -571,7 +572,7 @@ void VALUE::Printf(PGLOBAL g, FILE *f, uint n)
if (Null)
fprintf(f, "%s<null>\n", m);
else
- fprintf(f, strcat(strcat(GetCharString(buf), "\n"), m));
+ fprintf(f, "%s%s\n", m, GetCharString(buf));
} /* end of Printf */
@@ -2566,7 +2567,7 @@ bool DTVAL::SetValue_pval(PVAL valp, bool chktype)
} else if (valp->GetType() == TYPE_BIGINT &&
!(valp->GetBigintValue() % 1000)) {
// Assuming that this timestamp is in milliseconds
- Tval = valp->GetBigintValue() / 1000;
+ Tval = (int)(valp->GetBigintValue() / 1000);
} else
Tval = valp->GetIntValue();