summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2017-05-23 19:35:50 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2017-05-23 19:35:50 +0200
commit3e36eb230b65d53acc8e02b00a024e72ed249425 (patch)
treebe89d99353fc70488a5b43707fac12b960f2f29b /storage
parente8333389c89c946d3794ec9ea708d308318301a3 (diff)
downloadmariadb-git-3e36eb230b65d53acc8e02b00a024e72ed249425.tar.gz
Fix gcc compiler warnings reported by Sergei
modified: storage/connect/array.cpp modified: storage/connect/array.h modified: storage/connect/blkfil.cpp modified: storage/connect/blkfil.h modified: storage/connect/block.h modified: storage/connect/colblk.cpp modified: storage/connect/colblk.h modified: storage/connect/csort.h modified: storage/connect/filamvct.cpp modified: storage/connect/filter.cpp modified: storage/connect/filter.h modified: storage/connect/global.h modified: storage/connect/json.h modified: storage/connect/plgdbsem.h modified: storage/connect/plgdbutl.cpp modified: storage/connect/tabcol.cpp modified: storage/connect/tabcol.h modified: storage/connect/tabdos.cpp modified: storage/connect/tabdos.h modified: storage/connect/tabjson.cpp modified: storage/connect/table.cpp modified: storage/connect/tabodbc.cpp modified: storage/connect/tabodbc.h modified: storage/connect/tabsys.h modified: storage/connect/tabxml.h modified: storage/connect/value.cpp modified: storage/connect/value.h modified: storage/connect/xindex.cpp modified: storage/connect/xindex.h modified: storage/connect/xobject.cpp modified: storage/connect/xobject.h modified: storage/connect/xtable.h Set values as nullable when retrieving catalog info modified: storage/connect/jdbconn.cpp modified: storage/connect/mysql-test/connect/r/odbc_oracle.result modified: storage/connect/odbconn.cpp Change format of Jpath modified: storage/connect/json.cpp modified: storage/connect/jsonudf.cpp modified: storage/connect/mysql-test/connect/r/json.result modified: storage/connect/mysql-test/connect/r/json_udf.result modified: storage/connect/mysql-test/connect/r/json_udf_bin.result modified: storage/connect/mysql-test/connect/r/zip.result modified: storage/connect/mysql-test/connect/t/json.test modified: storage/connect/mysql-test/connect/t/json_udf.test modified: storage/connect/mysql-test/connect/t/json_udf_bin.test modified: storage/connect/mysql-test/connect/t/zip.test modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h modified: storage/connect/tabmgo.cpp Change null representation from ??? to <null> modified: storage/connect/json.cpp Change the name of UDF that are equal to a native JSON function name modified: storage/connect/jsonudf.cpp modified: storage/connect/jsonudf.h modified: storage/connect/mysql-test/connect/t/json_udf.inc modified: storage/connect/mysql-test/connect/t/json_udf2.inc Fix bug in making JSON project info modified: storage/connect/mongofam.cpp Fix COMPUTE when one argument is null modified: storage/connect/value.cpp Value is null only when nullable modified: storage/connect/value.h
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/CMakeLists.txt32
-rw-r--r--storage/connect/array.cpp30
-rw-r--r--storage/connect/array.h4
-rw-r--r--storage/connect/blkfil.cpp32
-rw-r--r--storage/connect/blkfil.h8
-rw-r--r--storage/connect/block.h4
-rw-r--r--storage/connect/catalog.h11
-rw-r--r--storage/connect/colblk.cpp30
-rw-r--r--storage/connect/colblk.h12
-rw-r--r--storage/connect/connect.cc601
-rw-r--r--storage/connect/csort.h4
-rw-r--r--storage/connect/domdoc.cpp20
-rw-r--r--storage/connect/domdoc.h8
-rw-r--r--storage/connect/filamap.cpp21
-rw-r--r--storage/connect/filamdbf.cpp10
-rw-r--r--storage/connect/filamdbf.h4
-rw-r--r--storage/connect/filamfix.cpp3
-rw-r--r--storage/connect/filamgz.cpp4
-rw-r--r--storage/connect/filamtxt.cpp35
-rw-r--r--storage/connect/filamtxt.h2
-rwxr-xr-xstorage/connect/filamvct.cpp109
-rw-r--r--storage/connect/filamvct.h6
-rw-r--r--storage/connect/filamzip.cpp164
-rw-r--r--storage/connect/filamzip.h47
-rw-r--r--storage/connect/filter.cpp123
-rw-r--r--storage/connect/filter.h7
-rw-r--r--storage/connect/global.h10
-rw-r--r--storage/connect/ha_connect.cc1511
-rw-r--r--storage/connect/ha_connect.h34
-rw-r--r--storage/connect/inihandl.c2
-rw-r--r--storage/connect/jdbccat.h20
-rw-r--r--storage/connect/jdbconn.cpp40
-rw-r--r--storage/connect/jdbconn.h30
-rw-r--r--storage/connect/json.cpp386
-rw-r--r--storage/connect/json.h33
-rw-r--r--storage/connect/jsonudf.cpp521
-rw-r--r--storage/connect/jsonudf.h18
-rw-r--r--storage/connect/libdoc.cpp27
-rw-r--r--storage/connect/macutil.cpp2
-rw-r--r--storage/connect/mongofam.cpp815
-rw-r--r--storage/connect/mongofam.h97
-rw-r--r--storage/connect/mycat.cc45
-rw-r--r--storage/connect/mycat.h5
-rw-r--r--storage/connect/myconn.cpp48
-rw-r--r--storage/connect/mysql-test/connect/disabled.def9
-rw-r--r--storage/connect/mysql-test/connect/r/bin.result4
-rw-r--r--storage/connect/mysql-test/connect/r/dir.result1
-rw-r--r--storage/connect/mysql-test/connect/r/grant.result58
-rw-r--r--storage/connect/mysql-test/connect/r/grant2.result79
-rw-r--r--storage/connect/mysql-test/connect/r/ini_grant.result8
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc_new.result4
-rw-r--r--storage/connect/mysql-test/connect/r/json.result148
-rw-r--r--storage/connect/mysql-test/connect/r/json_udf.result370
-rw-r--r--storage/connect/mysql-test/connect/r/json_udf_bin.result200
-rw-r--r--storage/connect/mysql-test/connect/r/mul_new.result136
-rw-r--r--storage/connect/mysql-test/connect/r/mysql_discovery.result13
-rw-r--r--storage/connect/mysql-test/connect/r/mysql_exec.result20
-rw-r--r--storage/connect/mysql-test/connect/r/mysql_grant.result8
-rw-r--r--storage/connect/mysql-test/connect/r/mysql_new.result25
-rw-r--r--storage/connect/mysql-test/connect/r/odbc_oracle.result32
-rw-r--r--storage/connect/mysql-test/connect/r/unsigned.result4
-rw-r--r--storage/connect/mysql-test/connect/r/upd.result2
-rw-r--r--storage/connect/mysql-test/connect/r/vcol.result29
-rw-r--r--storage/connect/mysql-test/connect/r/xml_grant.result10
-rw-r--r--storage/connect/mysql-test/connect/r/xml_mdev5261.result4
-rw-r--r--storage/connect/mysql-test/connect/r/zip.result28
-rw-r--r--storage/connect/mysql-test/connect/t/dir.test1
-rw-r--r--storage/connect/mysql-test/connect/t/jdbc_new.test4
-rw-r--r--storage/connect/mysql-test/connect/t/json.test148
-rw-r--r--storage/connect/mysql-test/connect/t/json_udf.inc4
-rw-r--r--storage/connect/mysql-test/connect/t/json_udf.test174
-rw-r--r--storage/connect/mysql-test/connect/t/json_udf2.inc4
-rw-r--r--storage/connect/mysql-test/connect/t/json_udf_bin.test131
-rw-r--r--storage/connect/mysql-test/connect/t/mul_new.test67
-rw-r--r--storage/connect/mysql-test/connect/t/mysql_new.test2
-rw-r--r--storage/connect/mysql-test/connect/t/secure_file_priv.test2
-rw-r--r--storage/connect/mysql-test/connect/t/unsigned.test4
-rw-r--r--storage/connect/mysql-test/connect/t/upd.test4
-rw-r--r--storage/connect/mysql-test/connect/t/vcol.test26
-rw-r--r--storage/connect/mysql-test/connect/t/zip.test28
-rw-r--r--storage/connect/myutil.cpp21
-rw-r--r--storage/connect/myutil.h8
-rw-r--r--storage/connect/odbccat.h18
-rw-r--r--storage/connect/odbconn.cpp115
-rw-r--r--storage/connect/odbconn.h32
-rw-r--r--storage/connect/os.h3
-rw-r--r--storage/connect/osutil.c52
-rw-r--r--storage/connect/plgdbsem.h21
-rw-r--r--storage/connect/plgdbutl.cpp194
-rw-r--r--storage/connect/plgxml.cpp4
-rw-r--r--storage/connect/plgxml.h12
-rw-r--r--storage/connect/plugutil.cpp (renamed from storage/connect/plugutil.c)39
-rw-r--r--storage/connect/preparse.h4
-rw-r--r--storage/connect/reldef.cpp46
-rw-r--r--storage/connect/reldef.h18
-rw-r--r--storage/connect/tabcol.cpp16
-rw-r--r--storage/connect/tabcol.h8
-rw-r--r--storage/connect/tabdos.cpp100
-rw-r--r--storage/connect/tabdos.h21
-rw-r--r--storage/connect/tabext.cpp106
-rw-r--r--storage/connect/tabext.h36
-rw-r--r--storage/connect/tabfix.cpp42
-rw-r--r--storage/connect/tabfix.h4
-rw-r--r--storage/connect/tabfmt.cpp26
-rw-r--r--storage/connect/tabfmt.h6
-rw-r--r--storage/connect/tabjdbc.cpp202
-rw-r--r--storage/connect/tabjdbc.h59
-rw-r--r--storage/connect/tabjson.cpp922
-rw-r--r--storage/connect/tabjson.h75
-rw-r--r--storage/connect/table.cpp14
-rw-r--r--storage/connect/tabmac.cpp2
-rw-r--r--storage/connect/tabmgo.cpp1480
-rw-r--r--storage/connect/tabmgo.h234
-rw-r--r--storage/connect/tabmul.cpp695
-rw-r--r--storage/connect/tabmul.h66
-rw-r--r--storage/connect/tabmysql.cpp150
-rw-r--r--storage/connect/tabmysql.h24
-rw-r--r--storage/connect/tabodbc.cpp473
-rw-r--r--storage/connect/tabodbc.h71
-rw-r--r--storage/connect/tabpivot.cpp389
-rw-r--r--storage/connect/tabpivot.h18
-rw-r--r--storage/connect/tabsys.cpp44
-rw-r--r--storage/connect/tabsys.h10
-rw-r--r--storage/connect/tabutil.cpp18
-rw-r--r--storage/connect/tabutil.h4
-rw-r--r--storage/connect/tabvct.cpp18
-rw-r--r--storage/connect/tabvir.cpp10
-rw-r--r--storage/connect/tabvir.h2
-rw-r--r--storage/connect/tabwmi.cpp4
-rw-r--r--storage/connect/tabwmi.h2
-rw-r--r--storage/connect/tabxml.cpp79
-rw-r--r--storage/connect/tabxml.h14
-rw-r--r--storage/connect/tabzip.cpp4
-rw-r--r--storage/connect/tabzip.h6
-rw-r--r--storage/connect/valblk.cpp60
-rw-r--r--storage/connect/valblk.h24
-rw-r--r--storage/connect/value.cpp379
-rw-r--r--storage/connect/value.h55
-rwxr-xr-xstorage/connect/xindex.cpp32
-rw-r--r--storage/connect/xindex.h4
-rw-r--r--storage/connect/xobject.cpp37
-rw-r--r--storage/connect/xobject.h14
-rw-r--r--storage/connect/xtable.h74
143 files changed, 7966 insertions, 5520 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index a602084b5bd..141117a6412 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -18,10 +18,10 @@ SET(CONNECT_PLUGIN_DYNAMIC "connect")
SET(CONNECT_SOURCES
ha_connect.cc connect.cc user_connect.cc mycat.cc
-fmdlex.c osutil.c plugutil.c rcmsg.c rcmsg.h
+fmdlex.c osutil.c rcmsg.c rcmsg.h
array.cpp blkfil.cpp colblk.cpp csort.cpp
-filamap.cpp filamdbf.cpp filamfix.cpp filamgz.cpp filamtxt.cpp
-filter.cpp json.cpp jsonudf.cpp maputil.cpp myconn.cpp myutil.cpp plgdbutl.cpp
+filamap.cpp filamdbf.cpp filamfix.cpp filamgz.cpp filamtxt.cpp filter.cpp
+json.cpp jsonudf.cpp maputil.cpp myconn.cpp myutil.cpp plgdbutl.cpp plugutil.cpp
reldef.cpp tabcol.cpp tabdos.cpp tabext.cpp tabfix.cpp tabfmt.cpp tabjson.cpp
table.cpp tabmul.cpp tabmysql.cpp taboccur.cpp tabpivot.cpp tabsys.cpp tabtbl.cpp
tabutil.cpp tabvir.cpp tabxcl.cpp valblk.cpp value.cpp xindex.cpp xobject.cpp
@@ -291,6 +291,31 @@ IF(CONNECT_WITH_ZIP)
add_definitions(-DZIP_SUPPORT -DNOCRYPT)
ENDIF(CONNECT_WITH_ZIP)
+#
+# MONGO (CMAKE NOT YET WORKING)
+#
+
+#OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
+
+#IF(CONNECT_WITH_MONGO)
+# IF(WIN32)
+# # Adding some typical places to search in
+# SET(PC_MONGO_INCLUDE_DIRS
+# C:/mongo-c-driver/include
+# D:/mongo-c-driver/include)
+# SET(PC_MONGO_LIBRARY_DIRS
+# C:/mongo-c-driver/lib
+# D:/mongo-c-driver/lib)
+# ENDIF(WIN32)
+# FIND_PACKAGE(libmongoc)
+# IF (MONGO_FOUND)
+# INCLUDE_DIRECTORIES(${MONGO_INCLUDE_DIR})
+# SET(MONGO_LIBRARY ${MONGO_LIBRARIES})
+# SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongofam.cpp mongofam.h)
+# add_definitions(-DMONGO_SUPPORT)
+# ENDIF(MONGO_FOUND)
+#ENDIF(CONNECT_WITH_MONGO)
+
#
# XMAP
@@ -310,6 +335,7 @@ MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES}
STORAGE_ENGINE
COMPONENT connect-engine
RECOMPILE_FOR_EMBEDDED
+# LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY} $(MONGO_LIBRARY)
LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY}
${ODBC_LIBRARY} ${JDBC_LIBRARY} ${IPHLPAPI_LIBRARY})
diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp
index 1998ab890e9..4b6e1df8e32 100644
--- a/storage/connect/array.cpp
+++ b/storage/connect/array.cpp
@@ -518,8 +518,8 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm)
vp = valp;
} else if (opc != OP_EXIST) {
- sprintf(g->Message, MSG(MISSING_ARG), opc);
- longjmp(g->jumper[g->jump_level], TYPE_ARRAY);
+ sprintf(g->Message, MSG(MISSING_ARG), opc);
+ throw TYPE_ARRAY;
} else // OP_EXIST
return Nval > 0;
@@ -681,15 +681,15 @@ void ARRAY::SetPrecision(PGLOBAL g, int p)
{
if (Vblp == NULL) {
strcpy(g->Message, MSG(PREC_VBLP_NULL));
- longjmp(g->jumper[g->jump_level], TYPE_ARRAY);
+ throw TYPE_ARRAY;
} // endif Vblp
bool was = Vblp->IsCi();
if (was && !p) {
strcpy(g->Message, MSG(BAD_SET_CASE));
- longjmp(g->jumper[g->jump_level], TYPE_ARRAY);
- } // endif Vblp
+ throw TYPE_ARRAY;
+ } // endif Vblp
if (was || !p)
return;
@@ -699,7 +699,7 @@ void ARRAY::SetPrecision(PGLOBAL g, int p)
if (!was && Type == TYPE_STRING)
// Must be resorted to eliminate duplicate strings
if (Sort(g))
- longjmp(g->jumper[g->jump_level], TYPE_ARRAY);
+ throw TYPE_ARRAY;
} // end of SetPrecision
@@ -973,18 +973,18 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm,
PSZ ARRAY::MakeArrayList(PGLOBAL g)
{
char *p, *tp;
- int i;
+ int i;
size_t z, len = 2;
if (Type == TYPE_LIST)
- return "(?" "?" "?)"; // To be implemented
+ return (PSZ)("(?" "?" "?)"); // To be implemented
z = MY_MAX(24, GetTypeSize(Type, Len) + 4);
tp = (char*)PlugSubAlloc(g, NULL, z);
for (i = 0; i < Nval; i++) {
Value->SetValue_pvblk(Vblp, i);
- Value->Print(g, tp, z);
+ Value->Prints(g, tp, z);
len += strlen(tp);
} // enfor i
@@ -996,7 +996,7 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
for (i = 0; i < Nval;) {
Value->SetValue_pvblk(Vblp, i);
- Value->Print(g, tp, z);
+ Value->Prints(g, tp, z);
strcat(p, tp);
strcat(p, (++i == Nval) ? ")" : ",");
} // enfor i
@@ -1010,7 +1010,7 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
/***********************************************************************/
/* Make file output of ARRAY contents. */
/***********************************************************************/
-void ARRAY::Print(PGLOBAL g, FILE *f, uint n)
+void ARRAY::Printf(PGLOBAL g, FILE *f, uint n)
{
char m[64];
int lim = MY_MIN(Nval,10);
@@ -1027,25 +1027,25 @@ void ARRAY::Print(PGLOBAL g, FILE *f, uint n)
if (Vblp)
for (int i = 0; i < lim; i++) {
Value->SetValue_pvblk(Vblp, i);
- Value->Print(g, f, n+4);
+ Value->Printf(g, f, n+4);
} // endfor i
} else
fprintf(f, "%sVALLST: numval=%d\n", m, Nval);
- } // end of Print
+ } // end of Printf
/***********************************************************************/
/* Make string output of ARRAY contents. */
/***********************************************************************/
-void ARRAY::Print(PGLOBAL, char *ps, uint z)
+void ARRAY::Prints(PGLOBAL, char *ps, uint z)
{
if (z < 16)
return;
sprintf(ps, "ARRAY: type=%d\n", Type);
// More to be implemented later
- } // end of Print
+ } // end of Prints
/* -------------------------- Class MULAR ---------------------------- */
diff --git a/storage/connect/array.h b/storage/connect/array.h
index dfc3638de8a..bd38344de06 100644
--- a/storage/connect/array.h
+++ b/storage/connect/array.h
@@ -56,8 +56,8 @@ class DllExport ARRAY : public XOBJECT, public CSORT { // Array descblock
virtual bool Compare(PXOB) {assert(false); return false;}
virtual bool SetFormat(PGLOBAL, FORMAT&) {assert(false); return false;}
//virtual int CheckSpcCol(PTDB, int) {return 0;}
- virtual void Print(PGLOBAL g, FILE *f, uint n);
- virtual void Print(PGLOBAL g, char *ps, uint z);
+ virtual void Printf(PGLOBAL g, FILE *f, uint n);
+ virtual void Prints(PGLOBAL g, char *ps, uint z);
// void Empty(void);
void SetPrecision(PGLOBAL g, int p);
bool AddValue(PGLOBAL g, PSZ sp);
diff --git a/storage/connect/blkfil.cpp b/storage/connect/blkfil.cpp
index 50535d20a3d..802095f2f82 100644
--- a/storage/connect/blkfil.cpp
+++ b/storage/connect/blkfil.cpp
@@ -1,11 +1,11 @@
/************* BlkFil C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: BLKFIL */
/* ------------- */
-/* Version 2.5 */
+/* Version 2.6 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2004-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2004-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -56,7 +56,7 @@ BLOCKFILTER::BLOCKFILTER(PTDBDOS tdbp, int op)
/***********************************************************************/
/* Make file output of BLOCKFILTER contents. */
/***********************************************************************/
-void BLOCKFILTER::Print(PGLOBAL, FILE *f, uint n)
+void BLOCKFILTER::Printf(PGLOBAL, FILE *f, uint n)
{
char m[64];
@@ -65,15 +65,15 @@ void BLOCKFILTER::Print(PGLOBAL, FILE *f, uint n)
fprintf(f, "%sBLOCKFILTER: at %p opc=%d opm=%d result=%d\n",
m, this, Opc, Opm, Result);
- } // end of Print
+ } // end of Printf
/***********************************************************************/
/* Make string output of BLOCKFILTER contents. */
/***********************************************************************/
-void BLOCKFILTER::Print(PGLOBAL, char *ps, uint z)
+void BLOCKFILTER::Prints(PGLOBAL, char *ps, uint z)
{
strncat(ps, "BlockFilter(s)", z);
- } // end of Print
+ } // end of Prints
/* ---------------------- Class BLKFILLOG ---------------------------- */
@@ -412,7 +412,7 @@ void BLKFILMR2::MakeValueBitmap(void)
Void = !Bmp[N]; // There are no good values in the file
for (i = 0; i < N; i++) {
- Bxp[i] = ~0U;
+ Bxp[i] = ~0;
if (noteq)
Bmp[i] = Bxp[i];
@@ -595,8 +595,8 @@ BLKFILIN::BLKFILIN(PGLOBAL g, PTDBDOS tdbp, int op, int opm, PXOB *xp)
if (Colp->GetResultType() != Type) {
sprintf(g->Message, "BLKFILIN: %s", MSG(VALTYPE_NOMATCH));
- longjmp(g->jumper[g->jump_level], 99);
- } else if (Colp->GetValue()->IsCi())
+ throw g->Message;
+ } else if (Colp->GetValue()->IsCi())
Arap->SetPrecision(g, 1); // Case insensitive
Sorted = Colp->IsSorted() > 0;
@@ -708,7 +708,7 @@ void BLKFILIN2::MakeValueBitmap(void)
Void = !Bmp[N]; // There are no good values in the file
for (i = 0; i < N; i++) {
- Bxp[i] = ~0U;
+ Bxp[i] = ~0;
if (noteq) {
Bmp[i] = Bxp[i];
@@ -828,7 +828,7 @@ BLKFILIN2::BLKFILIN2(PGLOBAL g, PTDBDOS tdbp, int op, int opm, PXOB *xp)
Bxp[i] |= btp;
for (N = i--; i >= 0; i--)
- Bxp[i] = ~0U;
+ Bxp[i] = ~0;
break;
} // endif Bmp
@@ -995,7 +995,7 @@ int BLOCKINDEX::BlockEval(PGLOBAL g)
/***********************************************************************/
/* Make file output of BLOCKINDEX contents. */
/***********************************************************************/
-void BLOCKINDEX::Print(PGLOBAL g, FILE *f, UINT n)
+void BLOCKINDEX::Printf(PGLOBAL g, FILE *f, UINT n)
{
char m[64];
@@ -1006,17 +1006,17 @@ void BLOCKINDEX::Print(PGLOBAL g, FILE *f, UINT n)
m, this, Next, (Colp) ? Colp->GetName() : "Rowid", Kxp, Result);
if (Next)
- Next->Print(g, f, n);
+ Next->Printf(g, f, n);
- } // end of Print
+ } // end of Printf
/***********************************************************************/
/* Make string output of BLOCKINDEX contents. */
/***********************************************************************/
-void BLOCKINDEX::Print(PGLOBAL g, char *ps, UINT z)
+void BLOCKINDEX::Prints(PGLOBAL g, char *ps, UINT z)
{
strncat(ps, "BlockIndex(es)", z);
- } // end of Print
+ } // end of Prints
/* ------------------------------------------------------------------- */
diff --git a/storage/connect/blkfil.h b/storage/connect/blkfil.h
index 00b00139042..61b02c53c14 100644
--- a/storage/connect/blkfil.h
+++ b/storage/connect/blkfil.h
@@ -27,8 +27,8 @@ class DllExport BLOCKFILTER : public BLOCK { /* Block Filter */
// Methods
virtual void Reset(PGLOBAL) = 0;
virtual int BlockEval(PGLOBAL) = 0;
- virtual void Print(PGLOBAL g, FILE *f, uint n);
- virtual void Print(PGLOBAL g, char *ps, uint z);
+ virtual void Printf(PGLOBAL g, FILE *f, uint n);
+ virtual void Prints(PGLOBAL g, char *ps, uint z);
protected:
BLOCKFILTER(void) {} // Standard constructor not to be used
@@ -234,8 +234,8 @@ class DllExport BLOCKINDEX : public BLOCK { /* Indexing Test Block */
// Methods
void Reset(void);
virtual int BlockEval(PGLOBAL);
- virtual void Print(PGLOBAL g, FILE *f, UINT n);
- virtual void Print(PGLOBAL g, char *ps, UINT z);
+ virtual void Printf(PGLOBAL g, FILE *f, UINT n);
+ virtual void Prints(PGLOBAL g, char *ps, UINT z);
protected:
BLOCKINDEX(void) {} // Standard constructor not to be used
diff --git a/storage/connect/block.h b/storage/connect/block.h
index aa4edde5ec9..8ac7be80988 100644
--- a/storage/connect/block.h
+++ b/storage/connect/block.h
@@ -44,8 +44,8 @@ class DllExport BLOCK {
return (PlugSubAlloc(g, p, size));
} // end of new
- virtual void Print(PGLOBAL, FILE *, uint) {} // Produce file desc
- virtual void Print(PGLOBAL, char *, uint) {} // Produce string desc
+ virtual void Printf(PGLOBAL, FILE *, uint) {} // Produce file desc
+ virtual void Prints(PGLOBAL, char *, uint) {} // Produce string desc
#if !defined(__BORLANDC__)
// Avoid warning C4291 by defining a matching dummy delete operator
diff --git a/storage/connect/catalog.h b/storage/connect/catalog.h
index 70304c410cc..48347d7519e 100644
--- a/storage/connect/catalog.h
+++ b/storage/connect/catalog.h
@@ -36,7 +36,7 @@ typedef struct _curtab {
/* Defines the structure used to get column catalog info. */
/***********************************************************************/
typedef struct _colinfo {
- char *Name;
+ PCSZ Name;
int Type;
int Offset;
int Length;
@@ -45,9 +45,9 @@ typedef struct _colinfo {
int Scale;
int Opt;
int Freq;
- char *Remark;
- char *Datefmt;
- char *Fieldfmt;
+ PCSZ Remark;
+ PCSZ Datefmt;
+ PCSZ Fieldfmt;
ushort Flags; // Used by MariaDB CONNECT handlers
} COLINFO, *PCOLINFO;
@@ -68,11 +68,9 @@ class DllExport CATALOG {
bool GetDefHuge(void) {return DefHuge;}
void SetDefHuge(bool b) {DefHuge = b;}
char *GetCbuf(void) {return Cbuf;}
-//char *GetDataPath(void) {return (char*)DataPath;}
// Methods
virtual void Reset(void) {}
-//virtual void SetDataPath(PGLOBAL g, const char *path) {}
virtual bool CheckName(PGLOBAL, char*) {return true;}
virtual bool ClearName(PGLOBAL, PSZ) {return true;}
virtual PRELDEF MakeOneTableDesc(PGLOBAL, LPCSTR, LPCSTR) {return NULL;}
@@ -102,7 +100,6 @@ class DllExport CATALOG {
int Cblen; /* Length of suballoc. buffer */
CURTAB Ctb; /* Used to enumerate tables */
bool DefHuge; /* true: tables default to huge */
-//LPCSTR DataPath; /* Is the Path of DB data dir */
}; // end of class CATALOG
#endif // __CATALOG__H
diff --git a/storage/connect/colblk.cpp b/storage/connect/colblk.cpp
index 58841387249..e34c2a7252d 100644
--- a/storage/connect/colblk.cpp
+++ b/storage/connect/colblk.cpp
@@ -195,10 +195,10 @@ int COLBLK::GetLengthEx(void)
/* corresponding to this column and convert it to buffer type. */
/***********************************************************************/
void COLBLK::ReadColumn(PGLOBAL g)
- {
+{
sprintf(g->Message, MSG(UNDEFINED_AM), "ReadColumn");
- longjmp(g->jumper[g->jump_level], TYPE_COLBLK);
- } // end of ReadColumn
+ throw TYPE_COLBLK;
+} // end of ReadColumn
/***********************************************************************/
/* WriteColumn: what this routine does is to access the last line */
@@ -206,15 +206,15 @@ void COLBLK::ReadColumn(PGLOBAL g)
/* corresponding to this column from the column buffer and type. */
/***********************************************************************/
void COLBLK::WriteColumn(PGLOBAL g)
- {
+{
sprintf(g->Message, MSG(UNDEFINED_AM), "WriteColumn");
- longjmp(g->jumper[g->jump_level], TYPE_COLBLK);
- } // end of WriteColumn
+ throw TYPE_COLBLK;
+} // end of WriteColumn
/***********************************************************************/
/* Make file output of a column descriptor block. */
/***********************************************************************/
-void COLBLK::Print(PGLOBAL, FILE *f, uint n)
+void COLBLK::Printf(PGLOBAL, FILE *f, uint n)
{
char m[64];
int i;
@@ -232,15 +232,15 @@ void COLBLK::Print(PGLOBAL, FILE *f, uint n)
fprintf(f,
" coluse=%04X status=%04X buftyp=%d value=%p name=%s\n",
ColUse, Status, Buf_Type, Value, Name);
- } // end of Print
+ } // end of Printf
/***********************************************************************/
/* Make string output of a column descriptor block. */
/***********************************************************************/
-void COLBLK::Print(PGLOBAL, char *ps, uint)
+void COLBLK::Prints(PGLOBAL, char *ps, uint)
{
sprintf(ps, "R%d.%s", To_Tdb->GetTdb_No(), Name);
- } // end of Print
+ } // end of Prints
/***********************************************************************/
@@ -260,10 +260,10 @@ SPCBLK::SPCBLK(PCOLUMN cp)
/* corresponding to this column from the column buffer and type. */
/***********************************************************************/
void SPCBLK::WriteColumn(PGLOBAL g)
- {
+{
sprintf(g->Message, MSG(SPCOL_READONLY), Name);
- longjmp(g->jumper[g->jump_level], TYPE_COLBLK);
- } // end of WriteColumn
+ throw TYPE_COLBLK;
+} // end of WriteColumn
/***********************************************************************/
/* RIDBLK constructor for the ROWID special column. */
@@ -377,7 +377,7 @@ PRTBLK::PRTBLK(PCOLUMN cp) : SPCBLK(cp)
void PRTBLK::ReadColumn(PGLOBAL g)
{
if (Pname == NULL) {
- char *p;
+ const char *p;
Pname = To_Tdb->GetDef()->GetStringCatInfo(g, "partname", "?");
p = strrchr(Pname, '#');
@@ -407,7 +407,7 @@ SIDBLK::SIDBLK(PCOLUMN cp) : SPCBLK(cp)
void SIDBLK::ReadColumn(PGLOBAL)
{
//if (Sname == NULL) {
- Sname = (char*)To_Tdb->GetServer();
+ Sname = To_Tdb->GetServer();
Value->SetValue_psz(Sname);
// } // endif Sname
diff --git a/storage/connect/colblk.h b/storage/connect/colblk.h
index c64f9d95129..608aa040787 100644
--- a/storage/connect/colblk.h
+++ b/storage/connect/colblk.h
@@ -72,8 +72,8 @@ class DllExport COLBLK : public XOBJECT {
virtual void SetTo_Val(PVAL) {}
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
- virtual void Print(PGLOBAL g, FILE *, uint);
- virtual void Print(PGLOBAL g, char *, uint);
+ virtual void Printf(PGLOBAL g, FILE *, uint);
+ virtual void Prints(PGLOBAL g, char *, uint);
virtual bool VarSize(void) {return false;}
bool InitValue(PGLOBAL g);
@@ -154,7 +154,7 @@ class DllExport FIDBLK : public SPCBLK {
virtual void ReadColumn(PGLOBAL g);
protected:
- PSZ Fn; // The current To_File of the table
+ PCSZ Fn; // The current To_File of the table
OPVAL Op; // The file part operator
}; // end of class FIDBLK
@@ -178,7 +178,7 @@ class DllExport TIDBLK : public SPCBLK {
TIDBLK(void) {}
// Members
- PSZ Tname; // The current table name
+ PCSZ Tname; // The current table name
}; // end of class TIDBLK
/***********************************************************************/
@@ -201,7 +201,7 @@ class DllExport PRTBLK : public SPCBLK {
PRTBLK(void) {}
// Members
- PSZ Pname; // The current partition name
+ PCSZ Pname; // The current partition name
}; // end of class PRTBLK
/***********************************************************************/
@@ -224,7 +224,7 @@ class DllExport SIDBLK : public SPCBLK {
SIDBLK(void) {}
// Members
- PSZ Sname; // The current server name
+ PCSZ Sname; // The current server name
}; // end of class SIDBLK
#endif // __COLBLK__H
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 098119e7be1..e15cc724b85 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) Olivier Bertrand 2004 - 2015
+/* Copyright (C) Olivier Bertrand 2004 - 2017
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,10 +15,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/***********************************************************************/
-/* Author Olivier BERTRAND bertrandop@gmail.com 2004-2015 */
+/* Author Olivier BERTRAND bertrandop@gmail.com 2004-2017 */
/* */
-/* WHAT THIS PROGRAM DOES: */
-/* ----------------------- */
+/* WHAT THIS PROGRAM DOES: */
+/* ----------------------- */
/* This program are the CONNECT general purpose semantic routines. */
/***********************************************************************/
#ifdef USE_PRAGMA_IMPLEMENTATION
@@ -117,11 +117,10 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
handler);
// Set the database path for this table
- handler->SetDataPath(g, pathname);
+ if (handler->SetDataPath(g, pathname))
+ return true;
if (dbuserp->Catalog) {
-// ((MYCAT *)dbuserp->Catalog)->SetHandler(handler); done later
-// ((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname);
return false; // Nothing else to do
} // endif Catalog
@@ -138,9 +137,6 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
if (!(dbuserp->Catalog= new MYCAT(handler)))
return true;
-//((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname);
-//dbuserp->UseTemp= TMP_AUTO;
-
/*********************************************************************/
/* All is correct. */
/*********************************************************************/
@@ -172,7 +168,7 @@ bool CntInfo(PGLOBAL g, PTDB tp, PXF info)
// info->mean_rec_length= tdbp->GetLrecl();
info->mean_rec_length= 0;
- info->data_file_name= (b) ? NULL : tdbp->GetFile(g);
+ info->data_file_name= (b) ? NULL : (char*)tdbp->GetFile(g);
return true;
} else {
info->data_file_length= 0;
@@ -188,49 +184,43 @@ bool CntInfo(PGLOBAL g, PTDB tp, PXF info)
/* GetTDB: Get the table description block of a CONNECT table. */
/***********************************************************************/
PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
- {
- int rc;
- PTDB tdbp;
- PTABLE tabp;
- PDBUSER dup= PlgGetUser(g);
- volatile PCATLG cat= (dup) ? dup->Catalog : NULL; // Safe over longjmp
-
- if (trace)
- printf("CntGetTDB: name=%s mode=%d cat=%p\n", name, mode, cat);
+{
+ PTDB tdbp;
+ PTABLE tabp;
+ PDBUSER dup = PlgGetUser(g);
+ volatile PCATLG cat = (dup) ? dup->Catalog : NULL; // Safe over longjmp
- if (!cat)
- return NULL;
+ if (trace)
+ printf("CntGetTDB: name=%s mode=%d cat=%p\n", name, mode, cat);
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return NULL;
- } // endif jump_level
+ if (!cat)
+ return NULL;
- if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
- tdbp= NULL;
- goto err;
- } // endif rc
+ try {
+ // Get table object from the catalog
+ tabp = new(g) XTAB(name);
- // Get table object from the catalog
- tabp= new(g) XTAB(name);
+ if (trace)
+ printf("CntGetTDB: tabp=%p\n", tabp);
- if (trace)
- printf("CntGetTDB: tabp=%p\n", tabp);
+ // Perhaps this should be made thread safe
+ ((MYCAT*)cat)->SetHandler(h);
- // Perhaps this should be made thread safe
- ((MYCAT*)cat)->SetHandler(h);
+ if (!(tdbp = cat->GetTable(g, tabp, mode)))
+ printf("CntGetTDB: %s\n", g->Message);
- if (!(tdbp= cat->GetTable(g, tabp, mode)))
- printf("CntGetTDB: %s\n", g->Message);
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
- err:
if (trace)
printf("Returning tdbp=%p mode=%d\n", tdbp, mode);
- g->jump_level--;
return tdbp;
- } // end of CntGetTDB
+} // end of CntGetTDB
/***********************************************************************/
/* OPENTAB: Open a Table. */
@@ -239,7 +229,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
bool del, PHC)
{
char *p;
- int i, n, rc;
+ int i, n;
bool rcop= true;
PCOL colp;
//PCOLUMN cp;
@@ -254,120 +244,116 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
return true;
} // endif tdbp
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return true;
- } // endif jump_level
-
- if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
- goto err;
- } // endif rc
-
- if (!c1) {
- if (mode == MODE_INSERT)
- // Allocate all column blocks for that table
- tdbp->ColDB(g, NULL, 0);
-
- } else for (p= c1; *p; p+= n) {
- // Allocate only used column blocks
- if (trace)
- printf("Allocating column %s\n", p);
-
- g->Message[0] = 0; // To check whether ColDB made an error message
- colp= tdbp->ColDB(g, p, 0);
-
- if (!colp && !(mode == MODE_INSERT && tdbp->IsSpecial(p))) {
- if (g->Message[0] == 0)
- sprintf(g->Message, MSG(COL_ISNOT_TABLE), p, tdbp->GetName());
-
- goto err;
- } // endif colp
-
- n= strlen(p) + 1;
- } // endfor p
-
- for (i= 0, colp= tdbp->GetColumns(); colp; i++, colp= colp->GetNext()) {
- if (colp->InitValue(g))
- goto err;
-
- if (mode == MODE_INSERT)
- // Allow type conversion
- if (colp->SetBuffer(g, colp->GetValue(), true, false))
- goto err;
-
- colp->AddColUse(U_P); // For PLG tables
- } // endfor colp
-
- /*********************************************************************/
- /* In Update mode, the updated column blocks must be distinct from */
- /* the read column blocks. So make a copy of the TDB and allocate */
- /* its column blocks in mode write (required by XML tables). */
- /*********************************************************************/
- if (mode == MODE_UPDATE) {
- PTDBASE utp;
-
- if (!(utp= (PTDBASE)tdbp->Duplicate(g))) {
- sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName());
- goto err;
- } // endif tp
-
- if (!c2)
- // Allocate all column blocks for that table
- utp->ColDB(g, NULL, 0);
- else for (p= c2; *p; p+= n) {
- // Allocate only used column blocks
- colp= utp->ColDB(g, p, 0);
- n= strlen(p) + 1;
- } // endfor p
-
- for (i= 0, colp= utp->GetColumns(); colp; i++, colp= colp->GetNext()) {
- if (colp->InitValue(g))
- goto err;
-
- if (colp->SetBuffer(g, colp->GetValue(), true, false))
- goto err;
-
- } // endfor colp
-
- // Attach the updated columns list to the main table
- tdbp->SetSetCols(utp->GetColumns());
- } else if (tdbp && mode == MODE_INSERT)
- tdbp->SetSetCols(tdbp->GetColumns());
-
- // Now do open the physical table
- if (trace)
- printf("Opening table %s in mode %d tdbp=%p\n",
- tdbp->GetName(), mode, tdbp);
-
-//tdbp->SetMode(mode);
-
- if (del/* && (tdbp->GetFtype() != RECFM_NAF*/) {
- // To avoid erasing the table when doing a partial delete
- // make a fake Next
+ try {
+ if (!c1) {
+ if (mode == MODE_INSERT)
+ // Allocate all column blocks for that table
+ tdbp->ColDB(g, NULL, 0);
+
+ } else for (p = c1; *p; p += n) {
+ // Allocate only used column blocks
+ if (trace)
+ printf("Allocating column %s\n", p);
+
+ g->Message[0] = 0; // To check whether ColDB made an error message
+ colp = tdbp->ColDB(g, p, 0);
+
+ if (!colp && !(mode == MODE_INSERT && tdbp->IsSpecial(p))) {
+ if (g->Message[0] == 0)
+ sprintf(g->Message, MSG(COL_ISNOT_TABLE), p, tdbp->GetName());
+
+ throw 1;
+ } // endif colp
+
+ n = strlen(p) + 1;
+ } // endfor p
+
+ for (i = 0, colp = tdbp->GetColumns(); colp; i++, colp = colp->GetNext()) {
+ if (colp->InitValue(g))
+ throw 2;
+
+ if (mode == MODE_INSERT)
+ // Allow type conversion
+ if (colp->SetBuffer(g, colp->GetValue(), true, false))
+ throw 3;
+
+ colp->AddColUse(U_P); // For PLG tables
+ } // endfor colp
+
+ /*******************************************************************/
+ /* In Update mode, the updated column blocks must be distinct from */
+ /* the read column blocks. So make a copy of the TDB and allocate */
+ /* its column blocks in mode write (required by XML tables). */
+ /*******************************************************************/
+ if (mode == MODE_UPDATE) {
+ PTDBASE utp;
+
+ if (!(utp = (PTDBASE)tdbp->Duplicate(g))) {
+ sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName());
+ throw 4;
+ } // endif tp
+
+ if (!c2)
+ // Allocate all column blocks for that table
+ utp->ColDB(g, NULL, 0);
+ else for (p = c2; *p; p += n) {
+ // Allocate only used column blocks
+ colp = utp->ColDB(g, p, 0);
+ n = strlen(p) + 1;
+ } // endfor p
+
+ for (i = 0, colp = utp->GetColumns(); colp; i++, colp = colp->GetNext()) {
+ if (colp->InitValue(g))
+ throw 5;
+
+ if (colp->SetBuffer(g, colp->GetValue(), true, false))
+ throw 6;
+
+ } // endfor colp
+
+ // Attach the updated columns list to the main table
+ tdbp->SetSetCols(utp->GetColumns());
+ } else if (tdbp && mode == MODE_INSERT)
+ tdbp->SetSetCols(tdbp->GetColumns());
+
+ // Now do open the physical table
+ if (trace)
+ printf("Opening table %s in mode %d tdbp=%p\n",
+ tdbp->GetName(), mode, tdbp);
+
+ //tdbp->SetMode(mode);
+
+ if (del/* && (tdbp->GetFtype() != RECFM_NAF*/) {
+ // To avoid erasing the table when doing a partial delete
+ // make a fake Next
// PDOSDEF ddp= new(g) DOSDEF;
// PTDB tp= new(g) TDBDOS(ddp, NULL);
- tdbp->SetNext((PTDB)1);
- dup->Check &= ~CHK_DELETE;
- } // endif del
+ tdbp->SetNext((PTDB)1);
+ dup->Check &= ~CHK_DELETE;
+ } // endif del
- if (trace)
- printf("About to open the table: tdbp=%p\n", tdbp);
+ if (trace)
+ printf("About to open the table: tdbp=%p\n", tdbp);
- if (mode != MODE_ANY && mode != MODE_ALTER) {
- if (tdbp->OpenDB(g)) {
- printf("%s\n", g->Message);
- goto err;
- } else
- tdbp->SetNext(NULL);
+ if (mode != MODE_ANY && mode != MODE_ALTER) {
+ if (tdbp->OpenDB(g)) {
+ printf("%s\n", g->Message);
+ throw 7;
+ } else
+ tdbp->SetNext(NULL);
+
+ } // endif mode
- } // endif mode
+ rcop = false;
- rcop= false;
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
- err:
- g->jump_level--;
return rcop;
} // end of CntOpenTable
@@ -387,50 +373,40 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp)
/* Evaluate all columns after a record is read. */
/***********************************************************************/
RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool reset, bool mrr)
- {
+{
RCODE rc= RC_OK;
PCOL colp;
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- if (trace) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- printf("EvalColumns: %s\n", g->Message);
- } // endif
-
- return RC_FX;
- } // endif jump_level
-
- if (setjmp(g->jumper[++g->jump_level]) != 0) {
- if (trace)
- printf("Error reading columns: %s\n", g->Message);
+ try {
+ for (colp = tdbp->GetColumns(); rc == RC_OK && colp;
+ colp = colp->GetNext()) {
+ if (reset)
+ colp->Reset();
- rc= RC_FX;
- goto err;
- } // endif rc
+ // Virtual columns are computed by MariaDB
+ if (!colp->GetColUse(U_VIRTUAL) && (!mrr || colp->GetKcol()))
+ if (colp->Eval(g))
+ rc = RC_FX;
- for (colp= tdbp->GetColumns(); rc == RC_OK && colp;
- colp= colp->GetNext()) {
- if (reset)
- colp->Reset();
+ } // endfor colp
- // Virtual columns are computed by MariaDB
- if (!colp->GetColUse(U_VIRTUAL) && (!mrr || colp->GetKcol()))
- if (colp->Eval(g))
- rc= RC_FX;
+ } catch (int n) {
+ if (trace)
+ printf("Error %d reading columns: %s\n", n, g->Message);
- } // endfor colp
+ rc = RC_FX;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
- err:
- g->jump_level--;
return rc;
- } // end of EvalColumns
+} // end of EvalColumns
/***********************************************************************/
/* ReadNext: Read next record sequentially. */
/***********************************************************************/
RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
- {
+{
RCODE rc;
if (!tdbp)
@@ -445,76 +421,66 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
((PTDBASE)tdbp)->ResetKindex(g, NULL);
} // endif index
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return RC_FX;
- } // endif jump_level
-
- if ((setjmp(g->jumper[++g->jump_level])) != 0) {
- rc= RC_FX;
- goto err;
- } // endif rc
+ try {
+ // Do it now to avoid double eval when filtering
+ for (PCOL colp = tdbp->GetColumns(); colp; colp = colp->GetNext())
+ colp->Reset();
- // Do it now to avoid double eval when filtering
- for (PCOL colp= tdbp->GetColumns(); colp; colp= colp->GetNext())
- colp->Reset();
+ do {
+ if ((rc = (RCODE)tdbp->ReadDB(g)) == RC_OK)
+ if (!ApplyFilter(g, tdbp->GetFilter()))
+ rc = RC_NF;
- do {
- if ((rc= (RCODE)tdbp->ReadDB(g)) == RC_OK)
- if (!ApplyFilter(g, tdbp->GetFilter()))
- rc= RC_NF;
+ } while (rc == RC_NF);
- } while (rc == RC_NF);
+ if (rc == RC_OK)
+ rc = EvalColumns(g, tdbp, false);
- if (rc == RC_OK)
- rc= EvalColumns(g, tdbp, false);
+ } catch (int) {
+ rc = RC_FX;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ rc = RC_FX;
+ } // end catch
- err:
- g->jump_level--;
return rc;
- } // end of CntReadNext
+} // end of CntReadNext
/***********************************************************************/
/* WriteRow: Insert a new row into a table. */
/***********************************************************************/
RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
- {
- RCODE rc;
- PCOL colp;
-//PTDBASE tp= (PTDBASE)tdbp;
-
- if (!tdbp)
- return RC_FX;
-
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return RC_FX;
- } // endif jump_level
-
- if (setjmp(g->jumper[++g->jump_level]) != 0) {
- printf("%s\n", g->Message);
- rc= RC_FX;
- goto err;
- } // endif rc
-
- // Store column values in table write buffer(s)
- for (colp= tdbp->GetSetCols(); colp; colp= colp->GetNext())
- if (!colp->GetColUse(U_VIRTUAL))
- colp->WriteColumn(g);
-
- if (tdbp->IsIndexed())
- // Index values must be sorted before updating
- rc= (RCODE)((PTDBDOS)tdbp)->GetTxfp()->StoreValues(g, true);
- else
- // Return result code from write operation
- rc= (RCODE)tdbp->WriteDB(g);
-
- err:
- g->jump_level--;
- return rc;
- } // end of CntWriteRow
+{
+ RCODE rc;
+ PCOL colp;
+ //PTDBASE tp= (PTDBASE)tdbp;
+
+ if (!tdbp)
+ return RC_FX;
+
+ try {
+ // Store column values in table write buffer(s)
+ for (colp = tdbp->GetSetCols(); colp; colp = colp->GetNext())
+ if (!colp->GetColUse(U_VIRTUAL))
+ colp->WriteColumn(g);
+
+ if (tdbp->IsIndexed())
+ // Index values must be sorted before updating
+ rc = (RCODE)((PTDBDOS)tdbp)->GetTxfp()->StoreValues(g, true);
+ else
+ // Return result code from write operation
+ rc = (RCODE)tdbp->WriteDB(g);
+
+ } catch (int n) {
+ printf("Exception %d: %s\n", n, g->Message);
+ rc = RC_FX;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ rc = RC_FX;
+ } // end catch
+
+ return rc;
+} // end of CntWriteRow
/***********************************************************************/
/* UpdateRow: Update a row into a table. */
@@ -562,88 +528,78 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
/* CLOSETAB: Close a table. */
/***********************************************************************/
int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
- {
- int rc= RC_OK;
-//TDBASE *tbxp= (PTDBASE)tdbp;
-
- if (!tdbp)
- return rc; // Nothing to do
- else if (tdbp->GetUse() != USE_OPEN) {
- if (tdbp->GetAmType() == TYPE_AM_XML)
- tdbp->CloseDB(g); // Opened by GetMaxSize
-
- return rc;
- } // endif !USE_OPEN
-
- if (trace)
- printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n",
- tdbp, tdbp->GetMode(), nox, abort);
-
- if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) {
- if (tdbp->IsIndexed())
- rc= ((PTDBDOS)tdbp)->GetTxfp()->DeleteSortedRows(g);
-
- if (!rc)
- rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
-
- } else if (tdbp->GetMode() == MODE_UPDATE && tdbp->IsIndexed())
- rc= ((PTDBDOX)tdbp)->Txfp->UpdateSortedRows(g);
-
- switch(rc) {
- case RC_FX:
- abort= true;
- break;
- case RC_INFO:
- PushWarning(g, tdbp);
- break;
- } // endswitch rc
-
- // Prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- rc= RC_FX;
- goto err;
- } // endif
-
- if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) {
- rc= RC_FX;
- g->jump_level--;
- goto err;
- } // endif
-
- // This will close the table file(s) and also finalize write
- // operations such as Insert, Update, or Delete.
- tdbp->SetAbort(abort);
- tdbp->CloseDB(g);
- tdbp->SetAbort(false);
- g->jump_level--;
-
- if (trace > 1)
- printf("Table %s closed\n", tdbp->GetName());
-
-//if (!((PTDBDOX)tdbp)->GetModified())
-// return 0;
-
- if (nox || tdbp->GetMode() == MODE_READ || tdbp->GetMode() == MODE_ANY)
- return 0;
-
- if (trace > 1)
- printf("About to reset opt\n");
-
- if (!tdbp->IsRemote()) {
- // Make all the eventual indexes
- PTDBDOX tbxp = (PTDBDOX)tdbp;
- tbxp->ResetKindex(g, NULL);
- tbxp->SetKey_Col(NULL);
- rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1);
- } // endif remote
-
- err:
- if (trace > 1)
- printf("Done rc=%d\n", rc);
-
- return (rc == RC_OK || rc == RC_INFO) ? 0 : rc;
- } // end of CntCloseTable
+{
+ int rc = RC_OK;
+ //TDBASE *tbxp= (PTDBASE)tdbp;
+
+ if (!tdbp)
+ return rc; // Nothing to do
+ else if (tdbp->GetUse() != USE_OPEN) {
+ if (tdbp->GetAmType() == TYPE_AM_XML)
+ tdbp->CloseDB(g); // Opened by GetMaxSize
+
+ return rc;
+ } // endif !USE_OPEN
+
+ if (trace)
+ printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n",
+ tdbp, tdbp->GetMode(), nox, abort);
+
+ if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) {
+ if (tdbp->IsIndexed())
+ rc = ((PTDBDOS)tdbp)->GetTxfp()->DeleteSortedRows(g);
+
+ if (!rc)
+ rc = tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
+
+ } else if (tdbp->GetMode() == MODE_UPDATE && tdbp->IsIndexed())
+ rc = ((PTDBDOX)tdbp)->Txfp->UpdateSortedRows(g);
+
+ switch (rc) {
+ case RC_FX:
+ abort = true;
+ break;
+ case RC_INFO:
+ PushWarning(g, tdbp);
+ break;
+ } // endswitch rc
+
+ try {
+ // This will close the table file(s) and also finalize write
+ // operations such as Insert, Update, or Delete.
+ tdbp->SetAbort(abort);
+ tdbp->CloseDB(g);
+ tdbp->SetAbort(false);
+
+ if (trace > 1)
+ printf("Table %s closed\n", tdbp->GetName());
+
+ if (!nox && tdbp->GetMode() != MODE_READ && tdbp->GetMode() != MODE_ANY) {
+ if (trace > 1)
+ printf("About to reset opt\n");
+
+ if (!tdbp->IsRemote()) {
+ // Make all the eventual indexes
+ PTDBDOX tbxp = (PTDBDOX)tdbp;
+ tbxp->ResetKindex(g, NULL);
+ tbxp->SetKey_Col(NULL);
+ rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1);
+ } // endif remote
+
+ } // endif nox
+
+ } catch (int) {
+ rc = RC_FX;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ rc = RC_FX;
+ } // end catch
+
+ if (trace > 1)
+ htrc("Done rc=%d\n", rc);
+
+ return (rc == RC_OK || rc == RC_INFO) ? 0 : rc;
+} // end of CntCloseTable
/***********************************************************************/
/* Load and initialize the use of an index. */
@@ -752,8 +708,9 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName());
return RC_FX;
} else if (x == 2) {
- // Remote index
- if (op != OP_SAME && ptdb->ReadKey(g, op, kr))
+ // Remote index. Only used in read mode
+ if ((ptdb->GetMode() == MODE_READ || ptdb->GetMode() == MODE_READX)
+ && op != OP_SAME && ptdb->ReadKey(g, op, kr))
return RC_FX;
goto rnd;
diff --git a/storage/connect/csort.h b/storage/connect/csort.h
index 55ff6268a4b..6e700059881 100644
--- a/storage/connect/csort.h
+++ b/storage/connect/csort.h
@@ -49,8 +49,8 @@ class DllExport CSORT {
public:
// Methods
int Qsort(PGLOBAL g, int n); /* Sort calling routine */
-//virtual void Print(PGLOBAL g, FILE *f, uint n);
-//virtual void Print(PGLOBAL g, char *ps, uint z);
+//virtual void Printf(PGLOBAL g, FILE *f, uint n);
+//virtual void Prints(PGLOBAL g, char *ps, uint z);
#ifdef DEBTRACE
int GetNcmp(void) {return num_comp;}
#endif
diff --git a/storage/connect/domdoc.cpp b/storage/connect/domdoc.cpp
index 1622ec16c68..e24e10835c1 100644
--- a/storage/connect/domdoc.cpp
+++ b/storage/connect/domdoc.cpp
@@ -58,13 +58,15 @@ void CloseXMLFile(PGLOBAL g, PFBLOCK fp, bool all)
if (xp && xp->Count > 1 && !all) {
xp->Count--;
} else if (xp && xp->Count > 0) {
- try {
+ try {
if (xp->Docp)
xp->Docp->Release();
- } catch(_com_error e) {
- sprintf(g->Message, "%s %s", MSG(COM_ERROR), e.Description());
- } catch(...) {}
+ } catch(_com_error e) {
+ char *p = _com_util::ConvertBSTRToString(e.Description());
+ sprintf(g->Message, "%s %s", MSG(COM_ERROR), p);
+ delete[] p;
+ } catch(...) {}
CoUninitialize();
xp->Count = 0;
@@ -89,7 +91,7 @@ DOMDOC::DOMDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
/******************************************************************/
/* Initialize XML parser and check library compatibility. */
/******************************************************************/
-bool DOMDOC::Initialize(PGLOBAL g, char *entry, bool zipped)
+bool DOMDOC::Initialize(PGLOBAL g, PCSZ entry, bool zipped)
{
if (zipped && InitZip(g, entry))
return true;
@@ -155,7 +157,7 @@ PFBLOCK DOMDOC::LinkXblock(PGLOBAL g, MODE m, int rc, char *fn)
/******************************************************************/
/* Create the XML node. */
/******************************************************************/
-bool DOMDOC::NewDoc(PGLOBAL g, char *ver)
+bool DOMDOC::NewDoc(PGLOBAL g, PCSZ ver)
{
char buf[64];
MSXML2::IXMLDOMProcessingInstructionPtr pip;
@@ -490,9 +492,9 @@ PXATTR DOMNODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap)
/******************************************************************/
/* Add a new element child node to this node and return it. */
/******************************************************************/
-PXNODE DOMNODE::AddChildNode(PGLOBAL g, char *name, PXNODE np)
+PXNODE DOMNODE::AddChildNode(PGLOBAL g, PCSZ name, PXNODE np)
{
- char *p, *pn;
+ const char *p, *pn;
// char *p, *pn, *epf, *pf = NULL;
MSXML2::IXMLDOMNodePtr ep;
// _bstr_t uri((wchar_t*)NULL);
@@ -585,7 +587,7 @@ PXATTR DOMNODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
/******************************************************************/
/* Add a new text node to this node. */
/******************************************************************/
-void DOMNODE::AddText(PGLOBAL g, char *txtp)
+void DOMNODE::AddText(PGLOBAL g, PCSZ txtp)
{
MSXML2::IXMLDOMTextPtr tp= Docp->createTextNode((_bstr_t)txtp);
diff --git a/storage/connect/domdoc.h b/storage/connect/domdoc.h
index 7f269002d59..dd8936097e2 100644
--- a/storage/connect/domdoc.h
+++ b/storage/connect/domdoc.h
@@ -37,9 +37,9 @@ class DOMDOC : public XMLDOCUMENT {
virtual void SetNofree(bool b) {} // Only libxml2
// Methods
- virtual bool Initialize(PGLOBAL g, char *entry, bool zipped);
+ virtual bool Initialize(PGLOBAL g, PCSZ entry, bool zipped);
virtual bool ParseFile(PGLOBAL g, char *fn);
- virtual bool NewDoc(PGLOBAL g, char *ver);
+ virtual bool NewDoc(PGLOBAL g, PCSZ ver);
virtual void AddComment(PGLOBAL g, char *com);
virtual PXNODE GetRoot(PGLOBAL g);
virtual PXNODE NewRoot(PGLOBAL g, char *name);
@@ -78,9 +78,9 @@ class DOMNODE : public XMLNODE {
virtual PXLIST SelectNodes(PGLOBAL g, char *xp, PXLIST lp);
virtual PXNODE SelectSingleNode(PGLOBAL g, char *xp, PXNODE np);
virtual PXATTR GetAttribute(PGLOBAL g, char *name, PXATTR ap);
- virtual PXNODE AddChildNode(PGLOBAL g, char *name, PXNODE np);
+ virtual PXNODE AddChildNode(PGLOBAL g, PCSZ name, PXNODE np);
virtual PXATTR AddProperty(PGLOBAL g, char *name, PXATTR ap);
- virtual void AddText(PGLOBAL g, char *txtp);
+ virtual void AddText(PGLOBAL g, PCSZ txtp);
virtual void DeleteChild(PGLOBAL g, PXNODE dnp);
protected:
diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp
index 8fffaca3d06..84dff422db7 100644
--- a/storage/connect/filamap.cpp
+++ b/storage/connect/filamap.cpp
@@ -301,10 +301,9 @@ int MAPFAM::SkipRecord(PGLOBAL g, bool header)
PDBUSER dup = (PDBUSER)g->Activityp->Aptr;
// Skip this record
- while (*Mempos++ != '\n') ; // What about Unix ???
-
- if (Mempos >= Top)
- return RC_EF;
+ while (*Mempos++ != '\n') // What about Unix ???
+ if (Mempos == Top)
+ return RC_EF;
// Update progress information
dup->ProgCur = GetPos();
@@ -320,7 +319,7 @@ int MAPFAM::SkipRecord(PGLOBAL g, bool header)
/***********************************************************************/
int MAPFAM::ReadBuffer(PGLOBAL g)
{
- int rc, len;
+ int rc, len, n = 1;
// Are we at the end of the memory
if (Mempos >= Top) {
@@ -362,10 +361,14 @@ int MAPFAM::ReadBuffer(PGLOBAL g)
Placed = false;
// Immediately calculate next position (Used by DeleteDB)
- while (*Mempos++ != '\n') ; // What about Unix ???
+ while (*Mempos++ != '\n') // What about Unix ???
+ if (Mempos == Top) {
+ n = 0;
+ break;
+ } // endif Mempos
// Set caller line buffer
- len = (Mempos - Fpos) - 1;
+ len = (Mempos - Fpos) - n;
// Don't rely on ENDING setting
if (len > 0 && *(Mempos - 2) == '\r')
@@ -619,7 +622,9 @@ int MBKFAM::ReadBuffer(PGLOBAL g)
} // endif's
// Immediately calculate next position (Used by DeleteDB)
- while (*Mempos++ != '\n') ; // What about Unix ???
+ while (*Mempos++ != '\n') // What about Unix ???
+ if (Mempos == Top)
+ break;
// Set caller line buffer
len = (Mempos - Fpos) - Ending;
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index 55feaa02bc4..8878f2c922b 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -128,7 +128,7 @@ typedef struct _descriptor {
/* Moves file pointer to byte 32; fills buffer at buf with */
/* first 32 bytes of file. */
/****************************************************************************/
-static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf)
+static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf)
{
char endmark[2];
int dbc = 2, rc = RC_OK;
@@ -186,7 +186,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf)
/* DBFColumns: constructs the result blocks containing the description */
/* of all the columns of a DBF file that will be retrieved by #GetData. */
/****************************************************************************/
-PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, bool info)
+PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
{
int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_INT, TYPE_INT, TYPE_SHORT};
@@ -393,7 +393,7 @@ DBFBASE::DBFBASE(DBFBASE *txfp)
/* and header length. Set Records, check that Reclen is equal to lrecl and */
/* return the header length or 0 in case of error. */
/****************************************************************************/
-int DBFBASE::ScanHeader(PGLOBAL g, PSZ fn, int lrecl, int *rln, char *defpath)
+int DBFBASE::ScanHeader(PGLOBAL g, PCSZ fn, int lrecl, int *rln, PCSZ defpath)
{
int rc;
char filename[_MAX_PATH];
@@ -694,7 +694,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
} // endif Headlen
/**************************************************************************/
- /* Position the file at the beginning of the data. */
+ /* Position the file at the begining of the data. */
/**************************************************************************/
if (Tdbp->GetMode() == MODE_INSERT)
rc = fseek(Stream, 0, SEEK_END);
@@ -1034,7 +1034,7 @@ bool DBMFAM::AllocateBuffer(PGLOBAL g)
} // endif Headlen
/**************************************************************************/
- /* Position the file at the beginning of the data. */
+ /* Position the file at the begining of the data. */
/**************************************************************************/
Fpos = Mempos = Memory + Headlen;
Top--; // Because of EOF marker
diff --git a/storage/connect/filamdbf.h b/storage/connect/filamdbf.h
index 66458a10eaa..640fc349b4c 100644
--- a/storage/connect/filamdbf.h
+++ b/storage/connect/filamdbf.h
@@ -19,7 +19,7 @@ typedef class DBMFAM *PDBMFAM;
/****************************************************************************/
/* Functions used externally. */
/****************************************************************************/
-PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, bool info);
+PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info);
/****************************************************************************/
/* This is the base class for dBASE file access methods. */
@@ -31,7 +31,7 @@ class DllExport DBFBASE {
DBFBASE(PDBF txfp);
// Implementation
- int ScanHeader(PGLOBAL g, PSZ fname, int lrecl, int *rlen, char *defpath);
+ int ScanHeader(PGLOBAL g, PCSZ fname, int lrecl, int *rlen, PCSZ defpath);
protected:
// Default constructor, not to be used
diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp
index cd25429318a..962a4516bf2 100644
--- a/storage/connect/filamfix.cpp
+++ b/storage/connect/filamfix.cpp
@@ -761,7 +761,8 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
htrc("after write req=%d brc=%d nbw=%d\n", req, brc, nbw);
if (!brc || nbw != len) {
- char buf[256], *fn = (h == Hfile) ? To_File : "Tempfile";
+ char buf[256];
+ PCSZ fn = (h == Hfile) ? To_File : "Tempfile";
if (brc)
strcpy(buf, MSG(BAD_BYTE_NUM));
diff --git a/storage/connect/filamgz.cpp b/storage/connect/filamgz.cpp
index dc6f277ee27..df366ef15f9 100644
--- a/storage/connect/filamgz.cpp
+++ b/storage/connect/filamgz.cpp
@@ -920,8 +920,8 @@ int ZLBFAM::GetFileLength(PGLOBAL g)
/***********************************************************************/
bool ZLBFAM::AllocateBuffer(PGLOBAL g)
{
- char *msg;
- int n, zrc;
+ PCSZ msg;
+ int n, zrc;
#if 0
if (!Optimized && Tdbp->NeedIndexing(g)) {
diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp
index e53cdcd9ba9..382af51aae4 100644
--- a/storage/connect/filamtxt.cpp
+++ b/storage/connect/filamtxt.cpp
@@ -1,11 +1,11 @@
/*********** File AM Txt C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: FILAMTXT */
/* ------------- */
-/* Version 1.6 */
+/* Version 1.7 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -71,8 +71,23 @@ TXTFAM::TXTFAM(PDOSDEF tdp)
{
Tdbp = NULL;
To_Fb = NULL;
- To_File = tdp->Fn;
- Lrecl = tdp->Lrecl;
+
+ if (tdp) {
+ To_File = tdp->Fn;
+ Lrecl = tdp->Lrecl;
+ Eof = tdp->Eof;
+ Ending = tdp->Ending;
+ } else {
+ To_File = NULL;
+ Lrecl = 0;
+ Eof = false;
+#if defined(__WIN__)
+ Ending = 2;
+#else
+ Ending = 1;
+#endif
+ } // endif tdp
+
Placed = false;
IsRead = true;
Blocked = false;
@@ -103,8 +118,6 @@ TXTFAM::TXTFAM(PDOSDEF tdp)
Blksize = 0;
Fpos = Spos = Tpos = 0;
Padded = false;
- Eof = tdp->Eof;
- Ending = tdp->Ending;
Abort = false;
CrLf = (char*)(Ending == 1 ? "\n" : "\r\n");
} // end of TXTFAM standard constructor
@@ -973,7 +986,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
} else {
/*****************************************************************/
- /* Move of eventual preceding lines is not required here. */
+ /* Move of eventual preceding lines is not required here. */
/* Set the target file as being the source file itself. */
/* Set the future Tpos, and give Spos a value to block copying. */
/*****************************************************************/
@@ -1161,13 +1174,13 @@ int DOSFAM::RenameTempFile(PGLOBAL g)
if (rename(filename, filetemp)) { // Save file for security
sprintf(g->Message, MSG(RENAME_ERROR),
filename, filetemp, strerror(errno));
- longjmp(g->jumper[g->jump_level], 51);
- } else if (rename(tempname, filename)) {
+ throw 51;
+ } else if (rename(tempname, filename)) {
sprintf(g->Message, MSG(RENAME_ERROR),
tempname, filename, strerror(errno));
rc = rename(filetemp, filename); // Restore saved file
- longjmp(g->jumper[g->jump_level], 52);
- } else if (remove(filetemp)) {
+ throw 52;
+ } else if (remove(filetemp)) {
sprintf(g->Message, MSG(REMOVE_ERROR),
filetemp, strerror(errno));
rc = RC_INFO; // Acceptable
diff --git a/storage/connect/filamtxt.h b/storage/connect/filamtxt.h
index ae8f74a9830..1fdae8fcd37 100644
--- a/storage/connect/filamtxt.h
+++ b/storage/connect/filamtxt.h
@@ -80,7 +80,7 @@ class DllExport TXTFAM : public BLOCK {
protected:
// Members
PTDBDOS Tdbp; // To table class
- PSZ To_File; // Points to table file name
+ PCSZ To_File; // Points to table file name
PFBLOCK To_Fb; // Pointer to file block
PPARM To_Pos; // Pointer to position list
PPARM To_Sos; // Pointer to start position list
diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp
index fdc5433f4a4..62577009766 100755
--- a/storage/connect/filamvct.cpp
+++ b/storage/connect/filamvct.cpp
@@ -5,7 +5,7 @@
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -143,9 +143,9 @@ int VCTFAM::GetFileLength(PGLOBAL g)
{
if (Split) {
// Get the total file length
- char filename[_MAX_PATH];
- char *savfile = To_File;
- int i, len = 0;
+ char filename[_MAX_PATH];
+ PCSZ savfile = To_File;
+ int i, len = 0;
// Initialize the array of file structures
if (!Colfn) {
@@ -313,8 +313,8 @@ int VCTFAM::Cardinality(PGLOBAL g)
// and Last must be set from the file cardinality.
// Only happens when called by sub classes.
char filename[_MAX_PATH];
- PSZ savfn = To_File;
- int len, clen, card = -1;
+ PCSZ savfn = To_File;
+ int len, clen, card = -1;
PCOLDEF cdp = Tdbp->GetDef()->GetCols();
if (!Colfn) {
@@ -368,7 +368,7 @@ int VCTFAM::GetRowID(void)
/***********************************************************************/
/* VCT Create an empty file for Vector formatted tables. */
/***********************************************************************/
-bool VCTFAM::MakeEmptyFile(PGLOBAL g, char *fn)
+bool VCTFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn)
{
// Vector formatted file: this will create an empty file of the
// required length if it does not exists yet.
@@ -559,41 +559,42 @@ bool VCTFAM::AllocateBuffer(PGLOBAL g)
/* Do initial action when inserting. */
/***********************************************************************/
bool VCTFAM::InitInsert(PGLOBAL g)
- {
+{
+ bool rc = false;
+
// We come here in MODE_INSERT only
if (Last == Nrec) {
CurBlk = Block;
CurNum = 0;
AddBlock = !MaxBlk;
} else {
- int rc;
PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
// The starting point must be at the end of file as for append.
CurBlk = Block - 1;
CurNum = Last;
- // Prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return true;
- } // endif
+ try {
+ // Last block must be updated by new values
+ for (; cp; cp = (PVCTCOL)cp->Next)
+ cp->ReadBlock(g);
- if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) {
- g->jump_level--;
- return true;
- } // endif
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ rc = true;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ rc = true;
+ } // end catch
- // Last block must be updated by new values
- for (; cp; cp = (PVCTCOL)cp->Next)
- cp->ReadBlock(g);
-
- g->jump_level--;
} // endif Last
- // We are not currently using a temporary file for Insert
- T_Stream = Stream;
- return false;
+ if (!rc)
+ // We are not currently using a temporary file for Insert
+ T_Stream = Stream;
+
+ return rc;
} // end of InitInsert
/***********************************************************************/
@@ -878,8 +879,9 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/
bool VCTFAM::OpenTempFile(PGLOBAL g)
{
- char *opmode, tempname[_MAX_PATH];
- bool rc = false;
+ PCSZ opmode;
+ char tempname[_MAX_PATH];
+ bool rc = false;
/*********************************************************************/
/* Open the temporary file, Spos is at the beginning of file. */
@@ -1107,7 +1109,7 @@ void VCTFAM::CloseTableFile(PGLOBAL g, bool abort)
} else if (AddBlock) {
// Last block was not written
rc = ResetTableSize(g, CurBlk, Nrec);
- longjmp(g->jumper[g->jump_level], 44);
+ throw 44;
} // endif
} else if (mode == MODE_UPDATE) {
@@ -1527,8 +1529,8 @@ bool VCMFAM::AllocateBuffer(PGLOBAL g)
/* Do initial action when inserting. */
/***********************************************************************/
bool VCMFAM::InitInsert(PGLOBAL g)
- {
- int rc;
+{
+ bool rc = false;
volatile PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
// We come here in MODE_INSERT only
@@ -1542,24 +1544,22 @@ bool VCMFAM::InitInsert(PGLOBAL g)
CurNum = Last;
} // endif Last
- // Prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return true;
- } // endif
-
- if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) {
- g->jump_level--;
- return true;
- } // endif
+ try {
+ // Initialize the column block pointer
+ for (; cp; cp = (PVCTCOL)cp->Next)
+ cp->ReadBlock(g);
- // Initialize the column block pointer
- for (; cp; cp = (PVCTCOL)cp->Next)
- cp->ReadBlock(g);
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ rc = true;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ rc = true;
+ } // end catch
- g->jump_level--;
- return false;
- } // end of InitInsert
+ return rc;
+} // end of InitInsert
/***********************************************************************/
/* Data Base write routine for VMP access method. */
@@ -1998,7 +1998,7 @@ bool VECFAM::OpenTableFile(PGLOBAL g)
/***********************************************************************/
/* Open the file corresponding to one column. */
/***********************************************************************/
-bool VECFAM::OpenColumnFile(PGLOBAL g, char *opmode, int i)
+bool VECFAM::OpenColumnFile(PGLOBAL g, PCSZ opmode, int i)
{
char filename[_MAX_PATH];
PDBUSER dup = PlgGetUser(g);
@@ -2503,7 +2503,7 @@ void VECFAM::CloseTableFile(PGLOBAL g, bool abort)
if (wrc != RC_FX)
rc = ResetTableSize(g, Block, Last);
else
- longjmp(g->jumper[g->jump_level], 44);
+ throw 44;
} else if (mode == MODE_UPDATE) {
if (UseTemp && !InitUpdate && !Abort) {
@@ -3143,7 +3143,8 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
htrc("after write req=%d brc=%d nbw=%d\n", req, brc, nbw);
if (!brc || nbw != len) {
- char buf[256], *fn = (h == Hfile) ? To_File : "Tempfile";
+ char buf[256];
+ PCSZ fn = (h == Hfile) ? To_File : "Tempfile";
if (brc)
strcpy(buf, MSG(BAD_BYTE_NUM));
@@ -3319,7 +3320,7 @@ bool BGVFAM::SetBlockInfo(PGLOBAL g)
/***********************************************************************/
/* VEC Create an empty file for new Vector formatted tables. */
/***********************************************************************/
-bool BGVFAM::MakeEmptyFile(PGLOBAL g, char *fn)
+bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn)
{
// Vector formatted file this will create an empty file of the
// required length if it does not exists yet.
@@ -3329,7 +3330,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, char *fn)
PlugSetPath(filename, fn, Tdbp->GetPath());
#if defined(__WIN__)
- char *p;
+ PCSZ p;
DWORD rc;
bool brc;
LARGE_INTEGER of;
@@ -4164,8 +4165,8 @@ void BGVFAM::CloseTableFile(PGLOBAL g, bool abort)
} else if (AddBlock) {
// Last block was not written
rc = ResetTableSize(g, CurBlk, Nrec);
- longjmp(g->jumper[g->jump_level], 44);
- } // endif
+ throw 44;
+ } // endif
} else if (mode == MODE_UPDATE) {
// Write back to file any pending modifications
diff --git a/storage/connect/filamvct.h b/storage/connect/filamvct.h
index be66232acfb..85982403270 100644
--- a/storage/connect/filamvct.h
+++ b/storage/connect/filamvct.h
@@ -61,7 +61,7 @@ class DllExport VCTFAM : public FIXFAM {
virtual bool WriteBlock(PGLOBAL g, PVCTCOL colp);
protected:
- virtual bool MakeEmptyFile(PGLOBAL g, char *fn);
+ virtual bool MakeEmptyFile(PGLOBAL g, PCSZ fn);
virtual bool OpenTempFile(PGLOBAL g);
virtual bool MoveLines(PGLOBAL g) {return false;}
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
@@ -160,7 +160,7 @@ class DllExport VECFAM : public VCTFAM {
virtual bool MoveLines(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual int RenameTempFile(PGLOBAL g);
- bool OpenColumnFile(PGLOBAL g, char *opmode, int i);
+ bool OpenColumnFile(PGLOBAL g, PCSZ opmode, int i);
// Members
FILE* *Streams; // Points to Dos file structure array
@@ -235,7 +235,7 @@ class BGVFAM : public VCTFAM {
bool BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, bool b = false);
bool BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req);
bool BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req);
- virtual bool MakeEmptyFile(PGLOBAL g, char *fn);
+ virtual bool MakeEmptyFile(PGLOBAL g, PCSZ fn);
virtual bool OpenTempFile(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual bool CleanUnusedSpace(PGLOBAL g);
diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp
index 3d157da5e87..81511214bfe 100644
--- a/storage/connect/filamzip.cpp
+++ b/storage/connect/filamzip.cpp
@@ -1,7 +1,7 @@
/*********** File AM Zip C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: FILAMZIP */
/* ------------- */
-/* Version 1.1 */
+/* Version 1.3 */
/* */
/* COPYRIGHT: */
/* ---------- */
@@ -45,12 +45,12 @@
#define WRITEBUFFERSIZE (16384)
-bool ZipLoadFile(PGLOBAL g, char *zfn, char *fn, char *entry, bool append, bool mul);
+bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul);
/***********************************************************************/
/* Compress a file in zip when creating a table. */
/***********************************************************************/
-static bool ZipFile(PGLOBAL g, ZIPUTIL *zutp, char *fn, char *entry, char *buf)
+static bool ZipFile(PGLOBAL g, ZIPUTIL *zutp, PCSZ fn, PCSZ entry, char *buf)
{
int rc = RC_OK, size_read, size_buf = WRITEBUFFERSIZE;
FILE *fin;
@@ -88,7 +88,7 @@ static bool ZipFile(PGLOBAL g, ZIPUTIL *zutp, char *fn, char *entry, char *buf)
/***********************************************************************/
/* Find and Compress several files in zip when creating a table. */
/***********************************************************************/
-static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, char *pat, char *buf)
+static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf)
{
char filename[_MAX_PATH];
int rc;
@@ -203,7 +203,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, char *pat, char *buf)
/***********************************************************************/
/* Load and Compress a file in zip when creating a table. */
/***********************************************************************/
-bool ZipLoadFile(PGLOBAL g, char *zfn, char *fn, char *entry, bool append, bool mul)
+bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul)
{
char *buf;
bool err;
@@ -228,7 +228,7 @@ bool ZipLoadFile(PGLOBAL g, char *zfn, char *fn, char *entry, bool append, bool
/***********************************************************************/
/* Constructors. */
/***********************************************************************/
-ZIPUTIL::ZIPUTIL(PSZ tgt)
+ZIPUTIL::ZIPUTIL(PCSZ tgt)
{
zipfile = NULL;
target = tgt;
@@ -269,7 +269,7 @@ void ZIPUTIL::getTime(tm_zip& tmZip)
/* append: set true to append the zip file */
/* return: true if open, false otherwise. */
/***********************************************************************/
-bool ZIPUTIL::open(PGLOBAL g, char *filename, bool append)
+bool ZIPUTIL::open(PGLOBAL g, PCSZ filename, bool append)
{
if (!zipfile && !(zipfile = zipOpen64(filename,
append ? APPEND_STATUS_ADDINZIP
@@ -295,7 +295,7 @@ void ZIPUTIL::close()
/***********************************************************************/
/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */
/***********************************************************************/
-bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, char *fn, bool append)
+bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, PCSZ fn, bool append)
{
/*********************************************************************/
/* The file will be compressed. */
@@ -338,7 +338,7 @@ bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, char *fn, bool append)
/***********************************************************************/
/* Add target in zip file. */
/***********************************************************************/
-bool ZIPUTIL::addEntry(PGLOBAL g, char *entry)
+bool ZIPUTIL::addEntry(PGLOBAL g, PCSZ entry)
{
//?? we dont need the stinking time
zip_fileinfo zi = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -382,10 +382,11 @@ void ZIPUTIL::closeEntry()
/***********************************************************************/
/* Constructors. */
/***********************************************************************/
-UNZIPUTL::UNZIPUTL(PSZ tgt, bool mul)
+UNZIPUTL::UNZIPUTL(PCSZ tgt, bool mul)
{
zipfile = NULL;
target = tgt;
+ pwd = NULL;
fp = NULL;
memory = NULL;
size = 0;
@@ -401,6 +402,26 @@ UNZIPUTL::UNZIPUTL(PSZ tgt, bool mul)
#endif
} // end of UNZIPUTL standard constructor
+UNZIPUTL::UNZIPUTL(PDOSDEF tdp)
+{
+ zipfile = NULL;
+ target = tdp->GetEntry();
+ pwd = tdp->Pwd;
+ fp = NULL;
+ memory = NULL;
+ size = 0;
+ entryopen = false;
+ multiple = tdp->GetMul();
+ memset(fn, 0, sizeof(fn));
+
+ // Init the case mapping table.
+#if defined(__WIN__)
+ for (int i = 0; i < 256; ++i) mapCaseTable[i] = toupper(i);
+#else
+ for (int i = 0; i < 256; ++i) mapCaseTable[i] = i;
+#endif
+} // end of UNZIPUTL standard constructor
+
#if 0
UNZIPUTL::UNZIPUTL(PZIPUTIL zutp)
{
@@ -418,8 +439,8 @@ UNZIPUTL::UNZIPUTL(PZIPUTIL zutp)
/* This code is the copyright property of Alessandro Felice Cantatore. */
/* http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html */
/***********************************************************************/
-bool UNZIPUTL::WildMatch(PSZ pat, PSZ str) {
- PSZ s, p;
+bool UNZIPUTL::WildMatch(PCSZ pat, PCSZ str) {
+ PCSZ s, p;
bool star = FALSE;
loopStart:
@@ -434,7 +455,7 @@ loopStart:
if (!*++pat) return TRUE;
goto loopStart;
default:
- if (mapCaseTable[(uchar)*s] != mapCaseTable[(uchar)*p])
+ if (mapCaseTable[(uint)*s] != mapCaseTable[(uint)*p])
goto starCheck;
break;
} /* endswitch */
@@ -453,7 +474,7 @@ starCheck:
/* param: filename path and the filename of the zip file to open. */
/* return: true if open, false otherwise. */
/***********************************************************************/
-bool UNZIPUTL::open(PGLOBAL g, char *filename)
+bool UNZIPUTL::open(PGLOBAL g, PCSZ filename)
{
if (!zipfile && !(zipfile = unzOpen64(filename)))
sprintf(g->Message, "Zipfile open error on %s", filename);
@@ -543,7 +564,7 @@ int UNZIPUTL::nextEntry(PGLOBAL g)
/***********************************************************************/
/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */
/***********************************************************************/
-bool UNZIPUTL::OpenTable(PGLOBAL g, MODE mode, char *fn)
+bool UNZIPUTL::OpenTable(PGLOBAL g, MODE mode, PCSZ fn)
{
/*********************************************************************/
/* The file will be decompressed into virtual memory. */
@@ -581,7 +602,7 @@ bool UNZIPUTL::OpenTable(PGLOBAL g, MODE mode, char *fn)
if (openEntry(g))
return true;
- if (size > 0) {
+ if (size > 0) {
/*******************************************************************/
/* Link a Fblock. This make possible to automatically close it */
/* in case of error g->jump. */
@@ -613,6 +634,28 @@ bool UNZIPUTL::OpenTable(PGLOBAL g, MODE mode, char *fn)
} // end of OpenTableFile
/***********************************************************************/
+/* Insert only if the entry does not exist. */
+/***********************************************************************/
+bool UNZIPUTL::IsInsertOk(PGLOBAL g, PCSZ fn)
+{
+ bool ok = true, b = open(g, fn);
+
+ if (!b) {
+ if (!target || *target == 0) {
+ unz_global_info64 ginfo;
+ int err = unzGetGlobalInfo64(zipfile, &ginfo);
+
+ ok = !(err == UNZ_OK && ginfo.number_entry > 0);
+ } else // Check if the target exist
+ ok = (unzLocateFile(zipfile, target, 0) != UNZ_OK);
+
+ unzClose(zipfile);
+ } // endif b
+
+ return ok;
+} // end of IsInsertOk
+
+/***********************************************************************/
/* Open target in zip file. */
/***********************************************************************/
bool UNZIPUTL::openEntry(PGLOBAL g)
@@ -625,18 +668,24 @@ bool UNZIPUTL::openEntry(PGLOBAL g)
if (rc != UNZ_OK) {
sprintf(g->Message, "unzGetCurrentFileInfo64 rc=%d", rc);
return true;
- } else if ((rc = unzOpenCurrentFile(zipfile)) != UNZ_OK) {
+ } else if ((rc = unzOpenCurrentFilePassword(zipfile, pwd)) != UNZ_OK) {
sprintf(g->Message, "unzOpen fn=%s rc=%d", fn, rc);
return true;
} // endif rc
size = finfo.uncompressed_size;
- memory = new char[size + 1];
+
+ try {
+ memory = new char[size + 1];
+ } catch (...) {
+ strcpy(g->Message, "Out of memory");
+ return true;
+ } // end try/catch
if ((rc = unzReadCurrentFile(zipfile, memory, size)) < 0) {
sprintf(g->Message, "unzReadCurrentFile rc = %d", rc);
unzCloseCurrentFile(zipfile);
- free(memory);
+ delete[] memory;
memory = NULL;
entryopen = false;
} else {
@@ -661,7 +710,7 @@ void UNZIPUTL::closeEntry()
} // endif entryopen
if (memory) {
- free(memory);
+ delete[] memory;
memory = NULL;
} // endif memory
@@ -675,15 +724,17 @@ void UNZIPUTL::closeEntry()
UNZFAM::UNZFAM(PDOSDEF tdp) : MAPFAM(tdp)
{
zutp = NULL;
- target = tdp->GetEntry();
- mul = tdp->GetMul();
+ tdfp = tdp;
+ //target = tdp->GetEntry();
+ //mul = tdp->GetMul();
} // end of UNZFAM standard constructor
UNZFAM::UNZFAM(PUNZFAM txfp) : MAPFAM(txfp)
{
zutp = txfp->zutp;
- target = txfp->target;
- mul = txfp->mul;
+ tdfp = txfp->tdfp;
+ //target = txfp->target;
+ //mul = txfp->mul;
} // end of UNZFAM copy constructor
/***********************************************************************/
@@ -711,7 +762,13 @@ int UNZFAM::Cardinality(PGLOBAL g)
int card = -1;
int len = GetFileLength(g);
- card = (len / (int)Lrecl) * 2; // Estimated ???
+ if (len) {
+ // Estimated ???
+ card = (len / (int)Lrecl) * 2;
+ card = card ? card : 10; // Lrecl can be too big
+ } else
+ card = 0;
+
return card;
} // end of Cardinality
@@ -726,7 +783,7 @@ bool UNZFAM::OpenTableFile(PGLOBAL g)
/*********************************************************************/
/* Allocate the ZIP utility class. */
/*********************************************************************/
- zutp = new(g) UNZIPUTL(target, mul);
+ zutp = new(g) UNZIPUTL(tdfp);
// We used the file name relative to recorded datapath
PlugSetPath(filename, To_File, Tdbp->GetPath());
@@ -841,17 +898,19 @@ void UNZFAM::CloseTableFile(PGLOBAL g, bool)
UZXFAM::UZXFAM(PDOSDEF tdp) : MPXFAM(tdp)
{
zutp = NULL;
- target = tdp->GetEntry();
- mul = tdp->GetMul();
+ tdfp = tdp;
+ //target = tdp->GetEntry();
+ //mul = tdp->GetMul();
//Lrecl = tdp->GetLrecl();
} // end of UZXFAM standard constructor
UZXFAM::UZXFAM(PUZXFAM txfp) : MPXFAM(txfp)
{
zutp = txfp->zutp;
- target = txfp->target;
- mul = txfp->mul;
-//Lrecl = txfp->Lrecl;
+ tdfp = txfp->tdfp;
+ //target = txfp->target;
+ //mul = txfp->mul;
+ //Lrecl = txfp->Lrecl;
} // end of UZXFAM copy constructor
/***********************************************************************/
@@ -907,7 +966,7 @@ bool UZXFAM::OpenTableFile(PGLOBAL g)
/* Allocate the ZIP utility class. */
/*********************************************************************/
if (!zutp)
- zutp = new(g)UNZIPUTL(target, mul);
+ zutp = new(g)UNZIPUTL(tdfp);
// We used the file name relative to recorded datapath
PlugSetPath(filename, To_File, Tdbp->GetPath());
@@ -969,6 +1028,25 @@ bool ZIPFAM::OpenTableFile(PGLOBAL g)
{
char filename[_MAX_PATH];
MODE mode = Tdbp->GetMode();
+ int len = TXTFAM::GetFileLength(g);
+
+ // We used the file name relative to recorded datapath
+ PlugSetPath(filename, To_File, Tdbp->GetPath());
+
+ if (len < 0)
+ return true;
+ else if (!append && len > 0) {
+ strcpy(g->Message, "No insert into existing zip file");
+ return true;
+ } else if (append && len > 0) {
+ UNZIPUTL *zutp = new(g) UNZIPUTL(target, false);
+
+ if (!zutp->IsInsertOk(g, filename)) {
+ strcpy(g->Message, "No insert into existing entry");
+ return true;
+ } // endif Ok
+
+ } // endif's
/*********************************************************************/
/* Allocate the ZIP utility class. */
@@ -1028,15 +1106,31 @@ ZPXFAM::ZPXFAM(PDOSDEF tdp) : FIXFAM(tdp)
target = tdp->GetEntry();
append = tdp->GetAppend();
//Lrecl = tdp->GetLrecl();
-} // end of UZXFAM standard constructor
+} // end of ZPXFAM standard constructor
/***********************************************************************/
/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */
/***********************************************************************/
bool ZPXFAM::OpenTableFile(PGLOBAL g)
{
- char filename[_MAX_PATH];
- MODE mode = Tdbp->GetMode();
+ char filename[_MAX_PATH];
+ MODE mode = Tdbp->GetMode();
+ int len = TXTFAM::GetFileLength(g);
+
+ if (len < 0)
+ return true;
+ else if (!append && len > 0) {
+ strcpy(g->Message, "No insert into existing zip file");
+ return true;
+ } else if (append && len > 0) {
+ UNZIPUTL *zutp = new(g) UNZIPUTL(target, false);
+
+ if (!zutp->IsInsertOk(g, filename)) {
+ strcpy(g->Message, "No insert into existing entry");
+ return true;
+ } // endif Ok
+
+ } // endif's
/*********************************************************************/
/* Allocate the ZIP utility class. */
diff --git a/storage/connect/filamzip.h b/storage/connect/filamzip.h
index 3160703bd20..be17d954728 100644
--- a/storage/connect/filamzip.h
+++ b/storage/connect/filamzip.h
@@ -1,5 +1,5 @@
/************** filamzip H Declares Source Code File (.H) **************/
-/* Name: filamzip.h Version 1.1 */
+/* Name: filamzip.h Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */
/* */
@@ -27,16 +27,13 @@ typedef class ZPXFAM *PZPXFAM;
class DllExport ZIPUTIL : public BLOCK {
public:
// Constructor
- ZIPUTIL(PSZ tgt);
+ ZIPUTIL(PCSZ tgt);
//ZIPUTIL(ZIPUTIL *zutp);
- // Implementation
- //PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)UNZFAM(this); }
-
// Methods
- bool OpenTable(PGLOBAL g, MODE mode, char *fn, bool append);
- bool open(PGLOBAL g, char *fn, bool append);
- bool addEntry(PGLOBAL g, char *entry);
+ bool OpenTable(PGLOBAL g, MODE mode, PCSZ fn, bool append);
+ bool open(PGLOBAL g, PCSZ fn, bool append);
+ bool addEntry(PGLOBAL g, PCSZ entry);
void close(void);
void closeEntry(void);
int writeEntry(PGLOBAL g, char *buf, int len);
@@ -44,15 +41,10 @@ class DllExport ZIPUTIL : public BLOCK {
// Members
zipFile zipfile; // The ZIP container file
- PSZ target; // The target file name
-//unz_file_info finfo; // The current file info
+ PCSZ target; // The target file name
+ PCSZ pwd; // The ZIP file password
PFBLOCK fp;
-//char *memory;
-//uint size;
-//int multiple; // Multiple targets
bool entryopen; // True when open current entry
-//char fn[FILENAME_MAX]; // The current entry file name
-//char mapCaseTable[256];
}; // end of ZIPUTIL
/***********************************************************************/
@@ -61,25 +53,27 @@ class DllExport ZIPUTIL : public BLOCK {
class DllExport UNZIPUTL : public BLOCK {
public:
// Constructor
- UNZIPUTL(PSZ tgt, bool mul);
-//UNZIPUTL(UNZIPUTL *zutp);
+ UNZIPUTL(PCSZ tgt, bool mul);
+ UNZIPUTL(PDOSDEF tdp);
// Implementation
//PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)UNZFAM(this); }
// Methods
- bool OpenTable(PGLOBAL g, MODE mode, char *fn);
- bool open(PGLOBAL g, char *fn);
+ bool OpenTable(PGLOBAL g, MODE mode, PCSZ fn);
+ bool open(PGLOBAL g, PCSZ fn);
bool openEntry(PGLOBAL g);
void close(void);
void closeEntry(void);
- bool WildMatch(PSZ pat, PSZ str);
+ bool WildMatch(PCSZ pat, PCSZ str);
int findEntry(PGLOBAL g, bool next);
int nextEntry(PGLOBAL g);
+ bool IsInsertOk(PGLOBAL g, PCSZ fn);
// Members
unzFile zipfile; // The ZIP container file
- PSZ target; // The target file name
+ PCSZ target; // The target file name
+ PCSZ pwd; // The ZIP file password
unz_file_info finfo; // The current file info
PFBLOCK fp;
char *memory;
@@ -119,8 +113,7 @@ class DllExport UNZFAM : public MAPFAM {
protected:
// Members
UNZIPUTL *zutp;
- PSZ target;
- bool mul;
+ PDOSDEF tdfp;
}; // end of UNZFAM
/***********************************************************************/
@@ -147,8 +140,7 @@ class DllExport UZXFAM : public MPXFAM {
protected:
// Members
UNZIPUTL *zutp;
- PSZ target;
- bool mul;
+ PDOSDEF tdfp;
}; // end of UZXFAM
/***********************************************************************/
@@ -175,8 +167,9 @@ class DllExport ZIPFAM : public DOSFAM {
protected:
// Members
ZIPUTIL *zutp;
- PSZ target;
+ PCSZ target;
bool append;
+//bool replace;
}; // end of ZIPFAM
/***********************************************************************/
@@ -200,7 +193,7 @@ class DllExport ZPXFAM : public FIXFAM {
protected:
// Members
ZIPUTIL *zutp;
- PSZ target;
+ PCSZ target;
bool append;
}; // end of ZPXFAM
diff --git a/storage/connect/filter.cpp b/storage/connect/filter.cpp
index 262d6b58a70..d1cf8909917 100644
--- a/storage/connect/filter.cpp
+++ b/storage/connect/filter.cpp
@@ -1,7 +1,7 @@
/***************** Filter C++ Class Filter Code (.CPP) *****************/
-/* Name: FILTER.CPP Version 3.9 */
+/* Name: FILTER.CPP Version 4.0 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
/* */
/* This file contains the class FILTER function code. */
/***********************************************************************/
@@ -38,6 +38,13 @@
//#include "token.h"
//#include "select.h"
#include "xindex.h"
+#if defined(MONGO_SUPPORT)
+#include "filamtxt.h"
+#include "tabdos.h"
+#include "tabjson.h"
+#include "tabext.h"
+#include "tabmgo.h"
+#endif // MONGO_SUPPORT
/***********************************************************************/
/* Utility routines. */
@@ -87,8 +94,8 @@ BYTE OpBmp(PGLOBAL g, OPVAL opc)
case OP_EXIST: bt = 0x00; break;
default:
sprintf(g->Message, MSG(BAD_FILTER_OP), opc);
- longjmp(g->jumper[g->jump_level], TYPE_ARRAY);
- } // endswitch opc
+ throw TYPE_ARRAY;
+ } // endswitch opc
return bt;
} // end of OpBmp
@@ -1405,10 +1412,98 @@ PFIL FILTER::Copy(PTABS t)
} // end of Copy
#endif // 0
+/***********************************************************************/
+/* Make selector json representation for Mongo tables. */
+/***********************************************************************/
+#if defined(MONGO_SUPPORT)
+bool FILTER::MakeSelector(PGLOBAL g, PSTRG s, bool m)
+{
+ s->Append('{');
+
+ if (Opc == OP_AND || Opc == OP_OR) {
+ if (GetArgType(0) != TYPE_FILTER || GetArgType(1) != TYPE_FILTER)
+ return true;
+
+ s->Append("\"$");
+ s->Append(Opc == OP_AND ? "and" : "or");
+ s->Append("\":[");
+
+ if (((PFIL)Arg(0))->MakeSelector(g, s, m))
+ return true;
+
+ s->Append(',');
+
+ if (((PFIL)Arg(1))->MakeSelector(g, s, m))
+ return true;
+
+ s->Append(']');
+ } else {
+ char *pth, buf[501];
+
+ if (GetArgType(0) != TYPE_COLBLK)
+ return true;
+
+ s->Append('"');
+
+ if (m)
+ pth = ((PMGOCOL)Arg(0))->Jpath;
+ else if (!(pth = ((PJCOL)Arg(0))->GetJpath(g, false)))
+ return true;
+
+ s->Append(pth);
+ s->Append("\":{\"$");
+
+ switch (Opc) {
+ case OP_EQ:
+ s->Append("eq");
+ break;
+ case OP_NE:
+ s->Append("ne");
+ break;
+ case OP_GT:
+ s->Append("gt");
+ break;
+ case OP_GE:
+ s->Append("gte");
+ break;
+ case OP_LT:
+ s->Append("lt");
+ break;
+ case OP_LE:
+ s->Append("lte");
+ break;
+ //case OP_NULL:
+ // s->Append("ne");
+ // break;
+ //case OP_LIKE:
+ // s->Append("ne");
+ // break;
+ //case OP_EXIST:
+ // s->Append("ne");
+ // break;
+ default:
+ return true;
+ } // endswitch Opc
+
+ s->Append("\":");
+
+ if (GetArgType(1) == TYPE_COLBLK)
+ return true;
+
+ Arg(1)->Prints(g, buf, 500);
+ s->Append(buf);
+ s->Append('}');
+ } // endif Opc
+
+ s->Append('}');
+ return false;
+} // end of MakeSelector
+#endif // MONGO_SUPPORT
+
/*********************************************************************/
/* Make file output of FILTER contents. */
/*********************************************************************/
-void FILTER::Print(PGLOBAL g, FILE *f, uint n)
+void FILTER::Printf(PGLOBAL g, FILE *f, uint n)
{
char m[64];
@@ -1430,18 +1525,18 @@ void FILTER::Print(PGLOBAL g, FILE *f, uint n)
if (lin && fp->GetArgType(i) == TYPE_FILTER)
fprintf(f, "%s Filter at %p\n", m, fp->Arg(i));
else
- fp->Arg(i)->Print(g, f, n + 2);
+ fp->Arg(i)->Printf(g, f, n + 2);
} // endfor i
} // endfor fp
- } // end of Print
+ } // end of Printf
/***********************************************************************/
/* Make string output of TABLE contents (z should be checked). */
/***********************************************************************/
-void FILTER::Print(PGLOBAL g, char *ps, uint z)
+void FILTER::Prints(PGLOBAL g, char *ps, uint z)
{
#define FLEN 100
@@ -1469,7 +1564,7 @@ void FILTER::Print(PGLOBAL g, char *ps, uint z)
bcp = bxp;
p = bcp->Cold;
n = FLEN;
- fp->Arg(0)->Print(g, p, n);
+ fp->Arg(0)->Prints(g, p, n);
n = FLEN - strlen(p);
switch (fp->Opc) {
@@ -1515,7 +1610,7 @@ void FILTER::Print(PGLOBAL g, char *ps, uint z)
n = FLEN - strlen(p);
p += strlen(p);
- fp->Arg(1)->Print(g, p, n);
+ fp->Arg(1)->Prints(g, p, n);
} else
if (!bcp) {
strncat(ps, "???", z);
@@ -1578,7 +1673,7 @@ void FILTER::Print(PGLOBAL g, char *ps, uint z)
bcp = bxp;
} while (bcp); // enddo
- } // end of Print
+ } // end of Prints
/* -------------------- Derived Classes Functions -------------------- */
@@ -1696,8 +1791,6 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
if (trace)
htrc("PrepareFilter: fp=%p having=%d\n", fp, having);
-//if (fp)
-// fp->Print(g, debug, 0);
while (fp) {
if (fp->Opc == OP_SEP)
@@ -1711,7 +1804,7 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
break; // Remove eventual ending separator(s)
// if (fp->Convert(g, having))
-// longjmp(g->jumper[g->jump_level], TYPE_FILTER);
+// throw TYPE_ARRAY;
filp = fp;
fp = fp->Next;
@@ -1744,7 +1837,7 @@ DllExport bool ApplyFilter(PGLOBAL g, PFIL filp)
// return TRUE;
if (filp->Eval(g))
- longjmp(g->jumper[g->jump_level], TYPE_FILTER);
+ throw TYPE_FILTER;
if (trace > 1)
htrc("PlugFilter filp=%p result=%d\n",
diff --git a/storage/connect/filter.h b/storage/connect/filter.h
index 15730e2cc44..42cddb08655 100644
--- a/storage/connect/filter.h
+++ b/storage/connect/filter.h
@@ -61,8 +61,11 @@ class DllExport FILTER : public XOBJECT { /* Filter description block */
//virtual PXOB CheckSubQuery(PGLOBAL, PSQL);
//virtual bool CheckLocal(PTDB);
//virtual int CheckSpcCol(PTDB tdbp, int n);
- virtual void Print(PGLOBAL g, FILE *f, uint n);
- virtual void Print(PGLOBAL g, char *ps, uint z);
+#if defined(MONGO_SUPPORT)
+ bool MakeSelector(PGLOBAL g, PSTRG s, bool m);
+#endif // MONGO_SUPPORT
+ virtual void Printf(PGLOBAL g, FILE *f, uint n);
+ virtual void Prints(PGLOBAL g, char *ps, uint z);
// PFIL Linearize(bool nosep);
// PFIL Link(PGLOBAL g, PFIL fil2);
// PFIL RemoveLastSep(void);
diff --git a/storage/connect/global.h b/storage/connect/global.h
index 4d01a3ff05b..2f76b331f50 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -1,6 +1,6 @@
/***********************************************************************/
/* GLOBAL.H: Declaration file used by all CONNECT implementations. */
-/* (C) Copyright Olivier Bertrand 1993-2014 */
+/* (C) Copyright Olivier Bertrand 1993-2017 */
/***********************************************************************/
/***********************************************************************/
@@ -59,7 +59,7 @@
#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 1024 /* Maximum string length */
+#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 */
@@ -90,6 +90,7 @@
#define TYPE_BIGINT 5
#define TYPE_LIST 6
#define TYPE_INT 7
+#define TYPE_DATE 8
#define TYPE_DECIM 9
#define TYPE_BIN 10
#define TYPE_PCHAR 11
@@ -229,9 +230,10 @@ typedef struct _parm {
typedef struct _global { /* Global structure */
void *Sarea; /* Points to work area */
uint Sarea_Size; /* Work area size */
- PACTIVITY Activityp, ActivityStart;
+ PACTIVITY Activityp;
char Message[MAX_STR];
- int Createas; /* To pass info to created table */
+ ulong More; /* Used by jsonudf */
+ int Createas; /* To pass info to created table */
void *Xchk; /* indexes in create/alter */
short Alchecked; /* Checked for ALTER */
short Mrr; /* True when doing mrr */
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index f2727ba15f7..9618af48a5b 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -172,9 +172,9 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.05.0003 February 27, 2017";
+ char version[]= "Version 1.06.0001 April 17, 2017";
#if defined(__WIN__)
- char compver[]= "Version 1.05.0003 " __DATE__ " " __TIME__;
+ char compver[]= "Version 1.06.0001 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !__WIN__
char slash= '/';
@@ -209,14 +209,18 @@ pthread_mutex_t parmut = PTHREAD_MUTEX_INITIALIZER;
/***********************************************************************/
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
PQRYRES VirColumns(PGLOBAL g, bool info);
-PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info);
+PQRYRES JSONColumns(PGLOBAL g, char *db, char *dsn, PTOS topt, bool info);
PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info);
+#if defined(MONGO_SUPPORT)
+PQRYRES MGOColumns(PGLOBAL g, char *db, PTOS topt, bool info);
+#endif // 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, const char *host,
- const char *db, char *tab, const char *src, int port);
-bool ZipLoadFile(PGLOBAL, char*, char*, char*, bool, bool);
+bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, PCSZ host, PCSZ db,
+ PCSZ tab, PCSZ src, int port);
+bool ZipLoadFile(PGLOBAL, PCSZ, PCSZ, PCSZ, bool, bool);
bool ExactInfo(void);
+void mongo_init(bool);
USETEMP UseTemp(void);
int GetConvSize(void);
TYPCONV GetTypeConv(void);
@@ -509,7 +513,7 @@ ha_create_table_option connect_table_option_list[]=
HA_TOPTION_NUMBER("LRECL", lrecl, 0, 0, INT_MAX32, 1),
HA_TOPTION_NUMBER("BLOCK_SIZE", elements, 0, 0, INT_MAX32, 1),
//HA_TOPTION_NUMBER("ESTIMATE", estimate, 0, 0, INT_MAX32, 1),
- HA_TOPTION_NUMBER("MULTIPLE", multiple, 0, 0, 2, 1),
+ HA_TOPTION_NUMBER("MULTIPLE", multiple, 0, 0, 3, 1),
HA_TOPTION_NUMBER("HEADER", header, 0, 0, 3, 1),
HA_TOPTION_NUMBER("QUOTED", quoted, (ulonglong) -1, 0, 3, 1),
HA_TOPTION_NUMBER("ENDING", ending, (ulonglong) -1, 0, INT_MAX32, 1),
@@ -670,10 +674,14 @@ static int connect_init_func(void *p)
sql_print_information("CONNECT: %s", version);
#endif // !__WIN__
-#ifdef LIBXML2_SUPPORT
+#if defined(LIBXML2_SUPPORT)
XmlInitParserLib();
#endif // LIBXML2_SUPPORT
+#if defined(MONGO_SUPPORT)
+ mongo_init(true);
+#endif // MONGO_SUPPORT
+
init_connect_psi_keys();
connect_hton= (handlerton *)p;
@@ -712,6 +720,10 @@ static int connect_done_func(void *)
XmlCleanupParserLib();
#endif // LIBXML2_SUPPORT
+#if defined(MONGO_SUPPORT)
+ mongo_init(false);
+#endif // MONGO_SUPPORT
+
#ifdef JDBC_SUPPORT
JDBConn::ResetJVM();
#endif // JDBC_SUPPORT
@@ -1018,15 +1030,14 @@ ulonglong ha_connect::table_flags() const
/****************************************************************************/
/* Return the value of an option specified in an option list. */
/****************************************************************************/
-char *GetListOption(PGLOBAL g, const char *opname,
- const char *oplist, const char *def)
+PCSZ GetListOption(PGLOBAL g, PCSZ opname, PCSZ oplist, PCSZ def)
{
if (!oplist)
return (char*)def;
char key[16], val[256];
char *pk, *pv, *pn;
- char *opval= (char*)def;
+ PCSZ opval= def;
int n;
for (pk= (char*)oplist; pk; pk= ++pn) {
@@ -1034,15 +1045,15 @@ char *GetListOption(PGLOBAL g, const char *opname,
pv= strchr(pk, '=');
if (pv && (!pn || pv < pn)) {
- n= MY_MIN(static_cast<size_t>(pv - pk), sizeof(key) - 1);
- memcpy(key, pk, n);
+ n = MY_MIN(static_cast<size_t>(pv - pk), sizeof(key) - 1);
+ memcpy(key, pk, n);
key[n]= 0;
pv++;
- n= MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
+ n= MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
memcpy(val, pv, n);
val[n]= 0;
} else {
- n= MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
+ n= MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
memcpy(key, pk, n);
key[n]= 0;
val[0]= 0;
@@ -1062,9 +1073,9 @@ char *GetListOption(PGLOBAL g, const char *opname,
/****************************************************************************/
/* Return the value of a string option or NULL if not specified. */
/****************************************************************************/
-char *GetStringTableOption(PGLOBAL g, PTOS options, char *opname, char *sdef)
+PCSZ GetStringTableOption(PGLOBAL g, PTOS options, PCSZ opname, PCSZ sdef)
{
- const char *opval= NULL;
+ PCSZ opval= NULL;
if (!options)
return sdef;
@@ -1107,10 +1118,10 @@ char *GetStringTableOption(PGLOBAL g, PTOS options, char *opname, char *sdef)
/****************************************************************************/
/* Return the value of a Boolean option or bdef if not specified. */
/****************************************************************************/
-bool GetBooleanTableOption(PGLOBAL g, PTOS options, char *opname, bool bdef)
+bool GetBooleanTableOption(PGLOBAL g, PTOS options, PCSZ opname, bool bdef)
{
- bool opval= bdef;
- char *pv;
+ bool opval= bdef;
+ PCSZ pv;
if (!options)
return bdef;
@@ -1138,7 +1149,7 @@ bool GetBooleanTableOption(PGLOBAL g, PTOS options, char *opname, bool bdef)
/****************************************************************************/
/* Return the value of an integer option or NO_IVAL if not specified. */
/****************************************************************************/
-int GetIntegerTableOption(PGLOBAL g, PTOS options, char *opname, int idef)
+int GetIntegerTableOption(PGLOBAL g, PTOS options, PCSZ opname, int idef)
{
ulonglong opval= (ulonglong) NO_IVAL;
@@ -1160,10 +1171,10 @@ int GetIntegerTableOption(PGLOBAL g, PTOS options, char *opname, int idef)
opval= (options->compressed);
if ((ulonglong) opval == (ulonglong)NO_IVAL) {
- char *pv;
+ PCSZ pv;
if ((pv= GetListOption(g, opname, options->oplist)))
- opval= CharToNumber(pv, strlen(pv), ULONGLONG_MAX, true);
+ opval= CharToNumber((char*)pv, strlen(pv), ULONGLONG_MAX, true);
else
return idef;
@@ -1188,11 +1199,11 @@ PTOS ha_connect::GetTableOptionStruct(TABLE_SHARE *s)
/****************************************************************************/
/* Return the string eventually formatted with partition name. */
/****************************************************************************/
-char *ha_connect::GetRealString(const char *s)
+char *ha_connect::GetRealString(PCSZ s)
{
char *sv;
- if (IsPartitioned() && s && *partname) {
+ if (IsPartitioned() && s && partname && *partname) {
sv= (char*)PlugSubAlloc(xp->g, NULL, 0);
sprintf(sv, s, partname);
PlugSubAlloc(xp->g, NULL, strlen(sv) + 1);
@@ -1205,10 +1216,10 @@ char *ha_connect::GetRealString(const char *s)
/****************************************************************************/
/* Return the value of a string option or sdef if not specified. */
/****************************************************************************/
-char *ha_connect::GetStringOption(char *opname, char *sdef)
+PCSZ ha_connect::GetStringOption(PCSZ opname, PCSZ sdef)
{
- char *opval= NULL;
- PTOS options= GetTableOptionStruct();
+ PCSZ opval= NULL;
+ PTOS options= GetTableOptionStruct();
if (!stricmp(opname, "Connect")) {
LEX_STRING cnc= (tshp) ? tshp->connect_string
@@ -1267,7 +1278,7 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
/****************************************************************************/
/* Return the value of a Boolean option or bdef if not specified. */
/****************************************************************************/
-bool ha_connect::GetBooleanOption(char *opname, bool bdef)
+bool ha_connect::GetBooleanOption(PCSZ opname, bool bdef)
{
bool opval;
PTOS options= GetTableOptionStruct();
@@ -1284,7 +1295,7 @@ bool ha_connect::GetBooleanOption(char *opname, bool bdef)
/* Set the value of the opname option (does not work for oplist options) */
/* Currently used only to set the Sepindex value. */
/****************************************************************************/
-bool ha_connect::SetBooleanOption(char *opname, bool b)
+bool ha_connect::SetBooleanOption(PCSZ opname, bool b)
{
PTOS options= GetTableOptionStruct();
@@ -1302,7 +1313,7 @@ bool ha_connect::SetBooleanOption(char *opname, bool b)
/****************************************************************************/
/* Return the value of an integer option or NO_IVAL if not specified. */
/****************************************************************************/
-int ha_connect::GetIntegerOption(char *opname)
+int ha_connect::GetIntegerOption(PCSZ opname)
{
int opval;
PTOS options= GetTableOptionStruct();
@@ -1322,7 +1333,7 @@ int ha_connect::GetIntegerOption(char *opname)
/* Set the value of the opname option (does not work for oplist options) */
/* Currently used only to set the Lrecl value. */
/****************************************************************************/
-bool ha_connect::SetIntegerOption(char *opname, int n)
+bool ha_connect::SetIntegerOption(PCSZ opname, int n)
{
PTOS options= GetTableOptionStruct();
@@ -1497,7 +1508,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Flags |= U_NULLS;
// Mark virtual columns as such
- if (!fp->stored_in_db())
+ if (fp->vcol_info && !fp->stored_in_db())
pcf->Flags |= U_VIRTUAL;
pcf->Key= 0; // Not used when called from MySQL
@@ -1522,7 +1533,7 @@ PXOS ha_connect::GetIndexOptionStruct(KEY *kp)
/****************************************************************************/
/* Return a Boolean index option or false if not specified. */
/****************************************************************************/
-bool ha_connect::GetIndexOption(KEY *kp, char *opname)
+bool ha_connect::GetIndexOption(KEY *kp, PCSZ opname)
{
bool opval= false;
PXOS options= GetIndexOptionStruct(kp);
@@ -1534,7 +1545,7 @@ bool ha_connect::GetIndexOption(KEY *kp, char *opname)
opval= options->mapped;
} else if (kp->comment.str && kp->comment.length) {
- char *pv, *oplist= strz(xp->g, kp->comment);
+ PCSZ pv, oplist= strz(xp->g, kp->comment);
if ((pv= GetListOption(xp->g, opname, oplist)))
opval= (!*pv || *pv == 'y' || *pv == 'Y' || atoi(pv) != 0);
@@ -1739,9 +1750,9 @@ void ha_connect::AddColName(char *cp, Field *fp)
/***********************************************************************/
/* This function sets the current database path. */
/***********************************************************************/
-void ha_connect::SetDataPath(PGLOBAL g, const char *path)
+bool ha_connect::SetDataPath(PGLOBAL g, const char *path)
{
- datapath= SetPath(g, path);
+ return (!(datapath= SetPath(g, path)));
} // end of SetDataPath
/****************************************************************************/
@@ -1895,40 +1906,36 @@ int ha_connect::OpenTable(PGLOBAL g, bool del)
bool ha_connect::CheckColumnList(PGLOBAL g)
{
// Check the list of used fields (columns)
- int rc;
bool brc= false;
PCOL colp;
Field* *field;
Field* fp;
MY_BITMAP *map= table->read_set;
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return true;
- } // endif jump_level
-
- if ((rc= setjmp(g->jumper[++g->jump_level])) == 0) {
+ try {
for (field= table->field; fp= *field; field++)
if (bitmap_is_set(map, fp->field_index)) {
if (!(colp= tdbp->ColDB(g, (PSZ)fp->field_name, 0))) {
sprintf(g->Message, "Column %s not found in %s",
fp->field_name, tdbp->GetName());
- brc= true;
- goto fin;
- } // endif colp
+ throw 1;
+ } // endif colp
if ((brc= colp->InitValue(g)))
- goto fin;
+ throw 2;
colp->AddColUse(U_P); // For PLG tables
} // endif
- } else
- brc= true;
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ brc = true;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ brc = true;
+ } // end catch
- fin:
- g->jump_level--;
return brc;
} // end of CheckColumnList
@@ -1965,7 +1972,8 @@ int ha_connect::CloseTable(PGLOBAL g)
/***********************************************************************/
int ha_connect::MakeRecord(char *buf)
{
- char *p, *fmt, val[32];
+ PCSZ fmt;
+ char *p, val[32];
int rc= 0;
Field* *field;
Field *fp;
@@ -1996,7 +2004,7 @@ int ha_connect::MakeRecord(char *buf)
for (field= table->field; *field && !rc; field++) {
fp= *field;
- if (!fp->stored_in_db())
+ if (fp->vcol_info && !fp->stored_in_db())
continue; // This is a virtual column
if (bitmap_is_set(map, fp->field_index) || alter) {
@@ -2101,7 +2109,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *)
{
char attr_buffer[1024];
char data_buffer[1024];
- char *fmt;
+ PCSZ fmt;
int rc= 0;
PCOL colp;
PVAL value, sdvalin;
@@ -2117,7 +2125,8 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *)
for (Field **field=table->field ; *field ; field++) {
fp= *field;
- if (!fp->stored_in_db() || fp->option_struct->special)
+ if ((fp->vcol_info && !fp->stored_in_db()) ||
+ fp->option_struct->special)
continue; // Is a virtual column possible here ???
if ((xmod == MODE_INSERT && tdbp->GetAmType() != TYPE_AM_MYSQL
@@ -2274,7 +2283,7 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
const uchar *ptr;
//uint i, rem, len, klen, stlen;
uint i, rem, len, stlen;
- bool nq, both, oom= false;
+ bool nq, both, oom;
OPVAL op;
Field *fp;
const key_range *ranges[2];
@@ -2302,9 +2311,9 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
continue;
if (both && i > 0)
- oom|= qry->Append(") AND (");
+ qry->Append(") AND (");
else
- oom|= qry->Append(" WHERE (");
+ qry->Append(" WHERE (");
// klen= len= ranges[i]->length;
len= ranges[i]->length;
@@ -2317,14 +2326,14 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
nq= fp->str_needs_quotes();
if (kpart != kfp->key_part)
- oom|= qry->Append(" AND ");
+ qry->Append(" AND ");
if (q) {
- oom|= qry->Append(q);
- oom|= qry->Append((PSZ)fp->field_name);
- oom|= qry->Append(q);
+ qry->Append(q);
+ qry->Append((PSZ)fp->field_name);
+ qry->Append(q);
} else
- oom|= qry->Append((PSZ)fp->field_name);
+ qry->Append((PSZ)fp->field_name);
switch (ranges[i]->flag) {
case HA_READ_KEY_EXACT:
@@ -2349,10 +2358,10 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
goto err;
} // endswitch flag
- oom|= qry->Append((PSZ)GetValStr(op, false));
+ qry->Append((PSZ)GetValStr(op, false));
if (nq)
- oom|= qry->Append('\'');
+ qry->Append('\'');
if (kpart->key_part_flag & HA_VAR_LENGTH_PART) {
String varchar;
@@ -2360,17 +2369,17 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
varchar.set_quick((char*)ptr + HA_KEY_BLOB_LENGTH,
var_length, &my_charset_bin);
- oom|= qry->Append(varchar.ptr(), varchar.length(), nq);
+ qry->Append(varchar.ptr(), varchar.length(), nq);
} else {
char strbuff[MAX_FIELD_WIDTH];
String str(strbuff, sizeof(strbuff), kpart->field->charset()), *res;
res= fp->val_str(&str, ptr);
- oom|= qry->Append(res->ptr(), res->length(), nq);
+ qry->Append(res->ptr(), res->length(), nq);
} // endif flag
if (nq)
- oom |= qry->Append('\'');
+ qry->Append('\'');
if (stlen >= len)
break;
@@ -2385,7 +2394,9 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
} // endfor i
- if ((oom|= qry->Append(")")))
+ qry->Append(')');
+
+ if ((oom= qry->IsTruncated()))
strcpy(g->Message, "Out of memory");
dbug_tmp_restore_column_map(table->write_set, old_map);
@@ -2698,6 +2709,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
if (x)
return NULL;
+ else
+ pb0= pb1= pb2= ph0= ph1= ph2= NULL;
if (trace)
htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(),
@@ -2922,7 +2935,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
strncat(s, res->ptr(), res->length());
if (res->length() < 19)
- strcat(s, &"1970-01-01 00:00:00"[res->length()]);
+ strcat(s, "1970-01-01 00:00:00" + res->length());
strcat(s, "'}");
break;
@@ -2951,7 +2964,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
strncat(s, res->ptr(), res->length());
if (res->length() < 19)
- strcat(s, &"1970-01-01 00:00:00"[res->length()]);
+ strcat(s, "1970-01-01 00:00:00" + res->length());
strcat(s, "'}");
break;
@@ -3053,7 +3066,6 @@ const COND *ha_connect::cond_push(const COND *cond)
DBUG_ENTER("ha_connect::cond_push");
if (tdbp) {
- int rc;
PGLOBAL& g= xp->g;
AMT tty= tdbp->GetAmType();
bool x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
@@ -3061,58 +3073,66 @@ const COND *ha_connect::cond_push(const COND *cond)
tty == TYPE_AM_TBL || tty == TYPE_AM_MYSQL ||
tty == TYPE_AM_PLG || tty == TYPE_AM_JDBC || x);
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- DBUG_RETURN(cond);
- } // endif jump_level
+ // This should never happen but is done to avoid crashing
+ try {
+ if (b) {
+ PCFIL filp;
+ int rc;
- // This should never happen but is done to avoid crashing
- if ((rc= setjmp(g->jumper[++g->jump_level])) != 0)
- goto fin;
+ if ((filp = tdbp->GetCondFil()) && tdbp->GetCond() == cond &&
+ filp->Idx == active_index && filp->Type == tty)
+ goto fin;
- if (b) {
- PCFIL filp;
- int rc;
+ filp = new(g) CONDFIL(active_index, tty);
+ rc = filp->Init(g, this);
- if ((filp= tdbp->GetCondFil()) && filp->Cond == cond &&
- filp->Idx == active_index && filp->Type == tty)
- goto fin; // Already done
+ if (rc == RC_INFO) {
+ filp->Having = (char*)PlugSubAlloc(g, NULL, 256);
+ *filp->Having = 0;
+ } else if (rc == RC_FX)
+ goto fin;
- filp= new(g) CONDFIL(cond, active_index, tty);
- rc = filp->Init(g, this);
+ filp->Body = (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
+ *filp->Body = 0;
- if (rc == RC_INFO) {
- filp->Having = (char*)PlugSubAlloc(g, NULL, 256);
- *filp->Having = 0;
- } else if (rc == RC_FX)
- goto fin;
+ if (CheckCond(g, filp, cond)) {
+ if (filp->Having && strlen(filp->Having) > 255)
+ goto fin; // Memory collapse
- filp->Body = (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
- *filp->Body = 0;
+ if (trace)
+ htrc("cond_push: %s\n", filp->Body);
- if (CheckCond(g, filp, cond)) {
- if (filp->Having && strlen(filp->Having) > 255)
- goto fin; // Memory collapse
+ tdbp->SetCond(cond);
- if (trace)
- htrc("cond_push: %s\n", filp->Body);
+ if (!x)
+ PlugSubAlloc(g, NULL, strlen(filp->Body) + 1);
+ else
+ cond = NULL; // Does this work?
- if (!x)
- PlugSubAlloc(g, NULL, strlen(filp->Body) + 1);
- else
- cond= NULL; // Does this work?
+ tdbp->SetCondFil(filp);
+ } else if (x && cond)
+ tdbp->SetCondFil(filp); // Wrong filter
- tdbp->SetCondFil(filp);
- } else if (x && cond)
- tdbp->SetCondFil(filp); // Wrong filter
+ } else if (tdbp->CanBeFiltered()) {
+ if (!tdbp->GetCond() || tdbp->GetCond() != cond) {
+ tdbp->SetFilter(CondFilter(g, (Item *)cond));
- } else if (tty != TYPE_AM_JSN && tty != TYPE_AM_JSON)
- tdbp->SetFilter(CondFilter(g, (Item *)cond));
+ if (tdbp->GetFilter())
+ tdbp->SetCond(cond);
- fin:
- g->jump_level--;
- } // endif tdbp
+ } // endif cond
+
+ } // endif tty
+
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
+
+ fin:;
+ } // endif tdbp
// Let MySQL do the filtering
DBUG_RETURN(cond);
@@ -3262,26 +3282,36 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT*)
PGLOBAL& g= xp->g;
PDBUSER dup= PlgGetUser(g);
- // Ignore error on the opt file
- dup->Check &= ~CHK_OPT;
- tdbp= GetTDB(g);
- dup->Check |= CHK_OPT;
+ try {
+ // Ignore error on the opt file
+ dup->Check &= ~CHK_OPT;
+ tdbp = GetTDB(g);
+ dup->Check |= CHK_OPT;
- if (tdbp && !tdbp->IsRemote()) {
- bool dop= IsTypeIndexable(GetRealType(NULL));
- bool dox= (tdbp->GetDef()->Indexable() == 1);
+ if (tdbp && !tdbp->IsRemote()) {
+ bool dop = IsTypeIndexable(GetRealType(NULL));
+ bool dox = (tdbp->GetDef()->Indexable() == 1);
- if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) {
- if (rc == RC_INFO) {
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
- rc= 0;
- } else
- rc= HA_ERR_INTERNAL_ERROR;
+ if ((rc = ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) {
+ if (rc == RC_INFO) {
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ rc = 0;
+ } else
+ rc = HA_ERR_INTERNAL_ERROR;
- } // endif rc
+ } // endif rc
- } else if (!tdbp)
- rc= HA_ERR_INTERNAL_ERROR;
+ } else if (!tdbp)
+ rc = HA_ERR_INTERNAL_ERROR;
+
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ rc = HA_ERR_INTERNAL_ERROR;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ rc = HA_ERR_INTERNAL_ERROR;
+ } // end catch
return rc;
} // end of optimize
@@ -3476,7 +3506,7 @@ int ha_connect::delete_row(const uchar *)
/****************************************************************************/
-/* We seem to come here at the beginning of an index use. */
+/* We seem to come here at the begining of an index use. */
/****************************************************************************/
int ha_connect::index_init(uint idx, bool sorted)
{
@@ -3976,8 +4006,12 @@ int ha_connect::rnd_pos(uchar *buf, uchar *pos)
tdbp->SetFilter(NULL);
rc= rnd_next(buf);
- } else
- rc= HA_ERR_KEY_NOT_FOUND;
+ } else {
+ PGLOBAL g = GetPlug((table) ? table->in_use : NULL, xp);
+ strcpy(g->Message, "Not supported by this table type");
+ my_message(ER_ILLEGAL_HA, g->Message, MYF(0));
+ rc= HA_ERR_INTERNAL_ERROR;
+ } // endif SetRecpos
DBUG_RETURN(rc);
} // end of rnd_pos
@@ -4043,9 +4077,13 @@ int ha_connect::info(uint flag)
} // endif xmod
// This is necessary for getting file length
- if (table)
- SetDataPath(g, table->s->db.str);
- else
+ if (table) {
+ if (SetDataPath(g, table->s->db.str)) {
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+ } // endif SetDataPath
+
+ } else
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
if (!(tdbp= GetTDB(g)))
@@ -4195,35 +4233,36 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
case TAB_INI:
case TAB_VEC:
case TAB_JSON:
- if (options->filename && *options->filename) {
- if (!quick) {
- char *s, path[FN_REFLEN], dbpath[FN_REFLEN];
+ if (options->filename && *options->filename) {
+ if (!quick) {
+ char path[FN_REFLEN], dbpath[FN_REFLEN];
+
+ strcpy(dbpath, mysql_real_data_home);
+
+ if (db)
#if defined(__WIN__)
- s= "\\";
+ strcat(strcat(dbpath, db), "\\");
#else // !__WIN__
- s= "/";
+ strcat(strcat(dbpath, db), "/");
#endif // !__WIN__
- strcpy(dbpath, mysql_real_data_home);
-
- if (db)
- strcat(strcat(dbpath, db), s);
- (void) fn_format(path, options->filename, dbpath, "",
- MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
+ (void)fn_format(path, options->filename, dbpath, "",
+ MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
- if (!is_secure_file_path(path)) {
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
- return true;
- } // endif path
- }
- } else
+ if (!is_secure_file_path(path)) {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
+ return true;
+ } // endif path
+ }
+ } else
return false;
/* Fall through to check FILE_ACL */
case TAB_ODBC:
case TAB_JDBC:
case TAB_MYSQL:
- case TAB_DIR:
+ case TAB_MONGO:
+ case TAB_DIR:
case TAB_MAC:
case TAB_WMI:
case TAB_ZIP:
@@ -4528,9 +4567,11 @@ int ha_connect::external_lock(THD *thd, int lock_type)
DBUG_RETURN(0);
} else if (g->Xchk) {
if (!tdbp) {
- if (!(tdbp= GetTDB(g)))
- DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
- else if (!tdbp->GetDef()->Indexable()) {
+ if (!(tdbp = GetTDB(g))) {
+// DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ DBUG_RETURN(0);
+ } else if (!tdbp->GetDef()->Indexable()) {
sprintf(g->Message, "external_lock: Table %s is not indexable", tdbp->GetName());
// DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
@@ -4614,7 +4655,9 @@ int ha_connect::external_lock(THD *thd, int lock_type)
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
0, g->Message);
rc= 0;
- } // endif MakeIndex
+ //my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ //rc= HA_ERR_INTERNAL_ERROR;
+ } // endif MakeIndex
} else if (tdbp->GetDef()->Indexable() == 3) {
if (CheckVirtualIndex(NULL)) {
@@ -4635,9 +4678,12 @@ int ha_connect::external_lock(THD *thd, int lock_type)
// Make it a warning to avoid crash
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
rc= 0;
- } // endif Close
+ //my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ //rc = HA_ERR_INTERNAL_ERROR;
+ } // endif Close
locked= 0;
+// m_lock_type= lock_type;
xmod= MODE_ANY; // For info commands
DBUG_RETURN(rc);
} // endif MODE_ANY
@@ -4995,8 +5041,8 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
} // end of records_in_range
// Used to check whether a MYSQL table is created on itself
-bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
- const char *db, char *tab, const char *src, int port)
+bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, PCSZ host,
+ PCSZ db, PCSZ tab, PCSZ src, int port)
{
if (src)
return false;
@@ -5232,41 +5278,41 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
TABLE_SHARE *table_s,
HA_CREATE_INFO *create_info)
{
- char v=0;
- const char *fncn= "?";
- const char *user, *fn, *db, *host, *pwd, *sep, *tbl, *src;
- const char *col, *ocl, *rnk, *pic, *fcl, *skc, *zfn;
- char *tab, *dsn, *shm, *dpath;
+ char v=0;
+ PCSZ fncn= "?";
+ PCSZ user, fn, db, host, pwd, sep, tbl, src;
+ PCSZ col, ocl, rnk, pic, fcl, skc, zfn;
+ char *tab, *dsn, *shm, *dpath;
#if defined(__WIN__)
- char *nsp= NULL, *cls= NULL;
+ PCSZ nsp= NULL, cls= NULL;
#endif // __WIN__
-//int hdr, mxe;
- int port = 0, mxr = 0, rc = 0, mul = 0, lrecl = 0;
+//int hdr, mxe;
+ int port = 0, mxr = 0, rc = 0, mul = 0, lrecl = 0;
#if defined(ODBC_SUPPORT)
- POPARM sop= NULL;
- char *ucnc= NULL;
- bool cnc= false;
- int cto= -1, qto= -1;
+ POPARM sop= NULL;
+ PCSZ ucnc= NULL;
+ bool cnc= false;
+ int cto= -1, qto= -1;
#endif // ODBC_SUPPORT
#if defined(JDBC_SUPPORT)
- PJPARM sjp= NULL;
- char *driver= NULL;
- char *url= NULL;
-//char *prop= NULL;
- char *tabtyp= NULL;
+ PJPARM sjp= NULL;
+ PCSZ driver= NULL;
+ char *url= NULL;
+//char *prop= NULL;
+ PCSZ tabtyp= NULL;
#endif // JDBC_SUPPORT
- uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
- bool bif, ok= false, dbf= false;
- TABTYPE ttp= TAB_UNDEF;
- PQRYRES qrp= NULL;
- PCOLRES crp;
- PCONNECT xp= NULL;
- PGLOBAL g= GetPlug(thd, xp);
- PDBUSER dup= PlgGetUser(g);
- PCATLG cat= (dup) ? dup->Catalog : NULL;
- PTOS topt= table_s->option_struct;
- char buf[1024];
- String sql(buf, sizeof(buf), system_charset_info);
+ uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
+ bool bif, ok= false, dbf= false;
+ TABTYPE ttp= TAB_UNDEF;
+ PQRYRES qrp= NULL;
+ PCOLRES crp;
+ PCONNECT xp= NULL;
+ PGLOBAL g= GetPlug(thd, xp);
+ PDBUSER dup= PlgGetUser(g);
+ PCATLG cat= (dup) ? dup->Catalog : NULL;
+ PTOS topt= table_s->option_struct;
+ char buf[1024];
+ String sql(buf, sizeof(buf), system_charset_info);
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
@@ -5291,7 +5337,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (topt->oplist) {
host= GetListOption(g, "host", topt->oplist, "localhost");
user= GetListOption(g, "user", topt->oplist,
- (ttp == TAB_ODBC ? NULL : "root"));
+ ((ttp == TAB_ODBC || ttp == TAB_JDBC) ? NULL : "root"));
// Default value db can come from the DBNAME=xxx option.
db= GetListOption(g, "database", topt->oplist, db);
col= GetListOption(g, "colist", topt->oplist, col);
@@ -5328,549 +5374,508 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // ZIP_SUPPORT
} else {
host= "localhost";
- user= (ttp == TAB_ODBC ? NULL : "root");
+ user= ((ttp == TAB_ODBC || ttp == TAB_JDBC) ? NULL : "root");
} // endif option_list
if (!(shm= (char*)db))
db= table_s->db.str; // Default value
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- goto jer;
- } // endif jump_level
-
- if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- goto err;
- } // endif rc
-
- // Check table type
- if (ttp == TAB_UNDEF) {
- topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
- ttp= GetTypeID(topt->type);
- sprintf(g->Message, "No table_type. Was set to %s", topt->type);
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
- } else if (ttp == TAB_NIY) {
- sprintf(g->Message, "Unsupported table type %s", topt->type);
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- goto err;
- } // endif ttp
-
- if (!tab) {
- if (ttp == TAB_TBL) {
- // Make tab the first table of the list
- char *p;
-
- if (!tbl) {
- strcpy(g->Message, "Missing table list");
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- goto err;
- } // endif tbl
-
- tab= PlugDup(g, tbl);
-
- if ((p= strchr(tab, ',')))
- *p= 0;
-
- if ((p=strchr(tab, '.'))) {
- *p= 0;
- db= tab;
- tab= p + 1;
- } // endif p
-
- } else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL)))
- tab= table_s->table_name.str; // Default value
-
- } // endif tab
-
- switch (ttp) {
+ try {
+ // Check table type
+ if (ttp == TAB_UNDEF) {
+ topt->type = (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
+ ttp = GetTypeID(topt->type);
+ sprintf(g->Message, "No table_type. Was set to %s", topt->type);
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ } else if (ttp == TAB_NIY) {
+ sprintf(g->Message, "Unsupported table type %s", topt->type);
+ rc = HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } // endif ttp
+
+ if (!tab) {
+ if (ttp == TAB_TBL) {
+ // Make tab the first table of the list
+ char *p;
+
+ if (!tbl) {
+ strcpy(g->Message, "Missing table list");
+ rc = HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } // endif tbl
+
+ tab = PlugDup(g, tbl);
+
+ if ((p = strchr(tab, ',')))
+ *p = 0;
+
+ if ((p = strchr(tab, '.'))) {
+ *p = 0;
+ db = tab;
+ tab = p + 1;
+ } // endif p
+
+ } else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL)))
+ tab = table_s->table_name.str; // Default value
+
+ } // endif tab
+
+ switch (ttp) {
#if defined(ODBC_SUPPORT)
- case TAB_ODBC:
- dsn= strz(g, create_info->connect_string);
+ case TAB_ODBC:
+ dsn = strz(g, create_info->connect_string);
- if (fnc & (FNC_DSN | FNC_DRIVER)) {
- ok= true;
+ if (fnc & (FNC_DSN | FNC_DRIVER)) {
+ ok = true;
#if defined(PROMPT_OK)
- } else if (!stricmp(thd->main_security_ctx.host, "localhost")
- && cop == 1) {
- if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) {
- thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn));
- ok= true;
- } // endif dsn
+ } else if (!stricmp(thd->main_security_ctx.host, "localhost")
+ && cop == 1) {
+ if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) {
+ thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn));
+ ok = true;
+ } // endif dsn
#endif // PROMPT_OK
- } else if (!dsn) {
- sprintf(g->Message, "Missing %s connection string", topt->type);
- } else {
- // Store ODBC additional parameters
- sop= (POPARM)PlugSubAlloc(g, NULL, sizeof(ODBCPARM));
- sop->User= (char*)user;
- sop->Pwd= (char*)pwd;
- sop->Cto= cto;
- sop->Qto= qto;
- sop->UseCnc= cnc;
- ok= true;
- } // endif's
-
- supfnc |= (FNC_TABLE | FNC_DSN | FNC_DRIVER);
- break;
+ } else if (!dsn) {
+ sprintf(g->Message, "Missing %s connection string", topt->type);
+ } else {
+ // Store ODBC additional parameters
+ sop = (POPARM)PlugSubAlloc(g, NULL, sizeof(ODBCPARM));
+ sop->User = (char*)user;
+ sop->Pwd = (char*)pwd;
+ sop->Cto = cto;
+ sop->Qto = qto;
+ sop->UseCnc = cnc;
+ ok = true;
+ } // endif's
+
+ supfnc |= (FNC_TABLE | FNC_DSN | FNC_DRIVER);
+ break;
#endif // ODBC_SUPPORT
#if defined(JDBC_SUPPORT)
- case TAB_JDBC:
- if (fnc & FNC_DRIVER) {
- ok= true;
- } else if (!(url= strz(g, create_info->connect_string))) {
- strcpy(g->Message, "Missing URL");
- } else {
- // Store JDBC additional parameters
- int rc;
- PJDBCDEF jdef= new(g) JDBCDEF();
-
- jdef->SetName(create_info->alias);
- sjp= (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM));
- sjp->Driver= driver;
-// sjp->Properties = prop;
- sjp->Fsize= 0;
- sjp->Scrollable= false;
-
- if ((rc = jdef->ParseURL(g, url, false)) == RC_OK) {
- sjp->Url= url;
- sjp->User= (char*)user;
- sjp->Pwd= (char*)pwd;
- ok= true;
- } else if (rc == RC_NF) {
- if (jdef->GetTabname())
- tab= jdef->GetTabname();
-
- ok= jdef->SetParms(sjp);
- } // endif rc
-
- } // endif's
-
- supfnc |= (FNC_DRIVER | FNC_TABLE);
- break;
+ case TAB_JDBC:
+ if (fnc & FNC_DRIVER) {
+ ok = true;
+ } else if (!(url = strz(g, create_info->connect_string))) {
+ strcpy(g->Message, "Missing URL");
+ } else {
+ // Store JDBC additional parameters
+ int rc;
+ PJDBCDEF jdef = new(g) JDBCDEF();
+
+ jdef->SetName(create_info->alias);
+ sjp = (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM));
+ sjp->Driver = driver;
+ // sjp->Properties = prop;
+ sjp->Fsize = 0;
+ sjp->Scrollable = false;
+
+ if ((rc = jdef->ParseURL(g, url, false)) == RC_OK) {
+ sjp->Url = url;
+ sjp->User = (char*)user;
+ sjp->Pwd = (char*)pwd;
+ ok = true;
+ } else if (rc == RC_NF) {
+ if (jdef->GetTabname())
+ tab = (char*)jdef->GetTabname();
+
+ ok = jdef->SetParms(sjp);
+ } // endif rc
+
+ } // endif's
+
+ supfnc |= (FNC_DRIVER | FNC_TABLE);
+ break;
#endif // JDBC_SUPPORT
- case TAB_DBF:
- dbf= true;
- // Passthru
- case TAB_CSV:
- if (!fn && fnc != FNC_NO)
- sprintf(g->Message, "Missing %s file name", topt->type);
- else if (sep && strlen(sep) > 1)
- sprintf(g->Message, "Invalid separator %s", sep);
- else
- ok= true;
+ case TAB_DBF:
+ dbf = true;
+ // Passthru
+ case TAB_CSV:
+ if (!fn && fnc != FNC_NO)
+ sprintf(g->Message, "Missing %s file name", topt->type);
+ else if (sep && strlen(sep) > 1)
+ sprintf(g->Message, "Invalid separator %s", sep);
+ else
+ ok = true;
- break;
- case TAB_MYSQL:
- ok= true;
+ break;
+ case TAB_MYSQL:
+ ok = true;
- if (create_info->connect_string.str &&
- create_info->connect_string.length) {
- PMYDEF mydef= new(g) MYSQLDEF();
+ if (create_info->connect_string.str &&
+ create_info->connect_string.length) {
+ PMYDEF mydef = new(g) MYSQLDEF();
- dsn= strz(g, create_info->connect_string);
- mydef->SetName(create_info->alias);
+ dsn = strz(g, create_info->connect_string);
+ mydef->SetName(create_info->alias);
- if (!mydef->ParseURL(g, dsn, false)) {
- if (mydef->GetHostname())
- host= mydef->GetHostname();
+ if (!mydef->ParseURL(g, dsn, false)) {
+ if (mydef->GetHostname())
+ host = mydef->GetHostname();
- if (mydef->GetUsername())
- user= mydef->GetUsername();
+ if (mydef->GetUsername())
+ user = mydef->GetUsername();
- if (mydef->GetPassword())
- pwd= mydef->GetPassword();
+ if (mydef->GetPassword())
+ pwd = mydef->GetPassword();
- if (mydef->GetTabschema())
- db = mydef->GetTabschema();
+ if (mydef->GetTabschema())
+ db = mydef->GetTabschema();
- if (mydef->GetTabname())
- tab= mydef->GetTabname();
+ if (mydef->GetTabname())
+ tab = (char*)mydef->GetTabname();
- if (mydef->GetPortnumber())
- port= mydef->GetPortnumber();
+ if (mydef->GetPortnumber())
+ port = mydef->GetPortnumber();
- } else
- ok= false;
+ } else
+ ok = false;
- } else if (!user)
- user= "root";
+ } else if (!user)
+ user = "root";
- if (ok && CheckSelf(g, table_s, host, db, tab, src, port))
- ok= false;
+ if (ok && CheckSelf(g, table_s, host, db, tab, src, port))
+ ok = false;
- break;
+ break;
#if defined(__WIN__)
- case TAB_WMI:
- ok= true;
- break;
+ case TAB_WMI:
+ ok = true;
+ break;
#endif // __WIN__
#if defined(PIVOT_SUPPORT)
- case TAB_PIVOT:
- supfnc= FNC_NO;
+ case TAB_PIVOT:
+ supfnc = FNC_NO;
#endif // PIVOT_SUPPORT
- case TAB_PRX:
- case TAB_TBL:
- case TAB_XCL:
- case TAB_OCCUR:
- if (!src && !stricmp(tab, create_info->alias) &&
- (!db || !stricmp(db, table_s->db.str)))
- sprintf(g->Message, "A %s table cannot refer to itself", topt->type);
- else
- ok= true;
+ case TAB_PRX:
+ case TAB_TBL:
+ case TAB_XCL:
+ case TAB_OCCUR:
+ if (!src && !stricmp(tab, create_info->alias) &&
+ (!db || !stricmp(db, table_s->db.str)))
+ sprintf(g->Message, "A %s table cannot refer to itself", topt->type);
+ else
+ ok = true;
- break;
- case TAB_OEM:
- if (topt->module && topt->subtype)
- ok= true;
- else
- strcpy(g->Message, "Missing OEM module or subtype");
+ break;
+ case TAB_OEM:
+ if (topt->module && topt->subtype)
+ ok = true;
+ else
+ strcpy(g->Message, "Missing OEM module or subtype");
- break;
+ break;
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
- case TAB_XML:
+ case TAB_XML:
#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT
- case TAB_JSON:
- if (!fn && !zfn && !mul)
- sprintf(g->Message, "Missing %s file name", topt->type);
- else
- ok= true;
-
- break;
- case TAB_VIR:
- ok= true;
- break;
- default:
- sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
- break;
- } // endif ttp
+ case TAB_JSON:
+ dsn = strz(g, create_info->connect_string);
- // Check for supported catalog function
- if (ok && !(supfnc & fnc)) {
- sprintf(g->Message, "Unsupported catalog function %s for table type %s",
- fncn, topt->type);
- ok= false;
- } // endif supfnc
+ if (!fn && !zfn && !mul && !dsn)
+ sprintf(g->Message, "Missing %s file name", topt->type);
+ else
+ ok = true;
- if (src && fnc != FNC_NO) {
- strcpy(g->Message, "Cannot make catalog table from srcdef");
- ok= false;
- } // endif src
-
- if (ok) {
- char *cnm, *rem, *dft, *xtra, *key, *fmt;
- int i, len, prec, dec, typ, flg;
-
-// if (cat)
-// cat->SetDataPath(g, table_s->db.str);
-// else
-// return HA_ERR_INTERNAL_ERROR; // Should never happen
-
- dpath= SetPath(g, table_s->db.str);
+ break;
+#if defined(MONGO_SUPPORT)
+ case TAB_MONGO:
+ ok = true;
+ break;
+#endif // MONGO_SUPPORT
+ case TAB_VIR:
+ ok = true;
+ break;
+ default:
+ sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
+ break;
+ } // endif ttp
+
+ // Check for supported catalog function
+ if (ok && !(supfnc & fnc)) {
+ sprintf(g->Message, "Unsupported catalog function %s for table type %s",
+ fncn, topt->type);
+ ok = false;
+ } // endif supfnc
+
+ if (src && fnc != FNC_NO) {
+ strcpy(g->Message, "Cannot make catalog table from srcdef");
+ ok = false;
+ } // endif src
+
+ if (ok) {
+ const char *cnm, *rem;
+ char *dft, *xtra, *key, *fmt;
+ int i, len, prec, dec, typ, flg;
+
+ if (!(dpath = SetPath(g, table_s->db.str))) {
+ rc = HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } // endif dpath
- if (src && ttp != TAB_PIVOT && ttp != TAB_ODBC && ttp != TAB_JDBC) {
- qrp= SrcColumns(g, host, db, user, pwd, src, port);
+ if (src && ttp != TAB_PIVOT && ttp != TAB_ODBC && ttp != TAB_JDBC) {
+ qrp = SrcColumns(g, host, db, user, pwd, src, port);
- if (qrp && ttp == TAB_OCCUR)
- if (OcrSrcCols(g, qrp, col, ocl, rnk)) {
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- goto err;
- } // endif OcrSrcCols
+ if (qrp && ttp == TAB_OCCUR)
+ if (OcrSrcCols(g, qrp, col, ocl, rnk)) {
+ rc = HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } // endif OcrSrcCols
- } else switch (ttp) {
- case TAB_DBF:
- qrp= DBFColumns(g, dpath, fn, fnc == FNC_COL);
- break;
+ } else switch (ttp) {
+ case TAB_DBF:
+ qrp = DBFColumns(g, dpath, fn, fnc == FNC_COL);
+ break;
#if defined(ODBC_SUPPORT)
- case TAB_ODBC:
- switch (fnc) {
- case FNC_NO:
- case FNC_COL:
- if (src) {
- qrp= ODBCSrcCols(g, dsn, (char*)src, sop);
- src= NULL; // for next tests
- } else
- qrp= ODBCColumns(g, dsn, shm, tab, NULL,
- mxr, fnc == FNC_COL, sop);
+ case TAB_ODBC:
+ switch (fnc) {
+ case FNC_NO:
+ case FNC_COL:
+ if (src) {
+ qrp = ODBCSrcCols(g, dsn, (char*)src, sop);
+ src = NULL; // for next tests
+ } else
+ qrp = ODBCColumns(g, dsn, shm, tab, NULL,
+ mxr, fnc == FNC_COL, sop);
- break;
- case FNC_TABLE:
- qrp= ODBCTables(g, dsn, shm, tab, NULL, mxr, true, sop);
- break;
- case FNC_DSN:
- qrp= ODBCDataSources(g, mxr, true);
- break;
- case FNC_DRIVER:
- qrp= ODBCDrivers(g, mxr, true);
- break;
- default:
- sprintf(g->Message, "invalid catfunc %s", fncn);
- break;
- } // endswitch info
+ break;
+ case FNC_TABLE:
+ qrp = ODBCTables(g, dsn, shm, tab, NULL, mxr, true, sop);
+ break;
+ case FNC_DSN:
+ qrp = ODBCDataSources(g, mxr, true);
+ break;
+ case FNC_DRIVER:
+ qrp = ODBCDrivers(g, mxr, true);
+ break;
+ default:
+ sprintf(g->Message, "invalid catfunc %s", fncn);
+ break;
+ } // endswitch info
- break;
+ break;
#endif // ODBC_SUPPORT
#if defined(JDBC_SUPPORT)
- case TAB_JDBC:
- switch (fnc) {
- case FNC_NO:
- case FNC_COL:
- if (src) {
- qrp= JDBCSrcCols(g, (char*)src, sjp);
- src= NULL; // for next tests
- } else
- qrp= JDBCColumns(g, shm, tab, NULL, mxr, fnc == FNC_COL, sjp);
+ case TAB_JDBC:
+ switch (fnc) {
+ case FNC_NO:
+ case FNC_COL:
+ if (src) {
+ qrp = JDBCSrcCols(g, (char*)src, sjp);
+ src = NULL; // for next tests
+ } else
+ qrp = JDBCColumns(g, shm, tab, NULL, mxr, fnc == FNC_COL, sjp);
- break;
- case FNC_TABLE:
- qrp= JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp);
- break;
+ break;
+ case FNC_TABLE:
+ qrp = JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp);
+ break;
#if 0
- case FNC_DSN:
- qrp= JDBCDataSources(g, mxr, true);
- break;
+ case FNC_DSN:
+ qrp = JDBCDataSources(g, mxr, true);
+ break;
#endif // 0
- case FNC_DRIVER:
- qrp= JDBCDrivers(g, mxr, true);
- break;
- default:
- sprintf(g->Message, "invalid catfunc %s", fncn);
- break;
- } // endswitch info
+ case FNC_DRIVER:
+ qrp = JDBCDrivers(g, mxr, true);
+ break;
+ default:
+ sprintf(g->Message, "invalid catfunc %s", fncn);
+ break;
+ } // endswitch info
- break;
+ break;
#endif // JDBC_SUPPORT
- case TAB_MYSQL:
- qrp= MyColumns(g, thd, host, db, user, pwd, tab,
- NULL, port, fnc == FNC_COL);
- break;
- case TAB_CSV:
- qrp = CSVColumns(g, dpath, topt, fnc == FNC_COL);
- break;
+ case TAB_MYSQL:
+ qrp = MyColumns(g, thd, host, db, user, pwd, tab,
+ NULL, port, fnc == FNC_COL);
+ break;
+ case TAB_CSV:
+ qrp = CSVColumns(g, dpath, topt, fnc == FNC_COL);
+ break;
#if defined(__WIN__)
- case TAB_WMI:
- qrp= WMIColumns(g, nsp, cls, fnc == FNC_COL);
- break;
+ case TAB_WMI:
+ qrp = WMIColumns(g, nsp, cls, fnc == FNC_COL);
+ break;
#endif // __WIN__
- case TAB_PRX:
- case TAB_TBL:
- case TAB_XCL:
- case TAB_OCCUR:
- bif= fnc == FNC_COL;
- qrp= TabColumns(g, thd, db, tab, bif);
-
- if (!qrp && bif && fnc != FNC_COL) // tab is a view
- qrp= MyColumns(g, thd, host, db, user, pwd, tab, NULL, port, false);
-
- if (qrp && ttp == TAB_OCCUR && fnc != FNC_COL)
- if (OcrColumns(g, qrp, col, ocl, rnk)) {
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- goto err;
- } // endif OcrColumns
+ case TAB_PRX:
+ case TAB_TBL:
+ case TAB_XCL:
+ case TAB_OCCUR:
+ bif = fnc == FNC_COL;
+ qrp = TabColumns(g, thd, db, tab, bif);
+
+ if (!qrp && bif && fnc != FNC_COL) // tab is a view
+ qrp = MyColumns(g, thd, host, db, user, pwd, tab, NULL, port, false);
+
+ if (qrp && ttp == TAB_OCCUR && fnc != FNC_COL)
+ if (OcrColumns(g, qrp, col, ocl, rnk)) {
+ rc = HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } // endif OcrColumns
- break;
+ break;
#if defined(PIVOT_SUPPORT)
- case TAB_PIVOT:
- qrp= PivotColumns(g, tab, src, pic, fcl, skc, host, db, user, pwd, port);
- break;
+ case TAB_PIVOT:
+ qrp = PivotColumns(g, tab, src, pic, fcl, skc, host, db, user, pwd, port);
+ break;
#endif // PIVOT_SUPPORT
- case TAB_VIR:
- qrp= VirColumns(g, fnc == FNC_COL);
- break;
- case TAB_JSON:
- qrp= JSONColumns(g, (char*)db, topt, fnc == FNC_COL);
- break;
+ case TAB_VIR:
+ qrp = VirColumns(g, fnc == FNC_COL);
+ break;
+ case TAB_JSON:
+ qrp = JSONColumns(g, (char*)db, dsn, topt, fnc == FNC_COL);
+ break;
+#if defined(MONGO_SUPPORT)
+ case TAB_MONGO:
+ qrp = MGOColumns(g, (char*)db, topt, fnc == FNC_COL);
+ break;
+#endif // MONGO_SUPPORT
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
- case TAB_XML:
- qrp= XMLColumns(g, (char*)db, tab, topt, fnc == FNC_COL);
- break;
+ case TAB_XML:
+ qrp = XMLColumns(g, (char*)db, tab, topt, fnc == FNC_COL);
+ break;
#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT
- case TAB_OEM:
- qrp= OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL);
- break;
- default:
- strcpy(g->Message, "System error during assisted discovery");
- break;
- } // endswitch ttp
-
- if (!qrp) {
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- goto err;
- } // endif !qrp
-
- if (fnc != FNC_NO || src || ttp == TAB_PIVOT) {
- // Catalog like table
- for (crp= qrp->Colresp; !rc && crp; crp= crp->Next) {
- cnm= (ttp == TAB_PIVOT) ? crp->Name : encode(g, crp->Name);
- typ= crp->Type;
- len= crp->Length;
- dec= crp->Prec;
- flg= crp->Flag;
- v= (crp->Kdata->IsUnsigned()) ? 'U' : crp->Var;
- tm= (crp->Kdata->IsNullable()) ? 0 : NOT_NULL_FLAG;
-
- if (!len && typ == TYPE_STRING)
- len= 256; // STRBLK's have 0 length
-
- // Now add the field
- if (add_field(&sql, cnm, typ, len, dec, NULL, tm,
- NULL, NULL, NULL, NULL, flg, dbf, v))
- rc= HA_ERR_OUT_OF_MEM;
- } // endfor crp
-
- } else {
- char *schem= NULL;
- char *tn= NULL;
-
- // Not a catalog table
- if (!qrp->Nblin) {
- if (tab)
- sprintf(g->Message, "Cannot get columns from %s", tab);
- else
- strcpy(g->Message, "Fail to retrieve columns");
-
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- goto err;
- } // endif !nblin
-
- for (i= 0; !rc && i < qrp->Nblin; i++) {
- typ= len= prec= dec= 0;
- tm= NOT_NULL_FLAG;
- cnm= (char*)"noname";
- dft= xtra= key= fmt= tn= NULL;
- v= ' ';
- rem= NULL;
-
- for (crp= qrp->Colresp; crp; crp= crp->Next)
- switch (crp->Fld) {
- case FLD_NAME:
- if (ttp == TAB_PRX ||
- (ttp == TAB_CSV && topt->data_charset &&
- (!stricmp(topt->data_charset, "UTF8") ||
- !stricmp(topt->data_charset, "UTF-8"))))
- cnm= crp->Kdata->GetCharValue(i);
- else
- cnm= encode(g, crp->Kdata->GetCharValue(i));
-
- break;
- case FLD_TYPE:
- typ= crp->Kdata->GetIntValue(i);
- v = (crp->Nulls) ? crp->Nulls[i] : 0;
- break;
- case FLD_TYPENAME:
- tn= crp->Kdata->GetCharValue(i);
- break;
- case FLD_PREC:
- // PREC must be always before LENGTH
- len= prec= crp->Kdata->GetIntValue(i);
- break;
- case FLD_LENGTH:
- len= crp->Kdata->GetIntValue(i);
- break;
- case FLD_SCALE:
- dec = (!crp->Kdata->IsNull(i)) ? crp->Kdata->GetIntValue(i) : -1;
- break;
- case FLD_NULL:
- if (crp->Kdata->GetIntValue(i))
- tm= 0; // Nullable
-
- break;
- case FLD_FORMAT:
- fmt= (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL;
- break;
- case FLD_REM:
- rem= crp->Kdata->GetCharValue(i);
- break;
-// case FLD_CHARSET:
- // No good because remote table is already translated
-// if (*(csn= crp->Kdata->GetCharValue(i)))
-// cs= get_charset_by_name(csn, 0);
-
-// break;
- case FLD_DEFAULT:
- dft= crp->Kdata->GetCharValue(i);
- break;
- case FLD_EXTRA:
- xtra= crp->Kdata->GetCharValue(i);
-
- // Auto_increment is not supported yet
- if (!stricmp(xtra, "AUTO_INCREMENT"))
- xtra= NULL;
-
- break;
- case FLD_KEY:
- if (ttp == TAB_VIR)
- key= crp->Kdata->GetCharValue(i);
+ case TAB_OEM:
+ qrp = OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL);
+ break;
+ default:
+ strcpy(g->Message, "System error during assisted discovery");
+ break;
+ } // endswitch ttp
- break;
- case FLD_SCHEM:
+ if (!qrp) {
+ rc = HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } // endif !qrp
+
+ if (fnc != FNC_NO || src || ttp == TAB_PIVOT) {
+ // Catalog like table
+ for (crp = qrp->Colresp; !rc && crp; crp = crp->Next) {
+ cnm = (ttp == TAB_PIVOT) ? crp->Name : encode(g, crp->Name);
+ typ = crp->Type;
+ len = crp->Length;
+ dec = crp->Prec;
+ flg = crp->Flag;
+ v = (crp->Kdata->IsUnsigned()) ? 'U' : crp->Var;
+ tm = (crp->Kdata->IsNullable()) ? 0 : NOT_NULL_FLAG;
+
+ if (!len && typ == TYPE_STRING)
+ len = 256; // STRBLK's have 0 length
+
+ // Now add the field
+ if (add_field(&sql, cnm, typ, len, dec, NULL, tm,
+ NULL, NULL, NULL, NULL, flg, dbf, v))
+ rc = HA_ERR_OUT_OF_MEM;
+ } // endfor crp
+
+ } else {
+ char *schem = NULL;
+ char *tn = NULL;
+
+ // Not a catalog table
+ if (!qrp->Nblin) {
+ if (tab)
+ sprintf(g->Message, "Cannot get columns from %s", tab);
+ else
+ strcpy(g->Message, "Fail to retrieve columns");
+
+ rc = HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } // endif !nblin
+
+ for (i = 0; !rc && i < qrp->Nblin; i++) {
+ typ = len = prec = dec = 0;
+ tm = NOT_NULL_FLAG;
+ cnm = (char*)"noname";
+ dft = xtra = key = fmt = tn = NULL;
+ v = ' ';
+ rem = NULL;
+
+ for (crp = qrp->Colresp; crp; crp = crp->Next)
+ switch (crp->Fld) {
+ case FLD_NAME:
+ if (ttp == TAB_PRX ||
+ (ttp == TAB_CSV && topt->data_charset &&
+ (!stricmp(topt->data_charset, "UTF8") ||
+ !stricmp(topt->data_charset, "UTF-8"))))
+ cnm = crp->Kdata->GetCharValue(i);
+ else
+ cnm = encode(g, crp->Kdata->GetCharValue(i));
+
+ break;
+ case FLD_TYPE:
+ typ = crp->Kdata->GetIntValue(i);
+ v = (crp->Nulls) ? crp->Nulls[i] : 0;
+ break;
+ case FLD_TYPENAME:
+ tn = crp->Kdata->GetCharValue(i);
+ break;
+ case FLD_PREC:
+ // PREC must be always before LENGTH
+ len = prec = crp->Kdata->GetIntValue(i);
+ break;
+ case FLD_LENGTH:
+ len = crp->Kdata->GetIntValue(i);
+ break;
+ case FLD_SCALE:
+ dec = (!crp->Kdata->IsNull(i)) ? crp->Kdata->GetIntValue(i) : -1;
+ break;
+ case FLD_NULL:
+ if (crp->Kdata->GetIntValue(i))
+ tm = 0; // Nullable
+
+ break;
+ case FLD_FORMAT:
+ fmt = (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL;
+ break;
+ case FLD_REM:
+ rem = crp->Kdata->GetCharValue(i);
+ break;
+ // case FLD_CHARSET:
+ // No good because remote table is already translated
+ // if (*(csn= crp->Kdata->GetCharValue(i)))
+ // cs= get_charset_by_name(csn, 0);
+
+ // break;
+ case FLD_DEFAULT:
+ dft = crp->Kdata->GetCharValue(i);
+ break;
+ case FLD_EXTRA:
+ xtra = crp->Kdata->GetCharValue(i);
+
+ // Auto_increment is not supported yet
+ if (!stricmp(xtra, "AUTO_INCREMENT"))
+ xtra = NULL;
+
+ break;
+ case FLD_KEY:
+ if (ttp == TAB_VIR)
+ key = crp->Kdata->GetCharValue(i);
+
+ break;
+ case FLD_SCHEM:
#if defined(ODBC_SUPPORT) || defined(JDBC_SUPPORT)
- if ((ttp == TAB_ODBC || ttp == TAB_JDBC) && crp->Kdata) {
- if (schem && stricmp(schem, crp->Kdata->GetCharValue(i))) {
- sprintf(g->Message,
- "Several %s tables found, specify DBNAME", tab);
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- goto err;
- } else if (!schem)
- schem= crp->Kdata->GetCharValue(i);
-
- } // endif ttp
+ if ((ttp == TAB_ODBC || ttp == TAB_JDBC) && crp->Kdata) {
+ if (schem && stricmp(schem, crp->Kdata->GetCharValue(i))) {
+ sprintf(g->Message,
+ "Several %s tables found, specify DBNAME", tab);
+ rc = HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } else if (!schem)
+ schem = crp->Kdata->GetCharValue(i);
+
+ } // endif ttp
#endif // ODBC_SUPPORT || JDBC_SUPPORT
- default:
- break; // Ignore
- } // endswitch Fld
+ default:
+ break; // Ignore
+ } // endswitch Fld
#if defined(ODBC_SUPPORT)
- if (ttp == TAB_ODBC) {
- int plgtyp;
- bool w= false; // Wide character type
-
- // typ must be PLG type, not SQL type
- if (!(plgtyp= TranslateSQLType(typ, dec, prec, v, w))) {
- if (GetTypeConv() == TPC_SKIP) {
- // Skip this column
- sprintf(g->Message, "Column %s skipped (unsupported type %d)",
- cnm, typ);
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
- continue;
- } else {
- sprintf(g->Message, "Unsupported SQL type %d", typ);
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- goto err;
- } // endif type_conv
-
- } else
- typ= plgtyp;
-
- switch (typ) {
- case TYPE_STRING:
- if (w) {
- sprintf(g->Message, "Column %s is wide characters", cnm);
- push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message);
- } // endif w
-
- break;
- case TYPE_DOUBLE:
- // Some data sources do not count dec in length (prec)
- prec += (dec + 2); // To be safe
- break;
- case TYPE_DECIM:
- prec= len;
- break;
- default:
- dec= 0;
- } // endswitch typ
-
- } else
-#endif // ODBC_SUPPORT
-#if defined(JDBC_SUPPORT)
- if (ttp == TAB_JDBC) {
+ if (ttp == TAB_ODBC) {
int plgtyp;
+ bool w = false; // Wide character type
// typ must be PLG type, not SQL type
- if (!(plgtyp= TranslateJDBCType(typ, tn, dec, prec, v))) {
+ if (!(plgtyp = TranslateSQLType(typ, dec, prec, v, w))) {
if (GetTypeConv() == TPC_SKIP) {
// Skip this column
sprintf(g->Message, "Column %s skipped (unsupported type %d)",
@@ -5879,55 +5884,107 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
continue;
} else {
sprintf(g->Message, "Unsupported SQL type %d", typ);
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ rc = HA_ERR_INTERNAL_ERROR;
goto err;
} // endif type_conv
} else
- typ= plgtyp;
+ typ = plgtyp;
switch (typ) {
- case TYPE_DOUBLE:
- case TYPE_DECIM:
- // Some data sources do not count dec in length (prec)
- prec += (dec + 2); // To be safe
- break;
- default:
- dec= 0;
+ case TYPE_STRING:
+ if (w) {
+ sprintf(g->Message, "Column %s is wide characters", cnm);
+ push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message);
+ } // endif w
+
+ break;
+ case TYPE_DOUBLE:
+ // Some data sources do not count dec in length (prec)
+ prec += (dec + 2); // To be safe
+ break;
+ case TYPE_DECIM:
+ prec = len;
+ break;
+ default:
+ dec = 0;
} // endswitch typ
} else
#endif // ODBC_SUPPORT
- // Make the arguments as required by add_fields
- if (typ == TYPE_DOUBLE)
- prec= len;
+#if defined(JDBC_SUPPORT)
+ if (ttp == TAB_JDBC) {
+ int plgtyp;
+
+ // typ must be PLG type, not SQL type
+ if (!(plgtyp = TranslateJDBCType(typ, tn, dec, prec, v))) {
+ if (GetTypeConv() == TPC_SKIP) {
+ // Skip this column
+ sprintf(g->Message, "Column %s skipped (unsupported type %d)",
+ cnm, typ);
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ continue;
+ } else {
+ sprintf(g->Message, "Unsupported SQL type %d", typ);
+ rc = HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } // endif type_conv
+
+ } else
+ typ = plgtyp;
+
+ switch (typ) {
+ case TYPE_DOUBLE:
+ case TYPE_DECIM:
+ // Some data sources do not count dec in length (prec)
+ prec += (dec + 2); // To be safe
+ break;
+ default:
+ dec = 0;
+ } // endswitch typ
- if (typ == TYPE_DATE)
- prec= 0;
+ } else
+#endif // ODBC_SUPPORT
+ // Make the arguments as required by add_fields
+ if (typ == TYPE_DOUBLE)
+ prec = len;
- // Now add the field
- if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
- fmt, 0, dbf, v))
- rc= HA_ERR_OUT_OF_MEM;
- } // endfor i
+ if (typ == TYPE_DATE)
+ prec = 0;
- } // endif fnc
+ // Now add the field
+ if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
+ fmt, 0, dbf, v))
+ rc = HA_ERR_OUT_OF_MEM;
+ } // endfor i
- if (!rc)
- rc= init_table_share(thd, table_s, create_info, &sql);
+ } // endif fnc
- g->jump_level--;
- PopUser(xp);
- return rc;
- } // endif ok
+ if (!rc)
+ rc = init_table_share(thd, table_s, create_info, &sql);
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ //g->jump_level--;
+ //PopUser(xp);
+ //return rc;
+ } else {
+ rc = HA_ERR_UNSUPPORTED;
+ } // endif ok
+
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ rc = HA_ERR_INTERNAL_ERROR;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ rc = HA_ERR_INTERNAL_ERROR;
+ } // end catch
err:
- g->jump_level--;
- jer:
+ if (rc)
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+
PopUser(xp);
- return HA_ERR_INTERNAL_ERROR;
+ return rc;
} // end of connect_assisted_discovery
/**
@@ -6092,8 +6149,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (!part_info)
#endif // WITH_PARTITION_STORAGE_ENGINE
{const char *src= options->srcdef;
- char *host, *db, *tab= (char*)options->tabname;
- int port;
+ PCSZ host, db, tab= options->tabname;
+ int port;
host= GetListOption(g, "host", options->oplist, NULL);
db= GetStringOption("database", NULL);
@@ -6137,8 +6194,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endswitch ttp
if (type == TAB_XML) {
- bool dom; // True: MS-DOM, False libxml2
- char *xsup= GetListOption(g, "Xmlsup", options->oplist, "*");
+ bool dom; // True: MS-DOM, False libxml2
+ PCSZ xsup= GetListOption(g, "Xmlsup", options->oplist, "*");
// Note that if no support is specified, the default is MS-DOM
// on Windows and libxml2 otherwise
@@ -6209,7 +6266,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
for (field= table_arg->field; *field; field++) {
fp= *field;
- if (!fp->stored_in_db())
+ if (fp->vcol_info && !fp->stored_in_db())
continue; // This is a virtual column
if (fp->flags & AUTO_INCREMENT_FLAG) {
@@ -6398,15 +6455,15 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (options->zipped) {
// Check whether the zip entry must be made from a file
- char *fn = GetListOption(g, "Load", options->oplist, NULL);
+ PCSZ fn = GetListOption(g, "Load", options->oplist, NULL);
if (fn) {
- char zbuf[_MAX_PATH], buf[_MAX_PATH], dbpath[_MAX_PATH];
- char *entry = GetListOption(g, "Entry", options->oplist, NULL);
- char *a = GetListOption(g, "Append", options->oplist, "NO");
- bool append = *a == '1' || *a == 'Y' || *a == 'y' || !stricmp(a, "ON");
- char *m = GetListOption(g, "Mulentries", options->oplist, "NO");
- bool mul = *m == '1' || *m == 'Y' || *m == 'y' || !stricmp(m, "ON");
+ char zbuf[_MAX_PATH], buf[_MAX_PATH], dbpath[_MAX_PATH];
+ PCSZ entry = GetListOption(g, "Entry", options->oplist, NULL);
+ PCSZ a = GetListOption(g, "Append", options->oplist, "NO");
+ bool append = *a == '1' || *a == 'Y' || *a == 'y' || !stricmp(a, "ON");
+ PCSZ m = GetListOption(g, "Mulentries", options->oplist, "NO");
+ bool mul = *m == '1' || *m == 'Y' || *m == 'y' || !stricmp(m, "ON");
if (!entry && !mul) {
my_message(ER_UNKNOWN_ERROR, "Missing entry name", MYF(0));
@@ -6474,11 +6531,10 @@ int ha_connect::create(const char *name, TABLE *table_arg,
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
- SetDataPath(g, table_arg->s->db.str);
-
- if (cat) {
-// cat->SetDataPath(g, table_arg->s->db.str);
-
+ if (SetDataPath(g, table_arg->s->db.str)) {
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ rc = HA_ERR_INTERNAL_ERROR;
+ } else if (cat) {
#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (part_info)
strncpy(partname,
@@ -6534,8 +6590,9 @@ bool ha_connect::FileExists(const char *fn, bool bf)
return true;
if (table) {
- char *s, tfn[_MAX_PATH], filename[_MAX_PATH], path[_MAX_PATH];
- bool b= false;
+ const char *s;
+ char tfn[_MAX_PATH], filename[_MAX_PATH], path[_MAX_PATH];
+ bool b= false;
int n;
struct stat info;
@@ -6592,9 +6649,9 @@ bool ha_connect::CheckString(const char *str1, const char *str2)
/**
check whether a string option have changed
*/
-bool ha_connect::SameString(TABLE *tab, char *opn)
+bool ha_connect::SameString(TABLE *tab, PCSZ opn)
{
- char *str1, *str2;
+ PCSZ str1, str2;
tshp= tab->s; // The altered table
str1= GetStringOption(opn);
@@ -6606,7 +6663,7 @@ bool ha_connect::SameString(TABLE *tab, char *opn)
/**
check whether a Boolean option have changed
*/
-bool ha_connect::SameBool(TABLE *tab, char *opn)
+bool ha_connect::SameBool(TABLE *tab, PCSZ opn)
{
bool b1, b2;
@@ -6620,7 +6677,7 @@ bool ha_connect::SameBool(TABLE *tab, char *opn)
/**
check whether an integer option have changed
*/
-bool ha_connect::SameInt(TABLE *tab, char *opn)
+bool ha_connect::SameInt(TABLE *tab, PCSZ opn)
{
int i1, i2;
@@ -6799,7 +6856,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
// Conversion to outward table is only allowed for file based
// tables whose file does not exist.
tshp= altered_table->s;
- char *fn= GetStringOption("filename");
+ PCSZ fn= GetStringOption("filename");
tshp= NULL;
if (FileExists(fn, false)) {
@@ -7044,10 +7101,10 @@ maria_declare_plugin(connect)
PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */
- 0x0105, /* version number (1.05) */
+ 0x0106, /* version number (1.05) */
NULL, /* status variables */
connect_system_variables, /* system variables */
- "1.05.0003", /* string version */
- MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+ "1.06.0001", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index cb15d371b5c..8d8307b4bd1 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -61,7 +61,7 @@ public:
oldopn= newopn= NULL;
oldpix= newpix= NULL;}
- inline char *SetName(PGLOBAL g, char *name) {return PlugDup(g, name);}
+ inline char *SetName(PGLOBAL g, PCSZ name) {return PlugDup(g, name);}
bool oldsep; // Sepindex before create/alter
bool newsep; // Sepindex after create/alter
@@ -168,18 +168,18 @@ public:
static bool connect_init(void);
static bool connect_end(void);
TABTYPE GetRealType(PTOS pos= NULL);
- char *GetRealString(const char *s);
- char *GetStringOption(char *opname, char *sdef= NULL);
+ char *GetRealString(PCSZ s);
+ PCSZ GetStringOption(PCSZ opname, PCSZ sdef= NULL);
PTOS GetTableOptionStruct(TABLE_SHARE *s= NULL);
- bool GetBooleanOption(char *opname, bool bdef);
- bool SetBooleanOption(char *opname, bool b);
- int GetIntegerOption(char *opname);
- bool GetIndexOption(KEY *kp, char *opname);
- bool CheckString(const char *str1, const char *str2);
- bool SameString(TABLE *tab, char *opn);
- bool SetIntegerOption(char *opname, int n);
- bool SameInt(TABLE *tab, char *opn);
- bool SameBool(TABLE *tab, char *opn);
+ bool GetBooleanOption(PCSZ opname, bool bdef);
+ bool SetBooleanOption(PCSZ opname, bool b);
+ int GetIntegerOption(PCSZ opname);
+ bool GetIndexOption(KEY *kp, PCSZ opname);
+ bool CheckString(PCSZ str1, PCSZ str2);
+ bool SameString(TABLE *tab, PCSZ opn);
+ bool SetIntegerOption(PCSZ opname, int n);
+ bool SameInt(TABLE *tab, PCSZ opn);
+ bool SameBool(TABLE *tab, PCSZ opn);
bool FileExists(const char *fn, bool bf);
bool NoFieldOptionChange(TABLE *tab);
PFOS GetFieldOptionStruct(Field *fp);
@@ -187,8 +187,8 @@ public:
PXOS GetIndexOptionStruct(KEY *kp);
PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
bool CheckVirtualIndex(TABLE_SHARE *s);
- const char *GetDBName(const char *name);
- const char *GetTableName(void);
+ PCSZ GetDBName(PCSZ name);
+ PCSZ GetTableName(void);
char *GetPartName(void);
//int GetColNameLen(Field *fp);
//char *GetColName(Field *fp);
@@ -197,9 +197,9 @@ public:
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
bool IsPartitioned(void);
bool IsUnique(uint n);
- char *GetDataPath(void) {return (char*)datapath;}
+ PCSZ GetDataPath(void) {return datapath;}
- void SetDataPath(PGLOBAL g, const char *path);
+ bool SetDataPath(PGLOBAL g, PCSZ path);
PTDB GetTDB(PGLOBAL g);
int OpenTable(PGLOBAL g, bool del= false);
bool CheckColumnList(PGLOBAL g);
@@ -513,7 +513,7 @@ protected:
ulong hnum; // The number of this handler
query_id_t valid_query_id; // The one when tdbp was allocated
query_id_t creat_query_id; // The one when handler was allocated
- char *datapath; // Is the Path of DB data directory
+ PCSZ datapath; // Is the Path of DB data directory
PTDB tdbp; // To table class object
PVAL sdvalin1; // Used to convert date values
PVAL sdvalin2; // Used to convert date values
diff --git a/storage/connect/inihandl.c b/storage/connect/inihandl.c
index e5eb3567779..0ce0eb9fa0d 100644
--- a/storage/connect/inihandl.c
+++ b/storage/connect/inihandl.c
@@ -193,7 +193,7 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section )
}
for (key = section->key; key; key = key->next)
- if (key->name[0]) {
+ if (key->name && key->name[0]) {
fprintf(file, "%s", SVP(key->name));
if (key->value)
diff --git a/storage/connect/jdbccat.h b/storage/connect/jdbccat.h
index 7108aa376ce..0b87df8bb51 100644
--- a/storage/connect/jdbccat.h
+++ b/storage/connect/jdbccat.h
@@ -4,10 +4,10 @@
typedef struct jdbc_parms {
int CheckSize(int rows);
- char *Driver; // JDBC driver
- char *Url; // Driver URL
- char *User; // User connect info
- char *Pwd; // Password connect info
+ PCSZ Driver; // JDBC driver
+ PCSZ Url; // Driver URL
+ PCSZ User; // User connect info
+ PCSZ Pwd; // Password connect info
//char *Properties; // Connection property list
//int Cto; // Connect timeout
//int Qto; // Query timeout
@@ -19,12 +19,12 @@ typedef struct jdbc_parms {
/* JDBC catalog function prototypes. */
/***********************************************************************/
#if defined(PROMPT_OK)
-char *JDBCCheckConnection(PGLOBAL g, char *dsn, int cop);
+char *JDBCCheckConnection(PGLOBAL g, PCSZ dsn, int cop);
#endif // PROMPT_OK
//PQRYRES JDBCDataSources(PGLOBAL g, int maxres, bool info);
-PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table,
- char *colpat, int maxres, bool info, PJPARM sop);
-PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sop);
-PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat,
- char *tabtyp, int maxres, bool info, PJPARM sop);
+PQRYRES JDBCColumns(PGLOBAL g, PCSZ db, PCSZ table,
+ PCSZ colpat, int maxres, bool info, PJPARM sop);
+PQRYRES JDBCSrcCols(PGLOBAL g, PCSZ src, PJPARM sop);
+PQRYRES JDBCTables(PGLOBAL g, PCSZ db, PCSZ tabpat,
+ PCSZ tabtyp, int maxres, bool info, PJPARM sop);
PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info);
diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp
index c1d077406b7..6073936283c 100644
--- a/storage/connect/jdbconn.cpp
+++ b/storage/connect/jdbconn.cpp
@@ -189,8 +189,8 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
/***********************************************************************/
/* Allocate the structure used to refer to the result set. */
/***********************************************************************/
-static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db,
- char *tab, PQRYRES qrp)
+static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, PCSZ db,
+ PCSZ tab, PQRYRES qrp)
{
JCATPARM *cap;
@@ -213,7 +213,7 @@ static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db,
/* JDBCColumns: constructs the result blocks containing all columns */
/* of a JDBC table that will be retrieved by GetData commands. */
/***********************************************************************/
-PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat,
+PQRYRES JDBCColumns(PGLOBAL g, PCSZ db, PCSZ table, PCSZ colpat,
int maxres, bool info, PJPARM sjp)
{
int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING,
@@ -316,7 +316,7 @@ PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat,
/* JDBCSrcCols: constructs the result blocks containing the */
/* description of all the columns of a Srcdef option. */
/**************************************************************************/
-PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sjp)
+PQRYRES JDBCSrcCols(PGLOBAL g, PCSZ src, PJPARM sjp)
{
char *sqry;
PQRYRES qrp;
@@ -330,7 +330,7 @@ PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sjp)
sqry = (char*)PlugSubAlloc(g, NULL, strlen(src) + 2);
sprintf(sqry, src, "1=1"); // dummy where clause
} else
- sqry = src;
+ sqry = (char*)src;
qrp = jcp->GetMetaData(g, sqry);
jcp->Close();
@@ -341,7 +341,7 @@ PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sjp)
/* JDBCTables: constructs the result blocks containing all tables in */
/* an JDBC database that will be retrieved by GetData commands. */
/**************************************************************************/
-PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp,
+PQRYRES JDBCTables(PGLOBAL g, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
int maxres, bool info, PJPARM sjp)
{
int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING,
@@ -1059,7 +1059,7 @@ int JDBConn::Open(PJPARM sop)
/***********************************************************************/
/* Execute an SQL command. */
/***********************************************************************/
-int JDBConn::ExecSQLcommand(char *sql)
+int JDBConn::ExecSQLcommand(PCSZ sql)
{
int rc;
jint n;
@@ -1142,7 +1142,7 @@ int JDBConn::Fetch(int pos)
/***********************************************************************/
/* Restart from beginning of result set */
/***********************************************************************/
-int JDBConn::Rewind(char *sql)
+int JDBConn::Rewind(PCSZ sql)
{
int rbuf = -1;
@@ -1200,7 +1200,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
if (rank == 0)
if (!name || (jn = env->NewStringUTF(name)) == nullptr) {
sprintf(g->Message, "Fail to allocate jstring %s", SVP(name));
- longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
+ throw TYPE_AM_JDBC;
} // endif name
// Returns 666 is case of error
@@ -1208,7 +1208,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
if (Check((ctyp == 666) ? -1 : 1)) {
sprintf(g->Message, "Getting ctyp: %s", Msg);
- longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
+ throw TYPE_AM_JDBC;
} // endif Check
if (val->GetNullable())
@@ -1227,7 +1227,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
case 12: // VARCHAR
case -1: // LONGVARCHAR
case 1: // CHAR
- if (jb)
+ case 3: // DECIMAL
+ if (jb && ctyp != 3)
cn = (jstring)jb;
else if (!gmID(g, chrfldid, "StringField", "(ILjava/lang/String;)Ljava/lang/String;"))
cn = (jstring)env->CallObjectMethod(job, chrfldid, (jint)rank, jn);
@@ -1253,7 +1254,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
break;
case 8: // DOUBLE
case 2: // NUMERIC
- case 3: // DECIMAL
+//case 3: // DECIMAL
if (!gmID(g, dblfldid, "DoubleField", "(ILjava/lang/String;)D"))
val->SetValue((double)env->CallDoubleMethod(job, dblfldid, rank, jn));
else
@@ -1314,7 +1315,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
env->DeleteLocalRef(jn);
sprintf(g->Message, "SetColumnValue: %s rank=%d ctyp=%d", Msg, rank, (int)ctyp);
- longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
+ throw TYPE_AM_JDBC;
} // endif Check
if (rank == 0)
@@ -1325,7 +1326,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
/***********************************************************************/
/* Prepare an SQL statement for insert. */
/***********************************************************************/
-bool JDBConn::PrepareSQL(char *sql)
+bool JDBConn::PrepareSQL(PCSZ sql)
{
bool b = true;
PGLOBAL& g = m_G;
@@ -1348,7 +1349,7 @@ bool JDBConn::PrepareSQL(char *sql)
/***********************************************************************/
/* Execute an SQL query that returns a result set. */
/***********************************************************************/
-int JDBConn::ExecuteQuery(char *sql)
+int JDBConn::ExecuteQuery(PCSZ sql)
{
int rc = RC_FX;
jint ncol;
@@ -1376,7 +1377,7 @@ int JDBConn::ExecuteQuery(char *sql)
/***********************************************************************/
/* Execute an SQL query and get the affected rows. */
/***********************************************************************/
-int JDBConn::ExecuteUpdate(char *sql)
+int JDBConn::ExecuteUpdate(PCSZ sql)
{
int rc = RC_FX;
jint n;
@@ -1404,7 +1405,7 @@ int JDBConn::ExecuteUpdate(char *sql)
/***********************************************************************/
/* Get the number of lines of the result set. */
/***********************************************************************/
-int JDBConn::GetResultSize(char *sql, JDBCCOL *colp)
+int JDBConn::GetResultSize(PCSZ sql, JDBCCOL *colp)
{
int rc, n = 0;
@@ -1642,7 +1643,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
/* GetMetaData: constructs the result blocks containing the */
/* description of all the columns of an SQL command. */
/**************************************************************************/
- PQRYRES JDBConn::GetMetaData(PGLOBAL g, char *src)
+ PQRYRES JDBConn::GetMetaData(PGLOBAL g, PCSZ src)
{
static int buftyp[] = {TYPE_STRING, TYPE_INT, TYPE_INT,
TYPE_INT, TYPE_INT};
@@ -1844,7 +1845,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
PGLOBAL& g = m_G;
// void *buffer;
int i, ncol;
- PSZ fnc = "Unknown";
+ PCSZ fnc = "Unknown";
uint n;
short len, tp;
int crow = 0;
@@ -1942,6 +1943,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
} // endif len
pval[n] = AllocateValue(g, crp->Type, len);
+ pval[n]->SetNullable(true);
if (crp->Type == TYPE_STRING) {
pbuf[n] = (char*)PlugSubAlloc(g, NULL, len);
diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h
index 9d428142839..73271c8f5be 100644
--- a/storage/connect/jdbconn.h
+++ b/storage/connect/jdbconn.h
@@ -46,9 +46,9 @@ enum JCATINFO {
typedef struct tagJCATPARM {
JCATINFO Id; // Id to indicate function
PQRYRES Qrp; // Result set pointer
- char *DB; // Database (Schema)
- char *Tab; // Table name or pattern
- char *Pat; // Table type or column pattern
+ PCSZ DB; // Database (Schema)
+ PCSZ Tab; // Table name or pattern
+ PCSZ Pat; // Table type or column pattern
} JCATPARM;
typedef jint(JNICALL *CRTJVM) (JavaVM **, void **, void *);
@@ -77,7 +77,7 @@ public:
JDBConn(PGLOBAL g, TDBJDBC *tdbp);
int Open(PJPARM sop);
- int Rewind(char *sql);
+ int Rewind(PCSZ sql);
void Close(void);
PQRYRES AllocateResult(PGLOBAL g);
@@ -96,19 +96,19 @@ public:
//void SetQueryTimeout(DWORD sec) {m_QueryTimeout = sec;}
//void SetUserName(PSZ user) {m_User = user;}
//void SetUserPwd(PSZ pwd) {m_Pwd = pwd;}
- int GetResultSize(char *sql, JDBCCOL *colp);
- int ExecuteQuery(char *sql);
- int ExecuteUpdate(char *sql);
+ int GetResultSize(PCSZ sql, JDBCCOL *colp);
+ int ExecuteQuery(PCSZ sql);
+ int ExecuteUpdate(PCSZ sql);
int Fetch(int pos = 0);
- bool PrepareSQL(char *sql);
+ bool PrepareSQL(PCSZ sql);
int ExecuteSQL(void);
bool SetParam(JDBCCOL *colp);
- int ExecSQLcommand(char *sql);
+ int ExecSQLcommand(PCSZ sql);
void SetColumnValue(int rank, PSZ name, PVAL val);
int GetCatInfo(JCATPARM *cap);
//bool GetDataSources(PQRYRES qrp);
bool GetDrivers(PQRYRES qrp);
- PQRYRES GetMetaData(PGLOBAL g, char *src);
+ PQRYRES GetMetaData(PGLOBAL g, PCSZ src);
public:
// Set static variables
@@ -174,16 +174,10 @@ protected:
jmethodID timfldid; // The TimeField method ID
jmethodID tspfldid; // The TimestampField method ID
jmethodID bigfldid; // The BigintField method ID
- //DWORD m_LoginTimeout;
-//DWORD m_QueryTimeout;
-//DWORD m_UpdateOptions;
- char *Msg;
+ PCSZ Msg;
char *m_Wrap;
char m_IDQuoteChar[2];
-//PSZ m_Driver;
-//PSZ m_Url;
-//PSZ m_User;
- PSZ m_Pwd;
+ PCSZ m_Pwd;
int m_Ncol;
int m_Aff;
int m_Rows;
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp
index b473871e9f7..44758e7b0ad 100644
--- a/storage/connect/json.cpp
+++ b/storage/connect/json.cpp
@@ -53,6 +53,36 @@ void trans_func(unsigned int u, _EXCEPTION_POINTERS* pExp)
char *GetExceptionDesc(PGLOBAL g, unsigned int e);
#endif // SE_CATCH
+/***********************************************************************/
+/* IsNum: check whether this string is all digits. */
+/***********************************************************************/
+bool IsNum(PSZ s)
+{
+ for (char *p = s; *p; p++)
+ if (*p == ']')
+ break;
+ else if (!isdigit(*p) || *p == '-')
+ return false;
+
+ return true;
+} // end of IsNum
+
+/***********************************************************************/
+/* NextChr: return the first found '[' or Sep pointer. */
+/***********************************************************************/
+char *NextChr(PSZ s, char sep)
+{
+ char *p1 = strchr(s, '[');
+ char *p2 = strchr(s, sep);
+
+ if (!p2)
+ return p1;
+ else if (p1)
+ return MY_MIN(p1, p2);
+
+ return p2;
+} // end of NextChr
+
/***********************************************************************/
/* Parse a json string. */
@@ -60,7 +90,7 @@ char *GetExceptionDesc(PGLOBAL g, unsigned int e);
/***********************************************************************/
PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
{
- int i, rc, pretty = (ptyp) ? *ptyp : 3;
+ int i, pretty = (ptyp) ? *ptyp : 3;
bool b = false, pty[3] = {true, true, true};
PJSON jsp = NULL;
STRG src;
@@ -81,117 +111,91 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n')))
pty[0] = false;
-
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return NULL;
- } // endif jump_level
-
-#if defined(SE_CATCH)
- // Let's try to recover from any kind of interrupt
- _se_translator_function f = _set_se_translator(trans_func);
-
try {
-#endif // SE_CATCH --------------------- try section --------------------
- if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) {
- goto err;
- } // endif rc
-
-#if defined(SE_CATCH) // ------------- end of try section -----------------
- } catch (SE_Exception e) {
- sprintf(g->Message, "ParseJson: exception doing setjmp: %s (rc=%hd)",
- GetExceptionDesc(g, e.nSE), e.nSE);
- _set_se_translator(f);
- goto err;
- } catch (...) {
- strcpy(g->Message, "Exception doing setjmp");
- _set_se_translator(f);
- goto err;
- } // end of try-catches
-
- _set_se_translator(f);
-#endif // SE_CATCH
-
- for (i = 0; i < len; i++)
- switch (s[i]) {
- case '[':
- if (jsp)
- goto tryit;
- else if (!(jsp = ParseArray(g, ++i, src, pty)))
- goto err;
-
- break;
- case '{':
- if (jsp)
- goto tryit;
- else if (!(jsp = ParseObject(g, ++i, src, pty)))
- goto err;
-
- break;
- case ' ':
- case '\t':
- case '\n':
- case '\r':
- break;
- case ',':
- if (jsp && (pretty == 1 || pretty == 3)) {
- if (comma)
- *comma = true;
-
- pty[0] = pty[2] = false;
- break;
- } // endif pretty
-
- sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty);
- goto err;
- case '(':
- b = true;
- break;
- case ')':
- if (b) {
- b = false;
- break;
- } // endif b
-
- default:
- if (jsp)
- goto tryit;
- else if (!(jsp = ParseValue(g, i, src, pty)))
- goto err;
-
- break;
- }; // endswitch s[i]
-
- if (!jsp)
- sprintf(g->Message, "Invalid Json string '%.*s'", 50, s);
- else if (ptyp && pretty == 3) {
- *ptyp = 3; // Not recognized pretty
-
- for (i = 0; i < 3; i++)
- if (pty[i]) {
- *ptyp = i;
- break;
- } // endif pty
-
- } // endif ptyp
-
- g->jump_level--;
- return jsp;
+ for (i = 0; i < len; i++)
+ switch (s[i]) {
+ case '[':
+ if (jsp)
+ goto tryit;
+ else if (!(jsp = ParseArray(g, ++i, src, pty)))
+ throw 1;
+
+ break;
+ case '{':
+ if (jsp)
+ goto tryit;
+ else if (!(jsp = ParseObject(g, ++i, src, pty)))
+ throw 2;
+
+ break;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+ case ',':
+ if (jsp && (pretty == 1 || pretty == 3)) {
+ if (comma)
+ *comma = true;
+
+ pty[0] = pty[2] = false;
+ break;
+ } // endif pretty
+
+ sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty);
+ throw 3;
+ case '(':
+ b = true;
+ break;
+ case ')':
+ if (b) {
+ b = false;
+ break;
+ } // endif b
+
+ default:
+ if (jsp)
+ goto tryit;
+ else if (!(jsp = ParseValue(g, i, src, pty)))
+ throw 4;
+
+ break;
+ }; // endswitch s[i]
+
+ if (!jsp)
+ sprintf(g->Message, "Invalid Json string '%.*s'", 50, s);
+ else if (ptyp && pretty == 3) {
+ *ptyp = 3; // Not recognized pretty
+
+ for (i = 0; i < 3; i++)
+ if (pty[i]) {
+ *ptyp = i;
+ break;
+ } // endif pty
+
+ } // endif ptyp
+
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ jsp = NULL;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ jsp = NULL;
+ } // end catch
+
+ return jsp;
tryit:
if (pty[0] && (!pretty || pretty > 2)) {
if ((jsp = ParseArray(g, (i = 0), src, pty)) && ptyp && pretty == 3)
*ptyp = (pty[0]) ? 0 : 3;
- g->jump_level--;
return jsp;
} else
strcpy(g->Message, "More than one item in file");
-err:
- g->jump_level--;
- return NULL;
+ return NULL;
} // end of ParseJson
/***********************************************************************/
@@ -335,16 +339,16 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty)
PJVAL jvp = new(g) JVALUE;
for (; i < len; i++)
- switch (s[i]) {
- case '\n':
- pty[0] = pty[1] = false;
- case '\r':
- case ' ':
- case '\t':
- break;
- default:
- goto suite;
- } // endswitch
+ switch (s[i]) {
+ case '\n':
+ pty[0] = pty[1] = false;
+ case '\r':
+ case ' ':
+ case '\t':
+ break;
+ default:
+ goto suite;
+ } // endswitch
suite:
switch (s[i]) {
@@ -585,78 +589,75 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty)
{
PSZ str = NULL;
- bool b = false, err = true;
- JOUT *jp;
+ bool b = false, err = true;
+ JOUT *jp;
FILE *fs = NULL;
g->Message[0] = 0;
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return NULL;
- } // endif jump_level
-
- if (setjmp(g->jumper[++g->jump_level])) {
- str = NULL;
- goto fin;
- } // endif jmp
-
- if (!jsp) {
- strcpy(g->Message, "Null json tree");
- goto fin;
- } else if (!fn) {
- // Serialize to a string
- jp = new(g) JOUTSTR(g);
- b = pretty == 1;
- } else {
- if (!(fs = fopen(fn, "wb"))) {
- sprintf(g->Message, MSG(OPEN_MODE_ERROR),
- "w", (int)errno, fn);
- strcat(strcat(g->Message, ": "), strerror(errno));
- goto fin;;
- } else if (pretty >= 2) {
- // Serialize to a pretty file
- jp = new(g)JOUTPRT(g, fs);
+ try {
+ if (!jsp) {
+ strcpy(g->Message, "Null json tree");
+ throw 1;
+ } else if (!fn) {
+ // Serialize to a string
+ jp = new(g) JOUTSTR(g);
+ b = pretty == 1;
} else {
- // Serialize to a flat file
- b = true;
- jp = new(g)JOUTFILE(g, fs, pretty);
- } // endif's
-
- } // endif's
-
- switch (jsp->GetType()) {
- case TYPE_JAR:
- err = SerializeArray(jp, (PJAR)jsp, b);
- break;
- case TYPE_JOB:
- err = ((b && jp->Prty()) && jp->WriteChr('\t'));
- err |= SerializeObject(jp, (PJOB)jsp);
- break;
- case TYPE_JVAL:
- err = SerializeValue(jp, (PJVAL)jsp);
- break;
- default:
- strcpy(g->Message, "Invalid json tree");
- } // endswitch Type
+ if (!(fs = fopen(fn, "wb"))) {
+ sprintf(g->Message, MSG(OPEN_MODE_ERROR),
+ "w", (int)errno, fn);
+ strcat(strcat(g->Message, ": "), strerror(errno));
+ throw 2;
+ } else if (pretty >= 2) {
+ // Serialize to a pretty file
+ jp = new(g)JOUTPRT(g, fs);
+ } else {
+ // Serialize to a flat file
+ b = true;
+ jp = new(g)JOUTFILE(g, fs, pretty);
+ } // endif's
+
+ } // endif's
+
+ switch (jsp->GetType()) {
+ case TYPE_JAR:
+ err = SerializeArray(jp, (PJAR)jsp, b);
+ break;
+ case TYPE_JOB:
+ err = ((b && jp->Prty()) && jp->WriteChr('\t'));
+ err |= SerializeObject(jp, (PJOB)jsp);
+ break;
+ case TYPE_JVAL:
+ err = SerializeValue(jp, (PJVAL)jsp);
+ break;
+ default:
+ strcpy(g->Message, "Invalid json tree");
+ } // endswitch Type
+
+ if (fs) {
+ fputs(EL, fs);
+ fclose(fs);
+ str = (err) ? NULL : strcpy(g->Message, "Ok");
+ } else if (!err) {
+ str = ((JOUTSTR*)jp)->Strp;
+ jp->WriteChr('\0');
+ PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N);
+ } else {
+ if (!g->Message[0])
+ strcpy(g->Message, "Error in Serialize");
- if (fs) {
- fputs(EL, fs);
- fclose(fs);
- str = (err) ? NULL : strcpy(g->Message, "Ok");
- } else if (!err) {
- str = ((JOUTSTR*)jp)->Strp;
- jp->WriteChr('\0');
- PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N);
- } else {
- if (!g->Message[0])
- strcpy(g->Message, "Error in Serialize");
+ } // endif's
- } // endif's
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ str = NULL;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ str = NULL;
+ } // end catch
-fin:
- g->jump_level--;
return str;
} // end of Serialize
@@ -965,7 +966,7 @@ return false;
/***********************************************************************/
/* Add a new pair to an Object. */
/***********************************************************************/
-PJPR JOBJECT::AddPair(PGLOBAL g, PSZ key)
+PJPR JOBJECT::AddPair(PGLOBAL g, PCSZ key)
{
PJPR jpp = new(g) JPAIR(key);
@@ -1021,7 +1022,24 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSZ text)
if (!First && n)
return NULL;
- else for (PJPR jp = First; jp; jp = jp->Next)
+ else if (n == 1 && Size == 1 && !strcmp(First->GetKey(), "$date")) {
+ int i;
+
+ First->Val->GetText(g, text);
+ i = (text[1] == '-' ? 2 : 1);
+
+ if (IsNum(text + i)) {
+ // Date is in milliseconds
+ int j = (int)strlen(text);
+
+ if (j >= 4 + i)
+ text[j - 3] = 0; // Change it to seconds
+ else
+ strcpy(text, " 0");
+
+ } // endif text
+
+ } else for (PJPR jp = First; jp; jp = jp->Next)
jp->Val->GetText(g, text);
if (n)
@@ -1051,7 +1069,7 @@ bool JOBJECT::Merge(PGLOBAL g, PJSON jsp)
/***********************************************************************/
/* Set or add a value corresponding to the given key. */
/***********************************************************************/
-void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key)
+void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PCSZ key)
{
PJPR jp;
@@ -1071,7 +1089,7 @@ void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key)
/***********************************************************************/
/* Delete a value corresponding to the given key. */
/***********************************************************************/
-void JOBJECT::DeleteKey(PSZ key)
+void JOBJECT::DeleteKey(PCSZ key)
{
PJPR jp, *pjp = &First;
@@ -1250,10 +1268,10 @@ JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON()
/***********************************************************************/
/* Constructor for a given string. */
/***********************************************************************/
-JVALUE::JVALUE(PGLOBAL g, PSZ strp) : JSON()
+JVALUE::JVALUE(PGLOBAL g, PCSZ strp) : JSON()
{
Jsp = NULL;
- Value = AllocateValue(g, strp, TYPE_STRING);
+ Value = AllocateValue(g, (void*)strp, TYPE_STRING);
Next = NULL;
Del = false;
} // end of JVALUE constructor
@@ -1341,7 +1359,7 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
if (s)
strcat(strcat(text, " "), s);
else
- strcat(text, " ???");
+ strcat(text, " <null>");
return text;
} // end of GetText
@@ -1374,7 +1392,7 @@ void JVALUE::SetTiny(PGLOBAL g, char n)
{
Value = AllocateValue(g, &n, TYPE_TINY);
Jsp = NULL;
-} // end of SetInteger
+} // end of SetTiny
/***********************************************************************/
/* Set the Value's value as the given big integer. */
@@ -1408,6 +1426,6 @@ void JVALUE::SetString(PGLOBAL g, PSZ s, short c)
/***********************************************************************/
bool JVALUE::IsNull(void)
{
- return (Jsp) ? Jsp->IsNull() : (Value) ? Value->IsZero() : true;
+ return (Jsp) ? Jsp->IsNull() : (Value) ? Value->IsNull() : true;
} // end of IsNull
diff --git a/storage/connect/json.h b/storage/connect/json.h
index 4ea169e1b18..685c1dddcf2 100644
--- a/storage/connect/json.h
+++ b/storage/connect/json.h
@@ -1,7 +1,7 @@
/**************** json H Declares Source Code File (.H) ****************/
/* Name: json.h Version 1.2 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
/* */
/* This file contains the JSON classes declares. */
/***********************************************************************/
@@ -13,11 +13,12 @@
#define X
#endif
-enum JTYP {TYPE_STRG = 1,
- TYPE_DBL = 2,
- TYPE_BOOL = 4,
- TYPE_BINT = 5,
- TYPE_INTG = 7,
+enum JTYP {TYPE_STRG = TYPE_STRING,
+ TYPE_DBL = TYPE_DOUBLE,
+ TYPE_BOOL = TYPE_TINY,
+ TYPE_BINT = TYPE_BIGINT,
+ TYPE_DTM = TYPE_DATE,
+ TYPE_INTG = TYPE_INT,
TYPE_JSON = 12,
TYPE_JAR,
TYPE_JOB,
@@ -125,14 +126,14 @@ class JPAIR : public BLOCK {
friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeObject(JOUT *, PJOB);
public:
- JPAIR(PSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;}
+ JPAIR(PCSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;}
- inline PSZ GetKey(void) {return Key;}
+ inline PCSZ GetKey(void) {return Key;}
inline PJVAL GetVal(void) {return Val;}
inline PJPR GetNext(void) {return Next;}
protected:
- PSZ Key; // This pair key name
+ PCSZ Key; // This pair key name
PJVAL Val; // To the value of the pair
PJPR Next; // To the next pair
}; // end of class JPAIR
@@ -150,7 +151,7 @@ class JSON : public BLOCK {
virtual JTYP GetValType(void) {X return TYPE_JSON;}
virtual void InitArray(PGLOBAL g) {X}
//virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL) {X return NULL;}
- virtual PJPR AddPair(PGLOBAL g, PSZ key) {X return NULL;}
+ virtual PJPR AddPair(PGLOBAL g, PCSZ key) {X return NULL;}
virtual PJAR GetKeyList(PGLOBAL g) {X return NULL;}
virtual PJVAL GetValue(const char *key) {X return NULL;}
virtual PJOB GetObject(void) {return NULL;}
@@ -166,13 +167,13 @@ class JSON : public BLOCK {
virtual PSZ GetText(PGLOBAL g, PSZ text) {X return NULL;}
virtual bool Merge(PGLOBAL g, PJSON jsp) { X return true; }
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i) { X return true; }
- virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key) {X}
+ virtual void SetValue(PGLOBAL g, PJVAL jvp, PCSZ key) {X}
virtual void SetValue(PVAL valp) {X}
virtual void SetValue(PJSON jsp) {X}
virtual void SetString(PGLOBAL g, PSZ s, short c) {X}
virtual void SetInteger(PGLOBAL g, int n) {X}
virtual void SetFloat(PGLOBAL g, double f) {X}
- virtual void DeleteKey(char *k) {X}
+ virtual void DeleteKey(PCSZ k) {X}
virtual bool DeleteValue(int i) {X return true;}
virtual bool IsNull(void) {X return true;}
@@ -195,14 +196,14 @@ class JOBJECT : public JSON {
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, PSZ key);
+ virtual PJPR AddPair(PGLOBAL g, PCSZ key);
virtual PJOB GetObject(void) {return this;}
virtual PJVAL GetValue(const char* key);
virtual PJAR GetKeyList(PGLOBAL g);
virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual bool Merge(PGLOBAL g, PJSON jsp);
- virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key);
- virtual void DeleteKey(char *k);
+ virtual void SetValue(PGLOBAL g, PJVAL jvp, PCSZ key);
+ virtual void DeleteKey(PCSZ k);
virtual bool IsNull(void);
protected:
@@ -253,7 +254,7 @@ class JVALUE : public JSON {
JVALUE(PJSON jsp) : JSON()
{Jsp = jsp; Value = NULL; Next = NULL; Del = false;}
JVALUE(PGLOBAL g, PVAL valp);
- JVALUE(PGLOBAL g, PSZ strp);
+ JVALUE(PGLOBAL g, PCSZ strp);
using JSON::GetValue;
using JSON::SetValue;
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index f07a1ac818f..124e5bdc6ad 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -27,9 +27,11 @@
#endif
#define M 7
-uint GetJsonGrpSize(void);
-static int IsJson(UDF_ARGS *args, uint i);
-static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
+bool IsNum(PSZ s);
+char *NextChr(PSZ s, char sep);
+uint GetJsonGrpSize(void);
+static int IsJson(UDF_ARGS *args, uint i);
+static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
static char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error);
static char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -111,10 +113,9 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
PJNODE jnp = &Nodes[i];
if (*p) {
- if (p[--n] == ']') {
- p[n--] = 0;
- p++;
- } else {
+ if (p[n - 1] == ']') {
+ p[--n] = 0;
+ } else if (!IsNum(p)) {
// Wrong array specification
sprintf(g->Message, "Invalid array specification %s", p);
return true;
@@ -124,8 +125,7 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
b = true;
// To check whether a numeric Rank was specified
- for (int k = 0; dg && p[k]; k++)
- dg = isdigit(p[k]) > 0;
+ dg = IsNum(p);
if (!n) {
// Default specifications
@@ -160,13 +160,12 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
// Set the Op value;
switch (*p) {
case '+': jnp->Op = OP_ADD; break;
- case '*': jnp->Op = OP_MULT; break;
+ case 'x': jnp->Op = OP_MULT; break;
case '>': jnp->Op = OP_MAX; break;
case '<': jnp->Op = OP_MIN; break;
case '!': jnp->Op = OP_SEP; break; // Average
case '#': jnp->Op = OP_NUM; break;
- case 'x':
- case 'X': // Expand this array
+ case '*': // Expand this array
strcpy(g->Message, "Expand not supported by this function");
return true;
default:
@@ -232,9 +231,9 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
/*********************************************************************************/
my_bool JSNX::ParseJpath(PGLOBAL g)
{
- char *p, *p2 = NULL, *pbuf = NULL;
+ char *p, *p1 = NULL, *p2 = NULL, *pbuf = NULL;
int i;
- my_bool mul = false;
+ my_bool a, mul = false;
if (Parsed)
return false; // Already done
@@ -245,8 +244,12 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
if (!(pbuf = PlgDBDup(g, Jpath)))
return true;
- // The Jpath must be analyzed
- for (i = 0, p = pbuf; (p = strchr(p, ':')); i++, p++)
+ if (*pbuf == '$') pbuf++;
+ if (*pbuf == '.') pbuf++;
+ if (*pbuf == '[') p1 = pbuf++;
+
+ // Estimate the required number of nodes
+ for (i = 0, p = pbuf; (p = NextChr(p, '.')); i++, p++)
Nod++; // One path node found
if (!(Nodes = (PJNODE)PlgDBSubAlloc(g, NULL, (++Nod) * sizeof(JNODE))))
@@ -255,12 +258,28 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
memset(Nodes, 0, (Nod)* sizeof(JNODE));
// Analyze the Jpath for this column
- for (i = 0, p = pbuf; i < Nod; i++, p = (p2 ? p2 + 1 : p + strlen(p))) {
- if ((p2 = strchr(p, ':')))
- *p2 = 0;
+ for (i = 0, p = pbuf; p && i < Nod; i++, p = (p2 ? p2 : NULL)) {
+ a = (p1 != NULL);
+ p1 = strchr(p, '[');
+ p2 = strchr(p, '.');
+
+ if (!p2)
+ p2 = p1;
+ else if (p1) {
+ if (p1 < p2)
+ p2 = p1;
+ else if (p1 == p2 + 1)
+ *p2++ = 0; // Old syntax .[
+ else
+ p1 = NULL;
+
+ } // endif p1
+
+ if (p2)
+ *p2++ = 0;
// Jpath must be explicit
- if (*p == 0 || *p == '[') {
+ if (a || *p == 0 || *p == '[' || IsNum(p)) {
// Analyse intermediate array processing
if (SetArrayOptions(g, p, i, Nodes[i-1].Key))
return true;
@@ -279,6 +298,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
} // endfor i, p
+ Nod = i;
MulVal = AllocateValue(g, Value);
Parsed = true;
return false;
@@ -711,6 +731,7 @@ PSZ JSNX::Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k)
// Write to the path string
Jp = new(g) JOUTSTR(g);
+ Jp->WriteChr('$');
Jvalp = jvp;
K = k;
@@ -769,7 +790,12 @@ my_bool JSNX::LocateArray(PJAR jarp)
/*********************************************************************************/
my_bool JSNX::LocateObject(PJOB jobp)
{
- size_t m = Jp->N;
+ size_t m;
+
+ if (Jp->WriteChr('.'))
+ return true;
+
+ m = Jp->N;
for (PJPR pair = jobp->First; pair && !Found; pair = pair->Next) {
Jp->N = m;
@@ -790,19 +816,12 @@ my_bool JSNX::LocateObject(PJOB jobp)
/*********************************************************************************/
my_bool JSNX::LocateValue(PJVAL jvp)
{
- if (CompareTree(Jvalp, jvp)) {
+ if (CompareTree(Jvalp, jvp))
Found = (--K == 0);
- } else if (jvp->GetArray()) {
- if (Jp->WriteChr(':'))
- return true;
-
+ else if (jvp->GetArray())
return LocateArray(jvp->GetArray());
- } else if (jvp->GetObject()) {
- if (Jp->WriteChr(':'))
- return true;
-
+ else if (jvp->GetObject())
return LocateObject(jvp->GetObject());
- } // endif's
return false;
} // end of LocateValue
@@ -848,6 +867,7 @@ PSZ JSNX::LocateAll(PGLOBAL g, PJSON jsp, PJVAL jvp, int mx)
if (!g->Message[0])
strcpy(g->Message, "Invalid json tree");
+ return NULL;
} else {
if (Jp->N > 1)
Jp->N--;
@@ -858,7 +878,6 @@ PSZ JSNX::LocateAll(PGLOBAL g, PJSON jsp, PJVAL jvp, int mx)
return Jp->Strp;
} // endif's
- return NULL;
} // end of LocateAll
/*********************************************************************************/
@@ -964,26 +983,26 @@ my_bool JSNX::CompareTree(PJSON jp1, PJSON jp2)
/*********************************************************************************/
my_bool JSNX::AddPath(void)
{
- char s[16];
- my_bool b = false;
+ char s[16];
- if (Jp->WriteChr('"'))
+ if (Jp->WriteStr("\"$"))
return true;
for (int i = 0; i <= I; i++) {
- if (b) {
- if (Jp->WriteChr(':')) return true;
- } else
- b = true;
-
if (Jpnp[i].Type == TYPE_JAR) {
sprintf(s, "[%d]", Jpnp[i].N + B);
if (Jp->WriteStr(s))
return true;
- } else if (Jp->WriteStr(Jpnp[i].Key))
- return true;
+ } else {
+ if (Jp->WriteChr('.'))
+ return true;
+
+ if (Jp->WriteStr(Jpnp[i].Key))
+ return true;
+
+ } // endif's
} // endfor i
@@ -1104,7 +1123,7 @@ static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
} // endif g
g->Mrr = (args->arg_count && args->args[0]) ? 1 : 0;
- g->ActivityStart = (PACTIVITY)more;
+ g->More = more;
initid->maybe_null = mbn;
initid->max_length = reslen;
initid->ptr = (char*)g;
@@ -1379,6 +1398,7 @@ static my_bool CalcLen(UDF_ARGS *args, my_bool obj,
memlen += (k + sizeof(JOBJECT) + sizeof(JPAIR));
} else
memlen += sizeof(JARRAY);
+
switch (args->arg_type[i]) {
case STRING_RESULT:
if (n == 2 && args->args[i]) {
@@ -1448,13 +1468,13 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
} // endif b
- ml += (unsigned long)g->ActivityStart; // more
+ ml += g->More;
if (ml > g->Sarea_Size) {
free(g->Sarea);
if (!(g->Sarea = PlugAllocMem(g, ml))) {
- char errmsg[256];
+ char errmsg[MAX_STR];
sprintf(errmsg, MSG(WORK_AREA), g->Message);
strcpy(g->Message, errmsg);
@@ -1495,7 +1515,7 @@ static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i)
/*********************************************************************************/
/* Make a valid key from the passed argument. */
/*********************************************************************************/
-static PSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
+static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
{
if (args->arg_count > (unsigned)i) {
int j = 0, n = args->attribute_lengths[i];
@@ -1756,16 +1776,16 @@ void jsonvalue_deinit(UDF_INIT* initid)
/*********************************************************************************/
/* Make a Json array containing all the parameters. */
/*********************************************************************************/
-my_bool json_array_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+my_bool json_make_array_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
CalcLen(args, false, reslen, memlen);
return JsonInit(initid, args, message, false, reslen, memlen);
-} // end of json_array_init
+} // end of json_make_array_init
-char *json_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
- unsigned long *res_length, char *, char *)
+char *json_make_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *, char *)
{
char *str;
PGLOBAL g = (PGLOBAL)initid->ptr;
@@ -1792,12 +1812,12 @@ char *json_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
*res_length = strlen(str);
return str;
-} // end of json_array
+} // end of json_make_array
void json_array_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
-} // end of json_array_deinit
+} // end of json_make_array_deinit
/*********************************************************************************/
/* Add one or several values to a Json array. */
@@ -2080,16 +2100,16 @@ void json_array_delete_deinit(UDF_INIT* initid)
/*********************************************************************************/
/* Make a Json Object containing all the parameters. */
/*********************************************************************************/
-my_bool json_object_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+my_bool json_make_object_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
CalcLen(args, true, reslen, memlen);
return JsonInit(initid, args, message, false, reslen, memlen);
-} // end of json_object_init
+} // end of json_make_object_init
-char *json_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
- unsigned long *res_length, char *, char *)
+char *json_make_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *, char *)
{
char *str = NULL;
PGLOBAL g = (PGLOBAL)initid->ptr;
@@ -2114,12 +2134,12 @@ char *json_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
*res_length = strlen(str);
return str;
-} // end of json_object
+} // end of json_make_object
-void json_object_deinit(UDF_INIT* initid)
+void json_make_object_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
-} // end of json_object_deinit
+} // end of json_make_object_deinit
/*********************************************************************************/
/* Make a Json Object containing all not null parameters. */
@@ -2252,7 +2272,8 @@ my_bool json_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
- char *key, *str = NULL;
+ PCSZ key;
+ char *str = NULL;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->Xchk) {
@@ -2357,7 +2378,7 @@ char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
} // endif Xchk
if (!CheckMemory(g, initid, args, 1, false, true, true)) {
- char *key;
+ PCSZ key;
PJOB jobp;
PJSON jsp, top;
PJVAL jvp = MakeValue(g, args, 0, &top);
@@ -2913,7 +2934,6 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *)
{
char *p, *path, *str = NULL;
- int rc;
PJSON jsp;
PJSNX jsx;
PJVAL jvp;
@@ -2921,68 +2941,64 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (g->N) {
str = (char*)g->Activityp;
- goto fin;
+ goto err;
} else if (initid->const_item)
g->N = 1;
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- PUSH_WARNING(MSG(TOO_MANY_JUMPS));
- *is_null = 1;
- return NULL;
- } // endif jump_level
+ try {
+ if (!g->Xchk) {
+ if (CheckMemory(g, initid, args, 1, true)) {
+ PUSH_WARNING("CheckMemory error");
+ goto err;
+ } else
+ jvp = MakeValue(g, args, 0);
- if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
- PUSH_WARNING(g->Message);
- str = NULL;
- goto err;
- } // endif rc
+ if ((p = jvp->GetString())) {
+ if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ PUSH_WARNING(g->Message);
+ goto err;
+ } // endif jsp
- if (!g->Xchk) {
- if (CheckMemory(g, initid, args, 1, true)) {
- PUSH_WARNING("CheckMemory error");
- goto err;
- } else
- jvp = MakeValue(g, args, 0);
+ } else
+ jsp = jvp->GetJson();
- if ((p = jvp->GetString())) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto err;
- } // endif jsp
+ if (g->Mrr) { // First argument is a constant
+ g->Xchk = jsp;
+ JsonMemSave(g);
+ } // endif Mrr
} else
- jsp = jvp->GetJson();
+ jsp = (PJSON)g->Xchk;
- if (g->Mrr) { // First argument is a constant
- g->Xchk = jsp;
- JsonMemSave(g);
- } // endif Mrr
+ path = MakePSZ(g, args, 1);
+ jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
- } else
- jsp = (PJSON)g->Xchk;
-
- path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ if (jsx->SetJpath(g, path)) {
+ PUSH_WARNING(g->Message);
+ goto err;
+ } // endif SetJpath
- if (jsx->SetJpath(g, path)) {
- PUSH_WARNING(g->Message);
- goto err;
- } // endif SetJpath
+ jsx->ReadValue(g);
- jsx->ReadValue(g);
+ if (!jsx->GetValue()->IsNull())
+ str = jsx->GetValue()->GetCharValue();
- if (!jsx->GetValue()->IsNull())
- str = jsx->GetValue()->GetCharValue();
+ if (initid->const_item)
+ // Keep result of constant function
+ g->Activityp = (PACTIVITY)str;
- if (initid->const_item)
- // Keep result of constant function
- g->Activityp = (PACTIVITY)str;
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ PUSH_WARNING(g->Message);
+ str = NULL;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ PUSH_WARNING(g->Message);
+ str = NULL;
+ } // end catch
err:
- g->jump_level--;
-
- fin:
if (!str) {
*is_null = 1;
*res_length = 0;
@@ -3253,7 +3269,7 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
char *p, *path = NULL;
- int k, rc;
+ int k;
PJVAL jvp, jvp2;
PJSON jsp;
PJSNX jsx;
@@ -3273,61 +3289,58 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
} else if (initid->const_item)
g->N = 1;
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- PUSH_WARNING(MSG(TOO_MANY_JUMPS));
- *error = 1;
- *is_null = 1;
- return NULL;
- } // endif jump_level
+ try {
+ if (!g->Xchk) {
+ if (CheckMemory(g, initid, args, 1, !g->Xchk)) {
+ PUSH_WARNING("CheckMemory error");
+ *error = 1;
+ goto err;
+ } else
+ jvp = MakeValue(g, args, 0);
- if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
- PUSH_WARNING(g->Message);
- *error = 1;
- path = NULL;
- goto err;
- } // endif rc
+ if ((p = jvp->GetString())) {
+ if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ PUSH_WARNING(g->Message);
+ goto err;
+ } // endif jsp
- if (!g->Xchk) {
- if (CheckMemory(g, initid, args, 1, !g->Xchk)) {
- PUSH_WARNING("CheckMemory error");
- *error = 1;
- goto err;
- } else
- jvp = MakeValue(g, args, 0);
+ } else
+ jsp = jvp->GetJson();
- if ((p = jvp->GetString())) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto err;
- } // endif jsp
+ if (g->Mrr) { // First argument is a constant
+ g->Xchk = jsp;
+ JsonMemSave(g);
+ } // endif Mrr
} else
- jsp = jvp->GetJson();
+ jsp = (PJSON)g->Xchk;
- if (g->Mrr) { // First argument is a constant
- g->Xchk = jsp;
- JsonMemSave(g);
- } // endif Mrr
+ // The item to locate
+ jvp2 = MakeValue(g, args, 1);
- } else
- jsp = (PJSON)g->Xchk;
-
- // The item to locate
- jvp2 = MakeValue(g, args, 1);
+ k = (args->arg_count > 2) ? (int)*(long long*)args->args[2] : 1;
- k = (args->arg_count > 2) ? (int)*(long long*)args->args[2] : 1;
+ jsx = new(g) JSNX(g, jsp, TYPE_STRING);
+ path = jsx->Locate(g, jsp, jvp2, k);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING);
- path = jsx->Locate(g, jsp, jvp2, k);
+ if (initid->const_item)
+ // Keep result of constant function
+ g->Activityp = (PACTIVITY)path;
- if (initid->const_item)
- // Keep result of constant function
- g->Activityp = (PACTIVITY)path;
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ PUSH_WARNING(g->Message);
+ *error = 1;
+ path = NULL;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ PUSH_WARNING(g->Message);
+ *error = 1;
+ path = NULL;
+ } // end catch
err:
- g->jump_level--;
-
if (!path) {
*res_length = 0;
*is_null = 1;
@@ -3378,7 +3391,7 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
char *p, *path = NULL;
- int rc, mx = 10;
+ int mx = 10;
PJVAL jvp, jvp2;
PJSON jsp;
PJSNX jsx;
@@ -3399,62 +3412,59 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
} else if (initid->const_item)
g->N = 1;
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- PUSH_WARNING(MSG(TOO_MANY_JUMPS));
- *error = 1;
- *is_null = 1;
- return NULL;
- } // endif jump_level
+ try {
+ if (!g->Xchk) {
+ if (CheckMemory(g, initid, args, 1, true)) {
+ PUSH_WARNING("CheckMemory error");
+ *error = 1;
+ goto err;
+ } else
+ jvp = MakeValue(g, args, 0);
- if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
- PUSH_WARNING(g->Message);
- *error = 1;
- path = NULL;
- goto err;
- } // endif rc
+ if ((p = jvp->GetString())) {
+ if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ PUSH_WARNING(g->Message);
+ goto err;
+ } // endif jsp
- if (!g->Xchk) {
- if (CheckMemory(g, initid, args, 1, true)) {
- PUSH_WARNING("CheckMemory error");
- *error = 1;
- goto err;
- } else
- jvp = MakeValue(g, args, 0);
+ } else
+ jsp = jvp->GetJson();
- if ((p = jvp->GetString())) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto err;
- } // endif jsp
+ if (g->Mrr) { // First argument is a constant
+ g->Xchk = jsp;
+ JsonMemSave(g);
+ } // endif Mrr
} else
- jsp = jvp->GetJson();
+ jsp = (PJSON)g->Xchk;
- if (g->Mrr) { // First argument is a constant
- g->Xchk = jsp;
- JsonMemSave(g);
- } // endif Mrr
+ // The item to locate
+ jvp2 = MakeValue(g, args, 1);
- } else
- jsp = (PJSON)g->Xchk;
-
- // The item to locate
- jvp2 = MakeValue(g, args, 1);
+ if (args->arg_count > 2)
+ mx = (int)*(long long*)args->args[2];
- if (args->arg_count > 2)
- mx = (int)*(long long*)args->args[2];
+ jsx = new(g) JSNX(g, jsp, TYPE_STRING);
+ path = jsx->LocateAll(g, jsp, jvp2, mx);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING);
- path = jsx->LocateAll(g, jsp, jvp2, mx);
+ if (initid->const_item)
+ // Keep result of constant function
+ g->Activityp = (PACTIVITY)path;
- if (initid->const_item)
- // Keep result of constant function
- g->Activityp = (PACTIVITY)path;
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ PUSH_WARNING(g->Message);
+ *error = 1;
+ path = NULL;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ PUSH_WARNING(g->Message);
+ *error = 1;
+ path = NULL;
+ } // end catch
err:
- g->jump_level--;
-
if (!path) {
*res_length = 0;
*is_null = 1;
@@ -3632,11 +3642,11 @@ void jsoncontains_path_deinit(UDF_INIT* initid)
/*********************************************************************************/
/* This function is used by the json_set/insert/update_item functions. */
/*********************************************************************************/
-static char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
+char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
char *p, *path, *str = NULL;
- int w, rc;
+ int w;
my_bool b = true;
PJSON jsp;
PJSNX jsx;
@@ -3658,78 +3668,73 @@ static char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
w = 2;
else {
PUSH_WARNING("Logical error, please contact CONNECT developer");
- goto err;
+ goto fin;
} // endelse
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- PUSH_WARNING(MSG(TOO_MANY_JUMPS));
- *error = 1;
- goto fin;
- } // endif jump_level
+ try {
+ if (!g->Xchk) {
+ if (CheckMemory(g, initid, args, 1, true, false, true)) {
+ PUSH_WARNING("CheckMemory error");
+ throw 1;
+ } else
+ jvp = MakeValue(g, args, 0);
- if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
- PUSH_WARNING(g->Message);
- str = NULL;
- goto err;
- } // endif rc
+ if ((p = jvp->GetString())) {
+ if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ throw 2;
+ } // endif jsp
- if (!g->Xchk) {
- if (CheckMemory(g, initid, args, 1, true, false, true)) {
- PUSH_WARNING("CheckMemory error");
- goto err;
- } else
- jvp = MakeValue(g, args, 0);
+ } else
+ jsp = jvp->GetJson();
- if ((p = jvp->GetString())) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto err;
- } // endif jsp
+ if (g->Mrr) { // First argument is a constant
+ g->Xchk = jsp;
+ JsonMemSave(g);
+ } // endif Mrr
} else
- jsp = jvp->GetJson();
+ jsp = (PJSON)g->Xchk;
- if (g->Mrr) { // First argument is a constant
- g->Xchk = jsp;
- JsonMemSave(g);
- } // endif Mrr
+ jsx = new(g)JSNX(g, jsp, TYPE_STRING, initid->max_length, 0, true);
- } else
- jsp = (PJSON)g->Xchk;
+ for (uint i = 1; i + 1 < args->arg_count; i += 2) {
+ jvp = MakeValue(gb, args, i);
+ path = MakePSZ(g, args, i + 1);
- jsx = new(g)JSNX(g, jsp, TYPE_STRING, initid->max_length, 0, true);
-
- for (uint i = 1; i+1 < args->arg_count; i += 2) {
- jvp = MakeValue(gb, args, i);
- path = MakePSZ(g, args, i+1);
-
- if (jsx->SetJpath(g, path, false)) {
- PUSH_WARNING(g->Message);
- continue;
- } // endif SetJpath
+ if (jsx->SetJpath(g, path, false)) {
+ PUSH_WARNING(g->Message);
+ continue;
+ } // endif SetJpath
- if (w) {
- jsx->ReadValue(g);
- b = jsx->GetValue()->IsNull();
- b = (w == 1) ? b : !b;
- } // endif w
+ if (w) {
+ jsx->ReadValue(g);
+ b = jsx->GetValue()->IsNull();
+ b = (w == 1) ? b : !b;
+ } // endif w
- if (b && jsx->WriteValue(gb, jvp))
- PUSH_WARNING(g->Message);
+ if (b && jsx->WriteValue(gb, jvp))
+ PUSH_WARNING(g->Message);
- } // endfor i
+ } // endfor i
- // In case of error or file, return unchanged argument
- if (!(str = MakeResult(g, args, jsp, INT_MAX32)))
- str = MakePSZ(g, args, 0);
+ // In case of error or file, return unchanged argument
+ if (!(str = MakeResult(g, args, jsp, INT_MAX32)))
+ str = MakePSZ(g, args, 0);
- if (g->N)
- // Keep result of constant function
- g->Activityp = (PACTIVITY)str;
+ if (g->N)
+ // Keep result of constant function
+ g->Activityp = (PACTIVITY)str;
-err:
- g->jump_level--;
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ PUSH_WARNING(g->Message);
+ str = NULL;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ PUSH_WARNING(g->Message);
+ str = NULL;
+ } // end catch
fin:
if (!str) {
@@ -4556,7 +4561,7 @@ char *jbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
} // endif bsp
if (!CheckMemory(g, initid, args, 2, false, true, true)) {
- char *key;
+ PCSZ key;
PJOB jobp;
PJVAL jvp = MakeValue(g, args, 0, &top);
PJSON jsp = jvp->GetJson();
@@ -4636,7 +4641,7 @@ char *jbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
} // endif bsp
if (!CheckMemory(g, initid, args, 1, false, true, true)) {
- char *key;
+ PCSZ key;
PJOB jobp;
PJVAL jvp = MakeValue(g, args, 0, &top);
PJSON jsp = jvp->GetJson();
@@ -4905,7 +4910,7 @@ void jbin_item_merge_deinit(UDF_INIT* initid)
/*********************************************************************************/
/* This function is used by the jbin_set/insert/update functions. */
/*********************************************************************************/
-static char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
+char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
char *p, *path;
diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h
index d2890421c62..53fa555ee08 100644
--- a/storage/connect/jsonudf.h
+++ b/storage/connect/jsonudf.h
@@ -1,7 +1,7 @@
/******************** tabjson H Declares Source Code File (.H) *******************/
-/* Name: jsonudf.h Version 1.2 */
+/* Name: jsonudf.h Version 1.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
/* */
/* This file contains the JSON UDF function and class declares. */
/*********************************************************************************/
@@ -37,9 +37,9 @@ extern "C" {
DllExport char *jsonvalue(UDF_EXEC_ARGS);
DllExport void jsonvalue_deinit(UDF_INIT*);
- DllExport my_bool json_array_init(UDF_INIT*, UDF_ARGS*, char*);
- DllExport char *json_array(UDF_EXEC_ARGS);
- DllExport void json_array_deinit(UDF_INIT*);
+ DllExport my_bool json_make_array_init(UDF_INIT*, UDF_ARGS*, char*);
+ DllExport char *json_make_array(UDF_EXEC_ARGS);
+ DllExport void json_make_array_deinit(UDF_INIT*);
DllExport my_bool json_array_add_values_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_array_add_values(UDF_EXEC_ARGS);
@@ -53,9 +53,9 @@ extern "C" {
DllExport char *json_array_delete(UDF_EXEC_ARGS);
DllExport void json_array_delete_deinit(UDF_INIT*);
- DllExport my_bool json_object_init(UDF_INIT*, UDF_ARGS*, char*);
- DllExport char *json_object(UDF_EXEC_ARGS);
- DllExport void json_object_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*);
DllExport my_bool json_object_nonull_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_nonull(UDF_EXEC_ARGS);
@@ -232,7 +232,7 @@ extern "C" {
/*********************************************************************************/
typedef struct _jpn {
enum JTYP Type;
- PSZ Key;
+ PCSZ Key;
int N;
} JPN, *PJPN;
diff --git a/storage/connect/libdoc.cpp b/storage/connect/libdoc.cpp
index 2470d37c353..700d247da38 100644
--- a/storage/connect/libdoc.cpp
+++ b/storage/connect/libdoc.cpp
@@ -68,9 +68,9 @@ class LIBXMLDOC : public XMLDOCUMENT {
virtual void SetNofree(bool b) {Nofreelist = b;}
// Methods
- virtual bool Initialize(PGLOBAL g, char *entry, bool zipped);
+ virtual bool Initialize(PGLOBAL g, PCSZ entry, bool zipped);
virtual bool ParseFile(PGLOBAL g, char *fn);
- virtual bool NewDoc(PGLOBAL g, char *ver);
+ virtual bool NewDoc(PGLOBAL g, PCSZ ver);
virtual void AddComment(PGLOBAL g, char *com);
virtual PXNODE GetRoot(PGLOBAL g);
virtual PXNODE NewRoot(PGLOBAL g, char *name);
@@ -119,9 +119,9 @@ class XML2NODE : public XMLNODE {
virtual PXLIST SelectNodes(PGLOBAL g, char *xp, PXLIST lp);
virtual PXNODE SelectSingleNode(PGLOBAL g, char *xp, PXNODE np);
virtual PXATTR GetAttribute(PGLOBAL g, char *name, PXATTR ap);
- virtual PXNODE AddChildNode(PGLOBAL g, char *name, PXNODE np);
+ virtual PXNODE AddChildNode(PGLOBAL g, PCSZ name, PXNODE np);
virtual PXATTR AddProperty(PGLOBAL g, char *name, PXATTR ap);
- virtual void AddText(PGLOBAL g, char *txtp);
+ virtual void AddText(PGLOBAL g, PCSZ txtp);
virtual void DeleteChild(PGLOBAL g, PXNODE dnp);
protected:
@@ -373,7 +373,7 @@ LIBXMLDOC::LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
/******************************************************************/
/* Initialize XML parser and check library compatibility. */
/******************************************************************/
-bool LIBXMLDOC::Initialize(PGLOBAL g, char *entry, bool zipped)
+bool LIBXMLDOC::Initialize(PGLOBAL g, PCSZ entry, bool zipped)
{
if (zipped && InitZip(g, entry))
return true;
@@ -434,7 +434,7 @@ PFBLOCK LIBXMLDOC::LinkXblock(PGLOBAL g, MODE m, int rc, char *fn)
/******************************************************************/
/* Construct and add the XML processing instruction node. */
/******************************************************************/
-bool LIBXMLDOC::NewDoc(PGLOBAL g, char *ver)
+bool LIBXMLDOC::NewDoc(PGLOBAL g, PCSZ ver)
{
if (trace)
htrc("NewDoc\n");
@@ -863,14 +863,13 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
xmlFree(Content);
if ((Content = xmlNodeGetContent(Nodep))) {
- char *extra = " \t\r\n";
char *p1 = (char*)Content, *p2 = buf;
bool b = false;
// Copy content eliminating extra characters
for (; *p1; p1++)
if ((p2 - buf) < len) {
- if (strchr(extra, *p1)) {
+ if (strchr(" \t\r\n", *p1)) {
if (b) {
// This to have one blank between sub-nodes
*p2++ = ' ';
@@ -1020,19 +1019,19 @@ PXATTR XML2NODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap)
/******************************************************************/
/* Add a new child node to this node and return it. */
/******************************************************************/
-PXNODE XML2NODE::AddChildNode(PGLOBAL g, char *name, PXNODE np)
+PXNODE XML2NODE::AddChildNode(PGLOBAL g, PCSZ name, PXNODE np)
{
- char *p, *pn, *pf = NULL;
+ char *p, *pn, *pf = NULL, *nmp = PlugDup(g, name);
if (trace)
htrc("AddChildNode: %s\n", name);
// Is a prefix specified
- if ((pn = strchr(name, ':'))) {
- pf = name;
+ if ((pn = strchr(nmp, ':'))) {
+ pf = nmp;
*pn++ = '\0'; // Separate name from prefix
} else
- pn = name;
+ pn = nmp;
// If name has the format m[n] only m is taken as node name
if ((p = strchr(pn, '[')))
@@ -1096,7 +1095,7 @@ PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
/******************************************************************/
/* Add a new text node to this node. */
/******************************************************************/
-void XML2NODE::AddText(PGLOBAL g, char *txtp)
+void XML2NODE::AddText(PGLOBAL g, PCSZ txtp)
{
if (trace)
htrc("AddText: %s\n", txtp);
diff --git a/storage/connect/macutil.cpp b/storage/connect/macutil.cpp
index f5d3bb11fe9..b9600bdac2e 100644
--- a/storage/connect/macutil.cpp
+++ b/storage/connect/macutil.cpp
@@ -192,7 +192,7 @@ bool MACINFO::GetOneInfo(PGLOBAL g, int flag, void *v, int lv)
case 23:
break;
default:
- p = "";
+ p = PlugDup(g, "");
} // endswitch flag
} else switch (flag) {
diff --git a/storage/connect/mongofam.cpp b/storage/connect/mongofam.cpp
new file mode 100644
index 00000000000..0b9bd429d85
--- /dev/null
+++ b/storage/connect/mongofam.cpp
@@ -0,0 +1,815 @@
+/************ MONGO FAM C++ Program Source Code File (.CPP) ************/
+/* PROGRAM NAME: mongofam.cpp */
+/* ------------- */
+/* Version 1.1 */
+/* */
+/* COPYRIGHT: */
+/* ---------- */
+/* (C) Copyright to the author Olivier BERTRAND 20017 */
+/* */
+/* WHAT THIS PROGRAM DOES: */
+/* ----------------------- */
+/* This program are the MongoDB access method classes. */
+/* */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Include relevant sections of the System header files. */
+/***********************************************************************/
+#include "my_global.h"
+#if defined(__WIN__)
+//#include <io.h>
+//#include <fcntl.h>
+//#include <errno.h>
+#if defined(__BORLANDC__)
+#define __MFC_COMPAT__ // To define min/max as macro
+#endif // __BORLANDC__
+//#include <windows.h>
+#else // !__WIN__
+#if defined(UNIX) || defined(UNIV_LINUX)
+//#include <errno.h>
+#include <unistd.h>
+//#if !defined(sun) // Sun has the ftruncate fnc.
+//#define USETEMP // Force copy mode for DELETE
+//#endif // !sun
+#else // !UNIX
+//#include <io.h>
+#endif // !UNIX
+//#include <fcntl.h>
+#endif // !__WIN__
+
+/***********************************************************************/
+/* Include application header files: */
+/* global.h is header containing all global declarations. */
+/* plgdbsem.h is header containing the DB application declarations. */
+/* filamtxt.h is header containing the file AM classes declarations. */
+/***********************************************************************/
+#include "global.h"
+#include "plgdbsem.h"
+#include "reldef.h"
+#include "filamtxt.h"
+#include "tabdos.h"
+#include "tabjson.h"
+#include "mongofam.h"
+
+#if defined(UNIX) || defined(UNIV_LINUX)
+#include "osutil.h"
+//#define _fileno fileno
+//#define _O_RDONLY O_RDONLY
+#endif
+
+// Required to initialize libmongoc's internals
+void mongo_init(bool init)
+{
+ if (init)
+ mongoc_init();
+ else
+ mongoc_cleanup();
+
+} // end of mongo_init
+
+/* --------------------------- Class MGOFAM -------------------------- */
+
+/***********************************************************************/
+/* Constructors. */
+/***********************************************************************/
+MGOFAM::MGOFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
+{
+ Client = NULL;
+ Database = NULL;
+ Collection = NULL;
+ Cursor = NULL;
+ Query = NULL;
+ Opts = NULL;
+ To_Fbt = NULL;
+ Mode = MODE_ANY;
+ Uristr = tdp->Uri;
+ Db_name = tdp->Schema;
+ Coll_name = tdp->Collname;
+ Options = tdp->Options;
+ Filter = NULL;
+ Done = false;
+ Pipe = tdp->Pipe;
+ Lrecl = tdp->Lrecl + tdp->Ending;
+} // end of MGOFAM standard constructor
+
+ MGOFAM::MGOFAM(PMGOFAM tdfp) : DOSFAM(tdfp)
+{
+ Client = tdfp->Client;
+ Database = NULL;
+ Collection = tdfp->Collection;
+ Cursor = tdfp->Cursor;
+ Query = tdfp->Query;
+ Opts = tdfp->Opts;
+ To_Fbt = tdfp->To_Fbt;
+ Mode = tdfp->Mode;
+ Uristr = tdfp->Uristr;
+ Db_name = tdfp->Db_name;
+ Coll_name = tdfp->Coll_name;
+ Options = tdfp->Options;
+ Filter = NULL;
+ Done = tdfp->Done;
+ Pipe = tdfp->Pipe;
+ } // end of MGOFAM copy constructor
+
+#if 0
+void *MGOFAM::mgo_alloc(size_t n)
+{
+ char *mst = (char*)PlgDBSubAlloc(G, NULL, n + sizeof(size_t));
+
+ if (mst) {
+ *(size_t*)mst = n;
+ return mst + sizeof(size_t);
+ } // endif mst
+
+ return NULL;
+} // end of mgo_alloc
+
+void *MGOFAM::mgo_calloc(size_t n, size_t sz)
+{
+ void *m = mgo_alloc(n * sz);
+
+ if (m)
+ memset(m, 0, n * sz);
+
+ return m;
+} // end of mgo_calloc
+
+void *MGOFAM::mgo_realloc(void *m, size_t n)
+{
+ if (!m)
+ return n ? mgo_alloc(n) : NULL;
+
+ size_t *osz = (size_t*)((char*)m - sizeof(size_t));
+
+ if (n > *osz) {
+ void *nwm = mgo_alloc(n);
+
+ if (nwm)
+ memcpy(nwm, m, *osz);
+
+ return nwm;
+ } else {
+ *osz = n;
+ return m;
+ } // endif n
+
+} // end of mgo_realloc
+#endif // 0
+
+/***********************************************************************/
+/* Reset: reset position values at the beginning of file. */
+/***********************************************************************/
+void MGOFAM::Reset(void)
+{
+ TXTFAM::Reset();
+ Fpos = Tpos = Spos = 0;
+} // end of Reset
+
+/***********************************************************************/
+/* MGO GetFileLength: returns file size in number of bytes. */
+/***********************************************************************/
+int MGOFAM::GetFileLength(PGLOBAL g)
+{
+ return 0;
+} // end of GetFileLength
+
+/***********************************************************************/
+/* Cardinality: returns table cardinality in number of rows. */
+/* 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)
+{
+ if (g) {
+ if (!Init(g)) {
+ bson_t *query;
+ const char *jf = NULL;
+
+ if (Pipe)
+ return 10;
+ else if (Filter)
+ jf = Filter;
+
+ if (jf) {
+ query = bson_new_from_json((const uint8_t *)jf, -1, &Error);
+
+ if (!query) {
+ htrc("Wrong filter: %s", Error.message);
+ return 10;
+ } // endif Query
+
+ } else
+ query = bson_new();
+
+ int64_t card = (int)mongoc_collection_count(Collection,
+ MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error);
+
+ if (card < 0)
+ sprintf(g->Message, "Collection count: %s", Error.message);
+
+ bson_destroy(query);
+ return card;
+ } else
+ return -1;
+
+ } else
+ return 1;
+
+} // end of Cardinality
+
+/***********************************************************************/
+/* Note: This function is not really implemented yet. */
+/***********************************************************************/
+int MGOFAM::MaxBlkSize(PGLOBAL, int s)
+{
+ return s;
+} // end of MaxBlkSize
+
+/***********************************************************************/
+/* Init: initialize MongoDB processing. */
+/***********************************************************************/
+bool MGOFAM::Init(PGLOBAL g)
+{
+ if (Done)
+ return false;
+
+ if (Options && !Pipe) {
+ char *p = (char*)strchr(Options, ';');
+
+ if (p) {
+ *p++ = 0;
+
+ if (p)
+ Filter = p;
+
+ } // endif p
+
+ } // endif Options
+
+ Uri = mongoc_uri_new(Uristr);
+
+ if (!Uri) {
+ sprintf(g->Message, "Failed to parse URI: \"%s\"", Uristr);
+ return true;
+ } // endif Uri
+
+ // Create a new client pool instance
+ Pool = mongoc_client_pool_new(Uri);
+ mongoc_client_pool_set_error_api(Pool, 2);
+
+ // Register the application name so we can track it in the profile logs
+ // on the server. This can also be done from the URI.
+ mongoc_client_pool_set_appname(Pool, "Connect");
+
+ // Create a new client instance
+ Client = mongoc_client_pool_pop(Pool);
+ //Client = mongoc_client_new(uristr);
+
+ if (!Client) {
+ sprintf(g->Message, "Failed to get Client");
+ return true;
+ } // endif Client
+
+ //mongoc_client_set_error_api(Client, 2);
+
+ // Register the application name so we can track it in the profile logs
+ // on the server. This can also be done from the URI.
+ //mongoc_client_set_appname(Client, "Connect");
+
+ // Get a handle on the database Db_name and collection Coll_name
+ // Database = mongoc_client_get_database(Client, Db_name);
+ // Collection = mongoc_database_get_collection(Database, Coll_name);
+ Collection = mongoc_client_get_collection(Client, Db_name, Coll_name);
+
+ if (!Collection) {
+ sprintf(g->Message, "Failed to get Collection %s.%s", Db_name, Coll_name);
+ return true;
+ } // endif Collection
+
+ Done = true;
+ return false;
+} // end of Init
+
+/***********************************************************************/
+/* OpenDB: Data Base open routine for MONGO access method. */
+/***********************************************************************/
+bool MGOFAM::MakeCursor(PGLOBAL g)
+{
+ const char *p;
+ bool b = false, id = (Mode != MODE_READ), all = false;
+ uint len;
+ PSZ jp;
+ PCOL cp;
+ PSTRG s = NULL;
+
+ if (Options && !stricmp(Options, "all")) {
+ Options = NULL;
+ all = true;
+ } // endif Options
+
+ for (cp = Tdbp->GetColumns(); cp; cp = cp->GetNext())
+ if (!strcmp(cp->GetName(), "_id"))
+ id = true;
+ else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*"))
+ all = true;
+
+ if (Pipe) {
+ if (trace)
+ htrc("Pipeline: %s\n", Options);
+
+ p = strrchr(Options, ']');
+
+ if (!p) {
+ strcpy(g->Message, "Missing ] in pipeline");
+ return true;
+ } else
+ *(char*)p = 0;
+
+ s = new(g) STRING(g, 1023, (PSZ)Options);
+ len = s->GetLength();
+
+ if (Tdbp->GetFilter()) {
+ s->Append(",{\"$match\":");
+
+ if (!Tdbp->GetFilter()->MakeSelector(g, s, false)) {
+ s->Append('}');
+ Tdbp->SetFilter(NULL); // Not needed anymore
+ } else {
+ if (((TDBJSN*)Tdbp)->Xcol)
+ Tdbp->SetFilter(NULL); // Incompatible
+
+ htrc("Failed making selector\n");
+ s->Truncate(len);
+ } // endif Selector
+
+ } // endif To_Filter
+
+ if (!all) {
+ // Project list
+ len = s->GetLength();
+
+ if (Tdbp->GetColumns()) {
+ s->Append(",{\"$project\":{\"");
+
+ if (!id)
+ s->Append("_id\":0,\"");
+
+ for (PCOL cp = Tdbp->GetColumns(); cp; cp = cp->GetNext()) {
+ if (b)
+ s->Append(",\"");
+ else
+ b = true;
+
+ if ((jp = ((PJCOL)cp)->GetJpath(g, true)))
+ s->Append(jp);
+ else {
+ s->Truncate(len);
+ goto nop;
+ } // endif Jpath
+
+ s->Append("\":1");
+ } // endfor cp
+
+ } else
+ s->Append(",{\"$project\":{\"_id\":1}}");
+
+ s->Append("}}");
+ } // endif all
+
+ nop:
+ s->Append("]}");
+ s->Resize(s->GetLength() + 1);
+ p = s->GetStr();
+
+ if (trace)
+ htrc("New Pipeline: %s\n", p);
+
+ Query = bson_new_from_json((const uint8_t *)p, -1, &Error);
+
+ if (!Query) {
+ sprintf(g->Message, "Wrong pipeline: %s", Error.message);
+ return true;
+ } // endif Query
+
+ Cursor = mongoc_collection_aggregate(Collection, MONGOC_QUERY_NONE,
+ Query, NULL, NULL);
+
+ if (mongoc_cursor_error(Cursor, &Error)) {
+ sprintf(g->Message, "Mongo aggregate Failure: %s", Error.message);
+ return true;
+ } // endif cursor
+
+ } else {
+ if (Filter || Tdbp->GetFilter()) {
+ if (trace) {
+ if (Filter)
+ htrc("Filter: %s\n", Filter);
+
+ if (Tdbp->GetFilter()) {
+ char buf[512];
+
+ Tdbp->GetFilter()->Prints(g, buf, 511);
+ htrc("To_Filter: %s\n", buf);
+ } // endif To_Filter
+
+ } // endif trace
+
+ s = new(g) STRING(g, 1023, (PSZ)Filter);
+ len = s->GetLength();
+
+ if (Tdbp->GetFilter()) {
+ if (Filter)
+ s->Append(',');
+
+ if (Tdbp->GetFilter()->MakeSelector(g, s, false)) {
+ if (((TDBJSN*)Tdbp)->Xcol)
+ Tdbp->SetFilter(NULL); // Incompatible
+
+ htrc("Cannot make selector\n");
+ s->Truncate(len);
+ } else
+ Tdbp->SetFilter(NULL); // Not needed anymore
+
+ } // endif To_Filter
+
+ if (trace)
+ htrc("selector: %s\n", s->GetStr());
+
+ s->Resize(s->GetLength() + 1);
+
+ if (s->GetLength()) {
+ Query = bson_new_from_json((const uint8_t *)s->GetStr(), -1, &Error);
+
+ if (!Query) {
+ sprintf(g->Message, "Wrong filter: %s", Error.message);
+ return true;
+ } // endif Query
+
+ } else
+ Query = bson_new();
+
+ } else
+ Query = bson_new();
+
+ if (!all) {
+ if (Options && *Options) {
+ if (trace)
+ htrc("options=%s\n", Options);
+
+ p = Options;
+ } else if (Tdbp->GetColumns()) {
+ // Projection list
+ if (s)
+ s->Set("{\"projection\":{\"");
+ else
+ s = new(g) STRING(g, 511, "{\"projection\":{\"");
+
+ if (!id)
+ s->Append("_id\":0,\"");
+
+ for (PCOL cp = Tdbp->GetColumns(); cp; cp = cp->GetNext()) {
+ if (b)
+ s->Append(",\"");
+ else
+ b = true;
+
+ if ((jp = ((PJCOL)cp)->GetJpath(g, true)))
+ s->Append(jp);
+ else {
+ s->Reset();
+ s->Resize(0);
+ goto nope;
+ } // endif Jpath
+
+ s->Append("\":1");
+ } // endfor cp
+
+ s->Append("}}");
+ s->Resize(s->GetLength() + 1);
+ p = s->GetStr();
+ } else {
+ // count(*) ?
+ p = "{\"projection\":{\"_id\":1}}";
+ } // endif Options
+
+ Opts = bson_new_from_json((const uint8_t *)p, -1, &Error);
+
+ if (!Opts) {
+ sprintf(g->Message, "Wrong options: %s", Error.message);
+ return true;
+ } // endif Opts
+
+ } // endif all
+
+ nope:
+ Cursor = mongoc_collection_find_with_opts(Collection, Query, Opts, NULL);
+ } // endif Pipe
+
+ return false;
+} // end of MakeCursor
+
+/***********************************************************************/
+/* OpenTableFile: Open a MongoDB table. */
+/***********************************************************************/
+bool MGOFAM::OpenTableFile(PGLOBAL g)
+{
+ Mode = Tdbp->GetMode();
+
+ if (Pipe && Mode != MODE_READ) {
+ strcpy(g->Message, "Pipeline tables are read only");
+ return true;
+ } // endif Pipe
+
+ if (Init(g))
+ return true;
+
+ if (Mode == MODE_DELETE && !Tdbp->GetNext()) {
+ // Store the number of deleted lines
+ DelRows = Cardinality(g);
+
+ // Delete all documents
+ if (!mongoc_collection_remove(Collection, MONGOC_REMOVE_NONE,
+ Query, NULL, &Error)) {
+ sprintf(g->Message, "Remove all: %s", Error.message);
+ return true;
+ } // endif remove
+
+ } else if (Mode != MODE_INSERT)
+ if (MakeCursor(g))
+ return true;
+
+ return false;
+} // end of OpenTableFile
+
+/***********************************************************************/
+/* GetRowID: return the RowID of last read record. */
+/***********************************************************************/
+int MGOFAM::GetRowID(void)
+{
+ return Rows;
+} // end of GetRowID
+
+/***********************************************************************/
+/* GetPos: return the position of last read record. */
+/***********************************************************************/
+int MGOFAM::GetPos(void)
+{
+ return Fpos;
+} // end of GetPos
+
+/***********************************************************************/
+/* GetNextPos: return the position of next record. */
+/***********************************************************************/
+int MGOFAM::GetNextPos(void)
+{
+ return Fpos; // TODO
+} // end of GetNextPos
+
+/***********************************************************************/
+/* SetPos: Replace the table at the specified position. */
+/***********************************************************************/
+bool MGOFAM::SetPos(PGLOBAL g, int pos)
+{
+ Fpos = pos;
+ Placed = true;
+ return false;
+} // end of SetPos
+
+/***********************************************************************/
+/* Record file position in case of UPDATE or DELETE. */
+/***********************************************************************/
+bool MGOFAM::RecordPos(PGLOBAL g)
+{
+ strcpy(g->Message, "MGOFAM::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)
+{
+ strcpy(g->Message, "MGOFAM::InitDelete NIY");
+ return RC_FX;
+} // end of InitDelete
+
+/***********************************************************************/
+/* Skip one record in file. */
+/***********************************************************************/
+int MGOFAM::SkipRecord(PGLOBAL g, bool header)
+{
+ return RC_OK; // Dummy
+} // end of SkipRecord
+
+/***********************************************************************/
+/* Use to trace restaurants document contains. */
+/***********************************************************************/
+void MGOFAM::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k)
+{
+
+ if (!doc || bson_iter_init(iter, doc)) {
+ const char *key;
+
+ while (bson_iter_next(iter)) {
+ key = bson_iter_key(iter);
+ htrc("Found element key: \"%s\"\n", key);
+
+ if (BSON_ITER_HOLDS_UTF8(iter))
+ htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL));
+ else if (BSON_ITER_HOLDS_INT32(iter))
+ htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter));
+ else if (BSON_ITER_HOLDS_INT64(iter))
+ htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter));
+ else if (BSON_ITER_HOLDS_DOUBLE(iter))
+ htrc("%s.%s=%g\n", k, key, bson_iter_double(iter));
+ else if (BSON_ITER_HOLDS_DATE_TIME(iter))
+ htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter));
+ else if (BSON_ITER_HOLDS_OID(iter)) {
+ char str[25];
+
+ bson_oid_to_string(bson_iter_oid(iter), str);
+ htrc("%s.%s=%s\n", k, key, str);
+ } else if (BSON_ITER_HOLDS_DECIMAL128(iter)) {
+ char *str = NULL;
+ bson_decimal128_t dec;
+
+ bson_iter_decimal128(iter, &dec);
+ bson_decimal128_to_string(&dec, str);
+ htrc("%s.%s=%s\n", k, key, str);
+ } else if (BSON_ITER_HOLDS_DOCUMENT(iter)) {
+ bson_iter_t child;
+
+ if (bson_iter_recurse(iter, &child))
+ ShowDocument(&child, NULL, key);
+
+ } else if (BSON_ITER_HOLDS_ARRAY(iter)) {
+ bson_t *arr;
+ bson_iter_t itar;
+ const uint8_t *data = NULL;
+ uint32_t len = 0;
+
+ bson_iter_array(iter, &len, &data);
+ arr = bson_new_from_data(data, len);
+ ShowDocument(&itar, arr, key);
+ } // endif's
+
+ } // endwhile bson_iter_next
+
+ } // endif bson_iter_init
+
+} // end of ShowDocument
+
+/***********************************************************************/
+/* ReadBuffer: Get next document from a collection. */
+/***********************************************************************/
+int MGOFAM::ReadBuffer(PGLOBAL g)
+{
+ int rc = RC_OK;
+
+ if (mongoc_cursor_next(Cursor, &Document)) {
+ char *str = bson_as_json(Document, NULL);
+
+ if (trace > 1) {
+ bson_iter_t iter;
+ ShowDocument(&iter, Document, "");
+ } else if (trace == 1)
+ htrc("%s\n", str);
+
+ strncpy(Tdbp->GetLine(), str, Lrecl);
+ bson_free(str);
+ } else if (mongoc_cursor_error(Cursor, &Error)) {
+ sprintf(g->Message, "Mongo Cursor Failure: %s", Error.message);
+ rc = RC_FX;
+ } else {
+ //mongoc_cursor_destroy(Cursor);
+ rc = RC_EF;
+ } // endif's Cursor
+
+ return rc;
+} // end of ReadBuffer
+
+/***********************************************************************/
+/* WriteBuffer: File write routine for MGO access method. */
+/***********************************************************************/
+int MGOFAM::WriteBuffer(PGLOBAL g)
+{
+ int rc = RC_OK;
+ bson_t *doc;
+
+ //if (Mode == MODE_INSERT && !Collection) {
+ // if ((Database = mongoc_client_get_database(Client, db_name)))
+ // Collection = mongoc_database_create_collection(Database, coll_name,
+ // NULL, &Error);
+
+ // if (!Collection)
+ // if (Database) {
+ // sprintf(g->Message, "Create collection: %s", Error.message);
+ // return RC_FX;
+ // } else {
+ // sprintf(g->Message, "Fail to get database %s", db_name);
+ // return RC_FX;
+ // } // endif Database
+
+ //} // endif Collection
+
+ if (!(doc = bson_new_from_json((const uint8_t *)Tdbp->GetLine(),
+ -1, &Error))) {
+ sprintf(g->Message, "Wrong document: %s", Error.message);
+ return RC_FX;
+ } // endif doc
+
+ if (Mode != MODE_INSERT) {
+ bool b = false;
+ bson_iter_t iter;
+ bson_t *selector = bson_new();
+
+ bson_iter_init(&iter, Document);
+
+ if (bson_iter_find(&iter, "_id")) {
+ if (BSON_ITER_HOLDS_OID(&iter))
+ b = BSON_APPEND_OID(selector, "_id", bson_iter_oid(&iter));
+ else if (BSON_ITER_HOLDS_INT32(&iter))
+ b = BSON_APPEND_INT32(selector, "_id", bson_iter_int32(&iter));
+ else if (BSON_ITER_HOLDS_INT64(&iter))
+ b = BSON_APPEND_INT64(selector, "_id", bson_iter_int64(&iter));
+ else if (BSON_ITER_HOLDS_DOUBLE(&iter))
+ b = BSON_APPEND_DOUBLE(selector, "_id", bson_iter_double(&iter));
+ else if (BSON_ITER_HOLDS_UTF8(&iter))
+ b = BSON_APPEND_UTF8(selector, "_id", bson_iter_utf8(&iter, NULL));
+
+ } // endif iter
+
+ if (!b) {
+ strcpy(g->Message, "Cannot find _id");
+ return RC_FX;
+ } // endif oid
+
+ if (Mode == MODE_DELETE) {
+ if (!mongoc_collection_remove(Collection, MONGOC_REMOVE_NONE,
+ selector, NULL, &Error)) {
+ sprintf(g->Message, "Remove: %s", Error.message);
+ bson_destroy(selector);
+ return RC_FX;
+ } // endif remove
+
+ } else {
+ if (!mongoc_collection_update(Collection, MONGOC_UPDATE_NONE,
+ selector, doc, NULL, &Error)) {
+ sprintf(g->Message, "Update: %s", Error.message);
+ bson_destroy(selector);
+ return RC_FX;
+ } // endif remove
+
+ } // endif Mode
+
+ bson_destroy(selector);
+ } else if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE,
+ doc, NULL, &Error)) {
+ sprintf(g->Message, "Inserting: %s", Error.message);
+ rc = RC_FX;
+ } // endif insert
+
+ bson_destroy(doc);
+ return rc;
+} // end of WriteBuffer
+
+/***********************************************************************/
+/* Data Base delete line routine for MGO and BLK access methods. */
+/***********************************************************************/
+int MGOFAM::DeleteRecords(PGLOBAL g, int irc)
+{
+ return (irc == RC_OK) ? WriteBuffer(g) : RC_OK;
+} // end of DeleteRecords
+
+/***********************************************************************/
+/* Table file close routine for MGO access method. */
+/***********************************************************************/
+void MGOFAM::CloseTableFile(PGLOBAL g, bool)
+{
+ if (Query) bson_destroy(Query);
+ if (Opts) bson_destroy(Opts);
+ if (Cursor) mongoc_cursor_destroy(Cursor);
+ if (Collection) mongoc_collection_destroy(Collection);
+ // mongoc_database_destroy(Database);
+ // mongoc_client_destroy(Client);
+ if (Client) mongoc_client_pool_push(Pool, Client);
+ if (Pool) mongoc_client_pool_destroy(Pool);
+ if (Uri) mongoc_uri_destroy(Uri);
+//bson_mem_restore_vtable();
+//mongoc_cleanup();
+//G = NULL;
+ Done = false;
+} // end of CloseTableFile
+
+/***********************************************************************/
+/* Rewind routine for MGO access method. */
+/***********************************************************************/
+void MGOFAM::Rewind(void)
+{
+ mongoc_cursor_t *cursor = mongoc_cursor_clone(Cursor);
+
+ mongoc_cursor_destroy(Cursor);
+ Cursor = cursor;
+} // end of Rewind
+
diff --git a/storage/connect/mongofam.h b/storage/connect/mongofam.h
new file mode 100644
index 00000000000..f3b7ea3d05f
--- /dev/null
+++ b/storage/connect/mongofam.h
@@ -0,0 +1,97 @@
+/************** MongoFam H Declares Source Code File (.H) **************/
+/* Name: mongofam.h Version 1.3 */
+/* */
+/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* */
+/* This file contains the MongoDB access method classes declares. */
+/***********************************************************************/
+#pragma once
+
+/***********************************************************************/
+/* Include MongoDB library header files. */
+/***********************************************************************/
+#include <bson.h>
+#include <bcon.h>
+#include <mongoc.h>
+
+#include "block.h"
+//#include "array.h"
+
+typedef class TXTFAM *PTXF;
+typedef class MGOFAM *PMGOFAM;
+typedef class MGODEF *PMGODEF;
+typedef class TDBMGO *PTDBMGO;
+
+/***********************************************************************/
+/* This is the MongoDB Access Method class declaration. */
+/***********************************************************************/
+class DllExport MGOFAM : public DOSFAM {
+ friend void mongo_init(bool);
+public:
+ // Constructor
+ MGOFAM(PJDEF tdp);
+ MGOFAM(PMGOFAM txfp);
+
+ // Implementation
+ virtual AMT GetAmType(void) { return TYPE_AM_MGO; }
+ virtual bool GetUseTemp(void) { return false; }
+ virtual int GetPos(void);
+ virtual int GetNextPos(void);
+ virtual PTXF Duplicate(PGLOBAL g) { return (PTXF)new(g) MGOFAM(this); }
+ void SetLrecl(int lrecl) { Lrecl = lrecl; }
+
+ // Methods
+ virtual void Reset(void);
+ virtual int GetFileLength(PGLOBAL g);
+ virtual int Cardinality(PGLOBAL g);
+ virtual int MaxBlkSize(PGLOBAL g, int s);
+ virtual bool AllocateBuffer(PGLOBAL g) { return false; }
+ virtual int GetRowID(void);
+ virtual bool RecordPos(PGLOBAL g);
+ virtual bool SetPos(PGLOBAL g, int recpos);
+ virtual int SkipRecord(PGLOBAL g, bool header);
+ virtual bool OpenTableFile(PGLOBAL g);
+ virtual int ReadBuffer(PGLOBAL g);
+ virtual int WriteBuffer(PGLOBAL g);
+ virtual int DeleteRecords(PGLOBAL g, int irc);
+ virtual void CloseTableFile(PGLOBAL g, bool abort);
+ virtual void Rewind(void);
+
+protected:
+ virtual bool OpenTempFile(PGLOBAL g) { return false; }
+ virtual bool MoveIntermediateLines(PGLOBAL g, bool *b) { return false; }
+ virtual int RenameTempFile(PGLOBAL g) { return RC_OK; }
+ virtual int InitDelete(PGLOBAL g, int fpos, int spos);
+ bool Init(PGLOBAL g);
+ bool MakeCursor(PGLOBAL g);
+ void ShowDocument(bson_iter_t *i, const bson_t *b, const char *k);
+ //static void *mgo_alloc(size_t n);
+ //static void *mgo_calloc(size_t n, size_t sz);
+ //static void *mgo_realloc(void *m, size_t n);
+ //static void mgo_free(void *) {}
+
+
+ // Members
+//static PGLOBAL G;
+ mongoc_uri_t *Uri;
+ mongoc_client_pool_t *Pool; // Thread safe client pool
+ mongoc_client_t *Client; // The MongoDB client
+ mongoc_database_t *Database; // The MongoDB database
+ mongoc_collection_t *Collection; // The MongoDB collection
+ mongoc_cursor_t *Cursor;
+ const bson_t *Document;
+//bson_mem_vtable_t Vtable;
+ bson_t *Query; // MongoDB cursor filter
+ bson_t *Opts; // MongoDB cursor options
+ bson_error_t Error;
+ PFBLOCK To_Fbt; // Pointer to temp file block
+ MODE Mode;
+ const char *Uristr;
+ const char *Db_name;
+ const char *Coll_name;
+ const char *Options;
+ const char *Filter;
+ bool Done; // Init done
+ bool Pipe;
+}; // end of class MGOFAM
+
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index 1fcd8ac78da..0104213ed92 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -96,6 +96,9 @@
#if defined(XML_SUPPORT)
#include "tabxml.h"
#endif // XML_SUPPORT
+#if defined(MONGO_SUPPORT)
+#include "tabmgo.h"
+#endif // MONGO_SUPPORT
#if defined(ZIP_SUPPORT)
#include "tabzip.h"
#endif // ZIP_SUPPORT
@@ -161,7 +164,10 @@ TABTYPE GetTypeID(const char *type)
#ifdef ZIP_SUPPORT
: (!stricmp(type, "ZIP")) ? TAB_ZIP
#endif
- : (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
+#ifdef MONGO_SUPPORT
+ : (!stricmp(type, "MONGO")) ? TAB_MONGO
+#endif
+ : (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
} // end of GetTypeID
/***********************************************************************/
@@ -307,6 +313,7 @@ int GetIndexType(TABTYPE type)
case TAB_MYSQL:
case TAB_ODBC:
case TAB_JDBC:
+ case TAB_MONGO:
xtyp= 2;
break;
case TAB_VIR:
@@ -477,39 +484,6 @@ void MYCAT::Reset(void)
{
} // end of Reset
-#if 0
-/***********************************************************************/
-/* This function sets the current database path. */
-/***********************************************************************/
-void MYCAT::SetPath(PGLOBAL g, LPCSTR *datapath, const char *path)
- {
- if (path) {
- size_t len= strlen(path) + (*path != '.' ? 4 : 1);
- char *buf= (char*)PlugSubAlloc(g, NULL, len);
-
- if (PlugIsAbsolutePath(path))
- {
- strcpy(buf, path);
- *datapath= buf;
- return;
- }
-
- if (*path != '.') {
-#if defined(__WIN__)
- char *s= "\\";
-#else // !__WIN__
- char *s= "/";
-#endif // !__WIN__
- strcat(strcat(strcat(strcpy(buf, "."), s), path), s);
- } else
- strcpy(buf, path);
-
- *datapath= buf;
- } // endif path
-
- } // end of SetDataPath
-#endif // 0
-
/***********************************************************************/
/* GetTableDesc: retrieve a table descriptor. */
/* Look for a table descriptor matching the name and type. */
@@ -583,6 +557,9 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
#endif // PIVOT_SUPPORT
case TAB_VIR: tdp= new(g) VIRDEF; break;
case TAB_JSON: tdp= new(g) JSONDEF; break;
+#if defined(MONGO_SUPPORT)
+ case TAB_MONGO: tdp = new(g) MGODEF; break;
+#endif // MONGO_SUPPORT
#if defined(ZIP_SUPPORT)
case TAB_ZIP: tdp= new(g) ZIPDEF; break;
#endif // ZIP_SUPPORT
diff --git a/storage/connect/mycat.h b/storage/connect/mycat.h
index a3682b31f17..b6bdd5e5e11 100644
--- a/storage/connect/mycat.h
+++ b/storage/connect/mycat.h
@@ -98,10 +98,7 @@ class MYCAT : public CATALOG {
// Methods
void Reset(void);
-//void SetDataPath(PGLOBAL g, const char *path)
-// {SetPath(g, &DataPath, path);}
bool StoreIndex(PGLOBAL, PTABDEF) {return false;} // Temporary
-// PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name,
PRELDEF GetTableDesc(PGLOBAL g, PTABLE tablep,
LPCSTR type, PRELDEF *prp = NULL);
PTDB GetTable(PGLOBAL g, PTABLE tablep,
@@ -109,9 +106,7 @@ class MYCAT : public CATALOG {
void ClearDB(PGLOBAL g);
protected:
-// PRELDEF MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am);
PRELDEF MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am);
- //void SetPath(PGLOBAL g, LPCSTR *datapath, const char *path);
// Members
ha_connect *Hc; // The Connect handler
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index d05254a32a6..e68489faad5 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -135,10 +135,13 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA,
FLD_CHARSET};
- unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
- char *fld, *colname, *chset, *fmt, v, buf[128], uns[16], zero[16];
+ //unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
+ unsigned int length[] = {0, 4, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
+ PCSZ fmt;
+ char *fld, *colname, *chset, v, buf[128], uns[16], zero[16];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0;
+ bool b;
PQRYRES qrp;
PCOLRES crp;
MYSQLC myc;
@@ -157,7 +160,7 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
/* Do an evaluation of the result size. */
/********************************************************************/
STRING cmd(g, 64, "SHOW FULL COLUMNS FROM ");
- bool b = cmd.Append((PSZ)table);
+ b = cmd.Append((PSZ)table);
b |= cmd.Append(" FROM ");
b |= cmd.Append((PSZ)(db ? db : PlgGetUser(g)->DBName));
@@ -232,11 +235,31 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
fld = myc.GetCharField(1);
prec = 0;
len = 0;
- v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
+// v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
+ v = 0;
*uns = 0;
*zero = 0;
-
- switch ((nf = sscanf(fld, "%[^(](%d,%d", buf, &len, &prec))) {
+ b = false;
+
+ if (!strnicmp(fld, "enum", 4)) {
+ char *p2, *p1 = fld + 6; // to skip enum('
+
+ while (true) {
+ p2 = strchr(p1, '\'');
+ len = MY_MAX(len, p2 - p1);
+ if (*++p2 != ',') break;
+ p1 = p2 + 2;
+ } // endwhile
+
+ v = (len > 255) ? 'V' : 0;
+ strcpy(buf, "enum");
+ b = true;
+ } else if (!strnicmp(fld, "set", 3)) {
+ len = (int)strlen(fld) - 2;
+ v = 'V';
+ strcpy(buf, "set");
+ b = true;
+ } else switch ((nf = sscanf(fld, "%[^(](%d,%d", buf, &len, &prec))) {
case 3:
nf = sscanf(fld, "%[^(](%d,%d) %s %s", buf, &len, &prec, uns, zero);
break;
@@ -271,7 +294,7 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
colname, len);
PushWarning(g, thd);
v = 'V';
- } else
+ } else
len = MY_MIN(len, 4096);
} // endif type
@@ -286,6 +309,9 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
default: crp->Nulls[i] = v; break;
} // endswitch nf
+ if (b) // enum or set
+ nf = sscanf(fld, "%s ", buf); // get values
+
crp = crp->Next; // Type_Name
crp->Kdata->SetValue(buf, i);
@@ -849,7 +875,8 @@ MYSQL_FIELD *MYSQLC::GetNextField(void)
/***********************************************************************/
PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
{
- char *fmt, v;
+ PCSZ fmt;
+ char *name, v;
int n;
bool uns;
PCOLRES *pcrp, crp;
@@ -887,8 +914,9 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
memset(crp, 0, sizeof(COLRES));
crp->Ncol = ++qrp->Nbcol;
- crp->Name = (char*)PlugSubAlloc(g, NULL, fld->name_length + 1);
- strcpy(crp->Name, fld->name);
+ name = (char*)PlugSubAlloc(g, NULL, fld->name_length + 1);
+ strcpy(name, fld->name);
+ crp->Name = name;
if ((crp->Type = MYSQLtoPLG(fld->type, &v)) == TYPE_ERROR) {
sprintf(g->Message, "Type %d not supported for column %s",
diff --git a/storage/connect/mysql-test/connect/disabled.def b/storage/connect/mysql-test/connect/disabled.def
index 0e5a5fc64e3..217e61e00b6 100644
--- a/storage/connect/mysql-test/connect/disabled.def
+++ b/storage/connect/mysql-test/connect/disabled.def
@@ -9,10 +9,9 @@
# Do not use any TAB characters for whitespace.
#
##############################################################################
-#jdbc : Variable settings depend on machine configuration
-#jdbc_new : Variable settings depend on machine configuration
+jdbc : Variable settings depend on machine configuration
+jdbc_new : Variable settings depend on machine configuration
jdbc_oracle : Variable settings depend on machine configuration
jdbc_postgresql : Variable settings depend on machine configuration
-json : TABLE_TYPE = JSON conflicts with the SQL syntax
-json_udf : conflicts with the server JSON functions
-json_udf_bin : conflicts with the server JSON functions
+json_mgo : Need MongoDB running and its C Driver installed
+mongo : Need MongoDB running and its C Driver installed
diff --git a/storage/connect/mysql-test/connect/r/bin.result b/storage/connect/mysql-test/connect/r/bin.result
index 1baa18a1e4d..4ba353ac705 100644
--- a/storage/connect/mysql-test/connect/r/bin.result
+++ b/storage/connect/mysql-test/connect/r/bin.result
@@ -57,7 +57,7 @@ t1 CREATE TABLE `t1` (
`name` char(10) NOT NULL,
`birth` date NOT NULL,
`id` char(5) NOT NULL `FIELD_FORMAT`='S',
- `salary` double(9,2) NOT NULL DEFAULT 0.00 `FIELD_FORMAT`='F',
+ `salary` double(9,2) NOT NULL DEFAULT '0.00' `FIELD_FORMAT`='F',
`dept` int(4) NOT NULL `FIELD_FORMAT`='S'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `OPTION_LIST`='Endian=Little' `READONLY`=NO
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
@@ -76,7 +76,7 @@ t1 CREATE TABLE `t1` (
`name` char(10) NOT NULL,
`birth` date NOT NULL,
`id` char(5) NOT NULL `FIELD_FORMAT`='S',
- `salary` double(9,2) NOT NULL DEFAULT 0.00 `FIELD_FORMAT`='F',
+ `salary` double(9,2) NOT NULL DEFAULT '0.00' `FIELD_FORMAT`='F',
`dept` int(4) NOT NULL `FIELD_FORMAT`='S'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `OPTION_LIST`='Endian=Little' `READONLY`=YES
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
diff --git a/storage/connect/mysql-test/connect/r/dir.result b/storage/connect/mysql-test/connect/r/dir.result
index 99556c9b72d..34a591fb26c 100644
--- a/storage/connect/mysql-test/connect/r/dir.result
+++ b/storage/connect/mysql-test/connect/r/dir.result
@@ -25,7 +25,6 @@ SELECT fname, ftype, size FROM t1 ORDER BY fname, ftype, size;
fname ftype size
boys .txt 282
boyswin .txt 288
-SET STATEMENT sql_mode = '' FOR
INSERT INTO t1 VALUES ('','','','');
ERROR HY000: Got error 174 'COLBLK SetBuffer: undefined Access Method' from CONNECT
DROP TABLE t1;
diff --git a/storage/connect/mysql-test/connect/r/grant.result b/storage/connect/mysql-test/connect/r/grant.result
index 118d75408be..4e64b983ea7 100644
--- a/storage/connect/mysql-test/connect/r/grant.result
+++ b/storage/connect/mysql-test/connect/r/grant.result
@@ -4,8 +4,6 @@ set sql_mode="";
#
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
-connect user,localhost,user,,;
-connection user;
SELECT user();
user()
user@localhost
@@ -16,7 +14,6 @@ ftype CHAR(4) NOT NULL,
size DOUBLE(12,0) NOT NULL flag=5
) ENGINE=CONNECT TABLE_TYPE=DIR FILE_NAME='*.*';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
@@ -29,7 +26,6 @@ size DOUBLE(12,0) NOT NULL flag=5
SELECT fname, ftype, size FROM t1 WHERE size>0;
fname ftype size
t1 .frm 1081
-connection user;
SELECT user();
user()
user@localhost
@@ -48,12 +44,10 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
-connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
-connection user;
SELECT user();
user()
user@localhost
@@ -65,8 +59,6 @@ UPDATE v1 SET path=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-disconnect user;
-connection default;
SELECT user();
user()
root@localhost
@@ -82,8 +74,6 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
-connect user,localhost,user,,;
-connection user;
SELECT user();
user()
user@localhost
@@ -112,13 +102,11 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
@@ -141,12 +129,10 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
-connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
-connection user;
SELECT user();
user()
user@localhost
@@ -158,7 +144,6 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
@@ -168,15 +153,12 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=BIN;
Warnings:
Warning 1105 No file name. Table will use t1.bin
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
-disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
@@ -187,8 +169,6 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
-connect user,localhost,user,,;
-connection user;
SELECT user();
user()
user@localhost
@@ -217,13 +197,11 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
@@ -246,12 +224,10 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
-connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
-connection user;
SELECT user();
user()
user@localhost
@@ -263,7 +239,6 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
@@ -273,15 +248,12 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV;
Warnings:
Warning 1105 No file name. Table will use t1.csv
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
-disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
@@ -292,8 +264,6 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
-connect user,localhost,user,,;
-connection user;
SELECT user();
user()
user@localhost
@@ -322,13 +292,11 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
@@ -351,12 +319,10 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
-connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
-connection user;
SELECT user();
user()
user@localhost
@@ -368,7 +334,6 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
@@ -378,15 +343,12 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF;
Warnings:
Warning 1105 No file name. Table will use t1.dbf
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
-disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
@@ -397,8 +359,6 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
-connect user,localhost,user,,;
-connection user;
SELECT user();
user()
user@localhost
@@ -427,13 +387,11 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
@@ -456,12 +414,10 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
-connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
-connection user;
SELECT user();
user()
user@localhost
@@ -473,7 +429,6 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
@@ -483,15 +438,12 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=FIX;
Warnings:
Warning 1105 No file name. Table will use t1.fix
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
-disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
@@ -502,8 +454,6 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
-connect user,localhost,user,,;
-connection user;
SELECT user();
user()
user@localhost
@@ -532,13 +482,11 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=VEC MAX_ROWS=100 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=VEC MAX_ROWS=100 FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
@@ -561,12 +509,10 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
-connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
-connection user;
SELECT user();
user()
user@localhost
@@ -578,7 +524,6 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
@@ -588,15 +533,12 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=VEC MAX_ROWS=100;
Warnings:
Warning 1105 No file name. Table will use t1.vec
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
-disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
diff --git a/storage/connect/mysql-test/connect/r/grant2.result b/storage/connect/mysql-test/connect/r/grant2.result
index 73e41f49256..0259dd74cdc 100644
--- a/storage/connect/mysql-test/connect/r/grant2.result
+++ b/storage/connect/mysql-test/connect/r/grant2.result
@@ -5,7 +5,6 @@ CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
# Testing SQLCOM_SELECT
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -22,7 +21,6 @@ a
10
SELECT * FROM v1_baddefiner;
ERROR 28000: Access denied for user 'root'@'localhost' (using password: NO)
-connect user,localhost,user,,;
SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT * FROM v1_invoker;
@@ -30,11 +28,9 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT * FROM v1_definer;
a
10
-connection default;
DROP VIEW v1_invoker, v1_definer, v1_baddefiner;
DROP TABLE t1;
# Testing SQLCOM_UPDATE
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -42,17 +38,14 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
UPDATE t1 SET a=11;
UPDATE v1_invoker SET a=12;
UPDATE v1_definer SET a=13;
-connection user;
UPDATE t1 SET a=21;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE v1_invoker SET a=22;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE v1_definer SET a=23;
-connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_INSERT
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -60,17 +53,14 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
INSERT INTO t1 VALUES (11);
INSERT INTO v1_invoker VALUES (12);
INSERT INTO v1_definer VALUES (13);
-connection user;
INSERT INTO t1 VALUES (21);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO v1_invoker VALUES (22);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO v1_definer VALUES (23);
-connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_REPLACE
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -81,18 +71,15 @@ REPLACE INTO v1_invoker VALUES (12);
ERROR 42000: CONNECT Unsupported command
REPLACE INTO v1_definer VALUES (13);
ERROR 42000: CONNECT Unsupported command
-connection user;
REPLACE INTO t1 VALUES (21);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
REPLACE INTO v1_invoker VALUES (22);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
REPLACE INTO v1_definer VALUES (23);
ERROR 42000: CONNECT Unsupported command
-connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_DELETE
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10),(11),(12),(13),(21),(22),(23);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -100,17 +87,14 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
DELETE FROM t1 WHERE a=11;
DELETE FROM v1_invoker WHERE a=12;
DELETE FROM v1_definer WHERE a=13;
-connection user;
DELETE FROM t1 WHERE a=21;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1_invoker WHERE a=22;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1_definer WHERE a=23;
-connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_LOAD
-connection default;
CREATE TABLE t1 (a VARCHAR(128)) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -118,38 +102,29 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE t1;
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE v1_invoker;
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE v1_definer;
-connection user;
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE v1_invoker;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE v1_definer;
-connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_TRUNCATE
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
TRUNCATE TABLE t1;
INSERT INTO t1 VALUES (11);
-connection user;
TRUNCATE TABLE t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_DROP_TABLE
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
-connection user;
DROP TABLE t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_DROP_VIEW
# DROP VIEW does not need FILE_ACL.
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10),(11),(12),(13),(21),(22),(23);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -157,18 +132,13 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
DROP VIEW v1_invoker, v1_definer;
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
-connection user;
DROP VIEW v1_invoker;
DROP VIEW v1_definer;
-connection default;
DROP TABLE t1;
# Testing SQLCOM_CREATE_TABLE
-connection user;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
# Testing SQLCOM_LOCK_TABLES
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -185,7 +155,6 @@ LOCK TABLE v1_definer READ;
UNLOCK TABLES;
LOCK TABLE v1_definer WRITE;
UNLOCK TABLES;
-connection user;
LOCK TABLE t1 READ;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
LOCK TABLE t1 WRITE;
@@ -198,11 +167,9 @@ LOCK TABLE v1_definer READ;
UNLOCK TABLES;
LOCK TABLE v1_definer WRITE;
UNLOCK TABLES;
-connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_UPDATE_MULTI
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
CREATE TABLE t2 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t2.fix';
CREATE TABLE t3 (a INT);
@@ -262,7 +229,6 @@ UPDATE v2_definer a1,v1_invoker a2 SET a1.a=50 WHERE a1.a=a2.a;
UPDATE v2_definer a1,v1_definer a2 SET a1.a=50 WHERE a1.a=a2.a;
UPDATE v2_definer a1,v2_invoker a2 SET a1.a=50 WHERE a1.a=a2.a;
UPDATE v2_definer a1,v2_definer a2 SET a1.a=50 WHERE a1.a=a2.a;
-connection user;
UPDATE t1 a1,t1 a2 SET a1.a=50 WHERE a1.a=a2.a;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE t1 a1,t2 a2 SET a1.a=50 WHERE a1.a=a2.a;
@@ -352,11 +318,9 @@ UPDATE v2_definer a1,v1_definer a2 SET a1.a=50 WHERE a1.a=a2.a;
UPDATE v2_definer a1,v2_invoker a2 SET a1.a=50 WHERE a1.a=a2.a;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE v2_definer a1,v2_definer a2 SET a1.a=50 WHERE a1.a=a2.a;
-connection default;
DROP VIEW v1_invoker, v1_definer, v2_invoker, v2_definer;
DROP TABLE t1, t2, t3;
# Testing SQLCOM_DELETE_MULTI
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
CREATE TABLE t2 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t2.fix';
CREATE TABLE t3 (a INT);
@@ -416,7 +380,6 @@ DELETE a1 FROM v2_definer a1,v1_invoker a2 WHERE a1.a=a2.a;
DELETE a1 FROM v2_definer a1,v1_definer a2 WHERE a1.a=a2.a;
DELETE a1 FROM v2_definer a1,v2_invoker a2 WHERE a1.a=a2.a;
DELETE a1 FROM v2_definer a1,v2_definer a2 WHERE a1.a=a2.a;
-connection user;
DELETE a1 FROM t1 a1,t1 a2 WHERE a1.a=a2.a;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE a1 FROM t1 a1,t2 a2 WHERE a1.a=a2.a;
@@ -506,11 +469,9 @@ DELETE a1 FROM v2_definer a1,v1_definer a2 WHERE a1.a=a2.a;
DELETE a1 FROM v2_definer a1,v2_invoker a2 WHERE a1.a=a2.a;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE a1 FROM v2_definer a1,v2_definer a2 WHERE a1.a=a2.a;
-connection default;
DROP VIEW v1_invoker, v1_definer, v2_invoker, v2_definer;
DROP TABLE t1, t2, t3;
# Testing SQLCOM_CREATE_VIEW
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -519,18 +480,15 @@ CREATE VIEW v2 AS SELECT * FROM v1_invoker;
DROP VIEW v2;
CREATE VIEW v2 AS SELECT * FROM v1_definer;
DROP VIEW v2;
-connection user;
CREATE VIEW v2 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v2 AS SELECT * FROM v1_invoker;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v2 AS SELECT * FROM v1_definer;
DROP VIEW v2;
-connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_INSERT_SELECT
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -544,7 +502,6 @@ INSERT INTO v1_invoker SELECT * FROM v1_definer WHERE a=20;
INSERT INTO v1_definer SELECT * FROM t1 WHERE a=20;
INSERT INTO v1_definer SELECT * FROM v1_invoker WHERE a=20;
INSERT INTO v1_definer SELECT * FROM v1_definer WHERE a=20;
-connection user;
INSERT INTO t1 SELECT * FROM t1 WHERE a=20;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO t1 SELECT * FROM v1_invoker WHERE a=20;
@@ -562,11 +519,9 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO v1_definer SELECT * FROM v1_invoker WHERE a=20;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO v1_definer SELECT * FROM v1_definer WHERE a=20;
-connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_REPLACE_SELECT
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -589,7 +544,6 @@ REPLACE INTO v1_definer SELECT * FROM v1_invoker WHERE a=20;
ERROR 42000: CONNECT Unsupported command
REPLACE INTO v1_definer SELECT * FROM v1_definer WHERE a=20;
ERROR 42000: CONNECT Unsupported command
-connection user;
REPLACE INTO t1 SELECT * FROM t1 WHERE a=20;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
REPLACE INTO t1 SELECT * FROM v1_invoker WHERE a=20;
@@ -608,11 +562,9 @@ REPLACE INTO v1_definer SELECT * FROM v1_invoker WHERE a=20;
ERROR 42000: CONNECT Unsupported command
REPLACE INTO v1_definer SELECT * FROM v1_definer WHERE a=20;
ERROR 42000: CONNECT Unsupported command
-connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_RENAME_TABLE
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
RENAME TABLE t1 TO t2;
@@ -622,13 +574,10 @@ t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='t1.fix'
RENAME TABLE t2 TO t1;
-connection user;
RENAME TABLE t1 TO t2;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (for ALTER..RENAME)
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
ALTER TABLE t1 RENAME TO t2;
@@ -638,26 +587,20 @@ t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='t1.fix'
ALTER TABLE t2 RENAME TO t1;
-connection user;
ALTER TABLE t1 RENAME TO t2;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (changing ENGINE to non-CONNECT)
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
ALTER TABLE t1 ENGINE=MyISAM;
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
-connection user;
ALTER TABLE t1 ENGINE=MyISAM;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (changing ENGINE to CONNECT)
-connection default;
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
@@ -667,83 +610,63 @@ ALTER TABLE t1 ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10);
-connection user;
ALTER TABLE t1 ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_OPTIMIZE
-connection default;
CREATE TABLE t1 (a INT NOT NULL, KEY(a)) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
-connection user;
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize Error Access denied for user 'user'@'localhost' (using password: NO)
test.t1 optimize Error Got error 122 'This operation requires the FILE privilege' from CONNECT
test.t1 optimize error Corrupt
-connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (adding columns)
-connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
ALTER TABLE t1 ADD b INT;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
-connection user;
ALTER TABLE t1 ADD c INT;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (removing columns)
-connection default;
CREATE TABLE t1 (a INT,b INT,c INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10,10,10);
ALTER TABLE t1 DROP b;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
-connection user;
ALTER TABLE t1 DROP c;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (adding keys)
-connection default;
CREATE TABLE t1 (a INT NOT NULL,b INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10,10);
ALTER TABLE t1 ADD KEY(a);
-connection user;
ALTER TABLE t1 ADD KEY(b);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (removing keys)
-connection default;
CREATE TABLE t1 (a INT NOT NULL,b INT NOT NULL, KEY a(a), KEY b(b)) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10,10);
ALTER TABLE t1 DROP KEY a;
-connection user;
ALTER TABLE t1 DROP KEY b;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing SQLCOM_CREATE_INDEX and SQLCOM_DROP_INDEX
-connection default;
CREATE TABLE t1 (a INT NOT NULL,b INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10,10);
CREATE INDEX a ON t1 (a);
DROP INDEX a ON t1;
CREATE INDEX a ON t1 (a);
-connection user;
CREATE INDEX b ON t1 (b);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DROP INDEX a ON t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
# Testing stored procedures
CREATE PROCEDURE p_definer() SQL SECURITY DEFINER
@@ -758,11 +681,9 @@ CALL p_invoker();
DROP TABLE t1;
CALL p_baddefiner();
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection user;
CALL p_invoker();
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CALL p_definer();
-connection default;
DROP TABLE t1;
DROP PROCEDURE p_definer;
DROP PROCEDURE p_invoker;
diff --git a/storage/connect/mysql-test/connect/r/ini_grant.result b/storage/connect/mysql-test/connect/r/ini_grant.result
index 8cbf88123fb..68330278183 100644
--- a/storage/connect/mysql-test/connect/r/ini_grant.result
+++ b/storage/connect/mysql-test/connect/r/ini_grant.result
@@ -5,8 +5,6 @@ set sql_mode="";
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
set sql_mode=default;
-connect user,localhost,user,,;
-connection user;
SELECT user();
user()
user@localhost
@@ -35,13 +33,11 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES ('sec1','val1');
-connection user;
SELECT user();
user()
user@localhost
@@ -62,12 +58,10 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
-connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
-connection user;
SELECT user();
user()
user@localhost
@@ -79,8 +73,6 @@ UPDATE v1 SET val='val11';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-disconnect user;
-connection default;
DROP VIEW v1;
DROP TABLE t1;
DROP USER user@localhost;
diff --git a/storage/connect/mysql-test/connect/r/jdbc_new.result b/storage/connect/mysql-test/connect/r/jdbc_new.result
index 5cc4826213d..6f977166598 100644
--- a/storage/connect/mysql-test/connect/r/jdbc_new.result
+++ b/storage/connect/mysql-test/connect/r/jdbc_new.result
@@ -14,9 +14,7 @@ NULL NULL
SET GLOBAL time_zone='+1:00';
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=unknown';
-SELECT * FROM t1;
-ERROR HY000: Got error 174 'Connecting: java.sql.SQLException: Access denied for user 'unknown'@'localhost' (using password: NO) rc=-2' from CONNECT
-DROP TABLE t1;
+ERROR HY000: Connecting: java.sql.SQLException: Access denied for user 'unknown'@'localhost' (using password: NO) rc=-2
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/unknown?user=root';
ERROR HY000: Connecting: java.sql.SQLSyntaxErrorException: Unknown database 'unknown' rc=-2
diff --git a/storage/connect/mysql-test/connect/r/json.result b/storage/connect/mysql-test/connect/r/json.result
index aa6b04c58c7..6b6f40d2c47 100644
--- a/storage/connect/mysql-test/connect/r/json.result
+++ b/storage/connect/mysql-test/connect/r/json.result
@@ -24,15 +24,15 @@ DROP TABLE t1;
CREATE TABLE t1
(
ISBN CHAR(15),
-Language CHAR(2) FIELD_FORMAT='LANG',
-Subject CHAR(32) FIELD_FORMAT='SUBJECT',
-Authors INT(2) FIELD_FORMAT='AUTHOR:[#]',
-Title CHAR(32) FIELD_FORMAT='TITLE',
-Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
-Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
-Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
-Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
-Year int(4) FIELD_FORMAT='DATEPUB'
+Language CHAR(2) FIELD_FORMAT='$.LANG',
+Subject CHAR(32) FIELD_FORMAT='$.SUBJECT',
+Authors INT(2) FIELD_FORMAT='$.AUTHOR[#]',
+Title CHAR(32) FIELD_FORMAT='$.TITLE',
+Translation CHAR(32) FIELD_FORMAT='$.TRANSLATION',
+Translator CHAR(80) FIELD_FORMAT='$.TRANSLATOR',
+Publisher CHAR(20) FIELD_FORMAT='$.PUBLISHER.NAME',
+Location CHAR(16) FIELD_FORMAT='$.PUBLISHER.PLACE',
+Year int(4) FIELD_FORMAT='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1;
@@ -46,16 +46,16 @@ DROP TABLE t1;
CREATE TABLE t1
(
ISBN CHAR(15),
-Language CHAR(2) FIELD_FORMAT='LANG',
-Subject CHAR(32) FIELD_FORMAT='SUBJECT',
-AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[" and "]:FIRSTNAME',
-AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[" and "]:LASTNAME',
-Title CHAR(32) FIELD_FORMAT='TITLE',
-Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
-Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
-Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
-Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
-Year int(4) FIELD_FORMAT='DATEPUB'
+Language CHAR(2) FIELD_FORMAT='$.LANG',
+Subject CHAR(32) FIELD_FORMAT='$.SUBJECT',
+AuthorFN CHAR(128) FIELD_FORMAT='$.AUTHOR[" and "].FIRSTNAME',
+AuthorLN CHAR(128) FIELD_FORMAT='$.AUTHOR[" and "].LASTNAME',
+Title CHAR(32) FIELD_FORMAT='$.TITLE',
+Translation CHAR(32) FIELD_FORMAT='$.TRANSLATION',
+Translator CHAR(80) FIELD_FORMAT='$.TRANSLATOR',
+Publisher CHAR(20) FIELD_FORMAT='$.PUBLISHER.NAME',
+Location CHAR(16) FIELD_FORMAT='$.PUBLISHER.PLACE',
+Year int(4) FIELD_FORMAT='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1;
@@ -69,16 +69,16 @@ DROP TABLE t1;
CREATE TABLE t1
(
ISBN CHAR(15),
-Language CHAR(2) FIELD_FORMAT='LANG',
-Subject CHAR(32) FIELD_FORMAT='SUBJECT',
-AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
-AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
-Title CHAR(32) FIELD_FORMAT='TITLE',
-Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
-Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
-Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
-Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
-Year int(4) FIELD_FORMAT='DATEPUB'
+Language CHAR(2) FIELD_FORMAT='$.LANG',
+Subject CHAR(32) FIELD_FORMAT='$.SUBJECT',
+AuthorFN CHAR(128) FIELD_FORMAT='$.AUTHOR[*].FIRSTNAME',
+AuthorLN CHAR(128) FIELD_FORMAT='$.AUTHOR[*].LASTNAME',
+Title CHAR(32) FIELD_FORMAT='$.TITLE',
+Translation CHAR(32) FIELD_FORMAT='$.TRANSLATION',
+Translator CHAR(80) FIELD_FORMAT='$.TRANSLATOR',
+Publisher CHAR(20) FIELD_FORMAT='$.PUBLISHER.NAME',
+Location CHAR(16) FIELD_FORMAT='$.PUBLISHER.PLACE',
+Year int(4) FIELD_FORMAT='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1;
@@ -97,7 +97,7 @@ ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher L
CREATE TABLE t2 (
FIRSTNAME CHAR(32),
LASTNAME CHAR(32))
-ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json' OPTION_LIST='Object=[1]:AUTHOR';
+ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json' OPTION_LIST='Object=$[1].AUTHOR';
SELECT * FROM t2;
FIRSTNAME LASTNAME
William J. Pardi
@@ -176,17 +176,17 @@ DROP TABLE t1;
CREATE TABLE t1
(
ISBN CHAR(15) NOT NULL,
-Language CHAR(2) FIELD_FORMAT='LANG',
-Subject CHAR(32) FIELD_FORMAT='SUBJECT',
-AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
-AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
-Title CHAR(32) FIELD_FORMAT='TITLE',
-Translation CHAR(32) FIELD_FORMAT='TRANSLATED:PREFIX',
-TranslatorFN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:FIRSTNAME',
-TranslatorLN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:LASTNAME',
-Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
-Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
-Year int(4) FIELD_FORMAT='DATEPUB',
+Language CHAR(2) FIELD_FORMAT='$.LANG',
+Subject CHAR(32) FIELD_FORMAT='$.SUBJECT',
+AuthorFN CHAR(128) FIELD_FORMAT='$.AUTHOR[*].FIRSTNAME',
+AuthorLN CHAR(128) FIELD_FORMAT='$.AUTHOR[*].LASTNAME',
+Title CHAR(32) FIELD_FORMAT='$.TITLE',
+Translation CHAR(32) FIELD_FORMAT='$.TRANSLATED.PREFIX',
+TranslatorFN CHAR(80) FIELD_FORMAT='$.TRANSLATED.TRANSLATOR.FIRSTNAME',
+TranslatorLN CHAR(80) FIELD_FORMAT='$.TRANSLATED.TRANSLATOR.LASTNAME',
+Publisher CHAR(20) FIELD_FORMAT='$.PUBLISHER.NAME',
+Location CHAR(16) FIELD_FORMAT='$.PUBLISHER.PLACE',
+Year int(4) FIELD_FORMAT='$.DATEPUB',
INDEX IX(ISBN)
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bib0.json' LRECL=320 OPTION_LIST='Pretty=0';
@@ -209,9 +209,9 @@ DROP TABLE t1;
#
CREATE TABLE t1 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[X]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK::EXPENSE:["+"]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK::EXPENSE:[+]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[*].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[].EXPENSE["+"].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[].EXPENSE[+].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t1;
WHO WEEK WHAT AMOUNT
@@ -230,9 +230,9 @@ DROP TABLE t1;
#
CREATE TABLE t1 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[X]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[*].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[*].EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[*].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t1;
WHO WEEK WHAT AMOUNT
@@ -266,14 +266,14 @@ DROP TABLE t1;
#
CREATE TABLE t1 (
WHO CHAR(12) NOT NULL,
-WEEKS CHAR(12) NOT NULL FIELD_FORMAT='WEEK:[", "]:NUMBER',
-SUMS CHAR(64) NOT NULL FIELD_FORMAT='WEEK:["+"]:EXPENSE:[+]:AMOUNT',
-SUM DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[+]:EXPENSE:[+]:AMOUNT',
-AVGS CHAR(64) NOT NULL FIELD_FORMAT='WEEK:["+"]:EXPENSE:[!]:AMOUNT',
-SUMAVG DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[+]:EXPENSE:[!]:AMOUNT',
-AVGSUM DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[!]:EXPENSE:[+]:AMOUNT',
-AVGAVG DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[!]:EXPENSE:[!]:AMOUNT',
-AVERAGE DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[!]:EXPENSE:[X]:AMOUNT')
+WEEKS CHAR(12) NOT NULL FIELD_FORMAT='$.WEEK[", "].NUMBER',
+SUMS CHAR(64) NOT NULL FIELD_FORMAT='$.WEEK["+"].EXPENSE[+].AMOUNT',
+SUM DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[+].EXPENSE[+].AMOUNT',
+AVGS CHAR(64) NOT NULL FIELD_FORMAT='$.WEEK["+"].EXPENSE[!].AMOUNT',
+SUMAVG DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[+].EXPENSE[!].AMOUNT',
+AVGSUM DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[!].EXPENSE[+].AMOUNT',
+AVGAVG DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[!].EXPENSE[!].AMOUNT',
+AVERAGE DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[!].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t1;
WHO WEEKS SUMS SUM AVGS SUMAVG AVGSUM AVGAVG AVERAGE
@@ -286,9 +286,9 @@ DROP TABLE t1;
#
CREATE TABLE t2 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[0]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK:[0]:EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[0]:EXPENSE:[X]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[0].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[0].EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[0].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t2;
WHO WEEK WHAT AMOUNT
@@ -302,9 +302,9 @@ Janet 3 Food 18.00
Janet 3 Beer 18.00
CREATE TABLE t3 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[1]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK:[1]:EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[1]:EXPENSE:[X]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[1].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[1].EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[1].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t3;
WHO WEEK WHAT AMOUNT
@@ -318,9 +318,9 @@ Beth 4 Beer 15.00
Janet 4 Car 17.00
CREATE TABLE t4 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[2]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK:[2]:EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[2]:EXPENSE:[X]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[2].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[2].EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[2].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t4;
WHO WEEK WHAT AMOUNT
@@ -374,8 +374,8 @@ DROP TABLE t1, t2, t3, t4;
CREATE TABLE t2 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp3.json';
SELECT * FROM t2;
WHO WEEK WHAT AMOUNT
@@ -390,8 +390,8 @@ Janet 3 Beer 18.00
CREATE TABLE t3 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp4.json';
SELECT * FROM t3;
WHO WEEK WHAT AMOUNT
@@ -406,8 +406,8 @@ Janet 4 Car 17.00
CREATE TABLE t4 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp5.json';
SELECT * FROM t4;
WHO WEEK WHAT AMOUNT
@@ -425,8 +425,8 @@ Janet 5 Food 12.00
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp*.json' MULTIPLE=1;
SELECT * FROM t1 ORDER BY WHO, WEEK, WHAT, AMOUNT;
WHO WEEK WHAT AMOUNT
@@ -461,8 +461,8 @@ DROP TABLE t1;
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp%s.json';
ALTER TABLE t1
PARTITION BY LIST COLUMNS(WEEK) (
diff --git a/storage/connect/mysql-test/connect/r/json_udf.result b/storage/connect/mysql-test/connect/r/json_udf.result
index 1e83834cb8f..a36d3fe539d 100644
--- a/storage/connect/mysql-test/connect/r/json_udf.result
+++ b/storage/connect/mysql-test/connect/r/json_udf.result
@@ -35,18 +35,18 @@ JsonValue('[11, 22, 33]' json_)
[11,22,33]
[11,22,33]
[11,22,33]
-SELECT Json_Array();
-Json_Array()
+SELECT Json_Make_Array();
+Json_Make_Array()
[]
-SELECT Json_Array(56, 3.1416, 'My name is "Foo"', NULL);
-Json_Array(56, 3.1416, 'My name is "Foo"', NULL)
+SELECT Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL);
+Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL)
[56,3.141600,"My name is \"Foo\"",null]
-SELECT Json_Array(Json_Array(56, 3.1416, 'foo'), TRUE);
-Json_Array(Json_Array(56, 3.1416, 'foo'), TRUE)
+SELECT Json_Make_Array(Json_Make_Array(56, 3.1416, 'foo'), TRUE);
+Json_Make_Array(Json_Make_Array(56, 3.1416, 'foo'), TRUE)
[[56,3.141600,"foo"],true]
-SELECT Json_Array_Add(Json_Array(56, 3.1416, 'foo', NULL)) Array;
+SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL)) Array;
ERROR HY000: Can't initialize function 'json_array_add'; This function must have at least 2 arguments
-SELECT Json_Array_Add(Json_Array(56, 3.1416, 'foo', NULL), 'One more') Array;
+SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL), 'One more') Array;
Array
[56,3.141600,"foo",null,"One more"]
SELECT Json_Array_Add(JsonValue('one value'), 'One more');
@@ -70,33 +70,33 @@ Array
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 9);
Json_Array_Add('[5,3,8,7,9]' json_, 4, 9)
[5,3,8,7,9,4]
-SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), '[2]', 33, 1);
-Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), '[2]', 33, 1)
+SELECT Json_Array_Add(Json_Make_Array(1, 2, Json_Make_Array(11, 22)), '[2]', 33, 1);
+Json_Array_Add(Json_Make_Array(1, 2, Json_Make_Array(11, 22)), '[2]', 33, 1)
[1,2,[11,22],"[2]"]
-SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, '[2]', 1);
-Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, '[2]', 1)
+SELECT Json_Array_Add(Json_Make_Array(1, 2, Json_Make_Array(11, 22)), 33, '[2]', 1);
+Json_Array_Add(Json_Make_Array(1, 2, Json_Make_Array(11, 22)), 33, '[2]', 1)
[1,2,[11,33,22]]
-SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, 1, '[2]');
-Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, 1, '[2]')
+SELECT Json_Array_Add(Json_Make_Array(1, 2, Json_Make_Array(11, 22)), 33, 1, '[2]');
+Json_Array_Add(Json_Make_Array(1, 2, Json_Make_Array(11, 22)), 33, 1, '[2]')
[1,2,[11,33,22]]
-SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
+SELECT Json_Array_Add_Values(Json_Make_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
Array
[56,3.141600,"machin",null,"One more","Two more"]
-SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
+SELECT Json_Array_Add_Values(Json_Make_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
Array
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
-SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), n) Array FROM t1;
+SELECT Json_Array_Add_Values(Json_Make_Array(56, 3.1416, 'machin'), n) Array FROM t1;
Array
[56,3.141600,"machin",1]
[56,3.141600,"machin",2]
[56,3.141600,"machin",3]
[56,3.141600,"machin",4]
[56,3.141600,"machin",5]
-SELECT Json_Array_Add_Values(Json_Array(n, 3.1416, 'machin'), n) Array FROM t1;
+SELECT Json_Array_Add_Values(Json_Make_Array(n, 3.1416, 'machin'), n) Array FROM t1;
Array
[1,3.141600,"machin",1]
[2,3.141600,"machin",2]
@@ -106,49 +106,49 @@ Array
SELECT Json_Array_Add_Values('[56]', 3.1416, 'machin') Array;
Array
[56,3.141600,"machin"]
-SELECT Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), 0);
-Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), 0)
+SELECT Json_Array_Delete(Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL), 0);
+Json_Array_Delete(Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL), 0)
[3.141600,"My name is \"Foo\"",null]
-SELECT Json_Array_Delete(Json_Object(56, 3.1416, 'My name is Foo', NULL), 2);
-Json_Array_Delete(Json_Object(56, 3.1416, 'My name is Foo', NULL), 2)
+SELECT Json_Array_Delete(Json_Make_Object(56, 3.1416, 'My name is Foo', NULL), 2);
+Json_Array_Delete(Json_Make_Object(56, 3.1416, 'My name is Foo', NULL), 2)
{"56":56,"3.1416":3.141600,"My name is Foo":"My name is Foo","NULL":null}
Warnings:
Warning 1105 First argument target is not an array
-SELECT Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), '2');
-Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), '2')
+SELECT Json_Array_Delete(Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL), '2');
+Json_Array_Delete(Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL), '2')
[56,3.141600,"My name is \"Foo\"",null]
Warnings:
Warning 1105 Missing or null array index
-SELECT Json_Array_Delete(json_array(56, 3.1416, 'My name is "Foo"', NULL), '2', 2);
-Json_Array_Delete(json_array(56, 3.1416, 'My name is "Foo"', NULL), '2', 2)
+SELECT Json_Array_Delete(Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL), '2', 2);
+Json_Array_Delete(Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL), '2', 2)
[56,3.141600,"My name is \"Foo\"",null]
Warnings:
-Warning 1105 No sub-item at '2'
-SELECT Json_Object(56, 3.1416, 'foo', NULL);
-Json_Object(56, 3.1416, 'foo', NULL)
+Warning 1105 First argument target is not an array
+SELECT Json_Make_Object(56, 3.1416, 'foo', NULL);
+Json_Make_Object(56, 3.1416, 'foo', NULL)
{"56":56,"3.1416":3.141600,"foo":"foo","NULL":null}
-SELECT Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
-Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty)
+SELECT Json_Make_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
+Json_Make_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty)
{"qty":56,"price":3.141600,"truc":"foo","garanty":null}
-SELECT Json_Object();
-Json_Object()
+SELECT Json_Make_Object();
+Json_Make_Object()
{}
-SELECT Json_Object(Json_Array(56, 3.1416, 'foo'), NULL);
-Json_Object(Json_Array(56, 3.1416, 'foo'), NULL)
-{"Array(56, 3.1416, 'foo')":[56,3.141600,"foo"],"NULL":null}
-SELECT Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
-Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL)
+SELECT Json_Make_Object(Json_Make_Array(56, 3.1416, 'foo'), NULL);
+Json_Make_Object(Json_Make_Array(56, 3.1416, 'foo'), NULL)
+{"Make_Array(56, 3.1416, 'foo')":[56,3.141600,"foo"],"NULL":null}
+SELECT Json_Make_Array(Json_Make_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
+Json_Make_Array(Json_Make_Object(56 "qty", 3.1416 "price", 'foo') ,NULL)
[{"qty":56,"price":3.141600,"foo":"foo"},null]
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL);
Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL)
{"qty":56,"price":3.141600,"truc":"machin","garanty":null}
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty');
ERROR HY000: Can't initialize function 'json_object_key'; This function must have an even number of arguments
-SELECT Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
-Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color)
+SELECT Json_Object_Add(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
+Json_Object_Add(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color)
{"qty":56,"price":3.141600,"truc":"machin","garanty":null,"color":"blue"}
-SELECT Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
-Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price)
+SELECT Json_Object_Add(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
+Json_Object_Add(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price)
{"qty":56,"price":45.990000,"truc":"machin","garanty":null}
SELECT Json_Object_Add(Json_File('notexist.json'), 'cheese' item, '[1]', 1);
Json_Object_Add(Json_File('notexist.json'), 'cheese' item, '[1]', 1)
@@ -156,13 +156,13 @@ NULL
Warnings:
Warning 1105 Error 2 opening notexist.json
Warning 1105 First argument target is not an object
-SELECT Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'truc');
-Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'truc')
+SELECT Json_Object_Delete(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'truc');
+Json_Object_Delete(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'truc')
{"qty":56,"price":3.141600,"garanty":null}
-SELECT Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'chose');
-Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'chose')
+SELECT Json_Object_Delete(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'chose');
+Json_Object_Delete(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'chose')
{"qty":56,"price":3.141600,"truc":"machin","garanty":null}
-SELECT Json_Object_List(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty)) "Key List";
+SELECT Json_Object_List(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty)) "Key List";
Key List
["qty","price","truc","garanty"]
SELECT Json_Object_List('{"qty":56, "price":3.1416, "truc":"machin", "garanty":null}') "Key List";
@@ -183,12 +183,12 @@ TRANSLATOR CHAR(80),
PUBLISHER CHAR(32),
DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
-SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
-Json_Array(AUTHOR, TITLE, DATEPUB)
+SELECT Json_Make_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
+Json_Make_Array(AUTHOR, TITLE, DATEPUB)
["Jean-Christophe Bernadac","Construire une application XML",1999]
["William J. Pardi","XML en Action",1999]
-SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
-Json_Object(AUTHOR, TITLE, DATEPUB)
+SELECT Json_Make_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
+Json_Make_Object(AUTHOR, TITLE, DATEPUB)
{"AUTHOR":"Jean-Christophe Bernadac","TITLE":"Construire une application XML","DATEPUB":1999}
{"AUTHOR":"William J. Pardi","TITLE":"XML en Action","DATEPUB":1999}
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t2;
@@ -206,8 +206,8 @@ DEPARTMENT CHAr(4) NOT NULL FLAG=41,
SECRETARY CHAR(5) DEFAULT NULL FLAG=46,
SALARY DOUBLE(8,2) NOT NULL FLAG=52
) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1;
-SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
-Json_Object(SERIALNO, NAME, TITLE, SALARY)
+SELECT Json_Make_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
+Json_Make_Object(SERIALNO, NAME, TITLE, SALARY)
{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000}
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t3 GROUP BY DEPARTMENT;
DEPARTMENT Json_Array_Grp(NAME)
@@ -220,8 +220,8 @@ Warning 1105 Result truncated to json_grp_size values
SELECT JsonSet_Grp_Size(30);
JsonSet_Grp_Size(30)
30
-SELECT Json_Object(title, Json_Array_Grp(name) `json_names`) from t3 GROUP BY title;
-Json_Object(title, Json_Array_Grp(name) `json_names`)
+SELECT Json_Make_Object(title, Json_Array_Grp(name) `json_names`) from t3 GROUP BY title;
+Json_Make_Object(title, Json_Array_Grp(name) `json_names`)
{"title":"ADMINISTRATOR","names":["GOOSEPEN","FUNNIGUY","SHRINKY"]}
{"title":"DIRECTOR","names":["QUINN","WERTHER","STRONG"]}
{"title":"ENGINEER","names":["BROWNY","ORELLY","MARTIN","TONGHO","WALTER","SMITH"]}
@@ -230,26 +230,26 @@ Json_Object(title, Json_Array_Grp(name) `json_names`)
{"title":"SCIENTIST","names":["BIGHEAD","BIGHORN"]}
{"title":"SECRETARY","names":["MESSIFUL","HONEY","SHORTSIGHT","CHERRY","MONAPENNY"]}
{"title":"TYPIST","names":["KITTY","PLUMHEAD"]}
-SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
-Json_Array(DEPARTMENT, Json_Array_Grp(NAME))
+SELECT Json_Make_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
+Json_Make_Array(DEPARTMENT, Json_Array_Grp(NAME))
["0021",["STRONG","SHORTSIGHT"]]
["0318",["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]]
["0319",["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]]
["2452",["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]]
-SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
-Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES)
+SELECT Json_Make_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
+Json_Make_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES)
{"DEPARTMENT":"0021","NAMES":["STRONG","SHORTSIGHT"]}
{"DEPARTMENT":"0318","NAMES":["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]}
{"DEPARTMENT":"0319","NAMES":["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]}
{"DEPARTMENT":"2452","NAMES":["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]}
-SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
-Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES)
+SELECT Json_Make_Object(DEPARTMENT, Json_Array_Grp(Json_Make_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
+Json_Make_Object(DEPARTMENT, Json_Array_Grp(Json_Make_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES)
{"DEPARTMENT":"0021","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","TITLE":"DIRECTOR","SALARY":23000.000000},{"SERIALNO":"22222","NAME":"SHORTSIGHT","TITLE":"SECRETARY","SALARY":5500.000000}]}
{"DEPARTMENT":"0318","EMPLOYES":[{"SERIALNO":"74200","NAME":"BANCROFT","TITLE":"SALESMAN","SALARY":9600.000000},{"SERIALNO":"24888","NAME":"PLUMHEAD","TITLE":"TYPIST","SALARY":2800.000000},{"SERIALNO":"27845","NAME":"HONEY","TITLE":"SECRETARY","SALARY":4900.000000},{"SERIALNO":"73452","NAME":"TONGHO","TITLE":"ENGINEER","SALARY":6800.000000},{"SERIALNO":"74234","NAME":"WALTER","TITLE":"ENGINEER","SALARY":7400.000000},{"SERIALNO":"77777","NAME":"SHRINKY","TITLE":"ADMINISTRATOR","SALARY":7500.000000},{"SERIALNO":"70012","NAME":"WERTHER","TITLE":"DIRECTOR","SALARY":14500.000000},{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000},{"SERIALNO":"73111","NAME":"WHEELFOR","TITLE":"SALESMAN","SALARY":10030.000000}]}
{"DEPARTMENT":"0319","EMPLOYES":[{"SERIALNO":"76543","NAME":"BULLOZER","TITLE":"SALESMAN","SALARY":14800.000000},{"SERIALNO":"40567","NAME":"QUINN","TITLE":"DIRECTOR","SALARY":14000.000000},{"SERIALNO":"00137","NAME":"BROWNY","TITLE":"ENGINEER","SALARY":10500.000000},{"SERIALNO":"12345","NAME":"KITTY","TITLE":"TYPIST","SALARY":3000.450000},{"SERIALNO":"33333","NAME":"MONAPENNY","TITLE":"SECRETARY","SALARY":3800.000000},{"SERIALNO":"00023","NAME":"MARTIN","TITLE":"ENGINEER","SALARY":10000.000000},{"SERIALNO":"07654","NAME":"FUNNIGUY","TITLE":"ADMINISTRATOR","SALARY":8500.000000},{"SERIALNO":"45678","NAME":"BUGHAPPY","TITLE":"PROGRAMMER","SALARY":8500.000000},{"SERIALNO":"56789","NAME":"FODDERMAN","TITLE":"SALESMAN","SALARY":7000.000000},{"SERIALNO":"55555","NAME":"MESSIFUL","TITLE":"SECRETARY","SALARY":5000.500000},{"SERIALNO":"98765","NAME":"GOOSEPEN","TITLE":"ADMINISTRATOR","SALARY":4700.000000}]}
{"DEPARTMENT":"2452","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","TITLE":"SCIENTIST","SALARY":8000.000000},{"SERIALNO":"31416","NAME":"ORELLY","TITLE":"ENGINEER","SALARY":13400.000000},{"SERIALNO":"36666","NAME":"BIGHORN","TITLE":"SCIENTIST","SALARY":11000.000000},{"SERIALNO":"02345","NAME":"SMITH","TITLE":"ENGINEER","SALARY":9000.000000},{"SERIALNO":"11111","NAME":"CHERRY","TITLE":"SECRETARY","SALARY":4500.000000}]}
-SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
-Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES)
+SELECT Json_Make_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Make_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
+Json_Make_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Make_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES)
{"DEPARTMENT":"0021","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","SALARY":23000.000000}]}
{"DEPARTMENT":"0021","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"22222","NAME":"SHORTSIGHT","SALARY":5500.000000}]}
{"DEPARTMENT":"0318","TITLE":"ADMINISTRATOR","EMPLOYES":[{"SERIALNO":"77777","NAME":"SHRINKY","SALARY":7500.000000}]}
@@ -273,8 +273,8 @@ ERROR HY000: Can't initialize function 'json_object_grp'; This function requires
SELECT Json_Object_Grp(NAME, SALARY) FROM t3;
Json_Object_Grp(NAME, SALARY)
{"BANCROFT":9600.000000,"SMITH":9000.000000,"MERCHANT":8700.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"BIGHEAD":8000.000000,"SHRINKY":7500.000000,"WALTER":7400.000000,"FODDERMAN":7000.000000,"TONGHO":6800.000000,"SHORTSIGHT":5500.000000,"MESSIFUL":5000.500000,"HONEY":4900.000000,"GOOSEPEN":4700.000000,"CHERRY":4500.000000,"MONAPENNY":3800.000000,"KITTY":3000.450000,"PLUMHEAD":2800.000000,"STRONG":23000.000000,"BULLOZER":14800.000000,"WERTHER":14500.000000,"QUINN":14000.000000,"ORELLY":13400.000000,"BIGHORN":11000.000000,"BROWNY":10500.000000,"WHEELFOR":10030.000000,"MARTIN":10000.000000}
-SELECT Json_Object(DEPARTMENT, Json_Object_Grp(NAME, SALARY) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
-Json_Object(DEPARTMENT, Json_Object_Grp(NAME, SALARY) "Json_SALARIES")
+SELECT Json_Make_Object(DEPARTMENT, Json_Object_Grp(NAME, SALARY) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
+Json_Make_Object(DEPARTMENT, Json_Object_Grp(NAME, SALARY) "Json_SALARIES")
{"DEPARTMENT":"0021","SALARIES":{"STRONG":23000.000000,"SHORTSIGHT":5500.000000}}
{"DEPARTMENT":"0318","SALARIES":{"BANCROFT":9600.000000,"PLUMHEAD":2800.000000,"HONEY":4900.000000,"TONGHO":6800.000000,"WALTER":7400.000000,"SHRINKY":7500.000000,"WERTHER":14500.000000,"MERCHANT":8700.000000,"WHEELFOR":10030.000000}}
{"DEPARTMENT":"0319","SALARIES":{"BULLOZER":14800.000000,"QUINN":14000.000000,"BROWNY":10500.000000,"KITTY":3000.450000,"MONAPENNY":3800.000000,"MARTIN":10000.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"FODDERMAN":7000.000000,"MESSIFUL":5000.500000,"GOOSEPEN":4700.000000}}
@@ -309,26 +309,26 @@ SELECT JsonGet_String(Json_Array_Grp(name),'[>]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[>]')
WHEELFOR
SET @j1 = '[45,28,36,45,89]';
-SELECT JsonGet_String(@j1,'[1]');
-JsonGet_String(@j1,'[1]')
+SELECT JsonGet_String(@j1,'1');
+JsonGet_String(@j1,'1')
28
-SELECT JsonGet_String(@j1 json_,'[3]');
-JsonGet_String(@j1 json_,'[3]')
+SELECT JsonGet_String(@j1 json_,'3');
+JsonGet_String(@j1 json_,'3')
45
-SELECT JsonGet_String(Json_Array(45,28,36,45,89),'[3]');
-JsonGet_String(Json_Array(45,28,36,45,89),'[3]')
+SELECT JsonGet_String(Json_Make_Array(45,28,36,45,89),'3');
+JsonGet_String(Json_Make_Array(45,28,36,45,89),'3')
45
-SELECT JsonGet_String(Json_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Array(45,28,36,45,89),'[+]') "sum";
+SELECT JsonGet_String(Json_Make_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Make_Array(45,28,36,45,89),'[+]') "sum";
list egal sum
45+28+36+45+89 = 243.00
-SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
-JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]')
+SELECT JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.0');
+JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.0')
36
-SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*');
-JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*')
+SELECT JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.*');
+JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.*')
[36,45,89]
-SELECT JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
-JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc')
+SELECT JsonGet_String(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
+JsonGet_String(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc')
machin
SET @j2 = '{"qty":56,"price":3.141600,"truc":"machin","garanty":null}';
SELECT JsonGet_String(@j2 json_,'truc');
@@ -345,14 +345,14 @@ JsonGet_String(NULL json_, NULL)
NULL
Warnings:
Warning 1105
-SELECT department, JsonGet_String(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
+SELECT department, JsonGet_String(Json_Make_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries.[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500.00
0318 72230.00
0319 89800.95
2452 45900.00
-SELECT JsonGet_Int(@j1, '[4]');
-JsonGet_Int(@j1, '[4]')
+SELECT JsonGet_Int(@j1, '4');
+JsonGet_Int(@j1, '4')
89
SELECT JsonGet_Int(@j1, '[#]');
JsonGet_Int(@j1, '[#]')
@@ -360,26 +360,26 @@ JsonGet_Int(@j1, '[#]')
SELECT JsonGet_Int(@j1, '[+]');
JsonGet_Int(@j1, '[+]')
243
-SELECT JsonGet_Int(@j1 json_, '[3]');
-JsonGet_Int(@j1 json_, '[3]')
+SELECT JsonGet_Int(@j1 json_, '3');
+JsonGet_Int(@j1 json_, '3')
45
-SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '[3]');
-JsonGet_Int(Json_Array(45,28,36,45,89), '[3]')
+SELECT JsonGet_Int(Json_Make_Array(45,28,36,45,89), '3');
+JsonGet_Int(Json_Make_Array(45,28,36,45,89), '3')
45
-SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '["+"]');
-JsonGet_Int(Json_Array(45,28,36,45,89), '["+"]')
+SELECT JsonGet_Int(Json_Make_Array(45,28,36,45,89), '["+"]');
+JsonGet_Int(Json_Make_Array(45,28,36,45,89), '["+"]')
45
-SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '[+]');
-JsonGet_Int(Json_Array(45,28,36,45,89), '[+]')
+SELECT JsonGet_Int(Json_Make_Array(45,28,36,45,89), '[+]');
+JsonGet_Int(Json_Make_Array(45,28,36,45,89), '[+]')
243
-SELECT JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]');
-JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]')
+SELECT JsonGet_Int(Json_Make_Array(Json_Make_Array(45,28), Json_Make_Array(36,45,89)), '1.0');
+JsonGet_Int(Json_Make_Array(Json_Make_Array(45,28), Json_Make_Array(36,45,89)), '1.0')
36
-SELECT JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[0]:[1]');
-JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[0]:[1]')
+SELECT JsonGet_Int(Json_Make_Array(Json_Make_Array(45,28), Json_Make_Array(36,45,89)), '0.1');
+JsonGet_Int(Json_Make_Array(Json_Make_Array(45,28), Json_Make_Array(36,45,89)), '0.1')
28
-SELECT JsonGet_Int(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'qty');
-JsonGet_Int(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'qty')
+SELECT JsonGet_Int(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'qty');
+JsonGet_Int(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'qty')
56
SELECT JsonGet_Int(@j2 json_, 'price');
JsonGet_Int(@j2 json_, 'price')
@@ -390,38 +390,38 @@ JsonGet_Int(@j2, 'qty')
SELECT JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose');
JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose')
NULL
-SELECT JsonGet_Int(JsonGet_String(Json_Array(Json_Array(45,28),Json_Array(36,45,89)), '[1]:*'), '[+]') sum;
+SELECT JsonGet_Int(JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)), '1.*'), '[+]') sum;
sum
170
-SELECT department, JsonGet_Int(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"), 'salaries:[+]') Sumsal FROM t3 GROUP BY department;
+SELECT department, JsonGet_Int(Json_Make_Object(department, Json_Array_Grp(salary) "Json_salaries"), 'salaries.[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500
0318 72230
0319 89800
2452 45900
-SELECT JsonGet_Real(@j1, '[2]');
-JsonGet_Real(@j1, '[2]')
+SELECT JsonGet_Real(@j1, '2');
+JsonGet_Real(@j1, '2')
36.000000000000000
-SELECT JsonGet_Real(@j1 json_, '[3]', 2);
-JsonGet_Real(@j1 json_, '[3]', 2)
+SELECT JsonGet_Real(@j1 json_, '3', 2);
+JsonGet_Real(@j1 json_, '3', 2)
45.00
-SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[3]');
-JsonGet_Real(Json_Array(45,28,36,45,89), '[3]')
+SELECT JsonGet_Real(Json_Make_Array(45,28,36,45,89), '3');
+JsonGet_Real(Json_Make_Array(45,28,36,45,89), '3')
45.000000000000000
-SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '["+"]');
-JsonGet_Real(Json_Array(45,28,36,45,89), '["+"]')
+SELECT JsonGet_Real(Json_Make_Array(45,28,36,45,89), '["+"]');
+JsonGet_Real(Json_Make_Array(45,28,36,45,89), '["+"]')
45.000000000000000
-SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[+]');
-JsonGet_Real(Json_Array(45,28,36,45,89), '[+]')
+SELECT JsonGet_Real(Json_Make_Array(45,28,36,45,89), '[+]');
+JsonGet_Real(Json_Make_Array(45,28,36,45,89), '[+]')
243.000000000000000
-SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[!]');
-JsonGet_Real(Json_Array(45,28,36,45,89), '[!]')
+SELECT JsonGet_Real(Json_Make_Array(45,28,36,45,89), '[!]');
+JsonGet_Real(Json_Make_Array(45,28,36,45,89), '[!]')
48.600000000000000
-SELECT JsonGet_Real(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]');
-JsonGet_Real(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]')
+SELECT JsonGet_Real(Json_Make_Array(Json_Make_Array(45,28), Json_Make_Array(36,45,89)), '1.0');
+JsonGet_Real(Json_Make_Array(Json_Make_Array(45,28), Json_Make_Array(36,45,89)), '1.0')
36.000000000000000
-SELECT JsonGet_Real(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'price');
-JsonGet_Real(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'price')
+SELECT JsonGet_Real(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'price');
+JsonGet_Real(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'price')
3.141600000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_, 'qty');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_, 'qty')
@@ -435,7 +435,7 @@ JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'pric
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose')
NULL
-SELECT department, JsonGet_Real(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
+SELECT department, JsonGet_Real(Json_Make_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries.[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500.000000000000000
0318 72230.000000000000000
@@ -445,11 +445,11 @@ department Sumsal
# Documentation examples
#
SELECT
-JsonGet_Int(Json_Array(45,28,36,45,89), '[4]') "Rank",
-JsonGet_Int(Json_Array(45,28,36,45,89), '[#]') "Number",
-JsonGet_String(Json_Array(45,28,36,45,89), '[","]') "Concat",
-JsonGet_Int(Json_Array(45,28,36,45,89), '[+]') "Sum",
-JsonGet_Real(Json_Array(45,28,36,45,89), '[!]', 2) "Avg";
+JsonGet_Int(Json_Make_Array(45,28,36,45,89), '4') "Rank",
+JsonGet_Int(Json_Make_Array(45,28,36,45,89), '[#]') "Number",
+JsonGet_String(Json_Make_Array(45,28,36,45,89), '[","]') "Concat",
+JsonGet_Int(Json_Make_Array(45,28,36,45,89), '[+]') "Sum",
+JsonGet_Real(Json_Make_Array(45,28,36,45,89), '[!]', 2) "Avg";
Rank Number Concat Sum Avg
89 5 45,28,36,45,89 243 48.60
SELECT
@@ -464,33 +464,33 @@ Real
#
# Testing Locate
#
-SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
-JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin')
-truc
-SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
-JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56)
-qty
-SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
-JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416)
-price
-SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
-JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose')
+SELECT JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
+JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin')
+$.truc
+SELECT JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
+JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56)
+$.qty
+SELECT JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
+JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416)
+$.price
+SELECT JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
+JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose')
NULL
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'Jack') Path;
Path
-AUTHORS:[1]:FN
+$.AUTHORS[1].FN
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'jack' ci) Path;
Path
-AUTHORS:[1]:FN
+$.AUTHORS[1].FN
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"Jack", "LN":"London"}' json_) Path;
Path
-AUTHORS:[1]
+$.AUTHORS[1]
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"jack", "LN":"London"}' json_) Path;
Path
NULL
SELECT JsonLocate('[45,28,36,45,89]',36);
JsonLocate('[45,28,36,45,89]',36)
-[2]
+$[2]
SELECT JsonLocate('[45,28,36,45,89]' json_,28.0);
JsonLocate('[45,28,36,45,89]' json_,28.0)
NULL
@@ -499,71 +499,71 @@ Json_Locate_All('[45,28,36,45,89]',10)
[]
SELECT Json_Locate_All('[45,28,36,45,89]',45);
Json_Locate_All('[45,28,36,45,89]',45)
-["[0]","[3]"]
+["$[0]","$[3]"]
SELECT Json_Locate_All('[[45,28],36,45,89]',45);
Json_Locate_All('[[45,28],36,45,89]',45)
-["[0]:[0]","[2]"]
+["$[0][0]","$[2]"]
SELECT Json_Locate_All('[[45,28,45],36,45,89]',45);
Json_Locate_All('[[45,28,45],36,45,89]',45)
-["[0]:[0]","[0]:[2]","[2]"]
+["$[0][0]","$[0][2]","$[2]"]
SELECT Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'));
Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'))
-["[0]:[0]","[0]:[2]","[2]"]
+["$[0][0]","$[0][2]","$[2]"]
SELECT JsonLocate('[[45,28,45],36,45,89]',45,n) from t1;
JsonLocate('[[45,28,45],36,45,89]',45,n)
-[0]:[0]
-[0]:[2]
-[2]
+$[0][0]
+$[0][2]
+$[2]
NULL
NULL
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) FROM t1;
JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']'))
-[0]:[0]
-[0]:[2]
-[2]
+$[0][0]
+$[0][2]
+$[2]
NULL
NULL
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) AS `Path` FROM t1 GROUP BY n HAVING `Path` IS NOT NULL;
Path
-[0]:[0]
-[0]:[2]
-[2]
+$[0][0]
+$[0][2]
+$[2]
SELECT Json_Locate_All('[45,28,[36,45,89]]',45);
Json_Locate_All('[45,28,[36,45,89]]',45)
-["[0]","[2]:[1]"]
+["$[0]","$[2][1]"]
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0));
Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0))
[]
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',45.0);
Json_Locate_All('[[45,28],[36,45.0,89]]',45.0)
-["[1]:[1]"]
+["$[1][1]"]
SELECT JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_);
JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_)
-[1]
+$[1]
SELECT JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_);
JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_)
-[0]
+$[0]
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','45') "All paths";
All paths
[]
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_);
Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_)
-["[1]:[0]"]
+["$[1][0]"]
SELECT JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '[#]') "Nb of occurs";
Nb of occurs
2
SELECT Json_Locate_All('[[45,28],[[36,45],89]]',45,2);
Json_Locate_All('[[45,28],[[36,45],89]]',45,2)
-["[0]:[0]"]
-SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]');
-JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]')
-[0]
+["$[0][0]"]
+SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'0');
+JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'0')
+$[0]
SELECT JsonLocate(Json_File('test/biblio.json'), 'Knab');
JsonLocate(Json_File('test/biblio.json'), 'Knab')
-[0]:AUTHOR:[1]:LASTNAME
+$[0].AUTHOR[1].LASTNAME
SELECT Json_Locate_All('test/biblio.json' jfile_, 'Knab');
Json_Locate_All('test/biblio.json' jfile_, 'Knab')
-["[0]:AUTHOR:[1]:LASTNAME"]
+["$[0].AUTHOR[1].LASTNAME"]
#
# Testing json files
#
@@ -595,54 +595,54 @@ Warning 1105 File pretty format doesn't match the specified pretty value
SELECT Json_File('test/fx.json', 0);
Json_File('test/fx.json', 0)
[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]
-SELECT Json_File('test/fx.json', '[0]');
-Json_File('test/fx.json', '[0]')
+SELECT Json_File('test/fx.json', '0');
+Json_File('test/fx.json', '0')
{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]}
SELECT Json_File('test/fx.json', '[?]');
Json_File('test/fx.json', '[?]')
NULL
Warnings:
Warning 1105 Invalid function specification ?
-SELECT JsonGet_String(Json_File('test/fx.json'), '[1]:*');
-JsonGet_String(Json_File('test/fx.json'), '[1]:*')
+SELECT JsonGet_String(Json_File('test/fx.json'), '1.*');
+JsonGet_String(Json_File('test/fx.json'), '1.*')
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]}
-SELECT JsonGet_String(Json_File('test/fx.json'), '[1]');
-JsonGet_String(Json_File('test/fx.json'), '[1]')
-6 car roadster 56000 ???
-SELECT JsonGet_Int(Json_File('test/fx.json'), '[1]:mileage') AS Mileage;
+SELECT JsonGet_String(Json_File('test/fx.json'), '1');
+JsonGet_String(Json_File('test/fx.json'), '1')
+6 car roadster 56000 <null>
+SELECT JsonGet_Int(Json_File('test/fx.json'), '1.mileage') AS Mileage;
Mileage
56000
-SELECT JsonGet_Real(Json_File('test/fx.json'), '[0]:price', 2) AS Price;
+SELECT JsonGet_Real(Json_File('test/fx.json'), '0.price', 2) AS Price;
Price
5.65
-SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings');
-Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings')
+SELECT Json_Array_Add(Json_File('test/fx.json', '2'), 6, 'ratings');
+Json_Array_Add(Json_File('test/fx.json', '2'), 6, 'ratings')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4,6]}
-SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings');
-Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings')
+SELECT Json_Array_Add(Json_File('test/fx.json', '2'), 6, 1, 'ratings');
+Json_Array_Add(Json_File('test/fx.json', '2'), 6, 1, 'ratings')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
-SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1);
-Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1)
+SELECT Json_Array_Add(Json_File('test/fx.json', '2'), 6, 'ratings', 1);
+Json_Array_Add(Json_File('test/fx.json', '2'), 6, 'ratings', 1)
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
-SELECT Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0);
-Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0)
+SELECT Json_Array_Add(Json_File('test/fx.json', '2.ratings'), 6, 0);
+Json_Array_Add(Json_File('test/fx.json', '2.ratings'), 6, 0)
[6,2,4]
-SELECT Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1);
-Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1)
+SELECT Json_Array_Delete(Json_File('test/fx.json', '2'), 'ratings', 1);
+Json_Array_Delete(Json_File('test/fx.json', '2'), 'ratings', 1)
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2]}
-SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin);
-Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin)
+SELECT Json_Object_Add(Json_File('test/fx.json', '2'), 'france' origin);
+Json_Object_Add(Json_File('test/fx.json', '2'), 'france' origin)
{"_id":7,"type":"food","item":"meat","origin":"france","ratings":[2,4]}
-SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size');
-Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size')
+SELECT Json_Object_Add(Json_File('test/fx.json', '2'), 70 H, 'size');
+Json_Object_Add(Json_File('test/fx.json', '2'), 70 H, 'size')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]}
Warnings:
Warning 1105 No sub-item at 'size'
-SELECT Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size');
-Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size')
+SELECT Json_Object_Add(Json_File('test/fx.json', '3'), 70 H, 'size');
+Json_Object_Add(Json_File('test/fx.json', '3'), 70 H, 'size')
{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":70},"ratings":[5,8,7]}
-SELECT Json_Object_List(Json_File('test/fx.json', '[3]:size'));
-Json_Object_List(Json_File('test/fx.json', '[3]:size'))
+SELECT Json_Object_List(Json_File('test/fx.json', '3.size'));
+Json_Object_List(Json_File('test/fx.json', '3.size'))
["W","L","H"]
DROP TABLE t1;
DROP TABLE t2;
diff --git a/storage/connect/mysql-test/connect/r/json_udf_bin.result b/storage/connect/mysql-test/connect/r/json_udf_bin.result
index 4e59b51c529..0c009d612fe 100644
--- a/storage/connect/mysql-test/connect/r/json_udf_bin.result
+++ b/storage/connect/mysql-test/connect/r/json_udf_bin.result
@@ -29,8 +29,8 @@ Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), NULL),
SELECT Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), TRUE), 1, '[1]');
Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), TRUE), 1, '[1]')
[56,[3.141600],true]
-SELECT Json_Array(1, TRUE, 0, FALSE);
-Json_Array(1, TRUE, 0, FALSE)
+SELECT Json_Make_Array(1, TRUE, 0, FALSE);
+Json_Make_Array(1, TRUE, 0, FALSE)
[1,true,0,false]
SELECT Json_Serialize(Jbin_Array(TRUE, FALSE));
Json_Serialize(Jbin_Array(TRUE, FALSE))
@@ -63,94 +63,94 @@ Json_Serialize(Jbin_File('gloss.json'))
{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}}
SELECT JsonLocate(Jbin_File('gloss.json'),'XML');
JsonLocate(Jbin_File('gloss.json'),'XML')
-glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso:[1]
+$.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso[1]
SELECT Json_Object_Key('first', 'foo', 'second', Jbin_Array('a', 33));
Json_Object_Key('first', 'foo', 'second', Jbin_Array('a', 33))
{"first":"foo","second":["a",33]}
-SELECT Json_Get_Item(Json_Array('a','b','c'), '[1]');
-Json_Get_Item(Json_Array('a','b','c'), '[1]')
+SELECT Json_Get_Item(Json_Make_Array('a','b','c'), '$[1]');
+Json_Get_Item(Json_Make_Array('a','b','c'), '$[1]')
NULL
-SELECT Json_Get_Item(Json_Object('foo' AS "first", Json_Array('a', 33) AS "json_second"), 'second') AS "item";
+SELECT Json_Get_Item(Json_Make_Object('foo' AS "first", Json_Make_Array('a', 33) AS "json_second"), '$.second') AS "item";
item
["a",33]
-SELECT Json_Get_Item(Jbin_Object('foo' first, Jbin_Array('a', 33) jbin_second), 'second:*') item;
+SELECT Json_Get_Item(Jbin_Object('foo' first, Jbin_Array('a', 33) jbin_second), '$.second') item;
item
["a",33]
-SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv');
-Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv')
+SELECT Json_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv');
+Json_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv')
{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}
-SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv'));
-Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv'))
+SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv'));
+Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv'))
{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}
-SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:*');
-Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:*')
+SELECT Json_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv');
+Json_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv')
{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}
-SELECT JsonGet_String(Json_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso') lang;
+SELECT JsonGet_String(Json_File('gloss.json'),'$.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso') lang;
lang
GML
-SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso') "See also";
+SELECT Json_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso') "See also";
See also
["GML","XML"]
-SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso')) "See also";
+SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso')) "See also";
See also
["GML","XML"]
-SELECT JsonGet_String(Json_Get_Item(Json_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso'),'[0]') lang;
+SELECT JsonGet_String(Json_Get_Item(Json_File('gloss.json'),'$.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso'),'$[0]') lang;
lang
GML
#
# Test Item Get/Set/Insert/Update UDF's
#
-SELECT Json_Get_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[]');
-Json_Get_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[]')
+SELECT Json_Get_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '$[]');
+Json_Get_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '$[]')
[1,2,{"trois":3,"quatre":4}]
-SELECT Json_Get_Item(Jbin_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[1]');
-Json_Get_Item(Jbin_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[1]')
+SELECT Json_Get_Item(Jbin_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '$[1]');
+Json_Get_Item(Jbin_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '$[1]')
NULL
-SELECT Json_Get_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '[1]');
-Json_Get_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '[1]')
+SELECT Json_Get_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '$[1]');
+Json_Get_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '$[1]')
NULL
-SELECT Json_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)));
-Json_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)))
+SELECT Json_Set_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)));
+Json_Set_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)))
[1,2,{"trois":3,"quatre":4}]
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 'foo');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '$.foo');
ERROR HY000: Can't initialize function 'json_set_item'; This function must have an odd number of arguments
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
-Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq')
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq');
+Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq')
[1,2,{"trois":3,"quatre":4,"cinq":5}]
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 7, '[1]');
-Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 7, '[1]')
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 7, '$[1]');
+Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 7, '$[1]')
[1,7,{"trois":3,"quatre":4}]
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 7, '[1]');
-Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 7, '[1]')
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 7, '$[1]');
+Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 7, '$[1]')
[1,7,{"trois":3,"quatre":4,"cinq":5}]
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Json_Array(7, 8, 9), '[1]');
-Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Json_Array(7, 8, 9), '[1]')
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Json_Make_Array(7, 8, 9), '$[1]');
+Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Json_Make_Array(7, 8, 9), '$[1]')
[1,[7,8,9],{"trois":3,"quatre":4}]
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]');
-Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]')
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '$[2]');
+Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '$[2]')
[1,2,[7,8,9]]
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]:*');
-Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]:*')
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '$[2].*');
+Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '$[2].*')
[1,2,{"trois":3,"quatre":4}]
Warnings:
Warning 1105 Invalid specification * in a write path
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 3.1416, 'foo');
-Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 3.1416, 'foo')
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 3.1416, '$.foo');
+Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 3.1416, '$.foo')
[1,2,{"trois":3,"quatre":4}]
-SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 'toto', '[1]:[2]');
-Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 'toto', '[1]:[2]')
+SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 'toto', '$[1][2]');
+Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 'toto', '$[1][2]')
[1,[7,8,"toto"],{"trois":3,"quatre":4}]
-SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 300, '[2]:nxt:total:[]');
-Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 300, '[2]:nxt:total:[]')
+SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 300, '$[2].nxt.total[]');
+Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 300, '$[2].nxt.total[]')
[1,[7,8,9],{"trois":3,"quatre":4,"nxt":{"total":[300]}}]
-SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 300, '[2]:nxt:total:[]');
-Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 300, '[2]:nxt:total:[]')
+SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][]', 300, '$[2].nxt.total[]');
+Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][]', 300, '$[2].nxt.total[]')
[1,[7,8,9,10],{"trois":3,"quatre":4,"cinq":5,"nxt":{"total":[300]}}]
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[1]', 5, '[2]:cinq', 10, '[1]:[]');
-Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[1]', 5, '[2]:cinq', 10, '[1]:[]')
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '$[1]', 5, '$[2].cinq', 10, '$[1][]');
+Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '$[1]', 5, '$[2].cinq', 10, '$[1][]')
[1,[7,8,9,10],{"trois":3,"quatre":4,"cinq":5}]
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 44, '[2]:quatre');
-Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 44, '[2]:quatre')
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 44, '$[2].quatre');
+Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 44, '$[2].quatre')
[1,2,{"trois":3,"quatre":44}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, 'truc');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, 'truc')
@@ -163,32 +163,32 @@ Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '*'
[1,2,{"trois":3,"quatre":4}]
Warnings:
Warning 1105 Invalid specification * in a write path
-SELECT Json_Serialize(Jbin_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq'));
-Json_Serialize(Jbin_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq'))
+SELECT Json_Serialize(Jbin_Set_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq'));
+Json_Serialize(Jbin_Set_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq'))
[1,2,{"trois":3,"quatre":4,"cinq":5}]
-SELECT Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
-Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq')
+SELECT Json_Insert_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq');
+Json_Insert_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq')
[1,2,{"trois":3,"quatre":4,"cinq":5}]
-SELECT Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
-Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq')
+SELECT Json_Update_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq');
+Json_Update_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq')
[1,2,{"trois":3,"quatre":4}]
-SELECT Json_Insert_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre');
-Json_Insert_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre')
+SELECT Json_Insert_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][]', 44, '$[2].quatre');
+Json_Insert_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][]', 44, '$[2].quatre')
[1,[7,8,9,10],{"trois":3,"quatre":4,"cinq":5}]
-SELECT Json_Update_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre');
-Json_Update_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre')
+SELECT Json_Update_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][]', 44, '$[2].quatre');
+Json_Update_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][]', 44, '$[2].quatre')
[1,[7,8,9],{"trois":3,"quatre":44}]
-SELECT Json_Insert_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]');
-Json_Insert_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]')
+SELECT Json_Insert_Item(Json_Make_Array(1, Json_Make_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][1]', 300, '$[2].nxt.total[]');
+Json_Insert_Item(Json_Make_Array(1, Json_Make_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][1]', 300, '$[2].nxt.total[]')
[1,[7,8,9],{"trois":3,"quatre":4,"cinq":5,"nxt":{"total":[300]}}]
-SELECT Json_Update_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]');
-Json_Update_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]')
+SELECT Json_Update_Item(Json_Make_Array(1, Json_Make_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][1]', 300, '$[2].nxt.total[]');
+Json_Update_Item(Json_Make_Array(1, Json_Make_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][1]', 300, '$[2].nxt.total[]')
[1,[7,10,9],{"trois":3,"quatre":4}]
-SELECT Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]');
-Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]')
+SELECT Json_Insert_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[]');
+Json_Insert_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[]')
[1,2,{"trois":3,"quatre":4},5]
-SELECT Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]');
-Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]')
+SELECT Json_Update_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[]');
+Json_Update_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[]')
[1,2,{"trois":3,"quatre":4}]
#
# Test merging items UDF's
@@ -196,7 +196,7 @@ Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5,
SELECT Json_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f'));
Json_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f'))
["a","b","c","d","e","f"]
-SELECT Json_Item_Merge(Json_Array('a','b','c'), Json_Array('d','e','f')) AS "Result";
+SELECT Json_Item_Merge(Json_Make_Array('a','b','c'), Json_Make_Array('d','e','f')) AS "Result";
Result
["a","b","c","d","e","f"]
SELECT Json_Array_Add(Jbin_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f')), 'and', 3);
@@ -216,7 +216,7 @@ Json_Object_Add(Jbin_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "d
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "a",5 "e",6 "f"));
Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "a",5 "e",6 "f"))
{"a":4,"b":2,"c":3,"e":5,"f":6}
-SELECT Json_Item_Merge('foo', Json_Array('d','e','f'));
+SELECT Json_Item_Merge('foo', Json_Make_Array('d','e','f'));
ERROR HY000: Can't initialize function 'json_item_merge'; First argument must be a json item
#
# Test making file UDF's
@@ -294,17 +294,17 @@ Json_File('bt1.json', 2)
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json')
bt1.json
-SELECT Json_Object(Jbin_Array_Add(Jbin_Array('a','b','c'), 'd') "Jbin_foo") AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Add(Jbin_Array('a','b','c'), 'd') "Jbin_foo") AS "Result";
Result
{"foo":["a","b","c","d"]}
-SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd')) AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd')) AS "Result";
Result
{"Array_Add(Jbin_File('bt1.json'), 'd')":["a","b","c","d"]}
-SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1") AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1") AS "Result";
Result
{"bt1":["a","b","c","d"]}
# This does modify the file
-SELECT Json_Object(Json_Array_Add(Jbin_File('bt1.json'), 'd') "Jfile_bt1") AS "Result";
+SELECT Json_Make_Object(Json_Array_Add(Jbin_File('bt1.json'), 'd') "Jfile_bt1") AS "Result";
Result
{"bt1":["a","b","c","d"]}
SELECT Json_File('bt1.json');
@@ -319,7 +319,7 @@ Json_File('bt1.json')
SELECT Json_File(Json_Array_Delete(Jbin_File('bt1.json'), 3), 2);
Json_File(Json_Array_Delete(Jbin_File('bt1.json'), 3), 2)
["a","b","c"]
-SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1", n "t1") AS "Result" from t1;
+SELECT Json_Make_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1", n "t1") AS "Result" from t1;
Result
{"bt1":["a","b","c","d"],"t1":1}
{"bt1":["a","b","c","d"],"t1":2}
@@ -432,23 +432,23 @@ SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json')
bt1.json
# Test DELETE from file
-SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 1)) AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 1)) AS "Result";
Result
{"Array_Delete(Jbin_File('bt1.json'), 1)":["a","c"]}
-SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 2) "Jbin_bt1") AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 2) "Jbin_bt1") AS "Result";
Result
{"bt1":["a","b"]}
-SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 0) "Jbin_bt1", n "t1") AS "Result" from t1;
+SELECT Json_Make_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 0) "Jbin_bt1", n "t1") AS "Result" from t1;
Result
{"bt1":["b","c"],"t1":1}
{"bt1":["b","c"],"t1":2}
{"bt1":["b","c"],"t1":3}
-SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
+SELECT Json_Make_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
Result
{"bt1":["a","b"]}
{"bt1":["a"]}
{"bt1":[]}
-SELECT Json_Object(Json_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
+SELECT Json_Make_Object(Json_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
Result
{"bt1":["a","b"]}
{"bt1":["a"]}
@@ -475,17 +475,17 @@ SELECT Json_Serialize(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"));
Json_Serialize(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"))
{"a":1,"b":2,"c":3,"d":4}
# First query (file not modified)
-SELECT Json_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jbin_new") AS "Result";
+SELECT Json_Make_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jbin_new") AS "Result";
Result
{"new":{"a":1,"b":2,"c":3,"d":4}}
# First query (file modified)
-SELECT Json_Object(Json_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jfile_new") AS "Result";
+SELECT Json_Make_Object(Json_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jfile_new") AS "Result";
Result
{"new":{"a":1,"b":2,"c":3,"d":4}}
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0)
bt2.json
-SELECT Json_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d") "Jbin_new", n "t1") AS "Result" from t1;
+SELECT Json_Make_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d") "Jbin_new", n "t1") AS "Result" from t1;
Result
{"new":{"a":1,"b":2,"c":3,"d":4},"t1":1}
{"new":{"a":1,"b":2,"c":3,"d":4},"t1":2}
@@ -526,22 +526,22 @@ SELECT Json_File(Json_Item_Merge(Jbin_File('bt2.json'), Jbin_Object(4 "d",5 "e",
Result
{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6}
-SELECT Json_Item_Merge(Json_Object(1 "a", 2 "b", 3 "c"), Json_Object(4 "d",5 "b",6 "f")) AS "Result";
+SELECT Json_Item_Merge(Json_Make_Object(1 "a", 2 "b", 3 "c"), Json_Make_Object(4 "d",5 "b",6 "f")) AS "Result";
Result
{"a":1,"b":5,"c":3,"d":4,"f":6}
-SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'b')) AS "Result";
+SELECT Json_Make_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'b')) AS "Result";
Result
{"Object_Delete(Jbin_File('bt2.json'), 'b')":{"a":1,"c":3,"d":4,"e":5,"f":6}}
-SELECT Json_Object(Jbin_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
+SELECT Json_Make_Object(Jbin_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
Result
{"bt1":{"a":1,"d":4,"e":5,"f":6}}
-SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
+SELECT Json_Make_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
Result
{"bt1":{"a":1,"d":4,"e":5,"f":6}}
-SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jfile_bt1") AS "Result";
+SELECT Json_Make_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jfile_bt1") AS "Result";
Result
{"bt1":{"a":1,"d":4,"e":5,"f":6}}
-SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'a') "Jbin_bt1", n "t1") AS "Result" from t1;
+SELECT Json_Make_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'a') "Jbin_bt1", n "t1") AS "Result" from t1;
Result
{"bt1":{"d":4,"e":5,"f":6},"t1":1}
{"bt1":{"d":4,"e":5,"f":6},"t1":2}
@@ -552,14 +552,14 @@ Key list
SELECT Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0);
Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0)
bt3.json
-SELECT Json_Array_Add(Json_File('bt3.json', 'b'), 66);
-Json_Array_Add(Json_File('bt3.json', 'b'), 66)
+SELECT Json_Array_Add(Json_File('bt3.json', '$.b'), 66);
+Json_Array_Add(Json_File('bt3.json', '$.b'), 66)
[44,55,66]
-SELECT Json_Array_Add(Json_File('bt3.json'), 66, 'b');
-Json_Array_Add(Json_File('bt3.json'), 66, 'b')
+SELECT Json_Array_Add(Json_File('bt3.json'), 66, '$.b');
+Json_Array_Add(Json_File('bt3.json'), 66, '$.b')
{"a":1,"b":[44,55,66]}
-SELECT Json_Array_Add(Jbin_File('bt3.json', 'b'), 66);
-Json_Array_Add(Jbin_File('bt3.json', 'b'), 66)
+SELECT Json_Array_Add(Jbin_File('bt3.json', '$.b'), 66);
+Json_Array_Add(Jbin_File('bt3.json', '$.b'), 66)
bt3.json
SELECT Json_File('bt3.json', 3);
Json_File('bt3.json', 3)
@@ -573,15 +573,15 @@ jfile_cols CHAR(12) NOT NULL)
ENGINE= MYISAM;
INSERT INTO t2 VALUES(1,'bt3.json');
# In this table, the jfile_cols column just contains a file name
-UPDATE t2 SET jfile_cols = Json_Array_Add(Jbin_File('bt3.json', 'b'), 66) WHERE n = 1;
+UPDATE t2 SET jfile_cols = Json_Array_Add(Jbin_File('bt3.json', '$.b'), 66) WHERE n = 1;
SELECT JsonGet_String(jfile_cols, '*') FROM t2;
JsonGet_String(jfile_cols, '*')
{"a":1,"b":[44,55,66]}
-UPDATE t2 SET jfile_cols = Json_Insert_Item(jfile_cols, 77, 'b:[]') WHERE n = 1;
-SELECT JsonGet_String(jfile_cols, 'b:*') FROM t2;
-JsonGet_String(jfile_cols, 'b:*')
+UPDATE t2 SET jfile_cols = Json_Insert_Item(jfile_cols, 77, '$.b[]') WHERE n = 1;
+SELECT JsonGet_String(jfile_cols, '$.b.*') FROM t2;
+JsonGet_String(jfile_cols, '$.b.*')
[44,55,66,77]
-UPDATE t2 SET jfile_cols = Json_Insert_Item(Jbin_Insert_Item(jfile_cols, 88, 'b:') , 99, 'b:') WHERE n = 1;
+UPDATE t2 SET jfile_cols = Json_Insert_Item(Jbin_Insert_Item(jfile_cols, 88, '$.b[]') , 99, '$.b[]') WHERE n = 1;
SELECT JsonGet_String(jfile_cols, '*') FROM t2;
JsonGet_String(jfile_cols, '*')
{"a":1,"b":[44,55,66,77,88,99]}
diff --git a/storage/connect/mysql-test/connect/r/mul_new.result b/storage/connect/mysql-test/connect/r/mul_new.result
new file mode 100644
index 00000000000..ba8112f5d1f
--- /dev/null
+++ b/storage/connect/mysql-test/connect/r/mul_new.result
@@ -0,0 +1,136 @@
+#
+# Testing multiple 1
+#
+CREATE TABLE t1 (
+Chiffre int(3) NOT NULL,
+Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='num1.csv' LRECL=20 HEADER=1;
+INSERT INTO t1 VALUES(1,'One'),(2,'Two'),(3,'Three'),(4,'Four'),(5,'Five'),(6,'Six');
+SELECT * FROM t1;
+Chiffre Lettre
+1 One
+2 Two
+3 Three
+4 Four
+5 Five
+6 Six
+CREATE TABLE t2 (
+Chiffre int(3) NOT NULL,
+Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE='CSV' FILE_NAME='subdir/num2.csv' LRECL=20 HEADER=1;
+INSERT INTO t2 VALUES(7,'Seven'),(8,'Eight'),(9,'Nine'),(10,'Ten'),(11,'Eleven'),(12,'Twelve');
+SELECT * FROM t2;
+Chiffre Lettre
+7 Seven
+8 Eight
+9 Nine
+10 Ten
+11 Eleven
+12 Twelve
+CREATE TABLE t3 (
+Chiffre int(3) NOT NULL,
+Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE='CSV' FILE_NAME='num3.csv' LRECL=20 HEADER=1;
+INSERT INTO t3 VALUES(13,'Thirteen'),(14,'Fourteen'),(15,'Fifteen'),(16,'Sixteen'),(17,'Seventeen'),(18,'Eighteen');
+SELECT * FROM t3;
+Chiffre Lettre
+13 Thirteen
+14 Fourteen
+15 Fifteen
+16 Sixteen
+17 Seventeen
+18 Eighteen
+CREATE TABLE t4 (
+Chiffre int(3) NOT NULL,
+Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE='CSV' FILE_NAME='subdir/num4.csv' LRECL=20 HEADER=1;
+INSERT INTO t4 VALUES(19,'Nineteen'),(20,'Twenty'),(21,'Twenty one'),(22,'Twenty two'),(23,'Tenty three'),(24,'Twenty four');
+SELECT * FROM t4;
+Chiffre Lettre
+19 Nineteen
+20 Twenty
+21 Twenty one
+22 Twenty two
+23 Tenty three
+24 Twenty four
+CREATE TABLE t5 (
+Chiffre int(3) NOT NULL,
+Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE='CSV' FILE_NAME='num5.csv' LRECL=20 HEADER=1;
+INSERT INTO t5 VALUES(25,'Twenty five'),(26,'Twenty six'),(27,'Twenty seven'),(28,'Twenty eight'),(29,'Tenty eight'),(30,'Thirty');
+SELECT * FROM t5;
+Chiffre Lettre
+25 Twenty five
+26 Twenty six
+27 Twenty seven
+28 Twenty eight
+29 Tenty eight
+30 Thirty
+CREATE TABLE t_all (
+Chiffre int(3) not null,
+Lettre char(16) not null)
+ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='num?.csv' HEADER=1 LRECL=20 MULTIPLE=1;
+SELECT * FROM t_all ORDER BY Chiffre;
+Chiffre Lettre
+1 One
+2 Two
+3 Three
+4 Four
+5 Five
+6 Six
+13 Thirteen
+14 Fourteen
+15 Fifteen
+16 Sixteen
+17 Seventeen
+18 Eighteen
+25 Twenty five
+26 Twenty six
+27 Twenty seven
+28 Twenty eight
+29 Tenty eight
+30 Thirty
+#
+# Testing multiple 3
+#
+ALTER TABLE t_all MULTIPLE=3;
+Warnings:
+Warning 1105 This is an outward table, table data were not modified.
+SELECT * FROM t_all ORDER BY Chiffre;
+Chiffre Lettre
+1 One
+2 Two
+3 Three
+4 Four
+5 Five
+6 Six
+7 Seven
+8 Eight
+9 Nine
+10 Ten
+11 Eleven
+12 Twelve
+13 Thirteen
+14 Fourteen
+15 Fifteen
+16 Sixteen
+17 Seventeen
+18 Eighteen
+19 Nineteen
+20 Twenty
+21 Twenty one
+22 Twenty two
+23 Tenty three
+24 Twenty four
+25 Twenty five
+26 Twenty six
+27 Twenty seven
+28 Twenty eight
+29 Tenty eight
+30 Thirty
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+DROP TABLE t5;
+DROP TABLE t_all;
diff --git a/storage/connect/mysql-test/connect/r/mysql_discovery.result b/storage/connect/mysql-test/connect/r/mysql_discovery.result
index 32bd4761f37..4580c68558f 100644
--- a/storage/connect/mysql-test/connect/r/mysql_discovery.result
+++ b/storage/connect/mysql-test/connect/r/mysql_discovery.result
@@ -1,10 +1,5 @@
-connect master,127.0.0.1,root,,test,$MASTER_MYPORT,;
-connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,;
-connection master;
CREATE DATABASE connect;
-connection slave;
CREATE DATABASE connect;
-connection slave;
CREATE TABLE t1 (
`id` int(20) primary key,
`group` int NOT NULL default 1,
@@ -12,15 +7,14 @@ CREATE TABLE t1 (
`a\\` int unsigned,
`name` varchar(32) default 'name')
DEFAULT CHARSET=latin1;
-connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(20) NOT NULL,
- `group` int(11) NOT NULL DEFAULT 1,
- `a\\b` int(11) NOT NULL DEFAULT 2,
+ `group` int(11) NOT NULL DEFAULT '1',
+ `a\\b` int(11) NOT NULL DEFAULT '2',
`a\\` int(10) unsigned DEFAULT NULL,
`name` varchar(32) DEFAULT 'name'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`='MYSQL'
@@ -31,15 +25,12 @@ id group a\\b a\\ name
1 1 2 NULL foo
2 1 2 NULL fee
DROP TABLE t1;
-connection slave;
SELECT * FROM t1;
id group a\\b a\\ name
1 1 2 NULL foo
2 1 2 NULL fee
DROP TABLE t1;
-connection master;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
-connection slave;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
diff --git a/storage/connect/mysql-test/connect/r/mysql_exec.result b/storage/connect/mysql-test/connect/r/mysql_exec.result
index 1801456fd74..778577a1d8a 100644
--- a/storage/connect/mysql-test/connect/r/mysql_exec.result
+++ b/storage/connect/mysql-test/connect/r/mysql_exec.result
@@ -1,13 +1,8 @@
-connect master,127.0.0.1,root,,test,$MASTER_MYPORT,;
-connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,;
-connection master;
CREATE DATABASE connect;
-connection slave;
CREATE DATABASE connect;
#
# Checking Sending Commands
#
-connection master;
CREATE TABLE t1 (
command VARCHAR(128) NOT NULL,
warnings INT(4) NOT NULL FLAG=3,
@@ -31,8 +26,9 @@ insert into t1(msg) values('One'),(NULL),('Three') 1 3 Affected rows
Warning 0 1048 Column 'msg' cannot be null
insert into t1 values(2,'Deux') on duplicate key update msg = 'Two' 0 2 Affected rows
insert into t1(message) values('Four'),('Five'),('Six') 0 1054 Remote: Unknown column 'message' in 'field list'
-insert into t1(id) values(NULL) 0 1364 Remote: Field 'msg' doesn't have a default value
-update t1 set msg = 'Four' where id = 4 0 0 Affected rows
+insert into t1(id) values(NULL) 1 1 Affected rows
+Warning 0 1364 Field 'msg' doesn't have a default value
+update t1 set msg = 'Four' where id = 4 0 1 Affected rows
select * from t1 0 2 Result set columns
#
# Checking Using Procedure
@@ -45,22 +41,22 @@ READS SQL DATA
SELECT * FROM t1 WHERE command IN ('Warning','Note',cmd);
CALL p1('insert into t1(id) values(NULL)');
command warnings number message
-insert into t1(id) values(NULL) 0 1364 Remote: Field 'msg' doesn't have a default value
+insert into t1(id) values(NULL) 1 1 Affected rows
+Warning 0 1364 Field 'msg' doesn't have a default value
CALL p1('update t1 set msg = "Five" where id = 5');
command warnings number message
-update t1 set msg = "Five" where id = 5 0 0 Affected rows
+update t1 set msg = "Five" where id = 5 0 1 Affected rows
DROP PROCEDURE p1;
DROP TABLE t1;
-connection slave;
SELECT * FROM t1;
id msg
1 One
2 Two
3 Three
+4 Four
+5 Five
DROP TABLE t1;
-connection master;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
-connection slave;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
diff --git a/storage/connect/mysql-test/connect/r/mysql_grant.result b/storage/connect/mysql-test/connect/r/mysql_grant.result
index 11a3dbba36c..5f630834392 100644
--- a/storage/connect/mysql-test/connect/r/mysql_grant.result
+++ b/storage/connect/mysql-test/connect/r/mysql_grant.result
@@ -5,14 +5,11 @@ set sql_mode="";
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
set sql_mode=default;
-connect user,localhost,user,,;
-connection user;
SELECT user();
user()
user@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL OPTION_LIST='host=localhost,user=root1,port=PORT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
@@ -24,7 +21,6 @@ a
10
20
30
-connection user;
SELECT user();
user()
user@localhost
@@ -43,12 +39,10 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
-connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
-connection user;
SELECT user();
user()
user@localhost
@@ -60,8 +54,6 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-disconnect user;
-connection default;
SELECT user();
user()
root@localhost
diff --git a/storage/connect/mysql-test/connect/r/mysql_new.result b/storage/connect/mysql-test/connect/r/mysql_new.result
index 69402ff7532..309d69abe7e 100644
--- a/storage/connect/mysql-test/connect/r/mysql_new.result
+++ b/storage/connect/mysql-test/connect/r/mysql_new.result
@@ -1,10 +1,5 @@
-connect master,127.0.0.1,root,,test,$MASTER_MYPORT,;
-connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,;
-connection master;
CREATE DATABASE connect;
-connection slave;
CREATE DATABASE connect;
-connection slave;
CREATE TABLE t1 (a int, b char(10));
INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
SELECT * FROM t1;
@@ -17,7 +12,6 @@ NULL NULL
#
# Testing errors
#
-connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://unknown@127.0.0.1:SLAVE_PORT/test/t1';
ERROR HY000: (1045) Access denied for user 'unknown'@'localhost' (using password: NO)
@@ -45,14 +39,10 @@ ERROR HY000: Got error 174 '(1054) Unknown column 'x' in 'field list' [SELECT `x
DROP TABLE t1;
CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
-connection slave;
ALTER TABLE t1 RENAME t1backup;
-connection master;
SELECT * FROM t1;
ERROR HY000: Got error 174 '(1146) Table 'test.t1' doesn't exist [SELECT `a`, `b` FROM `t1`]' from CONNECT
-connection slave;
ALTER TABLE t1backup RENAME t1;
-connection master;
DROP TABLE t1;
#
# Testing SELECT, etc.
@@ -121,7 +111,6 @@ NULL NULL
2 0
3 0
DROP TABLE t1;
-connection slave;
DROP TABLE t1;
#
# Testing numeric data types
@@ -140,7 +129,6 @@ t1 CREATE TABLE `t1` (
`h` decimal(20,5) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265);
-connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT';
SHOW CREATE TABLE t1;
@@ -159,7 +147,6 @@ SELECT * FROM t1;
a b c d e f g h
100 3333 41235 1234567890 235000000000 3.14159 3.14159265 3141.59265
DROP TABLE t1;
-connection slave;
DROP TABLE t1;
#
# Testing character data types
@@ -175,7 +162,6 @@ INSERT INTO t1 VALUES('Welcome','Hello, World');
SELECT * FROM t1;
a b
Welcome Hello, World
-connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT';
SHOW CREATE TABLE t1;
@@ -188,7 +174,6 @@ SELECT * FROM t1;
a b
Welcome Hello, World
DROP TABLE t1;
-connection slave;
DROP TABLE t1;
#
# Testing temporal data types
@@ -200,10 +185,10 @@ t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` datetime DEFAULT NULL,
`c` time DEFAULT NULL,
- `d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
+ `d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`e` year(4) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
-INSERT IGNORE INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
+INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
Warnings:
Note 1265 Data truncated for column 'a' at row 1
Note 1265 Data truncated for column 'c' at row 1
@@ -211,7 +196,6 @@ Warning 1265 Data truncated for column 'e' at row 1
SELECT * FROM t1;
a b c d e
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
-connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT';
SHOW CREATE TABLE t1;
@@ -220,18 +204,15 @@ t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` datetime DEFAULT NULL,
`c` time DEFAULT NULL,
- `d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
+ `d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`e` year(4) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT' `TABLE_TYPE`='MYSQL'
SELECT * FROM t1;
a b c d e
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
DROP TABLE t1;
-connection slave;
DROP TABLE t1;
-connection master;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
-connection slave;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
diff --git a/storage/connect/mysql-test/connect/r/odbc_oracle.result b/storage/connect/mysql-test/connect/r/odbc_oracle.result
index 8dc7dc07bb1..db7f78f67cd 100644
--- a/storage/connect/mysql-test/connect/r/odbc_oracle.result
+++ b/storage/connect/mysql-test/connect/r/odbc_oracle.result
@@ -72,11 +72,11 @@ TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr'
CATFUNC=Columns;
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
- MTR T1 A 3 DECIMAL 38 40 0 10 1
- MTR T1 B 6 NUMBER 38 40 NULL NULL 1
- MTR T2 A 12 VARCHAR2 64 64 NULL NULL 1
- MTR V1 A 3 DECIMAL 38 40 0 10 1
- MTR V1 B 6 NUMBER 38 40 NULL NULL 1
+NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
+NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
+NULL MTR T2 A 12 VARCHAR2 64 64 NULL NULL 1 NULL
+NULL MTR V1 A 3 DECIMAL 38 40 0 10 1 NULL
+NULL MTR V1 B 6 NUMBER 38 40 NULL NULL 1 NULL
DROP TABLE t1;
# All columns in all schemas (limited with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
@@ -84,18 +84,18 @@ TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr'
CATFUNC=Columns TABNAME='%.%';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
- MTR T1 A 3 DECIMAL 38 40 0 10 1
- MTR T1 B 6 NUMBER 38 40 NULL NULL 1
- MTR T2 A 12 VARCHAR2 64 64 NULL NULL 1
- MTR V1 A 3 DECIMAL 38 40 0 10 1
- MTR V1 B 6 NUMBER 38 40 NULL NULL 1
+NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
+NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
+NULL MTR T2 A 12 VARCHAR2 64 64 NULL NULL 1 NULL
+NULL MTR V1 A 3 DECIMAL 38 40 0 10 1 NULL
+NULL MTR V1 B 6 NUMBER 38 40 NULL NULL 1 NULL
DROP TABLE t1;
# All tables "T1" in all schemas (limited with WHERE)
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' CATFUNC=Columns TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
- MTR T1 A 3 DECIMAL 38 40 0 10 1
- MTR T1 B 6 NUMBER 38 40 NULL NULL 1
+NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
+NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
DROP TABLE t1;
# Table "T1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
@@ -103,8 +103,8 @@ TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr'
CATFUNC=Columns TABNAME='MTR.T1';
SELECT * FROM t1 ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
- MTR T1 A 3 DECIMAL 38 40 0 10 1
- MTR T1 B 6 NUMBER 38 40 NULL NULL 1
+NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
+NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
DROP TABLE t1;
# All tables "T1" in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
@@ -112,8 +112,8 @@ TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr'
CATFUNC=Columns TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
- MTR T1 A 3 DECIMAL 38 40 0 10 1
- MTR T1 B 6 NUMBER 38 40 NULL NULL 1
+NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
+NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
DROP TABLE t1;
#
# Checking tables
diff --git a/storage/connect/mysql-test/connect/r/unsigned.result b/storage/connect/mysql-test/connect/r/unsigned.result
index ca5a5ffe31e..b993133a3c4 100644
--- a/storage/connect/mysql-test/connect/r/unsigned.result
+++ b/storage/connect/mysql-test/connect/r/unsigned.result
@@ -27,13 +27,13 @@ UPDATE t1 SET e = d;
SELECT * FROM t1;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
-UPDATE IGNORE t1 SET c = d;
+UPDATE t1 SET c = d;
Warnings:
Warning 1264 Out of range value for column 'c' at row 1
SELECT * FROM t1;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
-UPDATE IGNORE t1 SET c = e;
+UPDATE t1 SET c = e;
Warnings:
Warning 1264 Out of range value for column 'c' at row 1
SELECT * FROM t1;
diff --git a/storage/connect/mysql-test/connect/r/upd.result b/storage/connect/mysql-test/connect/r/upd.result
index 8faf00896bb..fa519c4b688 100644
--- a/storage/connect/mysql-test/connect/r/upd.result
+++ b/storage/connect/mysql-test/connect/r/upd.result
@@ -1,4 +1,3 @@
-SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
CREATE TABLE employee
(
serialno CHAR(5) NOT NULL,
@@ -1626,4 +1625,3 @@ serialno name sex title manager department secretary salary
#
DROP PROCEDURE test.tst_up;
DROP TABLE employee;
-SET sql_mode = DEFAULT;
diff --git a/storage/connect/mysql-test/connect/r/vcol.result b/storage/connect/mysql-test/connect/r/vcol.result
deleted file mode 100644
index 1e3ecf8450a..00000000000
--- a/storage/connect/mysql-test/connect/r/vcol.result
+++ /dev/null
@@ -1,29 +0,0 @@
-create table t1 (
-#linenum int(6) not null default 0 special=rowid,
-name char(12) not null,
-city char(11) not null,
-birth date not null date_format='DD/MM/YYYY',
-hired date not null date_format='DD/MM/YYYY' flag=36,
-agehired int(3) as (floor(datediff(hired,birth)/365.25))
-)
-engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47;
-select * from t1;
-name city birth hired agehired
-John Boston 1986-01-25 2010-06-02 24
-Henry Boston 1987-06-07 2008-04-01 20
-George San Jose 1981-08-10 2010-06-02 28
-Sam Chicago 1979-11-22 2007-10-10 27
-James Dallas 1992-05-13 2009-12-14 17
-Bill Boston 1986-09-11 2008-02-10 21
-drop table t1;
-create table t1 (
-#linenum int(6) not null default 0 special=rowid,
-name char(12) not null,
-city char(11) not null,
-birth date not null date_format='DD/MM/YYYY',
-hired date not null date_format='DD/MM/YYYY' flag=36,
-agehired int(3) as (floor(datediff(hired,birth)/365.25)),
-index (agehired)
-)
-engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47;
-ERROR 42000: Table handler doesn't support NULL in given index. Please change column 'agehired' to be NOT NULL or use another handler
diff --git a/storage/connect/mysql-test/connect/r/xml_grant.result b/storage/connect/mysql-test/connect/r/xml_grant.result
index 817d3f5bf57..9eb818bf32f 100644
--- a/storage/connect/mysql-test/connect/r/xml_grant.result
+++ b/storage/connect/mysql-test/connect/r/xml_grant.result
@@ -6,8 +6,6 @@ Warning 1105 No file name. Table will use t1.xml
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
-connect user,localhost,user,,;
-connection user;
SELECT user();
user()
user@localhost
@@ -36,13 +34,11 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row' FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row' FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
@@ -65,12 +61,10 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
-connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
-connection user;
SELECT user();
user()
user@localhost
@@ -82,7 +76,6 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
SELECT user();
user()
root@localhost
@@ -92,15 +85,12 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmls
Warnings:
Warning 1105 No file name. Table will use t1.xml
INSERT INTO t1 VALUES (10);
-connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
-connection default;
DROP TABLE t1;
-disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
diff --git a/storage/connect/mysql-test/connect/r/xml_mdev5261.result b/storage/connect/mysql-test/connect/r/xml_mdev5261.result
index f91194d570c..3d67edd34ab 100644
--- a/storage/connect/mysql-test/connect/r/xml_mdev5261.result
+++ b/storage/connect/mysql-test/connect/r/xml_mdev5261.result
@@ -19,7 +19,7 @@ SELECT * FROM t1 WHERE i = 5;
i
5
ALTER TABLE t1 DROP INDEX i;
-ERROR 42000: Can't DROP INDEX `i`; check that it exists
+ERROR 42000: Can't DROP 'i'; check that column/key exists
DROP INDEX i ON t1;
-ERROR 42000: Can't DROP INDEX `i`; check that it exists
+ERROR 42000: Can't DROP 'i'; check that column/key exists
DROP TABLE t1;
diff --git a/storage/connect/mysql-test/connect/r/zip.result b/storage/connect/mysql-test/connect/r/zip.result
index c03b27bd428..c81546a4689 100644
--- a/storage/connect/mysql-test/connect/r/zip.result
+++ b/storage/connect/mysql-test/connect/r/zip.result
@@ -171,16 +171,16 @@ DROP TABLE t1,t2,t3,t4;
#
CREATE TABLE t1 (
_id INT(2) NOT NULL,
-name_first CHAR(9) NOT NULL FIELD_FORMAT='name:first',
-name_aka CHAR(4) DEFAULT NULL FIELD_FORMAT='name:aka',
-name_last CHAR(10) NOT NULL FIELD_FORMAT='name:last',
+name_first CHAR(9) NOT NULL FIELD_FORMAT='$.name.first',
+name_aka CHAR(4) DEFAULT NULL FIELD_FORMAT='$.name.aka',
+name_last CHAR(10) NOT NULL FIELD_FORMAT='$.name.last',
title CHAR(12) DEFAULT NULL,
birth CHAR(20) DEFAULT NULL,
death CHAR(20) DEFAULT NULL,
-contribs CHAR(7) NOT NULL FIELD_FORMAT='contribs:',
-awards_award CHAR(42) DEFAULT NULL FIELD_FORMAT='awards::award',
-awards_year CHAR(4) DEFAULT NULL FIELD_FORMAT='awards::year',
-awards_by CHAR(38) DEFAULT NULL FIELD_FORMAT='awards::by'
+contribs CHAR(7) NOT NULL FIELD_FORMAT='$.contribs',
+awards_award CHAR(42) DEFAULT NULL FIELD_FORMAT='$.awards.award',
+awards_year CHAR(4) DEFAULT NULL FIELD_FORMAT='$.awards.year',
+awards_by CHAR(38) DEFAULT NULL FIELD_FORMAT='$.awards.by'
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bios.zip' OPTION_LIST='ENTRY=bios.json,LOAD=bios.json' ZIPPED=YES;
SELECT * FROM t1;
_id name_first name_aka name_last title birth death contribs awards_award awards_year awards_by
@@ -211,16 +211,16 @@ _id name_first name_aka name_last title birth death contribs awards_award awards
10 Martin NULL Odersky NULL NULL NULL Scala NULL NULL NULL
CREATE TABLE t3 (
_id INT(2) NOT NULL,
-firstname CHAR(9) NOT NULL FIELD_FORMAT='name:first',
-aka CHAR(4) DEFAULT NULL FIELD_FORMAT='name:aka',
-lastname CHAR(10) NOT NULL FIELD_FORMAT='name:last',
+firstname CHAR(9) NOT NULL FIELD_FORMAT='$.name.first',
+aka CHAR(4) DEFAULT NULL FIELD_FORMAT='$.name.aka',
+lastname CHAR(10) NOT NULL FIELD_FORMAT='$.name.last',
title CHAR(12) DEFAULT NULL,
birth date DEFAULT NULL date_format="YYYY-DD-MM'T'hh:mm:ss'Z'",
death date DEFAULT NULL date_format="YYYY-DD-MM'T'hh:mm:ss'Z'",
-contribs CHAR(64) NOT NULL FIELD_FORMAT='contribs:[", "]',
-award CHAR(42) DEFAULT NULL FIELD_FORMAT='awards:[x]:award',
-year CHAR(4) DEFAULT NULL FIELD_FORMAT='awards:[x]:year',
-`by` CHAR(38) DEFAULT NULL FIELD_FORMAT='awards:[x]:by'
+contribs CHAR(64) NOT NULL FIELD_FORMAT='$.contribs.[", "]',
+award CHAR(42) DEFAULT NULL FIELD_FORMAT='$.awards[*].award',
+year CHAR(4) DEFAULT NULL FIELD_FORMAT='$.awards[*].year',
+`by` CHAR(38) DEFAULT NULL FIELD_FORMAT='$.awards[*].by'
) ENGINE=CONNECT TABLE_TYPE='json' FILE_NAME='bios.zip' ZIPPED=YES;
SELECT * FROM t3 WHERE _id = 1;
_id firstname aka lastname title birth death contribs award year by
diff --git a/storage/connect/mysql-test/connect/t/dir.test b/storage/connect/mysql-test/connect/t/dir.test
index 8a56d4f8829..fb69813d9f0 100644
--- a/storage/connect/mysql-test/connect/t/dir.test
+++ b/storage/connect/mysql-test/connect/t/dir.test
@@ -26,7 +26,6 @@ SELECT fname, ftype, size FROM t1 ORDER BY fname, ftype, size;
# TODO: add a better error message
--error ER_GET_ERRMSG
-SET STATEMENT sql_mode = '' FOR
INSERT INTO t1 VALUES ('','','','');
DROP TABLE t1;
diff --git a/storage/connect/mysql-test/connect/t/jdbc_new.test b/storage/connect/mysql-test/connect/t/jdbc_new.test
index 5586cf8c027..86c4ad57c5f 100644
--- a/storage/connect/mysql-test/connect/t/jdbc_new.test
+++ b/storage/connect/mysql-test/connect/t/jdbc_new.test
@@ -24,11 +24,9 @@ SET GLOBAL time_zone='+1:00';
# Bad user name
# Suppress "mysql_real_connect failed:" (printed in _DEBUG build)
--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " ""
+--error ER_UNKNOWN_ERROR
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=unknown';
---error ER_GET_ERRMSG
-SELECT * FROM t1;
-DROP TABLE t1;
# Bad database name
--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " ""
diff --git a/storage/connect/mysql-test/connect/t/json.test b/storage/connect/mysql-test/connect/t/json.test
index fa962d3b302..018489525f7 100644
--- a/storage/connect/mysql-test/connect/t/json.test
+++ b/storage/connect/mysql-test/connect/t/json.test
@@ -35,15 +35,15 @@ DROP TABLE t1;
CREATE TABLE t1
(
ISBN CHAR(15),
- Language CHAR(2) FIELD_FORMAT='LANG',
- Subject CHAR(32) FIELD_FORMAT='SUBJECT',
- Authors INT(2) FIELD_FORMAT='AUTHOR:[#]',
- Title CHAR(32) FIELD_FORMAT='TITLE',
- Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
- Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
- Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
- Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
- Year int(4) FIELD_FORMAT='DATEPUB'
+ Language CHAR(2) FIELD_FORMAT='$.LANG',
+ Subject CHAR(32) FIELD_FORMAT='$.SUBJECT',
+ Authors INT(2) FIELD_FORMAT='$.AUTHOR[#]',
+ Title CHAR(32) FIELD_FORMAT='$.TITLE',
+ Translation CHAR(32) FIELD_FORMAT='$.TRANSLATION',
+ Translator CHAR(80) FIELD_FORMAT='$.TRANSLATOR',
+ Publisher CHAR(20) FIELD_FORMAT='$.PUBLISHER.NAME',
+ Location CHAR(16) FIELD_FORMAT='$.PUBLISHER.PLACE',
+ Year int(4) FIELD_FORMAT='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1;
@@ -55,16 +55,16 @@ DROP TABLE t1;
CREATE TABLE t1
(
ISBN CHAR(15),
- Language CHAR(2) FIELD_FORMAT='LANG',
- Subject CHAR(32) FIELD_FORMAT='SUBJECT',
- AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[" and "]:FIRSTNAME',
- AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[" and "]:LASTNAME',
- Title CHAR(32) FIELD_FORMAT='TITLE',
- Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
- Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
- Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
- Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
- Year int(4) FIELD_FORMAT='DATEPUB'
+ Language CHAR(2) FIELD_FORMAT='$.LANG',
+ Subject CHAR(32) FIELD_FORMAT='$.SUBJECT',
+ AuthorFN CHAR(128) FIELD_FORMAT='$.AUTHOR[" and "].FIRSTNAME',
+ AuthorLN CHAR(128) FIELD_FORMAT='$.AUTHOR[" and "].LASTNAME',
+ Title CHAR(32) FIELD_FORMAT='$.TITLE',
+ Translation CHAR(32) FIELD_FORMAT='$.TRANSLATION',
+ Translator CHAR(80) FIELD_FORMAT='$.TRANSLATOR',
+ Publisher CHAR(20) FIELD_FORMAT='$.PUBLISHER.NAME',
+ Location CHAR(16) FIELD_FORMAT='$.PUBLISHER.PLACE',
+ Year int(4) FIELD_FORMAT='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1;
@@ -76,16 +76,16 @@ DROP TABLE t1;
CREATE TABLE t1
(
ISBN CHAR(15),
- Language CHAR(2) FIELD_FORMAT='LANG',
- Subject CHAR(32) FIELD_FORMAT='SUBJECT',
- AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
- AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
- Title CHAR(32) FIELD_FORMAT='TITLE',
- Translation CHAR(32) FIELD_FORMAT='TRANSLATION',
- Translator CHAR(80) FIELD_FORMAT='TRANSLATOR',
- Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
- Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
- Year int(4) FIELD_FORMAT='DATEPUB'
+ Language CHAR(2) FIELD_FORMAT='$.LANG',
+ Subject CHAR(32) FIELD_FORMAT='$.SUBJECT',
+ AuthorFN CHAR(128) FIELD_FORMAT='$.AUTHOR[*].FIRSTNAME',
+ AuthorLN CHAR(128) FIELD_FORMAT='$.AUTHOR[*].LASTNAME',
+ Title CHAR(32) FIELD_FORMAT='$.TITLE',
+ Translation CHAR(32) FIELD_FORMAT='$.TRANSLATION',
+ Translator CHAR(80) FIELD_FORMAT='$.TRANSLATOR',
+ Publisher CHAR(20) FIELD_FORMAT='$.PUBLISHER.NAME',
+ Location CHAR(16) FIELD_FORMAT='$.PUBLISHER.PLACE',
+ Year int(4) FIELD_FORMAT='$.DATEPUB'
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1;
@@ -98,7 +98,7 @@ SELECT * FROM t1 WHERE ISBN = '9782212090819';
CREATE TABLE t2 (
FIRSTNAME CHAR(32),
LASTNAME CHAR(32))
-ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json' OPTION_LIST='Object=[1]:AUTHOR';
+ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json' OPTION_LIST='Object=$[1].AUTHOR';
SELECT * FROM t2;
INSERT INTO t2 VALUES('Charles','Dickens');
SELECT * FROM t1;
@@ -122,17 +122,17 @@ DROP TABLE t1;
CREATE TABLE t1
(
ISBN CHAR(15) NOT NULL,
- Language CHAR(2) FIELD_FORMAT='LANG',
- Subject CHAR(32) FIELD_FORMAT='SUBJECT',
- AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
- AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
- Title CHAR(32) FIELD_FORMAT='TITLE',
- Translation CHAR(32) FIELD_FORMAT='TRANSLATED:PREFIX',
- TranslatorFN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:FIRSTNAME',
- TranslatorLN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:LASTNAME',
- Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
- Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
- Year int(4) FIELD_FORMAT='DATEPUB',
+ Language CHAR(2) FIELD_FORMAT='$.LANG',
+ Subject CHAR(32) FIELD_FORMAT='$.SUBJECT',
+ AuthorFN CHAR(128) FIELD_FORMAT='$.AUTHOR[*].FIRSTNAME',
+ AuthorLN CHAR(128) FIELD_FORMAT='$.AUTHOR[*].LASTNAME',
+ Title CHAR(32) FIELD_FORMAT='$.TITLE',
+ Translation CHAR(32) FIELD_FORMAT='$.TRANSLATED.PREFIX',
+ TranslatorFN CHAR(80) FIELD_FORMAT='$.TRANSLATED.TRANSLATOR.FIRSTNAME',
+ TranslatorLN CHAR(80) FIELD_FORMAT='$.TRANSLATED.TRANSLATOR.LASTNAME',
+ Publisher CHAR(20) FIELD_FORMAT='$.PUBLISHER.NAME',
+ Location CHAR(16) FIELD_FORMAT='$.PUBLISHER.PLACE',
+ Year int(4) FIELD_FORMAT='$.DATEPUB',
INDEX IX(ISBN)
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bib0.json' LRECL=320 OPTION_LIST='Pretty=0';
@@ -148,9 +148,9 @@ DROP TABLE t1;
--echo #
CREATE TABLE t1 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[X]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK::EXPENSE:["+"]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK::EXPENSE:[+]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[*].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[].EXPENSE["+"].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[].EXPENSE[+].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t1;
DROP TABLE t1;
@@ -160,9 +160,9 @@ DROP TABLE t1;
--echo #
CREATE TABLE t1 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[X]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[*].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[*].EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[*].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
#--error ER_GET_ERRMSG
SELECT * FROM t1;
@@ -173,14 +173,14 @@ DROP TABLE t1;
--echo #
CREATE TABLE t1 (
WHO CHAR(12) NOT NULL,
-WEEKS CHAR(12) NOT NULL FIELD_FORMAT='WEEK:[", "]:NUMBER',
-SUMS CHAR(64) NOT NULL FIELD_FORMAT='WEEK:["+"]:EXPENSE:[+]:AMOUNT',
-SUM DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[+]:EXPENSE:[+]:AMOUNT',
-AVGS CHAR(64) NOT NULL FIELD_FORMAT='WEEK:["+"]:EXPENSE:[!]:AMOUNT',
-SUMAVG DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[+]:EXPENSE:[!]:AMOUNT',
-AVGSUM DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[!]:EXPENSE:[+]:AMOUNT',
-AVGAVG DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[!]:EXPENSE:[!]:AMOUNT',
-AVERAGE DOUBLE(8,2) NOT NULL FIELD_FORMAT='WEEK:[!]:EXPENSE:[X]:AMOUNT')
+WEEKS CHAR(12) NOT NULL FIELD_FORMAT='$.WEEK[", "].NUMBER',
+SUMS CHAR(64) NOT NULL FIELD_FORMAT='$.WEEK["+"].EXPENSE[+].AMOUNT',
+SUM DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[+].EXPENSE[+].AMOUNT',
+AVGS CHAR(64) NOT NULL FIELD_FORMAT='$.WEEK["+"].EXPENSE[!].AMOUNT',
+SUMAVG DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[+].EXPENSE[!].AMOUNT',
+AVGSUM DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[!].EXPENSE[+].AMOUNT',
+AVGAVG DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[!].EXPENSE[!].AMOUNT',
+AVERAGE DOUBLE(8,2) NOT NULL FIELD_FORMAT='$.WEEK[!].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t1;
DROP TABLE t1;
@@ -190,25 +190,25 @@ DROP TABLE t1;
--echo #
CREATE TABLE t2 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[0]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK:[0]:EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[0]:EXPENSE:[X]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[0].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[0].EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[0].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t2;
CREATE TABLE t3 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[1]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK:[1]:EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[1]:EXPENSE:[X]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[1].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[1].EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[1].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t3;
CREATE TABLE t4 (
WHO CHAR(12),
-WEEK INT(2) FIELD_FORMAT='WEEK:[2]:NUMBER',
-WHAT CHAR(32) FIELD_FORMAT='WEEK:[2]:EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[2]:EXPENSE:[X]:AMOUNT')
+WEEK INT(2) FIELD_FORMAT='$.WEEK[2].NUMBER',
+WHAT CHAR(32) FIELD_FORMAT='$.WEEK[2].EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.WEEK[2].EXPENSE[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.json';
SELECT * FROM t4;
@@ -230,24 +230,24 @@ DROP TABLE t1, t2, t3, t4;
CREATE TABLE t2 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp3.json';
SELECT * FROM t2;
CREATE TABLE t3 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp4.json';
SELECT * FROM t3;
CREATE TABLE t4 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp5.json';
SELECT * FROM t4;
@@ -257,8 +257,8 @@ SELECT * FROM t4;
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp*.json' MULTIPLE=1;
SELECT * FROM t1 ORDER BY WHO, WEEK, WHAT, AMOUNT;
DROP TABLE t1;
@@ -269,8 +269,8 @@ DROP TABLE t1;
CREATE TABLE t1 (
WHO CHAR(12),
WEEK INT(2),
-WHAT CHAR(32) FIELD_FORMAT='EXPENSE:[X]:WHAT',
-AMOUNT DOUBLE(8,2) FIELD_FORMAT='EXPENSE:[X]:AMOUNT')
+WHAT CHAR(32) FIELD_FORMAT='$.EXPENSE[*].WHAT',
+AMOUNT DOUBLE(8,2) FIELD_FORMAT='$.EXPENSE.[*].AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='mulexp%s.json';
ALTER TABLE t1
PARTITION BY LIST COLUMNS(WEEK) (
diff --git a/storage/connect/mysql-test/connect/t/json_udf.inc b/storage/connect/mysql-test/connect/t/json_udf.inc
index 2ade7ad02fe..4f675023c44 100644
--- a/storage/connect/mysql-test/connect/t/json_udf.inc
+++ b/storage/connect/mysql-test/connect/t/json_udf.inc
@@ -9,11 +9,11 @@ if (!$HA_CONNECT_SO) {
--skip Needs a dynamically built ha_connect.so
}
---eval CREATE FUNCTION json_array RETURNS STRING SONAME '$HA_CONNECT_SO';
+--eval CREATE FUNCTION json_make_array RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_array_add RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_array_add_values RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_array_delete RETURNS STRING SONAME '$HA_CONNECT_SO';
---eval CREATE FUNCTION json_object RETURNS STRING SONAME '$HA_CONNECT_SO';
+--eval CREATE FUNCTION json_make_object RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_object_nonull RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_object_key RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_object_add RETURNS STRING SONAME '$HA_CONNECT_SO';
diff --git a/storage/connect/mysql-test/connect/t/json_udf.test b/storage/connect/mysql-test/connect/t/json_udf.test
index d11e2fd7cf6..35dbbfed706 100644
--- a/storage/connect/mysql-test/connect/t/json_udf.test
+++ b/storage/connect/mysql-test/connect/t/json_udf.test
@@ -22,13 +22,13 @@ SELECT JsonValue(FALSE);
SELECT JsonValue();
SELECT JsonValue('[11, 22, 33]' json_) FROM t1;
#
-SELECT Json_Array();
-SELECT Json_Array(56, 3.1416, 'My name is "Foo"', NULL);
-SELECT Json_Array(Json_Array(56, 3.1416, 'foo'), TRUE);
+SELECT Json_Make_Array();
+SELECT Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL);
+SELECT Json_Make_Array(Json_Make_Array(56, 3.1416, 'foo'), TRUE);
#
--error ER_CANT_INITIALIZE_UDF
-SELECT Json_Array_Add(Json_Array(56, 3.1416, 'foo', NULL)) Array;
-SELECT Json_Array_Add(Json_Array(56, 3.1416, 'foo', NULL), 'One more') Array;
+SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL)) Array;
+SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL), 'One more') Array;
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(JsonValue('one value'), 'One more');
--error ER_CANT_INITIALIZE_UDF
@@ -39,38 +39,38 @@ SELECT Json_Array_Add(5 json_, 'One more');
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 9);
-SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), '[2]', 33, 1);
-SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, '[2]', 1);
-SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, 1, '[2]');
+SELECT Json_Array_Add(Json_Make_Array(1, 2, Json_Make_Array(11, 22)), '[2]', 33, 1);
+SELECT Json_Array_Add(Json_Make_Array(1, 2, Json_Make_Array(11, 22)), 33, '[2]', 1);
+SELECT Json_Array_Add(Json_Make_Array(1, 2, Json_Make_Array(11, 22)), 33, 1, '[2]');
#
-SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
-SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
-SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), n) Array FROM t1;
-SELECT Json_Array_Add_Values(Json_Array(n, 3.1416, 'machin'), n) Array FROM t1;
+SELECT Json_Array_Add_Values(Json_Make_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
+SELECT Json_Array_Add_Values(Json_Make_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
+SELECT Json_Array_Add_Values(Json_Make_Array(56, 3.1416, 'machin'), n) Array FROM t1;
+SELECT Json_Array_Add_Values(Json_Make_Array(n, 3.1416, 'machin'), n) Array FROM t1;
SELECT Json_Array_Add_Values('[56]', 3.1416, 'machin') Array;
#
-SELECT Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), 0);
-SELECT Json_Array_Delete(Json_Object(56, 3.1416, 'My name is Foo', NULL), 2);
-SELECT Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), '2');
-SELECT Json_Array_Delete(json_array(56, 3.1416, 'My name is "Foo"', NULL), '2', 2);
+SELECT Json_Array_Delete(Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL), 0);
+SELECT Json_Array_Delete(Json_Make_Object(56, 3.1416, 'My name is Foo', NULL), 2);
+SELECT Json_Array_Delete(Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL), '2');
+SELECT Json_Array_Delete(Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL), '2', 2);
#
-SELECT Json_Object(56, 3.1416, 'foo', NULL);
-SELECT Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
-SELECT Json_Object();
-SELECT Json_Object(Json_Array(56, 3.1416, 'foo'), NULL);
-SELECT Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
+SELECT Json_Make_Object(56, 3.1416, 'foo', NULL);
+SELECT Json_Make_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
+SELECT Json_Make_Object();
+SELECT Json_Make_Object(Json_Make_Array(56, 3.1416, 'foo'), NULL);
+SELECT Json_Make_Array(Json_Make_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL);
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty');
#
-SELECT Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
-SELECT Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
+SELECT Json_Object_Add(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
+SELECT Json_Object_Add(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
SELECT Json_Object_Add(Json_File('notexist.json'), 'cheese' item, '[1]', 1);
#
-SELECT Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'truc');
-SELECT Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'chose');
+SELECT Json_Object_Delete(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'truc');
+SELECT Json_Object_Delete(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'chose');
#
-SELECT Json_Object_List(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty)) "Key List";
+SELECT Json_Object_List(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty)) "Key List";
SELECT Json_Object_List('{"qty":56, "price":3.1416, "truc":"machin", "garanty":null}') "Key List";
--echo #
@@ -89,8 +89,8 @@ CREATE TABLE t2
DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
-SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
-SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
+SELECT Json_Make_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
+SELECT Json_Make_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t2;
SELECT Json_Array_Grp(TITLE) FROM t2;
@@ -106,19 +106,19 @@ CREATE TABLE t3 (
SALARY DOUBLE(8,2) NOT NULL FLAG=52
) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1;
-SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
+SELECT Json_Make_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t3 GROUP BY DEPARTMENT;
#SET connect_json_grp_size=30; Deprecated
SELECT JsonSet_Grp_Size(30);
-SELECT Json_Object(title, Json_Array_Grp(name) `json_names`) from t3 GROUP BY title;
-SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
-SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
-SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
-SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
+SELECT Json_Make_Object(title, Json_Array_Grp(name) `json_names`) from t3 GROUP BY title;
+SELECT Json_Make_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
+SELECT Json_Make_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
+SELECT Json_Make_Object(DEPARTMENT, Json_Array_Grp(Json_Make_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
+SELECT Json_Make_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Make_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Object_Grp(SALARY) FROM t3;
SELECT Json_Object_Grp(NAME, SALARY) FROM t3;
-SELECT Json_Object(DEPARTMENT, Json_Object_Grp(NAME, SALARY) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
+SELECT Json_Make_Object(DEPARTMENT, Json_Object_Grp(NAME, SALARY) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Array_Grp(NAME) FROM t3;
#
SELECT Json_Object_Key(name, title) FROM t3 WHERE DEPARTMENT = 318;
@@ -131,59 +131,59 @@ SELECT JsonGet_String(Json_Array_Grp(name),'[#]') FROM t3;
SELECT JsonGet_String(Json_Array_Grp(name),'[","]') FROM t3;
SELECT JsonGet_String(Json_Array_Grp(name),'[>]') FROM t3;
SET @j1 = '[45,28,36,45,89]';
-SELECT JsonGet_String(@j1,'[1]');
-SELECT JsonGet_String(@j1 json_,'[3]');
-SELECT JsonGet_String(Json_Array(45,28,36,45,89),'[3]');
-SELECT JsonGet_String(Json_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Array(45,28,36,45,89),'[+]') "sum";
-SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
-SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*');
-SELECT JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
+SELECT JsonGet_String(@j1,'1');
+SELECT JsonGet_String(@j1 json_,'3');
+SELECT JsonGet_String(Json_Make_Array(45,28,36,45,89),'3');
+SELECT JsonGet_String(Json_Make_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Make_Array(45,28,36,45,89),'[+]') "sum";
+SELECT JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.0');
+SELECT JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)),'1.*');
+SELECT JsonGet_String(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
SET @j2 = '{"qty":56,"price":3.141600,"truc":"machin","garanty":null}';
SELECT JsonGet_String(@j2 json_,'truc');
SELECT JsonGet_String(@j2,'truc');
SELECT JsonGet_String(@j2,'chose');
SELECT JsonGet_String(NULL json_, NULL);
-SELECT department, JsonGet_String(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
+SELECT department, JsonGet_String(Json_Make_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries.[+]') Sumsal FROM t3 GROUP BY department;
#
-SELECT JsonGet_Int(@j1, '[4]');
+SELECT JsonGet_Int(@j1, '4');
SELECT JsonGet_Int(@j1, '[#]');
SELECT JsonGet_Int(@j1, '[+]');
-SELECT JsonGet_Int(@j1 json_, '[3]');
-SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '[3]');
-SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '["+"]');
-SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '[+]');
-SELECT JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]');
-SELECT JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[0]:[1]');
-SELECT JsonGet_Int(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'qty');
+SELECT JsonGet_Int(@j1 json_, '3');
+SELECT JsonGet_Int(Json_Make_Array(45,28,36,45,89), '3');
+SELECT JsonGet_Int(Json_Make_Array(45,28,36,45,89), '["+"]');
+SELECT JsonGet_Int(Json_Make_Array(45,28,36,45,89), '[+]');
+SELECT JsonGet_Int(Json_Make_Array(Json_Make_Array(45,28), Json_Make_Array(36,45,89)), '1.0');
+SELECT JsonGet_Int(Json_Make_Array(Json_Make_Array(45,28), Json_Make_Array(36,45,89)), '0.1');
+SELECT JsonGet_Int(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'qty');
SELECT JsonGet_Int(@j2 json_, 'price');
SELECT JsonGet_Int(@j2, 'qty');
SELECT JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose');
-SELECT JsonGet_Int(JsonGet_String(Json_Array(Json_Array(45,28),Json_Array(36,45,89)), '[1]:*'), '[+]') sum;
-SELECT department, JsonGet_Int(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"), 'salaries:[+]') Sumsal FROM t3 GROUP BY department;
+SELECT JsonGet_Int(JsonGet_String(Json_Make_Array(Json_Make_Array(45,28),Json_Make_Array(36,45,89)), '1.*'), '[+]') sum;
+SELECT department, JsonGet_Int(Json_Make_Object(department, Json_Array_Grp(salary) "Json_salaries"), 'salaries.[+]') Sumsal FROM t3 GROUP BY department;
#
-SELECT JsonGet_Real(@j1, '[2]');
-SELECT JsonGet_Real(@j1 json_, '[3]', 2);
-SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[3]');
-SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '["+"]');
-SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[+]');
-SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[!]');
-SELECT JsonGet_Real(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]');
-SELECT JsonGet_Real(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'price');
+SELECT JsonGet_Real(@j1, '2');
+SELECT JsonGet_Real(@j1 json_, '3', 2);
+SELECT JsonGet_Real(Json_Make_Array(45,28,36,45,89), '3');
+SELECT JsonGet_Real(Json_Make_Array(45,28,36,45,89), '["+"]');
+SELECT JsonGet_Real(Json_Make_Array(45,28,36,45,89), '[+]');
+SELECT JsonGet_Real(Json_Make_Array(45,28,36,45,89), '[!]');
+SELECT JsonGet_Real(Json_Make_Array(Json_Make_Array(45,28), Json_Make_Array(36,45,89)), '1.0');
+SELECT JsonGet_Real(Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'price');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_, 'qty');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'price');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'price', 4);
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose');
-SELECT department, JsonGet_Real(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
+SELECT department, JsonGet_Real(Json_Make_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries.[+]') Sumsal FROM t3 GROUP BY department;
--echo #
--echo # Documentation examples
--echo #
SELECT
- JsonGet_Int(Json_Array(45,28,36,45,89), '[4]') "Rank",
- JsonGet_Int(Json_Array(45,28,36,45,89), '[#]') "Number",
- JsonGet_String(Json_Array(45,28,36,45,89), '[","]') "Concat",
- JsonGet_Int(Json_Array(45,28,36,45,89), '[+]') "Sum",
- JsonGet_Real(Json_Array(45,28,36,45,89), '[!]', 2) "Avg";
+ JsonGet_Int(Json_Make_Array(45,28,36,45,89), '4') "Rank",
+ JsonGet_Int(Json_Make_Array(45,28,36,45,89), '[#]') "Number",
+ JsonGet_String(Json_Make_Array(45,28,36,45,89), '[","]') "Concat",
+ JsonGet_Int(Json_Make_Array(45,28,36,45,89), '[+]') "Sum",
+ JsonGet_Real(Json_Make_Array(45,28,36,45,89), '[!]', 2) "Avg";
SELECT
JsonGet_String('{"qty":7,"price":29.50,"garanty":null}', 'price') "String",
JsonGet_Int('{"qty":7,"price":29.50,"garanty":null}', 'price') "Int",
@@ -193,10 +193,10 @@ SELECT JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}', 'price', 3) "Real"
--echo #
--echo # Testing Locate
--echo #
-SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
-SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
-SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
-SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
+SELECT JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
+SELECT JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
+SELECT JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
+SELECT JsonLocate(Json_Make_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'Jack') Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'jack' ci) Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"Jack", "LN":"London"}' json_) Path;
@@ -220,7 +220,7 @@ SELECT Json_Locate_All('[[45,28],[[36,45],89]]','45') "All paths";
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_);
SELECT JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '[#]') "Nb of occurs";
SELECT Json_Locate_All('[[45,28],[[36,45],89]]',45,2);
-SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]');
+SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'0');
SELECT JsonLocate(Json_File('test/biblio.json'), 'Knab');
SELECT Json_Locate_All('test/biblio.json' jfile_, 'Knab');
@@ -237,21 +237,21 @@ SELECT Jfile_Make(Jbin_File('test/fx.json'), 0);
SELECT Json_File('test/fx.json', 1);
SELECT Json_File('test/fx.json', 2);
SELECT Json_File('test/fx.json', 0);
-SELECT Json_File('test/fx.json', '[0]');
+SELECT Json_File('test/fx.json', '0');
SELECT Json_File('test/fx.json', '[?]');
-SELECT JsonGet_String(Json_File('test/fx.json'), '[1]:*');
-SELECT JsonGet_String(Json_File('test/fx.json'), '[1]');
-SELECT JsonGet_Int(Json_File('test/fx.json'), '[1]:mileage') AS Mileage;
-SELECT JsonGet_Real(Json_File('test/fx.json'), '[0]:price', 2) AS Price;
-SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings');
-SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings');
-SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1);
-SELECT Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0);
-SELECT Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1);
-SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin);
-SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size');
-SELECT Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size');
-SELECT Json_Object_List(Json_File('test/fx.json', '[3]:size'));
+SELECT JsonGet_String(Json_File('test/fx.json'), '1.*');
+SELECT JsonGet_String(Json_File('test/fx.json'), '1');
+SELECT JsonGet_Int(Json_File('test/fx.json'), '1.mileage') AS Mileage;
+SELECT JsonGet_Real(Json_File('test/fx.json'), '0.price', 2) AS Price;
+SELECT Json_Array_Add(Json_File('test/fx.json', '2'), 6, 'ratings');
+SELECT Json_Array_Add(Json_File('test/fx.json', '2'), 6, 1, 'ratings');
+SELECT Json_Array_Add(Json_File('test/fx.json', '2'), 6, 'ratings', 1);
+SELECT Json_Array_Add(Json_File('test/fx.json', '2.ratings'), 6, 0);
+SELECT Json_Array_Delete(Json_File('test/fx.json', '2'), 'ratings', 1);
+SELECT Json_Object_Add(Json_File('test/fx.json', '2'), 'france' origin);
+SELECT Json_Object_Add(Json_File('test/fx.json', '2'), 70 H, 'size');
+SELECT Json_Object_Add(Json_File('test/fx.json', '3'), 70 H, 'size');
+SELECT Json_Object_List(Json_File('test/fx.json', '3.size'));
DROP TABLE t1;
DROP TABLE t2;
@@ -264,3 +264,5 @@ DROP TABLE t3;
--remove_file $MYSQLD_DATADIR/test/biblio.json
--remove_file $MYSQLD_DATADIR/test/employee.dat
--remove_file $MYSQLD_DATADIR/test/fx.json
+
+
diff --git a/storage/connect/mysql-test/connect/t/json_udf2.inc b/storage/connect/mysql-test/connect/t/json_udf2.inc
index 4c74e2c11f2..fe23692af46 100644
--- a/storage/connect/mysql-test/connect/t/json_udf2.inc
+++ b/storage/connect/mysql-test/connect/t/json_udf2.inc
@@ -1,10 +1,10 @@
--disable_query_log
-DROP FUNCTION json_array;
+DROP FUNCTION json_make_array;
DROP FUNCTION json_array_add;
DROP FUNCTION json_array_add_values;
DROP FUNCTION json_array_delete;
-DROP FUNCTION json_object;
+DROP FUNCTION json_make_object;
DROP FUNCTION json_object_nonull;
DROP FUNCTION json_object_key;
DROP FUNCTION json_object_add;
diff --git a/storage/connect/mysql-test/connect/t/json_udf_bin.test b/storage/connect/mysql-test/connect/t/json_udf_bin.test
index e4ee422c263..cbbfca9d2d2 100644
--- a/storage/connect/mysql-test/connect/t/json_udf_bin.test
+++ b/storage/connect/mysql-test/connect/t/json_udf_bin.test
@@ -16,7 +16,7 @@ SELECT Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), JsonGet_
SELECT Json_Array_Delete(Jbin_Array_Add_Values(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), "One more", 2), 4);
SELECT Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), NULL), '[1]', 1);
SELECT Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), TRUE), 1, '[1]');
-SELECT Json_Array(1, TRUE, 0, FALSE);
+SELECT Json_Make_Array(1, TRUE, 0, FALSE);
SELECT Json_Serialize(Jbin_Array(TRUE, FALSE));
#
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL);
@@ -35,65 +35,65 @@ SELECT Json_Serialize(Jbin_File('gloss.json'));
SELECT JsonLocate(Jbin_File('gloss.json'),'XML');
#
SELECT Json_Object_Key('first', 'foo', 'second', Jbin_Array('a', 33));
-SELECT Json_Get_Item(Json_Array('a','b','c'), '[1]');
-SELECT Json_Get_Item(Json_Object('foo' AS "first", Json_Array('a', 33) AS "json_second"), 'second') AS "item";
-SELECT Json_Get_Item(Jbin_Object('foo' first, Jbin_Array('a', 33) jbin_second), 'second:*') item;
-SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv');
-SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv'));
-SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:*');
-SELECT JsonGet_String(Json_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso') lang;
-SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso') "See also";
-SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso')) "See also";
-SELECT JsonGet_String(Json_Get_Item(Json_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso'),'[0]') lang;
+SELECT Json_Get_Item(Json_Make_Array('a','b','c'), '$[1]');
+SELECT Json_Get_Item(Json_Make_Object('foo' AS "first", Json_Make_Array('a', 33) AS "json_second"), '$.second') AS "item";
+SELECT Json_Get_Item(Jbin_Object('foo' first, Jbin_Array('a', 33) jbin_second), '$.second') item;
+SELECT Json_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv');
+SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv'));
+SELECT Json_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv');
+SELECT JsonGet_String(Json_File('gloss.json'),'$.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso') lang;
+SELECT Json_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso') "See also";
+SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'$.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso')) "See also";
+SELECT JsonGet_String(Json_Get_Item(Json_File('gloss.json'),'$.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso'),'$[0]') lang;
--echo #
--echo # Test Item Get/Set/Insert/Update UDF's
--echo #
-SELECT Json_Get_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[]');
-SELECT Json_Get_Item(Jbin_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[1]');
-SELECT Json_Get_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '[1]');
+SELECT Json_Get_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '$[]');
+SELECT Json_Get_Item(Jbin_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '$[1]');
+SELECT Json_Get_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '$[1]');
#
-SELECT Json_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)));
+SELECT Json_Set_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)));
--error ER_CANT_INITIALIZE_UDF
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 'foo');
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 7, '[1]');
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 7, '[1]');
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Json_Array(7, 8, 9), '[1]');
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]');
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]:*');
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 3.1416, 'foo');
-SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 'toto', '[1]:[2]');
-SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 300, '[2]:nxt:total:[]');
-SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 300, '[2]:nxt:total:[]');
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[1]', 5, '[2]:cinq', 10, '[1]:[]');
-SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 44, '[2]:quatre');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '$.foo');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 7, '$[1]');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 7, '$[1]');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Json_Make_Array(7, 8, 9), '$[1]');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '$[2]');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '$[2].*');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 3.1416, '$.foo');
+SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 'toto', '$[1][2]');
+SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 300, '$[2].nxt.total[]');
+SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][]', 300, '$[2].nxt.total[]');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '$[1]', 5, '$[2].cinq', 10, '$[1][]');
+SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 44, '$[2].quatre');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, 'truc');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '*');
-SELECT Json_Serialize(Jbin_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq'));
+SELECT Json_Serialize(Jbin_Set_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq'));
#
-SELECT Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
-SELECT Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
-SELECT Json_Insert_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre');
-SELECT Json_Update_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre');
-SELECT Json_Insert_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]');
-SELECT Json_Update_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]');
-SELECT Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]');
-SELECT Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]');
+SELECT Json_Insert_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq');
+SELECT Json_Update_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq');
+SELECT Json_Insert_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][]', 44, '$[2].quatre');
+SELECT Json_Update_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][]', 44, '$[2].quatre');
+SELECT Json_Insert_Item(Json_Make_Array(1, Json_Make_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][1]', 300, '$[2].nxt.total[]');
+SELECT Json_Update_Item(Json_Make_Array(1, Json_Make_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[2].cinq', 10, '$[1][1]', 300, '$[2].nxt.total[]');
+SELECT Json_Insert_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[]');
+SELECT Json_Update_Item(Json_Make_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '$[]');
--echo #
--echo # Test merging items UDF's
--echo #
SELECT Json_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f'));
-SELECT Json_Item_Merge(Json_Array('a','b','c'), Json_Array('d','e','f')) AS "Result";
+SELECT Json_Item_Merge(Json_Make_Array('a','b','c'), Json_Make_Array('d','e','f')) AS "Result";
SELECT Json_Array_Add(Jbin_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f')), 'and', 3);
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "d",5 "e",6 "f"));
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",2 "c"), Jbin_Array('d','e','f'));
SELECT Json_Object_Add(Jbin_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "d",5 "e",6 "f")), 'x' AS "and");
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "a",5 "e",6 "f"));
--error ER_CANT_INITIALIZE_UDF
-SELECT Json_Item_Merge('foo', Json_Array('d','e','f'));
+SELECT Json_Item_Merge('foo', Json_Make_Array('d','e','f'));
--echo #
--echo # Test making file UDF's
@@ -116,14 +116,14 @@ SELECT Json_Array_Add(Jbin_File('bt1.json'), 'd');
SELECT Json_File('bt1.json', 2);
--echo # Back to the original file
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
-SELECT Json_Object(Jbin_Array_Add(Jbin_Array('a','b','c'), 'd') "Jbin_foo") AS "Result";
-SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd')) AS "Result";
-SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1") AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Add(Jbin_Array('a','b','c'), 'd') "Jbin_foo") AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd')) AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1") AS "Result";
--echo # This does modify the file
-SELECT Json_Object(Json_Array_Add(Jbin_File('bt1.json'), 'd') "Jfile_bt1") AS "Result";
+SELECT Json_Make_Object(Json_Array_Add(Jbin_File('bt1.json'), 'd') "Jfile_bt1") AS "Result";
SELECT Json_File('bt1.json');
SELECT Json_File(Json_Array_Delete(Jbin_File('bt1.json'), 3), 2);
-SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1", n "t1") AS "Result" from t1;
+SELECT Json_Make_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1", n "t1") AS "Result" from t1;
SELECT Json_File(Json_Array_Add(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'), 'e')) AS "Result";
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
SELECT Json_File(Json_Array_Add(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'), 'e')) AS "Result" from t1;
@@ -140,11 +140,11 @@ SELECT Json_File(Jbin_Item_Merge(Jbin_File('bt1.json'), Jbin_Array('d','e','f'))
SELECT Json_File(Json_Item_Merge(Jbin_File('bt1.json'), Jbin_Array('d','e','f')));
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
--echo # Test DELETE from file
-SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 1)) AS "Result";
-SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 2) "Jbin_bt1") AS "Result";
-SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 0) "Jbin_bt1", n "t1") AS "Result" from t1;
-SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
-SELECT Json_Object(Json_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
+SELECT Json_Make_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 1)) AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 2) "Jbin_bt1") AS "Result";
+SELECT Json_Make_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 0) "Jbin_bt1", n "t1") AS "Result" from t1;
+SELECT Json_Make_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
+SELECT Json_Make_Object(Json_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
--echo # Show modified file
SELECT Json_File('bt1.json');
--echo # Object file
@@ -153,11 +153,11 @@ SELECT Json_File('bt2.json', 0);
SELECT Json_File('bt2.json');
SELECT Json_Serialize(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"));
--echo # First query (file not modified)
-SELECT Json_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jbin_new") AS "Result";
+SELECT Json_Make_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jbin_new") AS "Result";
--echo # First query (file modified)
-SELECT Json_Object(Json_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jfile_new") AS "Result";
+SELECT Json_Make_Object(Json_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jfile_new") AS "Result";
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
-SELECT Json_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d") "Jbin_new", n "t1") AS "Result" from t1;
+SELECT Json_Make_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d") "Jbin_new", n "t1") AS "Result" from t1;
SELECT Json_File(Json_Object_Add(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"), 5 "e")) AS "Result";
SELECT Json_Object_Add(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"), 5 "e") AS "Result" from t1;
SELECT Json_Object_Add(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"), n "n") AS "Result" from t1;
@@ -167,13 +167,13 @@ SELECT Json_File('bt2.json');
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
SELECT Json_Serialize(Jbin_Item_Merge(Jbin_File('bt2.json'), Jbin_Object(4 "d",5 "e",6 "f"))) AS "Result";
SELECT Json_File(Json_Item_Merge(Jbin_File('bt2.json'), Jbin_Object(4 "d",5 "e",6 "f"))) AS "Result";
-SELECT Json_Item_Merge(Json_Object(1 "a", 2 "b", 3 "c"), Json_Object(4 "d",5 "b",6 "f")) AS "Result";
+SELECT Json_Item_Merge(Json_Make_Object(1 "a", 2 "b", 3 "c"), Json_Make_Object(4 "d",5 "b",6 "f")) AS "Result";
#
-SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'b')) AS "Result";
-SELECT Json_Object(Jbin_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
-SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
-SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jfile_bt1") AS "Result";
-SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'a') "Jbin_bt1", n "t1") AS "Result" from t1;
+SELECT Json_Make_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'b')) AS "Result";
+SELECT Json_Make_Object(Jbin_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
+SELECT Json_Make_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
+SELECT Json_Make_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jfile_bt1") AS "Result";
+SELECT Json_Make_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'a') "Jbin_bt1", n "t1") AS "Result" from t1;
#
SELECT Json_Serialize(Jbin_Object_List(Jbin_File('bt2.json'))) "Key list";
@@ -181,9 +181,9 @@ SELECT Json_Serialize(Jbin_Object_List(Jbin_File('bt2.json'))) "Key list";
# Test documentation examples
#
SELECT Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0);
-SELECT Json_Array_Add(Json_File('bt3.json', 'b'), 66);
-SELECT Json_Array_Add(Json_File('bt3.json'), 66, 'b');
-SELECT Json_Array_Add(Jbin_File('bt3.json', 'b'), 66);
+SELECT Json_Array_Add(Json_File('bt3.json', '$.b'), 66);
+SELECT Json_Array_Add(Json_File('bt3.json'), 66, '$.b');
+SELECT Json_Array_Add(Jbin_File('bt3.json', '$.b'), 66);
SELECT Json_File('bt3.json', 3);
SELECT Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0);
#
@@ -193,11 +193,11 @@ CREATE TABLE t2 (
ENGINE= MYISAM;
INSERT INTO t2 VALUES(1,'bt3.json');
--echo # In this table, the jfile_cols column just contains a file name
-UPDATE t2 SET jfile_cols = Json_Array_Add(Jbin_File('bt3.json', 'b'), 66) WHERE n = 1;
+UPDATE t2 SET jfile_cols = Json_Array_Add(Jbin_File('bt3.json', '$.b'), 66) WHERE n = 1;
SELECT JsonGet_String(jfile_cols, '*') FROM t2;
-UPDATE t2 SET jfile_cols = Json_Insert_Item(jfile_cols, 77, 'b:[]') WHERE n = 1;
-SELECT JsonGet_String(jfile_cols, 'b:*') FROM t2;
-UPDATE t2 SET jfile_cols = Json_Insert_Item(Jbin_Insert_Item(jfile_cols, 88, 'b:') , 99, 'b:') WHERE n = 1;
+UPDATE t2 SET jfile_cols = Json_Insert_Item(jfile_cols, 77, '$.b[]') WHERE n = 1;
+SELECT JsonGet_String(jfile_cols, '$.b.*') FROM t2;
+UPDATE t2 SET jfile_cols = Json_Insert_Item(Jbin_Insert_Item(jfile_cols, 88, '$.b[]') , 99, '$.b[]') WHERE n = 1;
SELECT JsonGet_String(jfile_cols, '*') FROM t2;
DROP TABLE t1, t2;
@@ -210,3 +210,4 @@ DROP TABLE t1, t2;
--remove_file $MYSQLD_DATADIR/bt1.json
--remove_file $MYSQLD_DATADIR/bt2.json
--remove_file $MYSQLD_DATADIR/bt3.json
+
diff --git a/storage/connect/mysql-test/connect/t/mul_new.test b/storage/connect/mysql-test/connect/t/mul_new.test
new file mode 100644
index 00000000000..33011f6c6a7
--- /dev/null
+++ b/storage/connect/mysql-test/connect/t/mul_new.test
@@ -0,0 +1,67 @@
+let $MYSQLD_DATADIR= `select @@datadir`;
+--mkdir $MYSQLD_DATADIR/test/subdir/
+
+--echo #
+--echo # Testing multiple 1
+--echo #
+CREATE TABLE t1 (
+ Chiffre int(3) NOT NULL,
+ Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='num1.csv' LRECL=20 HEADER=1;
+INSERT INTO t1 VALUES(1,'One'),(2,'Two'),(3,'Three'),(4,'Four'),(5,'Five'),(6,'Six');
+SELECT * FROM t1;
+
+CREATE TABLE t2 (
+ Chiffre int(3) NOT NULL,
+ Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE='CSV' FILE_NAME='subdir/num2.csv' LRECL=20 HEADER=1;
+INSERT INTO t2 VALUES(7,'Seven'),(8,'Eight'),(9,'Nine'),(10,'Ten'),(11,'Eleven'),(12,'Twelve');
+SELECT * FROM t2;
+
+CREATE TABLE t3 (
+ Chiffre int(3) NOT NULL,
+ Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE='CSV' FILE_NAME='num3.csv' LRECL=20 HEADER=1;
+INSERT INTO t3 VALUES(13,'Thirteen'),(14,'Fourteen'),(15,'Fifteen'),(16,'Sixteen'),(17,'Seventeen'),(18,'Eighteen');
+SELECT * FROM t3;
+
+CREATE TABLE t4 (
+ Chiffre int(3) NOT NULL,
+ Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE='CSV' FILE_NAME='subdir/num4.csv' LRECL=20 HEADER=1;
+INSERT INTO t4 VALUES(19,'Nineteen'),(20,'Twenty'),(21,'Twenty one'),(22,'Twenty two'),(23,'Tenty three'),(24,'Twenty four');
+SELECT * FROM t4;
+
+CREATE TABLE t5 (
+ Chiffre int(3) NOT NULL,
+ Lettre char(16) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE='CSV' FILE_NAME='num5.csv' LRECL=20 HEADER=1;
+INSERT INTO t5 VALUES(25,'Twenty five'),(26,'Twenty six'),(27,'Twenty seven'),(28,'Twenty eight'),(29,'Tenty eight'),(30,'Thirty');
+SELECT * FROM t5;
+
+CREATE TABLE t_all (
+ Chiffre int(3) not null,
+ Lettre char(16) not null)
+ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='num?.csv' HEADER=1 LRECL=20 MULTIPLE=1;
+SELECT * FROM t_all ORDER BY Chiffre;
+
+--echo #
+--echo # Testing multiple 3
+--echo #
+ALTER TABLE t_all MULTIPLE=3;
+SELECT * FROM t_all ORDER BY Chiffre;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+DROP TABLE t5;
+DROP TABLE t_all;
+
+--remove_file $MYSQLD_DATADIR/test/subdir/num2.csv
+--remove_file $MYSQLD_DATADIR/test/subdir/num4.csv
+--rmdir $MYSQLD_DATADIR/test/subdir/
+--remove_file $MYSQLD_DATADIR/test/num1.csv
+--remove_file $MYSQLD_DATADIR/test/num3.csv
+--remove_file $MYSQLD_DATADIR/test/num5.csv
+
diff --git a/storage/connect/mysql-test/connect/t/mysql_new.test b/storage/connect/mysql-test/connect/t/mysql_new.test
index db9b1b704fc..de9cae7b87b 100644
--- a/storage/connect/mysql-test/connect/t/mysql_new.test
+++ b/storage/connect/mysql-test/connect/t/mysql_new.test
@@ -306,7 +306,7 @@ DROP TABLE t1;
CREATE TABLE t1 (a date, b datetime, c time, d timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, e year);
SHOW CREATE TABLE t1;
-INSERT IGNORE INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
+INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
SELECT * FROM t1;
connection master;
diff --git a/storage/connect/mysql-test/connect/t/secure_file_priv.test b/storage/connect/mysql-test/connect/t/secure_file_priv.test
index f7792536892..46633502034 100644
--- a/storage/connect/mysql-test/connect/t/secure_file_priv.test
+++ b/storage/connect/mysql-test/connect/t/secure_file_priv.test
@@ -10,4 +10,4 @@ let $SECUREDIR= `select @@secure_file_priv`;
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
DROP TABLE t1;
---remove_file $MYSQL_TMP_DIR/t1.dbf
+--remove_file $SECUREDIR/t1.dbf
diff --git a/storage/connect/mysql-test/connect/t/unsigned.test b/storage/connect/mysql-test/connect/t/unsigned.test
index 48f6bdc835c..44eb832f8ae 100644
--- a/storage/connect/mysql-test/connect/t/unsigned.test
+++ b/storage/connect/mysql-test/connect/t/unsigned.test
@@ -13,9 +13,9 @@ INSERT INTO t1(a,b,c,d) VALUES(255,65535,4294967295,18446744073709551615);
SELECT * FROM t1;
UPDATE t1 SET e = d;
SELECT * FROM t1;
-UPDATE IGNORE t1 SET c = d;
+UPDATE t1 SET c = d;
SELECT * FROM t1;
-UPDATE IGNORE t1 SET c = e;
+UPDATE t1 SET c = e;
SELECT * FROM t1;
UPDATE t1 SET d = e;
SELECT * FROM t1;
diff --git a/storage/connect/mysql-test/connect/t/upd.test b/storage/connect/mysql-test/connect/t/upd.test
index 28b566b5641..a3716694c4a 100644
--- a/storage/connect/mysql-test/connect/t/upd.test
+++ b/storage/connect/mysql-test/connect/t/upd.test
@@ -1,8 +1,6 @@
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/employee.dat $MYSQLD_DATADIR/test/employee.dat
-SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
-
CREATE TABLE employee
(
serialno CHAR(5) NOT NULL,
@@ -152,6 +150,4 @@ CALL test.tst_up();
DROP PROCEDURE test.tst_up;
DROP TABLE employee;
-SET sql_mode = DEFAULT;
-
--remove_file $MYSQLD_DATADIR/test/employee.dat
diff --git a/storage/connect/mysql-test/connect/t/vcol.test b/storage/connect/mysql-test/connect/t/vcol.test
deleted file mode 100644
index 0ed13c0e340..00000000000
--- a/storage/connect/mysql-test/connect/t/vcol.test
+++ /dev/null
@@ -1,26 +0,0 @@
-let datadir= `select @@datadir`;
---copy_file $MTR_SUITE_DIR/std_data/boys.txt $datadir/test/boys.txt
-
-create table t1 (
- #linenum int(6) not null default 0 special=rowid,
- name char(12) not null,
- city char(11) not null,
- birth date not null date_format='DD/MM/YYYY',
- hired date not null date_format='DD/MM/YYYY' flag=36,
- agehired int(3) as (floor(datediff(hired,birth)/365.25))
- )
-engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47;
-select * from t1;
-drop table t1;
-
---error ER_NULL_COLUMN_IN_INDEX
-create table t1 (
- #linenum int(6) not null default 0 special=rowid,
- name char(12) not null,
- city char(11) not null,
- birth date not null date_format='DD/MM/YYYY',
- hired date not null date_format='DD/MM/YYYY' flag=36,
- agehired int(3) as (floor(datediff(hired,birth)/365.25)),
- index (agehired)
- )
-engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47;
diff --git a/storage/connect/mysql-test/connect/t/zip.test b/storage/connect/mysql-test/connect/t/zip.test
index a4892e9ed4e..dce68c17eee 100644
--- a/storage/connect/mysql-test/connect/t/zip.test
+++ b/storage/connect/mysql-test/connect/t/zip.test
@@ -83,16 +83,16 @@ DROP TABLE t1,t2,t3,t4;
--echo #
CREATE TABLE t1 (
_id INT(2) NOT NULL,
-name_first CHAR(9) NOT NULL FIELD_FORMAT='name:first',
-name_aka CHAR(4) DEFAULT NULL FIELD_FORMAT='name:aka',
-name_last CHAR(10) NOT NULL FIELD_FORMAT='name:last',
+name_first CHAR(9) NOT NULL FIELD_FORMAT='$.name.first',
+name_aka CHAR(4) DEFAULT NULL FIELD_FORMAT='$.name.aka',
+name_last CHAR(10) NOT NULL FIELD_FORMAT='$.name.last',
title CHAR(12) DEFAULT NULL,
birth CHAR(20) DEFAULT NULL,
death CHAR(20) DEFAULT NULL,
-contribs CHAR(7) NOT NULL FIELD_FORMAT='contribs:',
-awards_award CHAR(42) DEFAULT NULL FIELD_FORMAT='awards::award',
-awards_year CHAR(4) DEFAULT NULL FIELD_FORMAT='awards::year',
-awards_by CHAR(38) DEFAULT NULL FIELD_FORMAT='awards::by'
+contribs CHAR(7) NOT NULL FIELD_FORMAT='$.contribs',
+awards_award CHAR(42) DEFAULT NULL FIELD_FORMAT='$.awards.award',
+awards_year CHAR(4) DEFAULT NULL FIELD_FORMAT='$.awards.year',
+awards_by CHAR(38) DEFAULT NULL FIELD_FORMAT='$.awards.by'
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bios.zip' OPTION_LIST='ENTRY=bios.json,LOAD=bios.json' ZIPPED=YES;
SELECT * FROM t1;
@@ -104,16 +104,16 @@ SELECT * FROM t2;
CREATE TABLE t3 (
_id INT(2) NOT NULL,
-firstname CHAR(9) NOT NULL FIELD_FORMAT='name:first',
-aka CHAR(4) DEFAULT NULL FIELD_FORMAT='name:aka',
-lastname CHAR(10) NOT NULL FIELD_FORMAT='name:last',
+firstname CHAR(9) NOT NULL FIELD_FORMAT='$.name.first',
+aka CHAR(4) DEFAULT NULL FIELD_FORMAT='$.name.aka',
+lastname CHAR(10) NOT NULL FIELD_FORMAT='$.name.last',
title CHAR(12) DEFAULT NULL,
birth date DEFAULT NULL date_format="YYYY-DD-MM'T'hh:mm:ss'Z'",
death date DEFAULT NULL date_format="YYYY-DD-MM'T'hh:mm:ss'Z'",
-contribs CHAR(64) NOT NULL FIELD_FORMAT='contribs:[", "]',
-award CHAR(42) DEFAULT NULL FIELD_FORMAT='awards:[x]:award',
-year CHAR(4) DEFAULT NULL FIELD_FORMAT='awards:[x]:year',
-`by` CHAR(38) DEFAULT NULL FIELD_FORMAT='awards:[x]:by'
+contribs CHAR(64) NOT NULL FIELD_FORMAT='$.contribs.[", "]',
+award CHAR(42) DEFAULT NULL FIELD_FORMAT='$.awards[*].award',
+year CHAR(4) DEFAULT NULL FIELD_FORMAT='$.awards[*].year',
+`by` CHAR(38) DEFAULT NULL FIELD_FORMAT='$.awards[*].by'
) ENGINE=CONNECT TABLE_TYPE='json' FILE_NAME='bios.zip' ZIPPED=YES;
SELECT * FROM t3 WHERE _id = 1;
diff --git a/storage/connect/myutil.cpp b/storage/connect/myutil.cpp
index d4416e188c8..c2053f1c832 100644
--- a/storage/connect/myutil.cpp
+++ b/storage/connect/myutil.cpp
@@ -42,7 +42,8 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_INT;
else if (!stricmp(typname, "smallint"))
type = TYPE_SHORT;
- else if (!stricmp(typname, "char") || !stricmp(typname, "varchar"))
+ else if (!stricmp(typname, "char") || !stricmp(typname, "varchar") ||
+ !stricmp(typname, "enum") || !stricmp(typname, "set"))
type = TYPE_STRING;
else if (!stricmp(typname, "double") || !stricmp(typname, "float") ||
!stricmp(typname, "real"))
@@ -87,10 +88,12 @@ int MYSQLtoPLG(char *typname, char *var)
else if (!stricmp(typname, "year"))
*var = 'Y';
- } else if (type == TYPE_STRING && !stricmp(typname, "varchar"))
- // This is to make the difference between CHAR and VARCHAR
- *var = 'V';
- else if (type == TYPE_ERROR && xconv == TPC_SKIP)
+ } else if (type == TYPE_STRING) {
+ if (!stricmp(typname, "varchar"))
+ // This is to make the difference between CHAR and VARCHAR
+ *var = 'V';
+
+ } else if (type == TYPE_ERROR && xconv == TPC_SKIP)
*var = 'K';
else
*var = 0;
@@ -266,9 +269,9 @@ int MYSQLtoPLG(int mytype, char *var)
/************************************************************************/
/* Returns the format corresponding to a MySQL date type number. */
/************************************************************************/
-char *MyDateFmt(int mytype)
+PCSZ MyDateFmt(int mytype)
{
- char *fmt;
+ PCSZ fmt;
switch (mytype) {
case MYSQL_TYPE_TIMESTAMP:
@@ -294,9 +297,9 @@ char *MyDateFmt(int mytype)
/************************************************************************/
/* Returns the format corresponding to a MySQL date type name. */
/************************************************************************/
-char *MyDateFmt(char *typname)
+PCSZ MyDateFmt(char *typname)
{
- char *fmt;
+ PCSZ fmt;
if (!stricmp(typname, "datetime") || !stricmp(typname, "timestamp"))
fmt = "YYYY-MM-DD hh:mm:ss";
diff --git a/storage/connect/myutil.h b/storage/connect/myutil.h
index 9c22cfef118..6991172b39e 100644
--- a/storage/connect/myutil.h
+++ b/storage/connect/myutil.h
@@ -6,9 +6,9 @@
enum enum_field_types PLGtoMYSQL(int type, bool dbf, char var = 0);
const char *PLGtoMYSQLtype(int type, bool dbf, char var = 0);
-int MYSQLtoPLG(char *typname, char *var = NULL);
-int MYSQLtoPLG(int mytype, char *var = NULL);
-char *MyDateFmt(int mytype);
-char *MyDateFmt(char *typname);
+int MYSQLtoPLG(char *typname, char *var = NULL);
+int MYSQLtoPLG(int mytype, char *var = NULL);
+PCSZ MyDateFmt(int mytype);
+PCSZ MyDateFmt(char *typname);
#endif // __MYUTIL__H
diff --git a/storage/connect/odbccat.h b/storage/connect/odbccat.h
index 3b729bcb4bb..05b82e49727 100644
--- a/storage/connect/odbccat.h
+++ b/storage/connect/odbccat.h
@@ -3,11 +3,11 @@
#define DEFAULT_QUERY_TIMEOUT -1 // means do not set
typedef struct odbc_parms {
- char *User; // User connect info
- char *Pwd; // Password connect info
- int Cto; // Connect timeout
- int Qto; // Query timeout
- bool UseCnc; // Use SQLConnect (!SQLDriverConnect)
+ PCSZ User; // User connect info
+ PCSZ Pwd; // Password connect info
+ int Cto; // Connect timeout
+ int Qto; // Query timeout
+ bool UseCnc; // Use SQLConnect (!SQLDriverConnect)
} ODBCPARM, *POPARM;
/***********************************************************************/
@@ -17,9 +17,9 @@ typedef struct odbc_parms {
char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop);
#endif // PROMPT_OK
PQRYRES ODBCDataSources(PGLOBAL g, int maxres, bool info);
-PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
- char *colpat, int maxres, bool info, POPARM sop);
+PQRYRES ODBCColumns(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ table,
+ PCSZ colpat, int maxres, bool info, POPARM sop);
PQRYRES ODBCSrcCols(PGLOBAL g, char *dsn, char *src, POPARM sop);
-PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat,
- char *tabtyp, int maxres, bool info, POPARM sop);
+PQRYRES ODBCTables(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ tabpat,
+ PCSZ tabtyp, int maxres, bool info, POPARM sop);
PQRYRES ODBCDrivers(PGLOBAL g, int maxres, bool info);
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index 433e392eace..a1283998068 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -1,7 +1,7 @@
-/************ Odbconn C++ Functions Source Code File (.CPP) ************/
-/* Name: ODBCONN.CPP Version 2.2 */
+/***********************************************************************/
+/* Name: ODBCONN.CPP Version 2.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
/* */
/* This file contains the ODBC connection classes functions. */
/***********************************************************************/
@@ -239,47 +239,43 @@ char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop)
/***********************************************************************/
/* Allocate the structure used to refer to the result set. */
/***********************************************************************/
-static CATPARM *AllocCatInfo(PGLOBAL g, CATINFO fid, char *db,
- char *tab, PQRYRES qrp)
- {
- size_t i, m, n;
- CATPARM *cap;
+static CATPARM *AllocCatInfo(PGLOBAL g, CATINFO fid, PCSZ db,
+ PCSZ tab, PQRYRES qrp)
+{
+ size_t i, m, n;
+ CATPARM *cap;
#if defined(_DEBUG)
- assert(qrp);
+ assert(qrp);
#endif
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return NULL;
- } // endif jump_level
-
- if (setjmp(g->jumper[++g->jump_level]) != 0) {
- printf("%s\n", g->Message);
- cap = NULL;
- goto fin;
- } // endif rc
-
- m = (size_t)qrp->Maxres;
- n = (size_t)qrp->Nbcol;
- cap = (CATPARM *)PlugSubAlloc(g, NULL, sizeof(CATPARM));
- memset(cap, 0, sizeof(CATPARM));
- cap->Id = fid;
- cap->Qrp = qrp;
- cap->DB = (PUCHAR)db;
- cap->Tab = (PUCHAR)tab;
- cap->Vlen = (SQLLEN* *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN *));
-
- for (i = 0; i < n; i++)
- cap->Vlen[i] = (SQLLEN *)PlugSubAlloc(g, NULL, m * sizeof(SQLLEN));
-
- cap->Status = (UWORD *)PlugSubAlloc(g, NULL, m * sizeof(UWORD));
-
- fin:
- g->jump_level--;
- return cap;
- } // end of AllocCatInfo
+ try {
+ m = (size_t)qrp->Maxres;
+ n = (size_t)qrp->Nbcol;
+ cap = (CATPARM *)PlugSubAlloc(g, NULL, sizeof(CATPARM));
+ memset(cap, 0, sizeof(CATPARM));
+ cap->Id = fid;
+ cap->Qrp = qrp;
+ cap->DB = db;
+ cap->Tab = tab;
+ cap->Vlen = (SQLLEN* *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN *));
+
+ for (i = 0; i < n; i++)
+ cap->Vlen[i] = (SQLLEN *)PlugSubAlloc(g, NULL, m * sizeof(SQLLEN));
+
+ cap->Status = (UWORD *)PlugSubAlloc(g, NULL, m * sizeof(UWORD));
+
+ } catch (int n) {
+ htrc("Exeption %d: %s\n", n, g->Message);
+ cap = NULL;
+ } catch (const char *msg) {
+ htrc(g->Message, msg);
+ printf("%s\n", g->Message);
+ cap = NULL;
+ } // end catch
+
+ return cap;
+} // end of AllocCatInfo
#if 0
/***********************************************************************/
@@ -309,8 +305,8 @@ static void ResetNullValues(CATPARM *cap)
/* ODBCColumns: constructs the result blocks containing all columns */
/* of an ODBC table that will be retrieved by GetData commands. */
/***********************************************************************/
-PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
- char *colpat, int maxres, bool info, POPARM sop)
+PQRYRES ODBCColumns(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ table,
+ PCSZ colpat, int maxres, bool info, POPARM sop)
{
int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT,
@@ -383,7 +379,7 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
if (!(cap = AllocCatInfo(g, CAT_COL, db, table, qrp)))
return NULL;
- cap->Pat = (PUCHAR)colpat;
+ cap->Pat = colpat;
/************************************************************************/
/* Now get the results into blocks. */
@@ -618,8 +614,8 @@ PQRYRES ODBCDataSources(PGLOBAL g, int maxres, bool info)
/* ODBCTables: constructs the result blocks containing all tables in */
/* an ODBC database that will be retrieved by GetData commands. */
/**************************************************************************/
-PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat,
- char *tabtyp, int maxres, bool info, POPARM sop)
+PQRYRES ODBCTables(PGLOBAL g, PCSZ dsn, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
+ int maxres, bool info, POPARM sop)
{
int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_STRING, TYPE_STRING};
@@ -681,7 +677,7 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat,
if (!(cap = AllocCatInfo(g, CAT_TAB, db, tabpat, qrp)))
return NULL;
- cap->Pat = (PUCHAR)tabtyp;
+ cap->Pat = tabtyp;
if (trace)
htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol);
@@ -879,7 +875,7 @@ PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat,
/***********************************************************************/
/* Implementation of DBX class. */
/***********************************************************************/
-DBX::DBX(RETCODE rc, PSZ msg)
+DBX::DBX(RETCODE rc, PCSZ msg)
{
m_RC = rc;
m_Msg = msg;
@@ -1020,7 +1016,7 @@ bool ODBConn::Check(RETCODE rc)
/***********************************************************************/
/* DB exception throw routines. */
/***********************************************************************/
-void ODBConn::ThrowDBX(RETCODE rc, PSZ msg, HSTMT hstmt)
+void ODBConn::ThrowDBX(RETCODE rc, PCSZ msg, HSTMT hstmt)
{
DBX* xp = new(m_G) DBX(rc, msg);
@@ -1030,7 +1026,7 @@ void ODBConn::ThrowDBX(RETCODE rc, PSZ msg, HSTMT hstmt)
} // end of ThrowDBX
-void ODBConn::ThrowDBX(PSZ msg)
+void ODBConn::ThrowDBX(PCSZ msg)
{
DBX* xp = new(m_G) DBX(0, "Error");
@@ -1110,7 +1106,7 @@ void ODBConn::OnSetOptions(HSTMT hstmt)
/***********************************************************************/
/* Open: connect to a data source. */
/***********************************************************************/
-int ODBConn::Open(PSZ ConnectString, POPARM sop, DWORD options)
+int ODBConn::Open(PCSZ ConnectString, POPARM sop, DWORD options)
{
PGLOBAL& g = m_G;
//ASSERT_VALID(this);
@@ -1192,7 +1188,7 @@ void ODBConn::AllocConnect(DWORD Options)
#if defined(_DEBUG)
if (Options & traceSQL) {
- SQLSetConnectOption(m_hdbc, SQL_OPT_TRACEFILE, (DWORD)"xodbc.out");
+ SQLSetConnectOption(m_hdbc, SQL_OPT_TRACEFILE, (SQLULEN)"xodbc.out");
SQLSetConnectOption(m_hdbc, SQL_OPT_TRACE, 1);
} // endif
#endif // _DEBUG
@@ -1215,7 +1211,7 @@ void ODBConn::AllocConnect(DWORD Options)
// Turn on cursor lib support
if (Options & useCursorLib)
- rc = SQLSetConnectOption(m_hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_ODBC);
+ rc = SQLSetConnectOption(m_hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_DRIVER);
return;
} // end of AllocConnect
@@ -1921,7 +1917,7 @@ bool ODBConn::ExecSQLcommand(char *sql)
/* GetMetaData: constructs the result blocks containing the */
/* description of all the columns of an SQL command. */
/**************************************************************************/
-PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src)
+PQRYRES ODBConn::GetMetaData(PGLOBAL g, PCSZ dsn, PCSZ src)
{
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_INT,
TYPE_SHORT, TYPE_SHORT};
@@ -2244,7 +2240,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
void *buffer;
int i, irc;
bool b;
- PSZ fnc = "Unknown";
+ PCSZ fnc = "Unknown";
UWORD n;
SWORD ncol, len, tp;
SQLULEN crow = 0;
@@ -2283,22 +2279,20 @@ int ODBConn::GetCatInfo(CATPARM *cap)
// Now do call the proper ODBC API
switch (cap->Id) {
case CAT_TAB:
-// rc = SQLSetStmtAttr(hstmt, SQL_ATTR_METADATA_ID,
-// (SQLPOINTER)false, 0);
fnc = "SQLTables";
rc = SQLTables(hstmt, name.ptr(2), name.length(2),
name.ptr(1), name.length(1),
name.ptr(0), name.length(0),
- cap->Pat, cap->Pat ? SQL_NTS : 0);
+ (SQLCHAR *)cap->Pat,
+ cap->Pat ? SQL_NTS : 0);
break;
case CAT_COL:
-// rc = SQLSetStmtAttr(hstmt, SQL_ATTR_METADATA_ID,
-// (SQLPOINTER)true, 0);
fnc = "SQLColumns";
rc = SQLColumns(hstmt, name.ptr(2), name.length(2),
name.ptr(1), name.length(1),
name.ptr(0), name.length(0),
- cap->Pat, cap->Pat ? SQL_NTS : 0);
+ (SQLCHAR *)cap->Pat,
+ cap->Pat ? SQL_NTS : 0);
break;
case CAT_KEY:
fnc = "SQLPrimaryKeys";
@@ -2346,6 +2340,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
} // endif len
pval[n] = AllocateValue(g, crp->Type, len);
+ pval[n]->SetNullable(true);
if (crp->Type == TYPE_STRING) {
pbuf[n] = (char*)PlugSubAlloc(g, NULL, len);
diff --git a/storage/connect/odbconn.h b/storage/connect/odbconn.h
index 063985218ec..5abb8354160 100644
--- a/storage/connect/odbconn.h
+++ b/storage/connect/odbconn.h
@@ -54,9 +54,9 @@ enum CATINFO {CAT_TAB = 1, /* SQLTables */
typedef struct tagCATPARM {
CATINFO Id; // Id to indicate function
PQRYRES Qrp; // Result set pointer
- PUCHAR DB; // Database (Schema)
- PUCHAR Tab; // Table name or pattern
- PUCHAR Pat; // Table type or column pattern
+ PCSZ DB; // Database (Schema)
+ PCSZ Tab; // Table name or pattern
+ PCSZ Pat; // Table type or column pattern
SQLLEN* *Vlen; // To array of indicator values
UWORD *Status; // To status block
// For SQLStatistics
@@ -80,23 +80,23 @@ class DBX : public BLOCK {
friend class ODBConn;
// Construction (by ThrowDBX only) -- destruction
protected:
- DBX(RETCODE rc, PSZ msg = NULL);
+ DBX(RETCODE rc, PCSZ msg = NULL);
public:
//virtual ~DBX() {}
//void operator delete(void*, PGLOBAL, void*) {};
// Implementation (use ThrowDBX to create)
RETCODE GetRC(void) {return m_RC;}
- PSZ GetMsg(void) {return m_Msg;}
- const char *GetErrorMessage(int i);
+ PCSZ GetMsg(void) {return m_Msg;}
+ PCSZ GetErrorMessage(int i);
protected:
bool BuildErrorMessage(ODBConn* pdb, HSTMT hstmt = SQL_NULL_HSTMT);
// Attributes
RETCODE m_RC;
- PSZ m_Msg;
- PSZ m_ErrMsg[MAX_NUM_OF_MSG];
+ PCSZ m_Msg;
+ PCSZ m_ErrMsg[MAX_NUM_OF_MSG];
}; // end of DBX class definition
/***********************************************************************/
@@ -119,7 +119,7 @@ class ODBConn : public BLOCK {
noOdbcDialog = 0x0008, // Don't display ODBC Connect dialog
forceOdbcDialog = 0x0010}; // Always display ODBC connect dialog
- int Open(PSZ ConnectString, POPARM sop, DWORD Options = 0);
+ int Open(PCSZ ConnectString, POPARM sop, DWORD Options = 0);
int Rewind(char *sql, ODBCCOL *tocols);
void Close(void);
PQRYRES AllocateResult(PGLOBAL g);
@@ -131,7 +131,7 @@ class ODBConn : public BLOCK {
bool IsOpen(void) {return m_hdbc != SQL_NULL_HDBC;}
PSZ GetStringInfo(ushort infotype);
int GetMaxValue(ushort infotype);
- PSZ GetConnect(void) {return m_Connect;}
+ PCSZ GetConnect(void) {return m_Connect;}
public:
// Operations
@@ -149,7 +149,7 @@ class ODBConn : public BLOCK {
int GetCatInfo(CATPARM *cap);
bool GetDataSources(PQRYRES qrp);
bool GetDrivers(PQRYRES qrp);
- PQRYRES GetMetaData(PGLOBAL g, char *dsn, char *src);
+ PQRYRES GetMetaData(PGLOBAL g, PCSZ dsn, PCSZ src);
public:
// Set special options
@@ -162,8 +162,8 @@ class ODBConn : public BLOCK {
// ODBC operations
protected:
bool Check(RETCODE rc);
- void ThrowDBX(RETCODE rc, PSZ msg, HSTMT hstmt = SQL_NULL_HSTMT);
- void ThrowDBX(PSZ msg);
+ void ThrowDBX(RETCODE rc, PCSZ msg, HSTMT hstmt = SQL_NULL_HSTMT);
+ void ThrowDBX(PCSZ msg);
void AllocConnect(DWORD dwOptions);
void Connect(void);
bool DriverConnect(DWORD Options);
@@ -187,9 +187,9 @@ class ODBConn : public BLOCK {
DWORD m_UpdateOptions;
DWORD m_RowsetSize;
char m_IDQuoteChar[2];
- PSZ m_Connect;
- PSZ m_User;
- PSZ m_Pwd;
+ PCSZ m_Connect;
+ PCSZ m_User;
+ PCSZ m_Pwd;
int m_Catver;
int m_Rows;
int m_Fetch;
diff --git a/storage/connect/os.h b/storage/connect/os.h
index 2dc603fdcda..8056a272990 100644
--- a/storage/connect/os.h
+++ b/storage/connect/os.h
@@ -17,13 +17,16 @@ typedef off_t off64_t;
#if defined(__WIN__)
typedef __int64 BIGINT;
+typedef _Null_terminated_ const char *PCSZ;
#else // !__WIN__
typedef longlong BIGINT;
#define FILE_BEGIN SEEK_SET
#define FILE_CURRENT SEEK_CUR
#define FILE_END SEEK_END
+typedef const char *PCSZ;
#endif // !__WIN__
+
#if !defined(__WIN__)
typedef const void *LPCVOID;
typedef const char *LPCTSTR;
diff --git a/storage/connect/osutil.c b/storage/connect/osutil.c
index 2e9e120b0c8..66743c7403b 100644
--- a/storage/connect/osutil.c
+++ b/storage/connect/osutil.c
@@ -43,34 +43,6 @@ PSZ strlwr(PSZ p)
return (p);
} /* end of strlwr */
-#if defined(NOT_USED) /*&& !defined(sun) && !defined(LINUX) && !defined(AIX)*/
-/***********************************************************************/
-/* Define stricmp function not existing in some UNIX libraries. */
-/***********************************************************************/
-int stricmp(char *str1, char *str2)
- {
- register int i;
- int n;
- char c;
- char *sup1 = malloc(strlen(str1) + 1);
- char *sup2 = malloc(strlen(str2) + 1);
-
- for (i = 0; c = str1[i]; i++)
- sup1[i] = toupper(c);
-
- sup1[i] = 0;
-
- for (i = 0; c = str2[i]; i++)
- sup2[i] = toupper(c);
-
- sup2[i] = 0;
- n = strcmp(sup1, sup2);
- free(sup1);
- free(sup2);
- return (n);
- } /* end of stricmp */
-#endif /* sun */
-
/***********************************************************************/
/* Define the splitpath function not existing in the UNIX library. */
/***********************************************************************/
@@ -143,13 +115,6 @@ my_bool CloseFileHandle(HANDLE h)
return (close(h)) ? TRUE : FALSE;
} /* end of CloseFileHandle */
-#if 0
-void Sleep(DWORD time)
- {
- //FIXME: TODO
- } /* end of Sleep */
-#endif
-
int GetLastError()
{
return errno;
@@ -210,21 +175,4 @@ BOOL MessageBeep(uint i __attribute__((unused)))
return TRUE;
} /* end of MessageBeep */
-#if 0
-/* This function is ridiculous and should be revisited */
-DWORD FormatMessage(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId,
- DWORD dwLanguageId, LPSTR lpBuffer, DWORD nSize, ...)
- {
- char buff[32];
- int n;
-
-//if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER)
-// return 0; /* means error */
-
- n = sprintf(buff, "Error code: %d", (int) dwMessageId);
- strncpy(lpBuffer, buff, nSize);
- return min(n, nSize);
- } /* end of FormatMessage */
-#endif
-
#endif // UNIX
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 800b1098d50..7308ab6ad8b 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -36,8 +36,6 @@ enum BLKTYP {TYPE_TABLE = 50, /* Table Name/Srcdef/... Block */
TYPE_COLCRT = 71, /* Column creation block */
TYPE_CONST = 72, /* Constant */
-/*-------------------- type tokenized string --------------------------*/
- TYPE_DATE = 8, /* Timestamp */
/*-------------------- additional values used by LNA ------------------*/
TYPE_COLIST = 14, /* Column list */
TYPE_COL = 41, /* Column */
@@ -80,7 +78,8 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
TAB_DMY = 25, /* DMY Dummy tables NIY */
TAB_JDBC = 26, /* Table accessed via JDBC */
TAB_ZIP = 27, /* ZIP file info table */
- TAB_NIY = 28}; /* Table not implemented yet */
+ TAB_MONGO = 28, /* Table retrieved from MongoDB */
+ TAB_NIY = 30}; /* Table not implemented yet */
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_ROWID = 1, /* ROWID type (special column) */
@@ -143,7 +142,8 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_MYX = 193, /* MYSQL EXEC access method type */
TYPE_AM_CAT = 195, /* Catalog access method type no */
TYPE_AM_ZIP = 198, /* ZIP access method type no */
- TYPE_AM_OUT = 200}; /* Output relations (storage) */
+ TYPE_AM_MGO = 199, /* MGO access method type no */
+ TYPE_AM_OUT = 200}; /* Output relations (storage) */
enum RECFM {RECFM_NAF = -2, /* Not a file */
RECFM_OEM = -1, /* OEM file access method */
@@ -553,7 +553,7 @@ typedef struct _qryres {
typedef struct _colres {
PCOLRES Next; /* To next result column */
PCOL Colp; /* To matching column block */
- PSZ Name; /* Column header */
+ PCSZ Name; /* Column header */
PVBLK Kdata; /* Column block of values */
char *Nulls; /* Column null value array */
int Type; /* Internal type */
@@ -583,7 +583,7 @@ void PlugLineDB(PGLOBAL, PSZ, short, void *, uint);
char *SetPath(PGLOBAL g, const char *path);
char *ExtractFromPath(PGLOBAL, char *, char *, OPVAL);
void AddPointer(PTABS, void *);
-PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int);
+PDTP MakeDateFormat(PGLOBAL, PCSZ, bool, bool, int);
int ExtractDate(char *, PDTP, int, int val[6]);
/**************************************************************************/
@@ -615,11 +615,10 @@ DllExport void *PlgDBrealloc(PGLOBAL, void *, MBLOCK&, size_t);
DllExport void NewPointer(PTABS, void *, void *);
//lExport char *GetIni(int n= 0); // Not used anymore
DllExport void SetTrc(void);
-DllExport char *GetListOption(PGLOBAL, const char *, const char *,
- const char *def=NULL);
-DllExport char *GetStringTableOption(PGLOBAL, PTOS, char *, char *);
-DllExport bool GetBooleanTableOption(PGLOBAL, PTOS, char *, bool);
-DllExport int GetIntegerTableOption(PGLOBAL, PTOS, char *, int);
+DllExport PCSZ GetListOption(PGLOBAL, PCSZ, PCSZ, PCSZ def=NULL);
+DllExport PCSZ GetStringTableOption(PGLOBAL, PTOS, PCSZ, PCSZ);
+DllExport bool GetBooleanTableOption(PGLOBAL, PTOS, PCSZ, bool);
+DllExport int GetIntegerTableOption(PGLOBAL, PTOS, PCSZ, int);
#define MSGID_NONE 0
#define MSGID_CANNOT_OPEN 1
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index 1910cdcdec8..c02c435baed 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -238,88 +238,84 @@ void ptrc(char const *fmt, ...)
PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
int *buftyp, XFLD *fldtyp,
unsigned int *length, bool blank, bool nonull)
- {
+{
char cname[NAM_LEN+1];
int i;
PCOLRES *pcrp, crp;
PQRYRES qrp;
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return NULL;
- } // endif jump_level
-
- if (setjmp(g->jumper[++g->jump_level]) != 0) {
- printf("%s\n", g->Message);
- qrp = NULL;
- goto fin;
- } // endif rc
-
- /************************************************************************/
- /* Allocate the structure used to contain the result set. */
- /************************************************************************/
- qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES));
- pcrp = &qrp->Colresp;
- qrp->Continued = false;
- qrp->Truncated = false;
- qrp->Info = false;
- qrp->Suball = true;
- qrp->Maxres = maxres;
- qrp->Maxsize = 0;
- qrp->Nblin = 0;
- qrp->Nbcol = 0; // will be ncol
- qrp->Cursor = 0;
- qrp->BadLines = 0;
-
- for (i = 0; i < ncol; i++) {
- *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
- crp = *pcrp;
- pcrp = &crp->Next;
- memset(crp, 0, sizeof(COLRES));
- crp->Colp = NULL;
- crp->Ncol = ++qrp->Nbcol;
- crp->Type = buftyp[i];
- crp->Length = length[i];
- crp->Clen = GetTypeSize(crp->Type, length[i]);
- crp->Prec = 0;
-
- if (ids > 0) {
+ try {
+ /**********************************************************************/
+ /* Allocate the structure used to contain the result set. */
+ /**********************************************************************/
+ qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES));
+ pcrp = &qrp->Colresp;
+ qrp->Continued = false;
+ qrp->Truncated = false;
+ qrp->Info = false;
+ qrp->Suball = true;
+ qrp->Maxres = maxres;
+ qrp->Maxsize = 0;
+ qrp->Nblin = 0;
+ qrp->Nbcol = 0; // will be ncol
+ qrp->Cursor = 0;
+ qrp->BadLines = 0;
+
+ for (i = 0; i < ncol; i++) {
+ *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
+ crp = *pcrp;
+ pcrp = &crp->Next;
+ memset(crp, 0, sizeof(COLRES));
+ crp->Colp = NULL;
+ crp->Ncol = ++qrp->Nbcol;
+ crp->Type = buftyp[i];
+ crp->Length = length[i];
+ crp->Clen = GetTypeSize(crp->Type, length[i]);
+ crp->Prec = 0;
+
+ if (ids > 0) {
#if defined(XMSG)
- // Get header from message file
- strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN);
- cname[NAM_LEN] = 0; // for truncated long names
+ // Get header from message file
+ strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN);
+ cname[NAM_LEN] = 0; // for truncated long names
#else // !XMSG
- GetRcString(ids + crp->Ncol, cname, sizeof(cname));
+ GetRcString(ids + crp->Ncol, cname, sizeof(cname));
#endif // !XMSG
- crp->Name = (PSZ)PlugDup(g, cname);
- } else
- crp->Name = NULL; // Will be set by caller
+ crp->Name = (PSZ)PlugDup(g, cname);
+ } else
+ crp->Name = NULL; // Will be set by caller
- if (fldtyp)
- crp->Fld = fldtyp[i];
- else
- crp->Fld = FLD_NO;
+ if (fldtyp)
+ crp->Fld = fldtyp[i];
+ else
+ crp->Fld = FLD_NO;
- // Allocate the Value Block that will contain data
- if (crp->Length || nonull)
- crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
- crp->Length, 0, true, blank, false);
- else
- crp->Kdata = NULL;
+ // Allocate the Value Block that will contain data
+ if (crp->Length || nonull)
+ crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
+ crp->Length, 0, true, blank, false);
+ else
+ crp->Kdata = NULL;
- if (trace)
- htrc("Column(%d) %s type=%d len=%d value=%p\n",
- crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata);
+ if (trace)
+ htrc("Column(%d) %s type=%d len=%d value=%p\n",
+ crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata);
- } // endfor i
+ } // endfor i
- *pcrp = NULL;
+ *pcrp = NULL;
- fin:
- g->jump_level--;
- return qrp;
- } // end of PlgAllocResult
+ } catch (int n) {
+ htrc("Exception %d: %s\n", n, g->Message);
+ qrp = NULL;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ htrc("%s\n", g->Message);
+ qrp = NULL;
+ } // end catch
+
+ return qrp;
+} // end of PlgAllocResult
/***********************************************************************/
/* Allocate and initialize the new DB User Block. */
@@ -365,8 +361,8 @@ PCATLG PlgGetCatalog(PGLOBAL g, bool jump)
if (!cat && jump) {
// Raise exception so caller doesn't have to check return value
strcpy(g->Message, MSG(NO_ACTIVE_DB));
- longjmp(g->jumper[g->jump_level], 1);
- } // endif cat
+ throw 1;
+ } // endif cat
return cat;
} // end of PlgGetCatalog
@@ -391,26 +387,27 @@ char *SetPath(PGLOBAL g, const char *path)
char *buf= NULL;
if (path) {
- size_t len= strlen(path) + (*path != '.' ? 4 : 1);
+ size_t len = strlen(path) + (*path != '.' ? 4 : 1);
+
+ if (!(buf = (char*)PlgDBSubAlloc(g, NULL, len)))
+ return NULL;
- buf= (char*)PlugSubAlloc(g, NULL, len);
-
if (PlugIsAbsolutePath(path)) {
- strcpy(buf, path);
- return buf;
- } // endif path
+ strcpy(buf, path);
+ return buf;
+ } // endif path
if (*path != '.') {
#if defined(__WIN__)
- char *s= "\\";
+ const char *s = "\\";
#else // !__WIN__
- char *s= "/";
+ const char *s = "/";
#endif // !__WIN__
strcat(strcat(strcat(strcpy(buf, "."), s), path), s);
} else
strcpy(buf, path);
- } // endif path
+ } // endif path
return buf;
} // end of SetPath
@@ -448,7 +445,7 @@ char *ExtractFromPath(PGLOBAL g, char *pBuff, char *FileName, OPVAL op)
static bool PlugCheckPattern(PGLOBAL g, LPCSTR string, LPCSTR pat)
{
if (pat && strlen(pat)) {
- // This leaves 512 bytes (MAX_STR / 2) for each components
+ // This leaves 2048 bytes (MAX_STR / 2) for each components
LPSTR name = g->Message + MAX_STR / 2;
strlwr(strcpy(name, string));
@@ -476,8 +473,8 @@ bool PlugEvalLike(PGLOBAL g, LPCSTR strg, LPCSTR pat, bool ci)
tp = g->Message;
else if (!(tp = new char[strlen(pat) + strlen(strg) + 2])) {
strcpy(g->Message, MSG(NEW_RETURN_NULL));
- longjmp(g->jumper[g->jump_level], OP_LIKE);
- } /* endif tp */
+ throw OP_LIKE;
+ } /* endif tp */
sp = tp + strlen(pat) + 1;
strlwr(strcpy(tp, pat)); /* Make a lower case copy of pat */
@@ -487,8 +484,8 @@ bool PlugEvalLike(PGLOBAL g, LPCSTR strg, LPCSTR pat, bool ci)
tp = g->Message; /* Use this as temporary work space. */
else if (!(tp = new char[strlen(pat) + 1])) {
strcpy(g->Message, MSG(NEW_RETURN_NULL));
- longjmp(g->jumper[g->jump_level], OP_LIKE);
- } /* endif tp */
+ throw OP_LIKE;
+ } /* endif tp */
strcpy(tp, pat); /* Make a copy to be worked into */
sp = (char*)strg;
@@ -676,7 +673,7 @@ void PlugConvertConstant(PGLOBAL g, void* & value, short& type)
/* format and a Strftime output format. Flag if not 0 indicates that */
/* non quoted blanks are not included in the output format. */
/***********************************************************************/
-PDTP MakeDateFormat(PGLOBAL g, PSZ dfmt, bool in, bool out, int flag)
+PDTP MakeDateFormat(PGLOBAL g, PCSZ dfmt, bool in, bool out, int flag)
{
int rc;
PDTP pdp = (PDTP)PlugSubAlloc(g, NULL, sizeof(DATPAR));
@@ -685,7 +682,7 @@ PDTP MakeDateFormat(PGLOBAL g, PSZ dfmt, bool in, bool out, int flag)
htrc("MakeDateFormat: dfmt=%s\n", dfmt);
memset(pdp, 0, sizeof(DATPAR));
- pdp->Format = pdp->Curp = dfmt;
+ pdp->Format = pdp->Curp = PlugDup(g, dfmt);
pdp->Outsize = 2 * strlen(dfmt) + 1;
if (in)
@@ -727,10 +724,11 @@ PDTP MakeDateFormat(PGLOBAL g, PSZ dfmt, bool in, bool out, int flag)
/***********************************************************************/
int ExtractDate(char *dts, PDTP pdp, int defy, int val[6])
{
- char *fmt, c, d, e, W[8][12];
- int i, k, m, numval;
- int n, y = 30;
- bool b = true; // true for null dates
+ PCSZ fmt;
+ char c, d, e, W[8][12];
+ int i, k, m, numval;
+ int n, y = 30;
+ bool b = true; // true for null dates
if (pdp)
fmt = pdp->InFmt;
@@ -1255,7 +1253,7 @@ void *PlgDBalloc(PGLOBAL g, void *area, MBLOCK& mp)
// in the area, do allocate from virtual storage.
#if defined(__WIN__)
if (mp.Size >= BIGMEM)
- mp.Memp = VirtualAlloc(NULL, mp.Size, MEM_COMMIT, PAGE_READWRITE);
+ mp.Memp = VirtualAlloc(NULL, mp.Size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
else
#endif
mp.Memp = malloc(mp.Size);
@@ -1494,7 +1492,7 @@ void PlugPutOut(PGLOBAL g, FILE *f, short t, void *v, uint n)
case TYPE_TABLE:
case TYPE_TDB:
case TYPE_XOBJECT:
- ((PBLOCK)v)->Print(g, f, n-2);
+ ((PBLOCK)v)->Printf(g, f, n-2);
break;
default:
@@ -1520,8 +1518,8 @@ DllExport void NewPointer(PTABS t, void *oldv, void *newv)
PGLOBAL g = t->G;
sprintf(g->Message, "NewPointer: %s", MSG(MEM_ALLOC_ERROR));
- longjmp(g->jumper[g->jump_level], 3);
- } else {
+ throw 3;
+ } else {
tp->Next = t->P1;
tp->Num = 0;
t->P1 = tp;
@@ -1557,15 +1555,15 @@ int FileComp(PGLOBAL g, char *file1, char *file2)
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"rb", (int)errno, fn[i]);
strcat(strcat(g->Message, ": "), strerror(errno));
- longjmp(g->jumper[g->jump_level], 666);
-// } else
+ throw 666;
+ // } else
// len[i] = 0; // File does not exist yet
} else {
if ((len[i] = _filelength(h[i])) < 0) {
sprintf(g->Message, MSG(FILELEN_ERROR), "_filelength", fn[i]);
- longjmp(g->jumper[g->jump_level], 666);
- } // endif len
+ throw 666;
+ } // endif len
} // endif h
diff --git a/storage/connect/plgxml.cpp b/storage/connect/plgxml.cpp
index eb31e24235b..f3d3a010266 100644
--- a/storage/connect/plgxml.cpp
+++ b/storage/connect/plgxml.cpp
@@ -45,7 +45,7 @@ XMLDOCUMENT::XMLDOCUMENT(char *nsl, char *nsdf, char *enc)
/******************************************************************/
/* Initialize zipped file processing. */
/******************************************************************/
-bool XMLDOCUMENT::InitZip(PGLOBAL g, char *entry)
+bool XMLDOCUMENT::InitZip(PGLOBAL g, PCSZ entry)
{
#if defined(ZIP_SUPPORT)
bool mul = (entry) ? strchr(entry, '*') || strchr(entry, '?') : false;
@@ -173,7 +173,7 @@ void XMLNODE::Delete(PXNODE dnp)
/******************************************************************/
/* Store a string in Buf, enventually reallocating it. */
/******************************************************************/
-char *XMLNODE::BufAlloc(PGLOBAL g, char *p, int n)
+char *XMLNODE::BufAlloc(PGLOBAL g, const char *p, int n)
{
if (Len < n) {
Len = n;
diff --git a/storage/connect/plgxml.h b/storage/connect/plgxml.h
index 6870764c503..82629e4c7db 100644
--- a/storage/connect/plgxml.h
+++ b/storage/connect/plgxml.h
@@ -76,9 +76,9 @@ class XMLDOCUMENT : public BLOCK {
virtual void SetNofree(bool b) = 0;
// Methods
- virtual bool Initialize(PGLOBAL, char *, bool) = 0;
+ virtual bool Initialize(PGLOBAL, PCSZ, bool) = 0;
virtual bool ParseFile(PGLOBAL, char *) = 0;
- virtual bool NewDoc(PGLOBAL, char *) = 0;
+ virtual bool NewDoc(PGLOBAL, PCSZ) = 0;
virtual void AddComment(PGLOBAL, char *) = 0;
virtual PXNODE GetRoot(PGLOBAL) = 0;
virtual PXNODE NewRoot(PGLOBAL, char *) = 0;
@@ -95,7 +95,7 @@ class XMLDOCUMENT : public BLOCK {
// Utility
bool MakeNSlist(PGLOBAL g);
- bool InitZip(PGLOBAL g, char *entry);
+ bool InitZip(PGLOBAL g, PCSZ entry);
char *GetMemDoc(PGLOBAL g, char *fn);
void CloseZip(void);
@@ -131,15 +131,15 @@ class XMLNODE : public BLOCK {
virtual PXLIST SelectNodes(PGLOBAL, char *, PXLIST = NULL) = 0;
virtual PXNODE SelectSingleNode(PGLOBAL, char *, PXNODE = NULL) = 0;
virtual PXATTR GetAttribute(PGLOBAL, char *, PXATTR = NULL) = 0;
- virtual PXNODE AddChildNode(PGLOBAL, char *, PXNODE = NULL) = 0;
+ virtual PXNODE AddChildNode(PGLOBAL, PCSZ, PXNODE = NULL) = 0;
virtual PXATTR AddProperty(PGLOBAL, char *, PXATTR = NULL) = 0;
- virtual void AddText(PGLOBAL, char *) = 0;
+ virtual void AddText(PGLOBAL, PCSZ) = 0;
virtual void DeleteChild(PGLOBAL, PXNODE) = 0;
protected:
PXNODE NewChild(PXNODE ncp);
void Delete(PXNODE dnp);
- char *BufAlloc(PGLOBAL g, char *p, int n);
+ char *BufAlloc(PGLOBAL g, const char *p, int n);
// Constructor
XMLNODE(PXDOC dp);
diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.cpp
index bfac8a5fd99..f0822526b98 100644
--- a/storage/connect/plugutil.c
+++ b/storage/connect/plugutil.cpp
@@ -139,31 +139,39 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
htrc("PlugInit: Language='%s'\n",
((!Language) ? "Null" : (char*)Language));
- if (!(g = malloc(sizeof(GLOBAL)))) {
- fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
- return NULL;
- } else {
+ try {
+ g = new GLOBAL;
+ } catch (...) {
+ fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
+ 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 = g->ActivityStart = NULL;
+ 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[256];
+ 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 */
+ //} /* endif g */
g->jump_level = -1; /* New setting to allow recursive call of Plug */
return(g);
@@ -182,7 +190,7 @@ int PlugExit(PGLOBAL g)
if (g->Sarea)
free(g->Sarea);
- free(g);
+ delete g;
return rc;
} /* end of PlugExit */
@@ -475,7 +483,7 @@ void *PlugAllocMem(PGLOBAL g, uint size)
/***********************************************************************/
BOOL PlugSubSet(PGLOBAL g __attribute__((unused)), void *memp, uint size)
{
- PPOOLHEADER pph = memp;
+ PPOOLHEADER pph = (PPOOLHEADER)memp;
pph->To_Free = (OFFSET)sizeof(POOLHEADER);
pph->FreeBlk = size - pph->To_Free;
@@ -501,7 +509,6 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
/*******************************************************************/
memp = g->Sarea;
-//size = ((size + 3) / 4) * 4; /* Round up size to multiple of 4 */
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp;
@@ -510,26 +517,24 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
memp, size, pph->To_Free, pph->FreeBlk);
if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
- char *pname = "Work";
+ PCSZ pname = "Work";
sprintf(g->Message,
"Not enough memory in %s area for request of %u (used=%d free=%d)",
- pname, (uint) size, pph->To_Free, pph->FreeBlk);
+ pname, (uint)size, pph->To_Free, pph->FreeBlk);
if (trace)
htrc("PlugSubAlloc: %s\n", g->Message);
- /* Nothing we can do if longjmp is not initialized. */
- assert(g->jump_level >= 0);
- longjmp(g->jumper[g->jump_level], 1);
+ throw 1234;
} /* endif size OS32 code */
/*********************************************************************/
/* Do the suballocation the simplest way. */
/*********************************************************************/
memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */
- pph->To_Free += size; /* New offset of pool free block */
- pph->FreeBlk -= size; /* New size of pool free block */
+ pph->To_Free += (OFFSET)size; /* New offset of pool free block */
+ pph->FreeBlk -= (uint)size; /* New size of pool free block */
if (trace > 3)
htrc("Done memp=%p used=%d free=%d\n",
diff --git a/storage/connect/preparse.h b/storage/connect/preparse.h
index 2892a958bdd..f16624548fb 100644
--- a/storage/connect/preparse.h
+++ b/storage/connect/preparse.h
@@ -7,14 +7,14 @@
/* Struct of variables used by the date format pre-parser. */
/***********************************************************************/
typedef struct _datpar {
- char *Format; // Points to format to decode
+ const char *Format; // Points to format to decode
char *Curp; // Points to current parsing position
char *InFmt; // Start of input format
char *OutFmt; // Start of output format
int Index[8]; // Indexes of date values
int Num; // Number of values to retrieve
int Flag; // 1: Input, 2: Output, 4: no output blank
- int Outsize; // Size of output buffers
+ int Outsize; // Size of output buffers
} DATPAR, *PDTP;
/***********************************************************************/
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index c6878737f1d..26cc27b1b01 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -88,7 +88,7 @@ PTOS RELDEF::GetTopt(void)
/***********************************************************************/
/* This function sets an integer table information. */
/***********************************************************************/
-bool RELDEF::SetIntCatInfo(PSZ what, int n)
+bool RELDEF::SetIntCatInfo(PCSZ what, int n)
{
return Hc->SetIntegerOption(what, n);
} // end of SetIntCatInfo
@@ -96,7 +96,7 @@ bool RELDEF::SetIntCatInfo(PSZ what, int n)
/***********************************************************************/
/* This function returns integer table information. */
/***********************************************************************/
-int RELDEF::GetIntCatInfo(PSZ what, int idef)
+int RELDEF::GetIntCatInfo(PCSZ what, int idef)
{
int n= Hc->GetIntegerOption(what);
@@ -106,7 +106,7 @@ int RELDEF::GetIntCatInfo(PSZ what, int idef)
/***********************************************************************/
/* This function returns Boolean table information. */
/***********************************************************************/
-bool RELDEF::GetBoolCatInfo(PSZ what, bool bdef)
+bool RELDEF::GetBoolCatInfo(PCSZ what, bool bdef)
{
bool b= Hc->GetBooleanOption(what, bdef);
@@ -116,9 +116,10 @@ bool RELDEF::GetBoolCatInfo(PSZ what, bool bdef)
/***********************************************************************/
/* This function returns size catalog information. */
/***********************************************************************/
-int RELDEF::GetSizeCatInfo(PSZ what, PSZ sdef)
+int RELDEF::GetSizeCatInfo(PCSZ what, PCSZ sdef)
{
- char * s, c;
+ char c;
+ PCSZ s;
int i, n= 0;
if (!(s= Hc->GetStringOption(what)))
@@ -138,9 +139,9 @@ int RELDEF::GetSizeCatInfo(PSZ what, PSZ sdef)
/***********************************************************************/
/* This function sets char table information in buf. */
/***********************************************************************/
-int RELDEF::GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size)
+int RELDEF::GetCharCatInfo(PCSZ what, PCSZ sdef, char *buf, int size)
{
- char *s= Hc->GetStringOption(what);
+ PCSZ s= Hc->GetStringOption(what);
strncpy(buf, ((s) ? s : sdef), size);
return size;
@@ -158,9 +159,10 @@ bool RELDEF::Partitioned(void)
/* This function returns string table information. */
/* Default parameter is "*" to get the handler default. */
/***********************************************************************/
-char *RELDEF::GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef)
+char *RELDEF::GetStringCatInfo(PGLOBAL g, PCSZ what, PCSZ sdef)
{
- char *name, *sval= NULL, *s= Hc->GetStringOption(what, sdef);
+ char *sval = NULL;
+ PCSZ name, s= Hc->GetStringOption(what, sdef);
if (s) {
if (!Hc->IsPartitioned() ||
@@ -168,12 +170,12 @@ char *RELDEF::GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef)
&& stricmp(what, "connect")))
sval= PlugDup(g, s);
else
- sval= s;
+ sval= (char*)s;
} else if (!stricmp(what, "filename")) {
// Return default file name
- char *ftype= Hc->GetStringOption("Type", "*");
- int i, n;
+ PCSZ ftype= Hc->GetStringOption("Type", "*");
+ int i, n;
if (IsFileType(GetTypeID(ftype))) {
name= Hc->GetPartName();
@@ -251,9 +253,9 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat,
/***********************************************************************/
/* This function returns the database data path. */
/***********************************************************************/
-PSZ TABDEF::GetPath(void)
+PCSZ TABDEF::GetPath(void)
{
- return (Database) ? (PSZ)Database : (Hc) ? Hc->GetDataPath() : NULL;
+ return (Database) ? Database : (Hc) ? Hc->GetDataPath() : NULL;
} // end of GetPath
/***********************************************************************/
@@ -277,8 +279,13 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
// Take care of the column definitions
i= poff= nof= nlg= 0;
+#if defined(__WIN__)
// Offsets of HTML and DIR tables start from 0, DBF at 1
- loff= (tc == TAB_DBF) ? 1 : (tc == TAB_XML || tc == TAB_DIR) ? -1 : 0;
+ loff= (tc == TAB_DBF) ? 1 : (tc == TAB_XML || tc == TAB_DIR) ? -1 : 0;
+#else // !__WIN__
+ // Offsets of HTML tables start from 0, DIR and DBF at 1
+ loff = (tc == TAB_DBF || tc == TAB_DIR) ? 1 : (tc == TAB_XML) ? -1 : 0;
+#endif // !__WIN__
while (true) {
// Default Offset depends on table type
@@ -540,7 +547,7 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
#endif // 0
// Is the library already loaded?
- if (!Hdll)
+ if (!Hdll && !(Hdll = dlopen(soname, RTLD_NOLOAD)))
// Load the desired shared library
if (!(Hdll = dlopen(soname, RTLD_LAZY))) {
error = dlerror();
@@ -610,9 +617,10 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
if (!*Module)
Module = Subtype;
- Desc = (char*)PlugSubAlloc(g, NULL, strlen(Module)
- + strlen(Subtype) + 3);
- sprintf(Desc, "%s(%s)", Module, Subtype);
+ char *desc = (char*)PlugSubAlloc(g, NULL, strlen(Module)
+ + strlen(Subtype) + 3);
+ sprintf(desc, "%s(%s)", Module, Subtype);
+ Desc = desc;
return false;
} // end of DefineAM
diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h
index 52a131dbf3d..8b19a413ade 100644
--- a/storage/connect/reldef.h
+++ b/storage/connect/reldef.h
@@ -42,13 +42,13 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
// Methods
PTOS GetTopt(void);
- bool GetBoolCatInfo(PSZ what, bool bdef);
- bool SetIntCatInfo(PSZ what, int ival);
+ bool GetBoolCatInfo(PCSZ what, bool bdef);
+ bool SetIntCatInfo(PCSZ what, int ival);
bool Partitioned(void);
- int GetIntCatInfo(PSZ what, int idef);
- int GetSizeCatInfo(PSZ what, PSZ sdef);
- int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size);
- char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef);
+ int GetIntCatInfo(PCSZ what, int idef);
+ int GetSizeCatInfo(PCSZ what, PCSZ sdef);
+ int GetCharCatInfo(PCSZ what, PCSZ sdef, char *buf, int size);
+ char *GetStringCatInfo(PGLOBAL g, PCSZ what, PCSZ sdef);
virtual int Indexable(void) {return 0;}
virtual bool Define(PGLOBAL g, PCATLG cat,
LPCSTR name, LPCSTR schema, LPCSTR am) = 0;
@@ -84,7 +84,7 @@ public:
void SetNext(PTABDEF tdfp) {Next = tdfp;}
int GetMultiple(void) {return Multiple;}
int GetPseudo(void) {return Pseudo;}
- PSZ GetPath(void);
+ PCSZ GetPath(void);
//PSZ GetPath(void)
// {return (Database) ? (PSZ)Database : Cat->GetDataPath();}
bool SepIndex(void) {return GetBoolCatInfo("SepIndex", false);}
@@ -105,8 +105,8 @@ public:
protected:
// Members
- PSZ Schema; /* Table schema (for ODBC) */
- PSZ Desc; /* Table description */
+ PCSZ Schema; /* Table schema (for ODBC) */
+ PCSZ Desc; /* Table description */
uint Catfunc; /* Catalog function ID */
int Card; /* (max) number of rows in table */
int Elemt; /* Number of rows in blocks or rowset */
diff --git a/storage/connect/tabcol.cpp b/storage/connect/tabcol.cpp
index fde1baa6317..5065d86ce6a 100644
--- a/storage/connect/tabcol.cpp
+++ b/storage/connect/tabcol.cpp
@@ -73,7 +73,7 @@ PTABLE XTAB::Link(PTABLE tab2)
/***********************************************************************/
/* Make file output of XTAB contents. */
/***********************************************************************/
-void XTAB::Print(PGLOBAL g, FILE *f, uint n)
+void XTAB::Printf(PGLOBAL g, FILE *f, uint n)
{
char m[64];
@@ -86,12 +86,12 @@ void XTAB::Print(PGLOBAL g, FILE *f, uint n)
PlugPutOut(g, f, TYPE_TDB, tp->To_Tdb, n + 2);
} /* endfor tp */
- } /* end of Print */
+ } /* end of Printf */
/***********************************************************************/
/* Make string output of XTAB contents. */
/***********************************************************************/
-void XTAB::Print(PGLOBAL, char *ps, uint z)
+void XTAB::Prints(PGLOBAL, char *ps, uint z)
{
char buf[128];
int i, n = (int)z - 1;
@@ -105,7 +105,7 @@ void XTAB::Print(PGLOBAL, char *ps, uint z)
n -= i;
} // endif tp
- } /* end of Print */
+ } /* end of Prints */
/***********************************************************************/
@@ -134,7 +134,7 @@ bool COLUMN::SetFormat(PGLOBAL g, FORMAT&)
/***********************************************************************/
/* Make file output of COLUMN contents. */
/***********************************************************************/
-void COLUMN::Print(PGLOBAL g, FILE *f, uint n)
+void COLUMN::Printf(PGLOBAL g, FILE *f, uint n)
{
char m[64];
@@ -149,12 +149,12 @@ void COLUMN::Print(PGLOBAL g, FILE *f, uint n)
PlugPutOut(g, f, TYPE_TABLE, To_Table, n + 2);
PlugPutOut(g, f, TYPE_XOBJECT, To_Col, n + 2);
- } /* end of Print */
+ } /* end of Printf */
/***********************************************************************/
/* Make string output of COLUMN contents. */
/***********************************************************************/
-void COLUMN::Print(PGLOBAL, char *ps, uint z)
+void COLUMN::Prints(PGLOBAL, char *ps, uint z)
{
char buf[80];
@@ -166,4 +166,4 @@ void COLUMN::Print(PGLOBAL, char *ps, uint z)
strncpy(ps, buf, z);
ps[z - 1] = '\0';
- } /* end of Print */
+ } /* end of Prints */
diff --git a/storage/connect/tabcol.h b/storage/connect/tabcol.h
index 3bfc37e69c1..e4657e2f261 100644
--- a/storage/connect/tabcol.h
+++ b/storage/connect/tabcol.h
@@ -38,8 +38,8 @@ class DllExport XTAB: public BLOCK { // Table Name-Schema-Srcdef block.
// Methods
PTABLE Link(PTABLE);
- void Print(PGLOBAL g, FILE *f, uint n);
- void Print(PGLOBAL g, char *ps, uint z);
+ void Printf(PGLOBAL g, FILE *f, uint n);
+ void Prints(PGLOBAL g, char *ps, uint z);
protected:
// Members
@@ -78,8 +78,8 @@ class DllExport COLUMN: public XOBJECT { // Column Name/Qualifier block.
void SetTo_Col(PCOL colp) {To_Col = colp;}
// Methods
- virtual void Print(PGLOBAL g, FILE *f, uint n);
- virtual void Print(PGLOBAL g, char *ps, uint z);
+ virtual void Printf(PGLOBAL g, FILE *f, uint n);
+ virtual void Prints(PGLOBAL g, char *ps, uint z);
// All methods below should never be used for COLUMN's
virtual void Reset(void) {assert(false);}
virtual bool Compare(PXOB) {assert(false); return false;}
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index d2bb3d7a4af..5c46077f8f0 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -1,11 +1,11 @@
/************* TabDos C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABDOS */
/* ------------- */
-/* Version 4.9.2 */
+/* Version 4.9.3 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -98,6 +98,7 @@ DOSDEF::DOSDEF(void)
Ofn = NULL;
Entry = NULL;
To_Indx = NULL;
+ Pwd = NULL;
Recfm = RECFM_VAR;
Mapped = false;
Zipped = false;
@@ -131,7 +132,8 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
bool map = (am && (*am == 'M' || *am == 'm'));
LPCSTR dfm = (am && (*am == 'F' || *am == 'f')) ? "F"
: (am && (*am == 'B' || *am == 'b')) ? "B"
- : (am && !stricmp(am, "DBF")) ? "D" : "V";
+ : (am && (*am == 'X' || *am == 'x')) ? "X"
+ : (am && !stricmp(am, "DBF")) ? "D" : "V";
if ((Zipped = GetBoolCatInfo("Zipped", false))) {
Entry = GetStringCatInfo(g, "Entry", NULL);
@@ -139,14 +141,16 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
: false;
Mulentries = GetBoolCatInfo("Mulentries", Mulentries);
Append = GetBoolCatInfo("Append", false);
- }
+ Pwd = GetStringCatInfo(g, "Password", NULL);
+ } // endif Zipped
Desc = Fn = GetStringCatInfo(g, "Filename", NULL);
Ofn = GetStringCatInfo(g, "Optname", Fn);
GetCharCatInfo("Recfm", (PSZ)dfm, buf, sizeof(buf));
Recfm = (toupper(*buf) == 'F') ? RECFM_FIX :
(toupper(*buf) == 'B') ? RECFM_BIN :
- (toupper(*buf) == 'D') ? RECFM_DBF : RECFM_VAR;
+ (toupper(*buf) == 'X') ? RECFM_NAF : // MGO
+ (toupper(*buf) == 'D') ? RECFM_DBF : RECFM_VAR;
Lrecl = GetIntCatInfo("Lrecl", 0);
if (Recfm != RECFM_DBF)
@@ -180,7 +184,7 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
/***********************************************************************/
bool DOSDEF::GetOptFileName(PGLOBAL g, char *filename)
{
- char *ftype;
+ PCSZ ftype;
switch (Recfm) {
case RECFM_VAR: ftype = ".dop"; break;
@@ -237,9 +241,9 @@ void DOSDEF::RemoveOptValues(PGLOBAL g)
/***********************************************************************/
bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
{
- char *ftype;
- char filename[_MAX_PATH];
- bool sep, rc = false;
+ PCSZ ftype;
+ char filename[_MAX_PATH];
+ bool sep, rc = false;
if (!To_Indx)
return false; // No index
@@ -351,7 +355,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
if (Zipped) {
#if defined(ZIP_SUPPORT)
if (Recfm == RECFM_VAR) {
- if (mode == MODE_READ || mode == MODE_ANY) {
+ if (mode == MODE_READ || mode == MODE_ANY || mode == MODE_ALTER) {
txfp = new(g) UNZFAM(this);
} else if (mode == MODE_INSERT) {
txfp = new(g) ZIPFAM(this);
@@ -362,7 +366,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
tdbp = new(g) TDBDOS(this, txfp);
} else {
- if (mode == MODE_READ || mode == MODE_ANY) {
+ if (mode == MODE_READ || mode == MODE_ANY || mode == MODE_ALTER) {
txfp = new(g) UZXFAM(this);
} else if (mode == MODE_INSERT) {
txfp = new(g) ZPXFAM(this);
@@ -1509,8 +1513,8 @@ PBF TDBDOS::CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv)
if (n == 8 && ctype != TYPE_LIST) {
// Should never happen
strcpy(g->Message, "Block opt: bad constant");
- longjmp(g->jumper[g->jump_level], 99);
- } // endif Conv
+ throw 99;
+ } // endif Conv
if (type[0] == 1) {
// Make it always as Column-op-Value
@@ -1790,8 +1794,8 @@ err:
/* Make a dynamic index. */
/***********************************************************************/
bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted)
- {
- int k, rc;
+{
+ int k;
volatile bool dynamic;
bool brc;
PCOL colp;
@@ -1861,13 +1865,7 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted)
} else // Column contains same values as ROWID
kxp = new(g) XXROW(this);
- // Prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return true;
- } // endif
-
- if (!(rc = setjmp(g->jumper[++g->jump_level])) != 0) {
+ try {
if (dynamic) {
ResetBlockFilter(g);
kxp->SetDynamic(dynamic);
@@ -1892,12 +1890,17 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted)
} // endif brc
- } else
- brc = true;
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ brc = true;
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ brc = true;
+ } // end catch
- g->jump_level--;
- return brc;
- } // end of InitialyzeIndex
+ return brc;
+} // end of InitialyzeIndex
/***********************************************************************/
/* DOS GetProgMax: get the max value for progress information. */
@@ -2118,7 +2121,8 @@ bool TDBDOS::OpenDB(PGLOBAL g)
return false;
} // endif use
- if (Mode == MODE_DELETE && !Next && Txfp->GetAmType() != TYPE_AM_DOS) {
+ if (Mode == MODE_DELETE && !Next && Txfp->GetAmType() != TYPE_AM_DOS
+ && Txfp->GetAmType() != TYPE_AM_MGO) {
// Delete all lines. Not handled in MAP or block mode
Txfp = new(g) DOSFAM((PDOSDEF)To_Def);
Txfp->SetTdbp(this);
@@ -2156,16 +2160,18 @@ bool TDBDOS::OpenDB(PGLOBAL g)
To_BlkFil = InitBlockFilter(g, To_Filter);
/*********************************************************************/
- /* Allocate the line buffer plus a null character. */
- /*********************************************************************/
- To_Line = (char*)PlugSubAlloc(g, NULL, Lrecl + 1);
+ /* Lrecl does not include line ending */
+ /*********************************************************************/
+ size_t linelen = Lrecl + ((PDOSDEF)To_Def)->Ending + 1;
+
+ To_Line = (char*)PlugSubAlloc(g, NULL, linelen);
if (Mode == MODE_INSERT) {
// Spaces between fields must be filled with blanks
memset(To_Line, ' ', Lrecl);
To_Line[Lrecl] = '\0';
} else
- memset(To_Line, 0, Lrecl + 1);
+ memset(To_Line, 0, linelen);
if (trace)
htrc("OpenDos: R%hd mode=%d To_Line=%p\n", Tdb_No, Mode, To_Line);
@@ -2304,8 +2310,8 @@ void TDBDOS::CloseDB(PGLOBAL g)
/***********************************************************************/
/* DOSCOL public constructor (also called by MAPCOL). */
/***********************************************************************/
-DOSCOL::DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
- : COLBLK(cdp, tp, i)
+DOSCOL::DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PCSZ am)
+ : COLBLK(cdp, tp, i)
{
char *p;
int prec = Format.Prec;
@@ -2335,7 +2341,7 @@ DOSCOL::DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
Dval = NULL;
Buf = NULL;
- if (txfp->Blocked && Opt && (cdp->GetMin() || cdp->GetDval())) {
+ if (txfp && txfp->Blocked && Opt && (cdp->GetMin() || cdp->GetDval())) {
int nblk = txfp->GetBlock();
Clustered = (cdp->GetXdb2()) ? 2 : 1;
@@ -2514,8 +2520,8 @@ void DOSCOL::ReadColumn(PGLOBAL g)
if (rc == RC_EF)
sprintf(g->Message, MSG(INV_DEF_READ), rc);
- longjmp(g->jumper[g->jump_level], 11);
- } // endif
+ throw 11;
+ } // endif
p = tdbp->To_Line + Deplac;
field = Long;
@@ -2570,8 +2576,8 @@ void DOSCOL::ReadColumn(PGLOBAL g)
break;
default:
sprintf(g->Message, MSG(BAD_RECFM), tdbp->Ftype);
- longjmp(g->jumper[g->jump_level], 34);
- } // endswitch Ftype
+ throw 34;
+ } // endswitch Ftype
// Set null when applicable
if (Nullable)
@@ -2679,8 +2685,8 @@ void DOSCOL::WriteColumn(PGLOBAL g)
break;
default:
sprintf(g->Message, "Invalid field format for column %s", Name);
- longjmp(g->jumper[g->jump_level], 31);
- } // endswitch BufType
+ throw 31;
+ } // endswitch BufType
p2 = Buf;
} else // Standard CONNECT format
@@ -2691,8 +2697,8 @@ void DOSCOL::WriteColumn(PGLOBAL g)
if ((len = strlen(p2)) > field) {
sprintf(g->Message, MSG(VALUE_TOO_LONG), p2, Name, field);
- longjmp(g->jumper[g->jump_level], 31);
- } else if (Dsp)
+ throw 31;
+ } else if (Dsp)
for (i = 0; i < len; i++)
if (p2[i] == '.')
p2[i] = Dsp;
@@ -2863,13 +2869,5 @@ bool DOSCOL::AddDistinctValue(PGLOBAL g)
return false;
} // end of AddDistinctValue
-/***********************************************************************/
-/* Make file output of a Dos column descriptor block. */
-/***********************************************************************/
-void DOSCOL::Print(PGLOBAL g, FILE *f, uint n)
- {
- COLBLK::Print(g, f, n);
- } // end of Print
-
/* ------------------------------------------------------------------- */
diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h
index 922d52ee399..948b357dc1f 100644
--- a/storage/connect/tabdos.h
+++ b/storage/connect/tabdos.h
@@ -39,9 +39,9 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
virtual PIXDEF GetIndx(void) {return To_Indx;}
virtual void SetIndx(PIXDEF xdp) {To_Indx = xdp;}
virtual bool IsHuge(void) {return Huge;}
- PSZ GetFn(void) {return Fn;}
- PSZ GetOfn(void) {return Ofn;}
- PSZ GetEntry(void) {return Entry;}
+ PCSZ GetFn(void) {return Fn;}
+ PCSZ GetOfn(void) {return Ofn;}
+ PCSZ GetEntry(void) {return Entry;}
bool GetMul(void) {return Mulentries;}
bool GetAppend(void) {return Append;}
void SetBlock(int block) { Block = block; }
@@ -74,9 +74,10 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
//virtual bool Erase(char *filename);
// Members
- PSZ Fn; /* Path/Name of corresponding file */
- PSZ Ofn; /* Base Path/Name of matching index files*/
- PSZ Entry; /* Zip entry name or pattern */
+ PCSZ Fn; /* Path/Name of corresponding file */
+ PCSZ Ofn; /* Base Path/Name of matching index files*/
+ PCSZ Entry; /* Zip entry name or pattern */
+ PCSZ Pwd; /* Zip password */
PIXDEF To_Indx; /* To index definitions blocks */
RECFM Recfm; /* 0:VAR, 1:FIX, 2:BIN, 3:VCT, 6:DBF */
bool Mapped; /* 0: disk file, 1: memory mapped file */
@@ -132,8 +133,8 @@ class DllExport TDBDOS : public TDBASE {
// Implementation
virtual AMT GetAmType(void) {return Txfp->GetAmType();}
- virtual PSZ GetFile(PGLOBAL) {return Txfp->To_File;}
- virtual void SetFile(PGLOBAL, PSZ fn) {Txfp->To_File = fn;}
+ virtual PCSZ GetFile(PGLOBAL) {return Txfp->To_File;}
+ virtual void SetFile(PGLOBAL, PCSZ fn) {Txfp->To_File = fn;}
virtual void SetAbort(bool b) {Abort = b;}
virtual RECFM GetFtype(void) {return Ftype;}
virtual bool SkipHeader(PGLOBAL) {return false;}
@@ -213,7 +214,7 @@ class DllExport DOSCOL : public COLBLK {
friend class TDBFIX;
public:
// Constructors
- DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am = "DOS");
+ DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PCSZ am = "DOS");
DOSCOL(DOSCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
@@ -231,12 +232,10 @@ class DllExport DOSCOL : public COLBLK {
virtual PVBLK GetDval(void) {return Dval;}
// Methods
- using COLBLK::Print;
virtual bool VarSize(void);
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
- virtual void Print(PGLOBAL g, FILE *, uint);
protected:
virtual bool SetMinMax(PGLOBAL g);
diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp
index e3518126a49..8f6e610dfc2 100644
--- a/storage/connect/tabext.cpp
+++ b/storage/connect/tabext.cpp
@@ -35,9 +35,9 @@
/***********************************************************************/
/* CONDFIL Constructor. */
/***********************************************************************/
-CONDFIL::CONDFIL(const Item *cond, uint idx, AMT type)
+CONDFIL::CONDFIL(uint idx, AMT type)
{
- Cond = cond;
+//Cond = cond;
Idx = idx;
Type = type;
Op = OP_XX;
@@ -61,7 +61,7 @@ int CONDFIL::Init(PGLOBAL g, PHC hc)
bool h;
if (options)
- alt = GetListOption(g, "Alias", options->oplist, NULL);
+ alt = (char*)GetListOption(g, "Alias", options->oplist, NULL);
while (alt) {
if (!(p = strchr(alt, '='))) {
@@ -267,7 +267,7 @@ TDBEXT::TDBEXT(PTDBEXT tdbp) : TDB(tdbp)
/******************************************************************/
/* Convert an UTF-8 string to latin characters. */
/******************************************************************/
-int TDBEXT::Decode(char *txt, char *buf, size_t n)
+int TDBEXT::Decode(PCSZ txt, char *buf, size_t n)
{
uint dummy_errors;
uint32 len = copy_and_convert(buf, n, &my_charset_latin1,
@@ -285,20 +285,20 @@ int TDBEXT::Decode(char *txt, char *buf, size_t n)
/***********************************************************************/
bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
{
- char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
+ PCSZ schmp = NULL;
+ char *catp = NULL, buf[NAM_LEN * 3];
int len;
- bool oom = false, first = true;
+ bool first = true;
PTABLE tablep = To_Table;
PCOL colp;
if (Srcdef) {
if ((catp = strstr(Srcdef, "%s"))) {
char *fil1, *fil2;
- PSZ ph = ((EXTDEF*)To_Def)->Phpos;
+ PCSZ ph = ((EXTDEF*)To_Def)->Phpos;
if (!ph)
- ph = (strstr(catp + 2, "%s")) ? const_cast<char*>("WH") :
- const_cast<char*>("W");
+ ph = (strstr(catp + 2, "%s")) ? "WH" : "W";
if (stricmp(ph, "H")) {
fil1 = (To_CondFil && *To_CondFil->Body)
@@ -342,7 +342,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
if (!first)
- oom |= Query->Append(", ");
+ Query->Append(", ");
else
first = false;
@@ -351,11 +351,11 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
- oom |= Query->Append(Quote);
- oom |= Query->Append(buf);
- oom |= Query->Append(Quote);
+ Query->Append(Quote);
+ Query->Append(buf);
+ Query->Append(Quote);
} else
- oom |= Query->Append(buf);
+ Query->Append(buf);
((PEXTCOL)colp)->SetRank(++Ncol);
} // endif colp
@@ -363,13 +363,13 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
} else
// !Columns can occur for queries such that sql count(*) from...
// for which we will count the rows from sql * from...
- oom |= Query->Append('*');
+ Query->Append('*');
} else
// SQL statement used to retrieve the size of the result
- oom |= Query->Append("count(*)");
+ Query->Append("count(*)");
- oom |= Query->Append(" FROM ");
+ Query->Append(" FROM ");
if (Catalog && *Catalog)
catp = Catalog;
@@ -381,17 +381,17 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
schmp = Schema;
if (catp) {
- oom |= Query->Append(catp);
+ Query->Append(catp);
if (schmp) {
- oom |= Query->Append('.');
- oom |= Query->Append(schmp);
+ Query->Append('.');
+ Query->Append(schmp);
} // endif schmp
- oom |= Query->Append('.');
+ Query->Append('.');
} else if (schmp) {
- oom |= Query->Append(schmp);
- oom |= Query->Append('.');
+ Query->Append(schmp);
+ Query->Append('.');
} // endif schmp
// Table name can be encoded in UTF-8
@@ -399,18 +399,18 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
- oom |= Query->Append(Quote);
- oom |= Query->Append(buf);
- oom |= Query->Append(Quote);
+ Query->Append(Quote);
+ Query->Append(buf);
+ Query->Append(Quote);
} else
- oom |= Query->Append(buf);
+ Query->Append(buf);
len = Query->GetLength();
if (To_CondFil) {
if (Mode == MODE_READ) {
- oom |= Query->Append(" WHERE ");
- oom |= Query->Append(To_CondFil->Body);
+ Query->Append(" WHERE ");
+ Query->Append(To_CondFil->Body);
len = Query->GetLength() + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
@@ -418,10 +418,11 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
} else
len += ((Mode == MODE_READX) ? 256 : 1);
- if (oom || Query->Resize(len)) {
+ if (Query->IsTruncated()) {
strcpy(g->Message, "MakeSQL: Out of memory");
return true;
- } // endif oom
+ } else
+ Query->Resize(len);
if (trace)
htrc("Query=%s\n", Query->GetStr());
@@ -435,15 +436,17 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
/***********************************************************************/
bool TDBEXT::MakeCommand(PGLOBAL g)
{
- char *p, *stmt, name[68], *body = NULL;
+ PCSZ schmp = NULL;
+ char *p, *stmt, name[132], *body = NULL;
char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
bool qtd = Quoted > 0;
+ char q = qtd ? *Quote : ' ';
int i = 0, k = 0;
// Make a lower case copy of the originale query and change
// back ticks to the data source identifier quoting character
do {
- qrystr[i] = (Qrystr[i] == '`') ? *Quote : tolower(Qrystr[i]);
+ qrystr[i] = (Qrystr[i] == '`') ? q : tolower(Qrystr[i]);
} while (Qrystr[i++]);
if (To_CondFil && (p = strstr(qrystr, " where "))) {
@@ -460,27 +463,50 @@ bool TDBEXT::MakeCommand(PGLOBAL g)
strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
if (strstr(" update delete low_priority ignore quick from ", name)) {
- strlwr(strcat(strcat(strcpy(name, Quote), Name), Quote));
- k += 2;
+ if (Quote) {
+ strlwr(strcat(strcat(strcpy(name, Quote), Name), Quote));
+ k += 2;
+ } else {
+ strcpy(g->Message, "Quoted must be specified");
+ return true;
+ } // endif Quote
+
} else
strlwr(strcpy(name, Name)); // Not a keyword
if ((p = strstr(qrystr, name))) {
for (i = 0; i < p - qrystr; i++)
- stmt[i] = (Qrystr[i] == '`') ? *Quote : Qrystr[i];
+ stmt[i] = (Qrystr[i] == '`') ? q : Qrystr[i];
stmt[i] = 0;
+
k += i + (int)strlen(Name);
- if (qtd && *(p - 1) == ' ')
+ if (Schema && *Schema)
+ schmp = Schema;
+
+ if (qtd && *(p - 1) == ' ') {
+ if (schmp)
+ strcat(strcat(stmt, schmp), ".");
+
strcat(strcat(strcat(stmt, Quote), TableName), Quote);
- else
+ } else {
+ if (schmp) {
+ if (qtd && *(p - 1) != ' ') {
+ stmt[i - 1] = 0;
+ strcat(strcat(strcat(stmt, schmp), "."), Quote);
+ } else
+ strcat(strcat(stmt, schmp), ".");
+
+ } // endif schmp
+
strcat(stmt, TableName);
+ } // endif's
i = (int)strlen(stmt);
do {
- stmt[i++] = (Qrystr[k] == '`') ? *Quote : Qrystr[k];
+ stmt[i++] = (Qrystr[k] == '`') ? q : Qrystr[k];
} while (Qrystr[k++]);
if (body)
@@ -539,7 +565,7 @@ int TDBEXT::GetProgMax(PGLOBAL g)
/***********************************************************************/
/* EXTCOL public constructor. */
/***********************************************************************/
-EXTCOL::EXTCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+EXTCOL::EXTCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: COLBLK(cdp, tdbp, i)
{
if (cprec) {
diff --git a/storage/connect/tabext.h b/storage/connect/tabext.h
index 2ef20c89f2c..a7f5fb9d856 100644
--- a/storage/connect/tabext.h
+++ b/storage/connect/tabext.h
@@ -28,14 +28,14 @@ class ALIAS : public BLOCK {
class CONDFIL : public BLOCK {
public:
// Constructor
- CONDFIL(const Item *cond, uint idx, AMT type);
+ CONDFIL(uint idx, AMT type);
// Functions
int Init(PGLOBAL g, PHC hc);
const char *Chk(const char *cln, bool *h);
// Members
- const Item *Cond;
+//const Item *Cond;
AMT Type;
uint Idx;
OPVAL Op;
@@ -60,10 +60,10 @@ public:
// Implementation
virtual const char *GetType(void) { return "EXT"; }
- inline PSZ GetTabname(void) { return Tabname; }
- inline PSZ GetTabschema(void) { return Tabschema; }
- inline PSZ GetUsername(void) { return Username; };
- inline PSZ GetPassword(void) { return Password; };
+ inline PCSZ GetTabname(void) { return Tabname; }
+ inline PCSZ GetTabschema(void) { return Tabschema; }
+ inline PCSZ GetUsername(void) { return Username; };
+ inline PCSZ GetPassword(void) { return Password; };
inline PSZ GetTabcat(void) { return Tabcat; }
inline PSZ GetSrcdef(void) { return Srcdef; }
inline char GetSep(void) { return (Sep) ? *Sep : 0; }
@@ -76,10 +76,10 @@ public:
protected:
// Members
- PSZ Tabname; /* External table name */
- PSZ Tabschema; /* External table schema */
- PSZ Username; /* User connect name */
- PSZ Password; /* Password connect info */
+ PCSZ Tabname; /* External table name */
+ PCSZ Tabschema; /* External table schema */
+ PCSZ Username; /* User connect name */
+ PCSZ Password; /* Password connect info */
PSZ Tabcat; /* External table catalog */
PSZ Tabtyp; /* Catalog table type */
PSZ Colpat; /* Catalog column pattern */
@@ -115,7 +115,7 @@ public:
virtual bool IsRemote(void) { return true; }
// Methods
- virtual PSZ GetServer(void) { return "Remote"; }
+ virtual PCSZ GetServer(void) { return "Remote"; }
virtual int GetRecpos(void);
// Database routines
@@ -127,19 +127,19 @@ protected:
virtual bool MakeSQL(PGLOBAL g, bool cnt);
//virtual bool MakeInsert(PGLOBAL g);
virtual bool MakeCommand(PGLOBAL g);
- int Decode(char *utf, char *buf, size_t n);
+ int Decode(PCSZ utf, char *buf, size_t n);
// Members
PQRYRES Qrp; // Points to storage result
PSTRG Query; // Constructed SQL query
- char *TableName; // Points to ODBC table name
- char *Schema; // Points to ODBC table Schema
- char *User; // User connect info
- char *Pwd; // Password connect info
+ PCSZ TableName; // Points to ODBC table name
+ PCSZ Schema; // Points to ODBC table Schema
+ PCSZ User; // User connect info
+ PCSZ Pwd; // Password connect info
char *Catalog; // Points to ODBC table Catalog
char *Srcdef; // The source table SQL definition
char *Count; // Points to count(*) SQL statement
- //char *Where; // Points to local where clause
+ //char *Where; // Points to local where clause
char *Quote; // The identifier quoting character
char *MulConn; // Used for multiple ODBC tables
char *DBQ; // The address part of Connect string
@@ -170,7 +170,7 @@ class DllExport EXTCOL : public COLBLK {
friend class TDBEXT;
public:
// Constructor
- EXTCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am);
+ EXTCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am);
EXTCOL(PEXTCOL colp, PTDB tdbp); // Constructor used in copy process
// Implementation
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp
index bf123cd36c8..a78d5861e53 100644
--- a/storage/connect/tabfix.cpp
+++ b/storage/connect/tabfix.cpp
@@ -1,11 +1,11 @@
/************* TabFix C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABFIX */
/* ------------- */
-/* Version 4.9.1 */
+/* Version 4.9.2 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -373,7 +373,7 @@ int TDBFIX::WriteDB(PGLOBAL g)
/***********************************************************************/
/* BINCOL public constructor. */
/***********************************************************************/
-BINCOL::BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
+BINCOL::BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PCSZ am)
: DOSCOL(g, cdp, tp, cp, i, am)
{
char c, *fmt = cdp->GetFmt();
@@ -411,8 +411,8 @@ BINCOL::BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
case 'D': M = sizeof(double); break;
default:
sprintf(g->Message, MSG(BAD_BIN_FMT), Fmt, Name);
- longjmp(g->jumper[g->jump_level], 11);
- } // endswitch Fmt
+ throw 11;
+ } // endswitch Fmt
} else if (IsTypeChar(Buf_Type))
Eds = 0;
@@ -486,8 +486,8 @@ void BINCOL::ReadColumn(PGLOBAL g)
if (rc == RC_EF)
sprintf(g->Message, MSG(INV_DEF_READ), rc);
- longjmp(g->jumper[g->jump_level], 11);
- } // endif
+ throw 11;
+ } // endif
p = tdbp->To_Line + Deplac;
@@ -545,8 +545,8 @@ void BINCOL::ReadColumn(PGLOBAL g)
break;
default:
sprintf(g->Message, MSG(BAD_BIN_FMT), Fmt, Name);
- longjmp(g->jumper[g->jump_level], 11);
- } // endswitch Fmt
+ throw 11;
+ } // endswitch Fmt
// Set null when applicable
if (Nullable)
@@ -595,8 +595,8 @@ void BINCOL::WriteColumn(PGLOBAL g)
} else if (Value->GetBinValue(p, Long, Status)) {
sprintf(g->Message, MSG(BIN_F_TOO_LONG),
Name, Value->GetSize(), Long);
- longjmp(g->jumper[g->jump_level], 31);
- } // endif p
+ throw 31;
+ } // endif p
break;
case 'S': // Short integer
@@ -604,8 +604,8 @@ void BINCOL::WriteColumn(PGLOBAL g)
if (n > 32767LL || n < -32768LL) {
sprintf(g->Message, MSG(VALUE_TOO_BIG), n, Name);
- longjmp(g->jumper[g->jump_level], 31);
- } else if (Status)
+ throw 31;
+ } else if (Status)
Value->GetValueNonAligned<short>(p, (short)n);
break;
@@ -614,8 +614,8 @@ void BINCOL::WriteColumn(PGLOBAL g)
if (n > 255LL || n < -256LL) {
sprintf(g->Message, MSG(VALUE_TOO_BIG), n, Name);
- longjmp(g->jumper[g->jump_level], 31);
- } else if (Status)
+ throw 31;
+ } else if (Status)
*p = (char)n;
break;
@@ -624,8 +624,8 @@ void BINCOL::WriteColumn(PGLOBAL g)
if (n > INT_MAX || n < INT_MIN) {
sprintf(g->Message, MSG(VALUE_TOO_BIG), n, Name);
- longjmp(g->jumper[g->jump_level], 31);
- } else if (Status)
+ throw 31;
+ } else if (Status)
Value->GetValueNonAligned<int>(p, (int)n);
break;
@@ -648,8 +648,8 @@ void BINCOL::WriteColumn(PGLOBAL g)
case 'C': // Characters
if ((n = (signed)strlen(Value->GetCharString(Buf))) > Long) {
sprintf(g->Message, MSG(BIN_F_TOO_LONG), Name, (int) n, Long);
- longjmp(g->jumper[g->jump_level], 31);
- } // endif n
+ throw 31;
+ } // endif n
if (Status) {
s = Value->GetCharString(Buf);
@@ -660,8 +660,8 @@ void BINCOL::WriteColumn(PGLOBAL g)
break;
default:
sprintf(g->Message, MSG(BAD_BIN_FMT), Fmt, Name);
- longjmp(g->jumper[g->jump_level], 11);
- } // endswitch Fmt
+ throw 31;
+ } // endswitch Fmt
if (Eds && Status) {
p = tdbp->To_Line + Deplac;
diff --git a/storage/connect/tabfix.h b/storage/connect/tabfix.h
index 4b9f9689992..53c0af1c422 100644
--- a/storage/connect/tabfix.h
+++ b/storage/connect/tabfix.h
@@ -65,7 +65,7 @@ class DllExport BINCOL : public DOSCOL {
friend class TDBFIX;
public:
// Constructors
- BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am = "BIN");
+ BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PCSZ am = "BIN");
BINCOL(BINCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
@@ -108,7 +108,7 @@ class TDBDCL : public TDBCAT {
{return DBFColumns(g, ((PTABDEF)To_Def)->GetPath(), Fn, false);}
// Members
- char *Fn; // The DBF file (path) name
+ PCSZ Fn; // The DBF file (path) name
}; // end of class TDBOCL
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 1a75d572ecd..516601a5eb4 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -81,7 +81,7 @@ USETEMP UseTemp(void);
/* of types (TYPE_STRING < TYPE_DOUBLE < TYPE_INT) (1 < 2 < 7). */
/* If these values are changed, this will have to be revisited. */
/***********************************************************************/
-PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info)
+PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info)
{
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_INT, TYPE_INT, TYPE_SHORT};
@@ -153,7 +153,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info)
tdp->Lrecl = 4096;
tdp->Multiple = GetIntegerTableOption(g, topt, "Multiple", 0);
- p = GetStringTableOption(g, topt, "Separator", ",");
+ p = (char*)GetStringTableOption(g, topt, "Separator", ",");
tdp->Sep = (strlen(p) == 2 && p[0] == '\\' && p[1] == 't') ? '\t' : *p;
#if defined(__WIN__)
@@ -167,7 +167,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info)
sep = tdp->Sep;
tdp->Quoted = GetIntegerTableOption(g, topt, "Quoted", -1);
- p = GetStringTableOption(g, topt, "Qchar", "");
+ p = (char*)GetStringTableOption(g, topt, "Qchar", "");
tdp->Qot = *p;
if (tdp->Qot && tdp->Quoted < 0)
@@ -517,7 +517,7 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
/*******************************************************************/
if (Zipped) {
#if defined(ZIP_SUPPORT)
- if (mode == MODE_READ || mode == MODE_ANY) {
+ if (mode == MODE_READ || mode == MODE_ANY || mode == MODE_ALTER) {
txfp = new(g) UNZFAM(this);
} else if (mode == MODE_INSERT) {
txfp = new(g) ZIPFAM(this);
@@ -1047,7 +1047,7 @@ bool TDBCSV::PrepareWriting(PGLOBAL g)
if (!strlen(Field[i])) {
// Generally null fields are not quoted
if (Quoted > 2)
- // Except if explicitly required
+ // Except if explicitely required
strcat(strcat(To_Line, qot), qot);
} else if (Qot && (strchr(Field[i], Sep) || *Field[i] == Qot
@@ -1435,8 +1435,8 @@ void CSVCOL::ReadColumn(PGLOBAL g)
if (rc == RC_EF)
sprintf(g->Message, MSG(INV_DEF_READ), rc);
- longjmp(g->jumper[g->jump_level], 34);
- } // endif
+ throw 34;
+ } // endif
if (tdbp->Mode != MODE_UPDATE) {
int colen = Long; // Column length
@@ -1453,8 +1453,8 @@ void CSVCOL::ReadColumn(PGLOBAL g)
Long = colen; // Restore column length
sprintf(g->Message, MSG(FLD_TOO_LNG_FOR),
Fldnum + 1, Name, To_Tdb->RowNumber(g), tdbp->GetFile(g));
- longjmp(g->jumper[g->jump_level], 34);
- } // endif Long
+ throw 34;
+ } // endif Long
// Now do the reading
DOSCOL::ReadColumn(g);
@@ -1516,8 +1516,8 @@ void CSVCOL::WriteColumn(PGLOBAL g)
if ((signed)strlen(p) > flen) {
sprintf(g->Message, MSG(BAD_FLD_LENGTH), Name, p, flen,
tdbp->RowNumber(g), tdbp->GetFile(g));
- longjmp(g->jumper[g->jump_level], 34);
- } else if (Dsp)
+ throw 34;
+ } else if (Dsp)
for (int i = 0; p[i]; i++)
if (p[i] == '.')
p[i] = Dsp;
@@ -1532,8 +1532,8 @@ void CSVCOL::WriteColumn(PGLOBAL g)
if (Fldnum < 0) {
// This can happen for wrong offset value in XDB files
sprintf(g->Message, MSG(BAD_FIELD_RANK), Fldnum + 1, Name);
- longjmp(g->jumper[g->jump_level], 34);
- } else
+ throw 34;
+ } else
strncpy(tdbp->Field[Fldnum], p, flen);
if (trace > 1)
diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h
index e5655435be7..396bba568ff 100644
--- a/storage/connect/tabfmt.h
+++ b/storage/connect/tabfmt.h
@@ -13,7 +13,7 @@ typedef class TDBFMT *PTDBFMT;
/***********************************************************************/
/* Functions used externally. */
/***********************************************************************/
-PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info);
+PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info);
/***********************************************************************/
/* CSV table. */
@@ -21,7 +21,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info);
class DllExport CSVDEF : public DOSDEF { /* Logical table description */
friend class TDBCSV;
friend class TDBCCL;
- friend PQRYRES CSVColumns(PGLOBAL, char *, PTOS, bool);
+ friend PQRYRES CSVColumns(PGLOBAL, PCSZ, PTOS, bool);
public:
// Constructor
CSVDEF(void);
@@ -53,7 +53,7 @@ public:
class DllExport TDBCSV : public TDBDOS {
friend class CSVCOL;
friend class MAPFAM;
- friend PQRYRES CSVColumns(PGLOBAL, char *, PTOS, bool);
+ friend PQRYRES CSVColumns(PGLOBAL, PCSZ, PTOS, bool);
public:
// Constructor
TDBCSV(PCSVDEF tdp, PTXF txfp);
diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp
index 5431e35e0ec..7c82a2fc138 100644
--- a/storage/connect/tabjdbc.cpp
+++ b/storage/connect/tabjdbc.cpp
@@ -227,41 +227,8 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (rc == RC_FX) // Error
return true;
-//else if (rc == RC_OK) { // Url was not a server name
-// Tabname = GetStringCatInfo(g, "Name",
-// (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
-// Tabname = GetStringCatInfo(g, "Tabname", Tabname);
-// Username = GetStringCatInfo(g, "User", NULL);
-// Password = GetStringCatInfo(g, "Password", NULL);
-//} // endif rc
-
-//if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
-// Read_Only = true;
Wrapname = GetStringCatInfo(g, "Wrapper", NULL);
-//Prop = GetStringCatInfo(g, "Properties", NULL);
-//Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
-//Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
-//Tabschema = GetStringCatInfo(g, "Dbname", NULL);
-//Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
-
-//if (Catfunc == FNC_COL)
-// Colpat = GetStringCatInfo(g, "Colpat", NULL);
-
-//if (Catfunc == FNC_TABLE)
-// Tabtyp = GetStringCatInfo(g, "Tabtype", NULL);
-
-//Qrystr = GetStringCatInfo(g, "Query_String", "?");
-//Sep = GetStringCatInfo(g, "Separator", NULL);
-//Xsrc = GetBoolCatInfo("Execsrc", FALSE);
-//Maxerr = GetIntCatInfo("Maxerr", 0);
-//Maxres = GetIntCatInfo("Maxres", 0);
-//Quoted = GetIntCatInfo("Quoted", 0);
-// Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT);
-// Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT);
-//Scrollable = GetBoolCatInfo("Scrollable", false);
-//Memory = GetIntCatInfo("Memory", 0);
-//Pseudo = 2; // FILID is Ok but not ROWID
return false;
} // end of DefineAM
@@ -341,9 +308,6 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBEXT(tdp)
WrapName = tdp->Wrapname;
Ops.User = tdp->Username;
Ops.Pwd = tdp->Password;
-// Ops.Properties = tdp->Prop;
-// Ops.Cto = tdp->Cto;
-// Ops.Qto = tdp->Qto;
Ops.Scrollable = tdp->Scrollable;
} else {
WrapName = NULL;
@@ -351,13 +315,9 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBEXT(tdp)
Ops.Url = NULL;
Ops.User = NULL;
Ops.Pwd = NULL;
-// Ops.Properties = NULL;
-// Ops.Cto = DEFAULT_LOGIN_TIMEOUT;
-// Ops.Qto = DEFAULT_QUERY_TIMEOUT;
Ops.Scrollable = false;
} // endif tdp
-//Ncol = 0;
Prepared = false;
Werr = false;
Rerr = false;
@@ -370,7 +330,6 @@ TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBEXT(tdbp)
Cnp = tdbp->Cnp;
WrapName = tdbp->WrapName;
Ops = tdbp->Ops;
-//Ncol = tdbp->Ncol;
Prepared = tdbp->Prepared;
Werr = tdbp->Werr;
Rerr = tdbp->Rerr;
@@ -406,10 +365,11 @@ PCOL TDBJDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/***********************************************************************/
bool TDBJDBC::MakeInsert(PGLOBAL g)
{
- char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
+ PCSZ schmp = NULL;
+ char *catp = NULL, buf[NAM_LEN * 3];
int len = 0;
uint pos;
- bool b = false, oom = false;
+ bool b = false;
PTABLE tablep = To_Table;
PCOL colp;
@@ -446,32 +406,32 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
Query = new(g)STRING(g, len, "INSERT INTO ");
if (catp) {
- oom |= Query->Append(catp);
+ Query->Append(catp);
if (schmp) {
- oom |= Query->Append('.');
- oom |= Query->Append(schmp);
+ Query->Append('.');
+ Query->Append(schmp);
} // endif schmp
- oom |= Query->Append('.');
+ Query->Append('.');
} else if (schmp) {
- oom |= Query->Append(schmp);
- oom |= Query->Append('.');
+ Query->Append(schmp);
+ Query->Append('.');
} // endif schmp
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
- oom |= Query->Append(Quote);
- oom |= Query->Append(buf);
- oom |= Query->Append(Quote);
+ Query->Append(Quote);
+ Query->Append(buf);
+ Query->Append(Quote);
} else
- oom |= Query->Append(buf);
+ Query->Append(buf);
- oom |= Query->Append('(');
+ Query->Append('(');
for (colp = Columns; colp; colp = colp->GetNext()) {
if (b)
- oom |= Query->Append(", ");
+ Query->Append(", ");
else
b = true;
@@ -480,15 +440,15 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
- oom |= Query->Append(Quote);
- oom |= Query->Append(buf);
- oom |= Query->Append(Quote);
+ Query->Append(Quote);
+ Query->Append(buf);
+ Query->Append(Quote);
} else
- oom |= Query->Append(buf);
+ Query->Append(buf);
} // endfor colp
- if ((oom |= Query->Append(") VALUES ("))) {
+ if ((Query->Append(") VALUES ("))) {
strcpy(g->Message, "MakeInsert: Out of memory");
return true;
} else // in case prepared statement fails
@@ -496,9 +456,9 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
// Make prepared statement
for (int i = 0; i < Nparm; i++)
- oom |= Query->Append("?,");
+ Query->Append("?,");
- if (oom) {
+ if (Query->IsTruncated()) {
strcpy(g->Message, "MakeInsert: Out of memory");
return true;
} else
@@ -737,18 +697,12 @@ bool TDBJDBC::SetRecpos(PGLOBAL g, int recpos)
{
if (Jcp->m_Full) {
Fpos = 0;
-// CurNum = 0;
CurNum = 1;
} else if (Memory == 3) {
-// Fpos = recpos;
-// CurNum = -1;
Fpos = 0;
CurNum = recpos;
} else if (Ops.Scrollable) {
// Is new position in the current row set?
-// if (recpos >= Curpos && recpos < Curpos + Rbuf) {
-// CurNum = recpos - Curpos;
-// Fpos = 0;
if (recpos > 0 && recpos <= Rbuf) {
CurNum = recpos;
Fpos = recpos;
@@ -797,7 +751,7 @@ bool TDBJDBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
To_CondFil->Body= (char*)PlugSubAlloc(g, NULL, 0);
*To_CondFil->Body= 0;
- if ((To_CondFil = hc->CheckCond(g, To_CondFil, To_CondFil->Cond)))
+ if ((To_CondFil = hc->CheckCond(g, To_CondFil, Cond)))
PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1);
} // endif active_index
@@ -911,7 +865,6 @@ int TDBJDBC::WriteDB(PGLOBAL g)
// an insert query for each line to insert
uint len = Query->GetLength();
char buf[64];
- bool oom = false;
// Make the Insert command value list
for (PCOL colp = Columns; colp; colp = colp->GetNext()) {
@@ -919,28 +872,28 @@ int TDBJDBC::WriteDB(PGLOBAL g)
char *s = colp->GetValue()->GetCharString(buf);
if (colp->GetResultType() == TYPE_STRING)
- oom |= Query->Append_quoted(s);
+ Query->Append_quoted(s);
else if (colp->GetResultType() == TYPE_DATE) {
DTVAL *dtv = (DTVAL*)colp->GetValue();
if (dtv->IsFormatted())
- oom |= Query->Append_quoted(s);
+ Query->Append_quoted(s);
else
- oom |= Query->Append(s);
+ Query->Append(s);
} else
- oom |= Query->Append(s);
+ Query->Append(s);
} else
- oom |= Query->Append("NULL");
+ Query->Append("NULL");
- oom |= Query->Append(',');
+ Query->Append(',');
} // endfor colp
- if (unlikely(oom)) {
+ if (unlikely(Query->IsTruncated())) {
strcpy(g->Message, "WriteDB: Out of memory");
return RC_FX;
- } // endif oom
+ } // endif Query
Query->RepLast(')');
@@ -990,11 +943,6 @@ int TDBJDBC::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
void TDBJDBC::CloseDB(PGLOBAL g)
{
- //if (To_Kindex) {
- // To_Kindex->Close();
- // To_Kindex = NULL;
- // } // endif
-
if (Jcp)
Jcp->Close();
@@ -1019,7 +967,7 @@ void TDBJDBC::CloseDB(PGLOBAL g)
/***********************************************************************/
/* JDBCCOL public constructor. */
/***********************************************************************/
-JDBCCOL::JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+JDBCCOL::JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: EXTCOL(cdp, tdbp, cprec, i, am)
{
} // end of JDBCCOL constructor
@@ -1039,54 +987,6 @@ JDBCCOL::JDBCCOL(JDBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{
} // end of JDBCCOL copy constructor
-#if 0
-/***********************************************************************/
-/* SetBuffer: prepare a column block for write operation. */
-/***********************************************************************/
-bool JDBCCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
-{
- if (!(To_Val = value)) {
- sprintf(g->Message, MSG(VALUE_ERROR), Name);
- return true;
- } else if (Buf_Type == value->GetType()) {
- // Values are of the (good) column type
- if (Buf_Type == TYPE_DATE) {
- // If any of the date values is formatted
- // output format must be set for the receiving table
- if (GetDomain() || ((DTVAL *)value)->IsFormatted())
- goto newval; // This will make a new value;
-
- } else if (Buf_Type == TYPE_DOUBLE)
- // Float values must be written with the correct (column) precision
- // Note: maybe this should be forced by ShowValue instead of this ?
- value->SetPrec(GetScale());
-
- Value = value; // Directly access the external value
- } else {
- // Values are not of the (good) column type
- if (check) {
- sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name,
- GetTypeName(Buf_Type), GetTypeName(value->GetType()));
- return true;
- } // endif check
-
- newval:
- if (InitValue(g)) // Allocate the matching value block
- return true;
-
- } // endif's Value, Buf_Type
-
- // Because Colblk's have been made from a copy of the original TDB in
- // case of Update, we must reset them to point to the original one.
- if (To_Tdb->GetOrig())
- To_Tdb = (PTDB)To_Tdb->GetOrig();
-
- // Set the Column
- Status = (ok) ? BUF_EMPTY : BUF_NO;
- return false;
-} // end of SetBuffer
-#endif // 0
-
/***********************************************************************/
/* ReadColumn: when SQLFetch is used there is nothing to do as the */
/* column buffer was bind to the record set. This is also the case */
@@ -1196,26 +1096,6 @@ PCMD TDBXJDC::MakeCMD(PGLOBAL g)
return xcmd;
} // end of MakeCMD
-#if 0
-/***********************************************************************/
-/* JDBC Bind Parameter function. */
-/***********************************************************************/
-bool TDBXJDC::BindParameters(PGLOBAL g)
-{
- PJDBCCOL colp;
-
- for (colp = (PJDBCCOL)Columns; colp; colp = (PJDBCCOL)colp->Next) {
- colp->AllocateBuffers(g, 0);
-
- if (Jcp->BindParam(colp))
- return true;
-
- } // endfor colp
-
- return false;
-} // end of BindParameters
-#endif // 0
-
/***********************************************************************/
/* XDBC GetMaxSize: returns table size (not always one row). */
/***********************************************************************/
@@ -1332,8 +1212,8 @@ int TDBXJDC::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
/* JSRCCOL public constructor. */
/***********************************************************************/
-JSRCCOL::JSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
- : JDBCCOL(cdp, tdbp, cprec, i, am)
+JSRCCOL::JSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
+ : JDBCCOL(cdp, tdbp, cprec, i, am)
{
// Set additional JDBC access method information for column.
Flag = cdp->GetOffset();
@@ -1416,17 +1296,3 @@ PQRYRES TDBJDBCL::GetResult(PGLOBAL g)
{
return JDBCColumns(g, Schema, Tab, Colpat, Maxres, false, &Ops);
} // end of GetResult
-
-#if 0
-/* ---------------------------TDBJSRC class -------------------------- */
-
-/***********************************************************************/
-/* GetResult: Get the list of JDBC data sources. */
-/***********************************************************************/
-PQRYRES TDBJSRC::GetResult(PGLOBAL g)
-{
- return JDBCDataSources(g, Maxres, false);
-} // end of GetResult
-
-/* ------------------------ End of TabJDBC --------------------------- */
-#endif // 0
diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h
index 46d2073e923..8fda3cec90b 100644
--- a/storage/connect/tabjdbc.h
+++ b/storage/connect/tabjdbc.h
@@ -1,7 +1,7 @@
/*************** Tabjdbc H Declares Source Code File (.H) **************/
-/* Name: TABJDBC.H Version 1.0 */
+/* Name: TABJDBC.H Version 1.1 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2016 */
+/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */
/* */
/* This file contains the TDBJDBC classes declares. */
/***********************************************************************/
@@ -14,9 +14,6 @@ typedef class TDBJDBC *PTDBJDBC;
typedef class JDBCCOL *PJDBCCOL;
typedef class TDBXJDC *PTDBXJDC;
typedef class JSRCCOL *PJSRCCOL;
-//typedef class TDBOIF *PTDBOIF;
-//typedef class OIFCOL *POIFCOL;
-//typedef class TDBJSRC *PTDBJSRC;
/***********************************************************************/
/* JDBC table. */
@@ -68,20 +65,14 @@ public:
// Methods
virtual PTDB Clone(PTABS t);
-//virtual int GetRecpos(void);
virtual bool SetRecpos(PGLOBAL g, int recpos);
-//virtual PSZ GetFile(PGLOBAL g);
-//virtual void SetFile(PGLOBAL g, PSZ fn);
virtual void ResetSize(void);
-//virtual int GetAffectedRows(void) {return AftRows;}
- virtual PSZ GetServer(void) { return "JDBC"; }
+ virtual PCSZ GetServer(void) { return "JDBC"; }
virtual int Indexable(void) { return 2; }
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int Cardinality(PGLOBAL g);
-//virtual int GetMaxSize(PGLOBAL g);
-//virtual int GetProgMax(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
@@ -91,21 +82,14 @@ public:
protected:
// Internal functions
-//int Decode(char *utf, char *buf, size_t n);
-//bool MakeSQL(PGLOBAL g, bool cnt);
bool MakeInsert(PGLOBAL g);
-//virtual bool MakeCommand(PGLOBAL g);
-//bool MakeFilter(PGLOBAL g, bool c);
bool SetParameters(PGLOBAL g);
-//char *MakeUpdate(PGLOBAL g);
-//char *MakeDelete(PGLOBAL g);
// Members
JDBConn *Jcp; // Points to a JDBC connection class
JDBCCOL *Cnp; // Points to count(*) column
JDBCPARM Ops; // Additional parameters
char *WrapName; // Points to Java wrapper name
-//int Ncol; // The column number
bool Prepared; // True when using prepared statement
bool Werr; // Write error
bool Rerr; // Rewind error
@@ -119,7 +103,7 @@ class JDBCCOL : public EXTCOL {
friend class TDBJDBC;
public:
// Constructors
- JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "JDBC");
+ JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "JDBC");
JDBCCOL(JDBCCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
@@ -152,12 +136,6 @@ public:
virtual AMT GetAmType(void) {return TYPE_AM_XDBC;}
// Methods
- //virtual int GetRecpos(void);
- //virtual PSZ GetFile(PGLOBAL g);
- //virtual void SetFile(PGLOBAL g, PSZ fn);
- //virtual void ResetSize(void);
- //virtual int GetAffectedRows(void) {return AftRows;}
- //virtual PSZ GetServer(void) {return "JDBC";}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
@@ -172,7 +150,6 @@ public:
protected:
// Internal functions
PCMD MakeCMD(PGLOBAL g);
- //bool BindParameters(PGLOBAL g);
// Members
PCMD Cmdlist; // The commands to execute
@@ -188,7 +165,7 @@ class JSRCCOL : public JDBCCOL {
friend class TDBXJDC;
public:
// Constructors
- JSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "JDBC");
+ JSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "JDBC");
// Implementation
virtual int GetAmType(void) {return TYPE_AM_JDBC;}
@@ -196,7 +173,6 @@ public:
// Methods
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
- // void Print(PGLOBAL g, FILE *, uint);
protected:
// Members
@@ -233,9 +209,9 @@ protected:
virtual PQRYRES GetResult(PGLOBAL g);
// Members
- char *Schema; // Points to schema name or NULL
- char *Tab; // Points to JDBC table name or pattern
- char *Tabtype; // Points to JDBC table type
+ PCSZ Schema; // Points to schema name or NULL
+ PCSZ Tab; // Points to JDBC table name or pattern
+ PCSZ Tabtype; // Points to JDBC table type
JDBCPARM Ops; // Additional parameters
}; // end of class TDBJTB
@@ -252,24 +228,7 @@ protected:
virtual PQRYRES GetResult(PGLOBAL g);
// Members
- char *Colpat; // Points to catalog column pattern
+ PCSZ Colpat; // Points to catalog column pattern
}; // end of class TDBJDBCL
-#if 0
-/***********************************************************************/
-/* This is the class declaration for the Data Sources catalog table. */
-/***********************************************************************/
-class TDBJSRC : public TDBJDRV {
-public:
- // Constructor
- TDBJSRC(PJDBCDEF tdp) : TDBJDRV(tdp) {}
-
-protected:
- // Specific routines
- virtual PQRYRES GetResult(PGLOBAL g);
-
- // No additional Members
-}; // end of class TDBJSRC
-#endif // 0
-
#endif // !NJDBC
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 1e11d454cfc..9950dfeda3e 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -1,6 +1,6 @@
/************* tabjson C++ Program Source Code File (.CPP) *************/
-/* PROGRAM NAME: tabjson Version 1.3 */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2016 */
+/* PROGRAM NAME: tabjson Version 1.4 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
/* This program are the JSON class DB execution routines. */
/***********************************************************************/
@@ -31,6 +31,9 @@
#if defined(ZIP_SUPPORT)
#include "filamzip.h"
#endif // ZIP_SUPPORT
+#if defined(MONGO_SUPPORT)
+#include "mongofam.h"
+#endif // MONGO_SUPPORT
#include "tabmul.h"
#include "checklvl.h"
#include "resource.h"
@@ -44,9 +47,11 @@
#define USE_G 1 /* Use recoverable memory if 1 */
/***********************************************************************/
-/* External function. */
+/* External functions. */
/***********************************************************************/
USETEMP UseTemp(void);
+bool IsNum(PSZ s);
+char *NextChr(PSZ s, char sep);
typedef struct _jncol {
struct _jncol *Next;
@@ -63,16 +68,17 @@ typedef struct _jncol {
/* JSONColumns: construct the result blocks containing the description */
/* of all the columns of a table contained inside a JSON file. */
/***********************************************************************/
-PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
+PQRYRES JSONColumns(PGLOBAL g, char *db, char *dsn, 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};
static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
- char colname[65], fmt[129];
+ char *p, colname[65], fmt[129];
int i, j, lvl, n = 0;
int ncol = sizeof(buftyp) / sizeof(int);
+ PCSZ sep;
PVAL valp;
JCOL jcol;
PJCL jcp, fjcp = NULL, pjcp = NULL;
@@ -104,6 +110,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
/*********************************************************************/
lvl = GetIntegerTableOption(g, topt, "Level", 0);
lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl;
+ sep = GetStringTableOption(g, topt, "Separator", ".");
tdp = new(g) JSONDEF;
#if defined(ZIP_SUPPORT)
@@ -112,20 +119,40 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
#endif // ZIP_SUPPORT
tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL);
- if (!tdp->Fn) {
+ if (!tdp->Fn && !dsn) {
strcpy(g->Message, MSG(MISSING_FNAME));
return NULL;
} // endif Fn
- tdp->Database = SetPath(g, db);
+ if (!(tdp->Database = SetPath(g, db)))
+ return NULL;
+
tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
+ tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL);
if (trace)
htrc("File %s objname=%s pretty=%d lvl=%d\n",
tdp->Fn, tdp->Objname, tdp->Pretty, lvl);
+ if (dsn && *dsn)
+ tdp->Uri = dsn;
+
+ if (tdp->Uri) {
+#if defined(MONGO_SUPPORT)
+ tdp->Collname = GetStringTableOption(g, topt, "Name", NULL);
+ tdp->Collname = GetStringTableOption(g, topt, "Tabname", tdp->Collname);
+ tdp->Schema = GetStringTableOption(g, topt, "Dbname", "test");
+ tdp->Options = PlugDup(g, "all");
+// tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
+ tdp->Pretty = 0;
+#else // !MONGO_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
+ return NULL;
+#endif // !MONGO_SUPPORT
+ } // endif Uri
+
if (tdp->Pretty == 2) {
if (tdp->Zipped) {
#if defined(ZIP_SUPPORT)
@@ -151,11 +178,18 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
if (tdp->Zipped) {
#if defined(ZIP_SUPPORT)
- tjnp = new(g)TDBJSN(tdp, new(g)UNZFAM(tdp));
+ tjnp = new(g)TDBJSN(tdp, new(g) UNZFAM(tdp));
#else // !ZIP_SUPPORT
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return NULL;
#endif // !ZIP_SUPPORT
+ } else if (tdp->Uri) {
+#if defined(MONGO_SUPPORT)
+ tjnp = new(g) TDBJSN(tdp, new(g) MGOFAM(tdp));
+#else // !MONGO_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
+ return NULL;
+#endif // !MONGO_SUPPORT
} else
tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp));
@@ -168,7 +202,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
G->Sarea_Size = tdp->Lrecl * 10;
G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
PlugSubSet(G, G->Sarea, G->Sarea_Size);
- G->jump_level = -1;
+ G->jump_level = 0;
tjnp->SetG(G);
#else
tjnp->SetG(g);
@@ -197,6 +231,14 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
jcol.Found = true;
colname[64] = 0;
fmt[128] = 0;
+ *fmt = '$';
+
+ if (!tdp->Uri) {
+ fmt[1] = '.';
+ p = fmt + 2;
+ } else
+ p = fmt + 1;
+
jrp = (PJPR*)PlugSubAlloc(g, NULL, sizeof(PJPR) * lvl);
/*********************************************************************/
@@ -209,7 +251,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
more:
strncpy(colname, jpp->GetKey(), 64);
- *fmt = 0;
+ *p = 0;
j = 0;
jvp = jpp->GetVal();
@@ -224,8 +266,8 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
jcol.Len = jcol.Scale = 0;
jcol.Cbn = true;
} else if (j < lvl) {
- if (!*fmt)
- strcpy(fmt, colname);
+ if (!*p)
+ strcat(fmt, colname);
jsp = jvp->GetJson();
@@ -234,13 +276,24 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
if (!jrp[j])
jrp[j] = jsp->GetFirst();
- strncat(strncat(fmt, ":", 128), jrp[j]->GetKey(), 128);
- strncat(strncat(colname, "_", 64), jrp[j]->GetKey(), 64);
- jvp = jrp[j]->GetVal();
- j++;
+ if (*jrp[j]->GetKey() != '$') {
+ strncat(strncat(fmt, sep, 128), jrp[j]->GetKey(), 128);
+ strncat(strncat(colname, "_", 64), jrp[j]->GetKey(), 64);
+ } // endif Key
+
+ jvp = jrp[j]->GetVal();
+ j++;
break;
case TYPE_JAR:
- strncat(fmt, ":", 128);
+ if (!tdp->Xcol || stricmp(tdp->Xcol, colname)) {
+ if (tdp->Uri)
+ strncat(strncat(fmt, sep, 128), "0", 128);
+ else
+ strncat(fmt, "[0]", 128);
+
+ } else
+ strncat(fmt, (tdp->Uri ? sep : "[]"), 128);
+
jvp = jsp->GetValue(0);
break;
default:
@@ -262,13 +315,18 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
break;
if (jcp) {
- if (jcp->Type != jcol.Type)
- jcp->Type = TYPE_STRING;
+ if (jcp->Type != jcol.Type) {
+ if (jcp->Type == TYPE_UNKNOWN)
+ jcp->Type = jcol.Type;
+ else if (jcol.Type != TYPE_UNKNOWN)
+ jcp->Type = TYPE_STRING;
+
+ } // endif Type
- if (*fmt && (!jcp->Fmt || strlen(jcp->Fmt) < strlen(fmt))) {
+ if (*p && (!jcp->Fmt || strlen(jcp->Fmt) < strlen(fmt))) {
jcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], strlen(fmt));
- } // endif *fmt
+ } // endif fmt
jcp->Len = MY_MAX(jcp->Len, jcol.Len);
jcp->Scale = MY_MAX(jcp->Scale, jcol.Scale);
@@ -282,7 +340,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
jcp->Name = PlugDup(g, colname);
length[0] = MY_MAX(length[0], strlen(colname));
- if (*fmt) {
+ if (*p) {
jcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], strlen(fmt));
} else
@@ -336,7 +394,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
skipit:
if (trace)
- htrc("CSVColumns: n=%d len=%d\n", n, length[0]);
+ htrc("JSONColumns: n=%d len=%d\n", n, length[0]);
/*********************************************************************/
/* Allocate the structures used to refer to the result set. */
@@ -404,6 +462,12 @@ JSONDEF::JSONDEF(void)
Limit = 1;
Base = 0;
Strict = false;
+ Sep = '.';
+#if defined(MONGO_SUPPORT)
+ Uri = NULL;
+ Collname = Schema = Options = NULL;
+ Pipe = false;
+#endif // MONGO_SUPPORT
} // end of JSONDEF constructor
/***********************************************************************/
@@ -417,7 +481,24 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
Pretty = GetIntCatInfo("Pretty", 2);
Limit = GetIntCatInfo("Limit", 10);
Base = GetIntCatInfo("Base", 0) ? 1 : 0;
- return DOSDEF::DefineAM(g, "DOS", poff);
+ Sep = *GetStringCatInfo(g, "Separator", ".");
+
+ if (Uri = GetStringCatInfo(g, "Connect", NULL)) {
+#if defined(MONGO_SUPPORT)
+ Collname = GetStringCatInfo(g, "Name",
+ (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
+ Collname = GetStringCatInfo(g, "Tabname", Collname);
+ Schema = GetStringCatInfo(g, "Dbname", "test");
+ Options = GetStringCatInfo(g, "Colist", NULL);
+ Pipe = GetBoolCatInfo("Pipeline", false);
+ Pretty = 0;
+#else // !MONGO_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
+ return true;
+#endif // !MONGO_SUPPORT
+ } // endif Uri
+
+ return DOSDEF::DefineAM(g, (Uri ? "XMGO" : "DOS"), poff);
} // end of DefineAM
/***********************************************************************/
@@ -439,9 +520,16 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
!(tmp == TMP_FORCE &&
(m == MODE_UPDATE || m == MODE_DELETE));
- if (Zipped) {
+ if (Uri) {
+#if defined(MONGO_SUPPORT)
+ txfp = new(g) MGOFAM(this);
+#else // !MONGO_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
+ return NULL;
+#endif // !MONGO_SUPPORT
+ } else if (Zipped) {
#if defined(ZIP_SUPPORT)
- if (m == MODE_READ || m == MODE_UPDATE) {
+ if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
txfp = new(g) UNZFAM(this);
} else if (m == MODE_INSERT) {
txfp = new(g) ZIPFAM(this);
@@ -463,7 +551,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
return NULL;
#endif // !GZ_SUPPORT
- } else if (map)
+ } else if (map)
txfp = new(g) MAPFAM(this);
else
txfp = new(g) DOSFAM(this);
@@ -478,7 +566,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
G->Sarea_Size = Lrecl * 10;
G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
PlugSubSet(G, G->Sarea, G->Sarea_Size);
- G->jump_level = -1;
+ G->jump_level = 0;
((TDBJSN*)tdbp)->G = G;
#else
((TDBJSN*)tdbp)->G = g;
@@ -486,7 +574,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
} else {
if (Zipped) {
#if defined(ZIP_SUPPORT)
- if (m == MODE_READ || m == MODE_UPDATE) {
+ if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
txfp = new(g) UNZFAM(this);
} else if (m == MODE_INSERT) {
strcpy(g->Message, "INSERT supported only for zipped JSON when pretty=0");
@@ -531,14 +619,16 @@ TDBJSN::TDBJSN(PJDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
Limit = tdp->Limit;
Pretty = tdp->Pretty;
B = tdp->Base ? 1 : 0;
+ Sep = tdp->Sep;
Strict = tdp->Strict;
} else {
Jmode = MODE_OBJECT;
Objname = NULL;
- Xcol = NULL;
+ Xcol = NULL;
Limit = 1;
Pretty = 0;
B = 0;
+ Sep = '.';
Strict = false;
} // endif tdp
@@ -568,6 +658,7 @@ TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp)
SameRow = tdbp->SameRow;
Xval = tdbp->Xval;
B = tdbp->B;
+ Sep = tdbp->Sep;
Pretty = tdbp->Pretty;
Strict = tdbp->Strict;
Comma = tdbp->Comma;
@@ -650,21 +741,27 @@ PJSON TDBJSN::FindRow(PGLOBAL g)
PJSON jsp = Row;
PJVAL val = NULL;
- for (objpath = PlugDup(g, Objname); jsp && objpath; objpath = p) {
- if ((p = strchr(objpath, ':')))
- *p++ = 0;
+ for (objpath = PlugDup(g, Objname); jsp && objpath; objpath = p) {
+ if ((p = strchr(objpath, Sep)))
+ *p++ = 0;
- if (*objpath != '[') { // objpass is a key
- val = (jsp->GetType() == TYPE_JOB) ?
- jsp->GetObject()->GetValue(objpath) : NULL;
- } else if (objpath[strlen(objpath)-1] == ']') {
- val = (jsp->GetType() == TYPE_JAR) ?
- jsp->GetArray()->GetValue(atoi(objpath+1) - B) : NULL;
- } else
- val = NULL;
+ if (*objpath != '[' && !IsNum(objpath)) { // objpass is a key
+ val = (jsp->GetType() == TYPE_JOB) ?
+ jsp->GetObject()->GetValue(objpath) : NULL;
+ } else {
+ if (*objpath == '[') {
+ if (objpath[strlen(objpath) - 1] == ']')
+ objpath++;
+ else
+ return NULL;
+ } // endif [
+
+ val = (jsp->GetType() == TYPE_JAR) ?
+ jsp->GetArray()->GetValue(atoi(objpath) - B) : NULL;
+ } // endif objpath
- jsp = (val) ? val->GetJson() : NULL;
- } // endfor objpath
+ jsp = (val) ? val->GetJson() : NULL;
+ } // endfor objpath
return jsp;
} // end of FindRow
@@ -695,6 +792,9 @@ bool TDBJSN::OpenDB(PGLOBAL g)
return true;
} // endswitch Jmode
+ if (Xcol && Txfp->GetAmType() != TYPE_AM_MGO)
+ To_Filter = NULL; // Imcompatible
+
} // endif Use
return TDBDOS::OpenDB(g);
@@ -780,63 +880,70 @@ int TDBJSN::ReadDB(PGLOBAL g)
/* Make the top tree from the object path. */
/***********************************************************************/
int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
- {
- if (Objname) {
- if (!Val) {
- // Parse and allocate Objname item(s)
- char *p;
- char *objpath = PlugDup(g, Objname);
- int i;
- PJOB objp;
- PJAR arp;
- PJVAL val = NULL;
-
- Top = NULL;
-
- for (; objpath; objpath = p) {
- if ((p = strchr(objpath, ':')))
- *p++ = 0;
-
- if (*objpath != '[') {
- objp = new(g) JOBJECT;
-
- if (!Top)
- Top = objp;
-
- if (val)
- val->SetValue(objp);
-
- val = new(g) JVALUE;
- objp->SetValue(g, val, objpath);
- } else if (objpath[strlen(objpath)-1] == ']') {
- arp = new(g) JARRAY;
+{
+ if (Objname) {
+ if (!Val) {
+ // Parse and allocate Objname item(s)
+ char *p;
+ char *objpath = PlugDup(g, Objname);
+ int i;
+ PJOB objp;
+ PJAR arp;
+ PJVAL val = NULL;
- if (!Top)
- Top = arp;
-
- if (val)
- val->SetValue(arp);
-
- val = new(g) JVALUE;
- i = atoi(objpath+1) - B;
- arp->SetValue(g, val, i);
- arp->InitArray(g);
- } else {
- sprintf(g->Message, "Invalid Table path %s", Objname);
- return RC_FX;
- } // endif objpath
-
- } // endfor p
+ Top = NULL;
- Val = val;
- } // endif Val
+ for (; objpath; objpath = p) {
+ if ((p = strchr(objpath, Sep)))
+ *p++ = 0;
- Val->SetValue(jsp);
- } else
- Top = jsp;
+ if (*objpath != '[' && !IsNum(objpath)) {
+ objp = new(g) JOBJECT;
- return RC_OK;
- } // end of MakeTopTree
+ if (!Top)
+ Top = objp;
+
+ if (val)
+ val->SetValue(objp);
+
+ val = new(g) JVALUE;
+ objp->SetValue(g, val, objpath);
+ } else {
+ if (*objpath == '[') {
+ // Old style
+ if (objpath[strlen(objpath) - 1] != ']') {
+ sprintf(g->Message, "Invalid Table path %s", Objname);
+ return RC_FX;
+ } else
+ objpath++;
+
+ } // endif objpath
+
+ arp = new(g) JARRAY;
+
+ if (!Top)
+ Top = arp;
+
+ if (val)
+ val->SetValue(arp);
+
+ val = new(g) JVALUE;
+ i = atoi(objpath) - B;
+ arp->SetValue(g, val, i);
+ arp->InitArray(g);
+ } // endif objpath
+
+ } // endfor p
+
+ Val = val;
+ } // endif Val
+
+ Val->SetValue(jsp);
+ } else
+ Top = jsp;
+
+ return RC_OK;
+} // end of MakeTopTree
/***********************************************************************/
/* PrepareWriting: Prepare the line for WriteDB. */
@@ -865,24 +972,21 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
} // end of PrepareWriting
- /***********************************************************************/
- /* WriteDB: Data Base write routine for DOS access method. */
- /***********************************************************************/
- int TDBJSN::WriteDB(PGLOBAL g)
+/***********************************************************************/
+/* WriteDB: Data Base write routine for DOS access method. */
+/***********************************************************************/
+int TDBJSN::WriteDB(PGLOBAL g)
{
int rc = TDBDOS::WriteDB(g);
#if USE_G
- if (rc == RC_FX)
- strcpy(g->Message, G->Message);
-
PlugSubSet(G, G->Sarea, G->Sarea_Size);
#endif
Row->Clear();
return rc;
} // end of WriteDB
- /* ---------------------------- JSONCOL ------------------------------ */
+/* ---------------------------- JSONCOL ------------------------------ */
/***********************************************************************/
/* JSONCOL public constructor. */
@@ -896,6 +1000,7 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
MulVal = NULL;
Nodes = NULL;
Nod = 0;
+ Sep = Tjp->Sep;
Xnod = -1;
Xpd = false;
Parsed = false;
@@ -913,7 +1018,8 @@ JSONCOL::JSONCOL(JSONCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
MulVal = col1->MulVal;
Nodes = col1->Nodes;
Nod = col1->Nod;
- Xnod = col1->Xnod;
+ Sep = col1->Sep;
+ Xnod = col1->Xnod;
Xpd = col1->Xpd;
Parsed = col1->Parsed;
} // end of JSONCOL copy constructor
@@ -956,125 +1062,132 @@ bool JSONCOL::CheckExpand(PGLOBAL g, int i, PSZ nm, bool b)
/* Analyse array processing options. */
/***********************************************************************/
bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
- {
- int n = (int)strlen(p);
- bool dg = true, b = false;
- PJNODE jnp = &Nodes[i];
-
- if (*p) {
- if (p[--n] == ']') {
- p[n--] = 0;
- p++;
- } else {
- // Wrong array specification
- sprintf(g->Message,
- "Invalid array specification %s for %s", p, Name);
- return true;
- } // endif p
-
- } else
- b = true;
-
- // To check whether a numeric Rank was specified
- for (int k = 0; dg && p[k]; k++)
- dg = isdigit(p[k]) > 0;
-
- if (!n) {
- // Default specifications
- if (CheckExpand(g, i, nm, false))
- return true;
- else if (jnp->Op != OP_EXP) {
- if (b) {
- // Return 1st value (B is the index base)
- jnp->Rank = Tjp->B;
- jnp->Op = OP_EQ;
- } else if (!Value->IsTypeNum()) {
- jnp->CncVal = AllocateValue(g, (void*)", ", TYPE_STRING);
- jnp->Op = OP_CNC;
- } else
- jnp->Op = OP_ADD;
-
- } // endif OP
-
- } else if (dg) {
- // Return nth value
- jnp->Rank = atoi(p) - Tjp->B;
- jnp->Op = OP_EQ;
- } else if (n == 1) {
- // Set the Op value;
- switch (*p) {
- case '+': jnp->Op = OP_ADD; break;
- case '*': jnp->Op = OP_MULT; break;
- case '>': jnp->Op = OP_MAX; break;
- case '<': jnp->Op = OP_MIN; break;
- case '!': jnp->Op = OP_SEP; break; // Average
- case '#': jnp->Op = OP_NUM; break;
- case 'x':
- case 'X': // Expand this array
- if (!Tjp->Xcol && nm) {
- Xpd = true;
- jnp->Op = OP_EXP;
- Tjp->Xval = i;
- Tjp->Xcol = nm;
- } else if (CheckExpand(g, i, nm, true))
- return true;
-
- break;
- default:
- sprintf(g->Message,
- "Invalid function specification %c for %s", *p, Name);
- return true;
- } // endswitch *p
-
- } else if (*p == '"' && p[n - 1] == '"') {
- // This is a concat specification
- jnp->Op = OP_CNC;
-
- if (n > 2) {
- // Set concat intermediate string
- p[n - 1] = 0;
- jnp->CncVal = AllocateValue(g, p + 1, TYPE_STRING);
- } // endif n
-
- } else {
- sprintf(g->Message, "Wrong array specification for %s", Name);
- return true;
- } // endif's
-
- // For calculated arrays, a local Value must be used
- switch (jnp->Op) {
- case OP_NUM:
- jnp->Valp = AllocateValue(g, TYPE_INT);
- break;
- case OP_ADD:
- case OP_MULT:
- case OP_SEP:
- if (!IsTypeChar(Buf_Type))
- jnp->Valp = AllocateValue(g, Buf_Type, 0, GetPrecision());
- else
- jnp->Valp = AllocateValue(g, TYPE_DOUBLE, 0, 2);
-
- break;
- case OP_MIN:
- case OP_MAX:
- jnp->Valp = AllocateValue(g, Buf_Type, Long, GetPrecision());
- break;
- case OP_CNC:
- if (IsTypeChar(Buf_Type))
- jnp->Valp = AllocateValue(g, TYPE_STRING, Long, GetPrecision());
- else
- jnp->Valp = AllocateValue(g, TYPE_STRING, 512);
-
- break;
- default:
- break;
- } // endswitch Op
-
- if (jnp->Valp)
- MulVal = AllocateValue(g, jnp->Valp);
+{
+ int n;
+ bool dg = true, b = false;
+ PJNODE jnp = &Nodes[i];
+
+ //if (*p == '[') p++; // Old syntax .[ or :[
+ n = (int)strlen(p);
+
+ if (*p) {
+ if (p[n - 1] == ']') {
+ p[--n] = 0;
+ } else if (!IsNum(p)) {
+ // Wrong array specification
+ sprintf(g->Message, "Invalid array specification %s for %s", p, Name);
+ return true;
+ } // endif p
+
+ } else
+ b = true;
+
+ // To check whether a numeric Rank was specified
+ dg = IsNum(p);
+
+ if (!n) {
+ // Default specifications
+ if (CheckExpand(g, i, nm, false))
+ return true;
+ else if (jnp->Op != OP_EXP) {
+ if (b) {
+ // Return 1st value (B is the index base)
+ jnp->Rank = Tjp->B;
+ jnp->Op = OP_EQ;
+ } else if (!Value->IsTypeNum()) {
+ jnp->CncVal = AllocateValue(g, (void*)", ", TYPE_STRING);
+ jnp->Op = OP_CNC;
+ } else
+ jnp->Op = OP_ADD;
+
+ } // endif OP
+
+ } else if (dg) {
+ // Return nth value
+ jnp->Rank = atoi(p) - Tjp->B;
+ jnp->Op = OP_EQ;
+ } else if (n == 1) {
+ // Set the Op value;
+ if (Sep == ':')
+ switch (*p) {
+ case '*': *p = 'x'; break;
+ case 'x':
+ case 'X': *p = '*'; break; // Expand this array
+ default: break;
+ } // endswitch p
+
+ switch (*p) {
+ case '+': jnp->Op = OP_ADD; break;
+ case 'x': jnp->Op = OP_MULT; break;
+ case '>': jnp->Op = OP_MAX; break;
+ case '<': jnp->Op = OP_MIN; break;
+ case '!': jnp->Op = OP_SEP; break; // Average
+ case '#': jnp->Op = OP_NUM; break;
+ case '*': // Expand this array
+ if (!Tjp->Xcol && nm) {
+ Xpd = true;
+ jnp->Op = OP_EXP;
+ Tjp->Xval = i;
+ Tjp->Xcol = nm;
+ } else if (CheckExpand(g, i, nm, true))
+ return true;
+
+ break;
+ default:
+ sprintf(g->Message,
+ "Invalid function specification %c for %s", *p, Name);
+ return true;
+ } // endswitch *p
+
+ } else if (*p == '"' && p[n - 1] == '"') {
+ // This is a concat specification
+ jnp->Op = OP_CNC;
+
+ if (n > 2) {
+ // Set concat intermediate string
+ p[n - 1] = 0;
+ jnp->CncVal = AllocateValue(g, p + 1, TYPE_STRING);
+ } // endif n
- return false;
- } // end of SetArrayOptions
+ } else {
+ sprintf(g->Message, "Wrong array specification for %s", Name);
+ return true;
+ } // endif's
+
+ // For calculated arrays, a local Value must be used
+ switch (jnp->Op) {
+ case OP_NUM:
+ jnp->Valp = AllocateValue(g, TYPE_INT);
+ break;
+ case OP_ADD:
+ case OP_MULT:
+ case OP_SEP:
+ if (!IsTypeChar(Buf_Type))
+ jnp->Valp = AllocateValue(g, Buf_Type, 0, GetPrecision());
+ else
+ jnp->Valp = AllocateValue(g, TYPE_DOUBLE, 0, 2);
+
+ break;
+ case OP_MIN:
+ case OP_MAX:
+ jnp->Valp = AllocateValue(g, Buf_Type, Long, GetPrecision());
+ break;
+ case OP_CNC:
+ if (IsTypeChar(Buf_Type))
+ jnp->Valp = AllocateValue(g, TYPE_STRING, Long, GetPrecision());
+ else
+ jnp->Valp = AllocateValue(g, TYPE_STRING, 512);
+
+ break;
+ default:
+ break;
+ } // endswitch Op
+
+ if (jnp->Valp)
+ MulVal = AllocateValue(g, jnp->Valp);
+
+ return false;
+} // end of SetArrayOptions
/***********************************************************************/
/* Parse the eventual passed Jpath information. */
@@ -1083,75 +1196,164 @@ bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
/* the node corresponding to that column. */
/***********************************************************************/
bool JSONCOL::ParseJpath(PGLOBAL g)
- {
- char *p, *p2 = NULL, *pbuf = NULL;
- int i;
- bool mul = false;
-
- if (Parsed)
- return false; // Already done
- else if (InitValue(g))
- return true;
- else if (!Jpath)
- Jpath = Name;
-
- if (To_Tdb->GetOrig()) {
- // This is an updated column, get nodes from origin
- for (PJCOL colp = (PJCOL)Tjp->GetColumns(); colp;
- colp = (PJCOL)colp->GetNext())
- if (!stricmp(Name, colp->GetName())) {
- Nod = colp->Nod;
- Nodes = colp->Nodes;
+{
+ char *p, *p1 = NULL, *p2 = NULL, *pbuf = NULL;
+ int i;
+ bool a, mul = false;
+
+ if (Parsed)
+ return false; // Already done
+ else if (InitValue(g))
+ return true;
+ else if (!Jpath)
+ Jpath = Name;
+
+ if (To_Tdb->GetOrig()) {
+ // This is an updated column, get nodes from origin
+ for (PJCOL colp = (PJCOL)Tjp->GetColumns(); colp;
+ colp = (PJCOL)colp->GetNext())
+ if (!stricmp(Name, colp->GetName())) {
+ Nod = colp->Nod;
+ Nodes = colp->Nodes;
Xpd = colp->Xpd;
- goto fin;
- } // endif Name
-
- sprintf(g->Message, "Cannot parse updated column %s", Name);
- return true;
- } // endif To_Orig
-
- pbuf = PlugDup(g, Jpath);
-
- // The Jpath must be analyzed
- for (i = 0, p = pbuf; (p = strchr(p, ':')); i++, p++)
- Nod++; // One path node found
-
- Nodes = (PJNODE)PlugSubAlloc(g, NULL, (++Nod) * sizeof(JNODE));
- memset(Nodes, 0, (Nod) * sizeof(JNODE));
-
- // Analyze the Jpath for this column
- for (i = 0, p = pbuf; i < Nod; i++, p = (p2 ? p2 + 1 : p + strlen(p))) {
- if ((p2 = strchr(p, ':')))
- *p2 = 0;
-
- // Jpath must be explicit
- if (*p == 0 || *p == '[') {
- // Analyse intermediate array processing
- if (SetArrayOptions(g, p, i, Nodes[i-1].Key))
- return true;
-
- } else if (*p == '*') {
- // Return JSON
- Nodes[i].Op = OP_XX;
- } else {
- Nodes[i].Key = p;
- Nodes[i].Op = OP_EXIST;
- } // endif's
+ goto fin;
+ } // endif Name
+
+ sprintf(g->Message, "Cannot parse updated column %s", Name);
+ return true;
+ } // endif To_Orig
+
+ pbuf = PlugDup(g, Jpath);
+ if (*pbuf == '$') pbuf++;
+ if (*pbuf == Sep) pbuf++;
+ if (*pbuf == '[') p1 = pbuf++;
+
+ // Estimate the required number of nodes
+ for (i = 0, p = pbuf; (p = NextChr(p, Sep)); i++, p++)
+ Nod++; // One path node found
+
+ Nodes = (PJNODE)PlugSubAlloc(g, NULL, (++Nod) * sizeof(JNODE));
+ memset(Nodes, 0, (Nod) * sizeof(JNODE));
+
+ // Analyze the Jpath for this column
+ for (i = 0, p = pbuf; p && i < Nod; i++, p = (p2 ? p2 : NULL)) {
+ a = (p1 != NULL);
+ p1 = strchr(p, '[');
+ p2 = strchr(p, Sep);
+
+ if (!p2)
+ p2 = p1;
+ else if (p1) {
+ if (p1 < p2)
+ p2 = p1;
+ else if (p1 == p2 + 1)
+ *p2++ = 0; // Old syntax .[ or :[
+ else
+ p1 = NULL;
+
+ } // endif p1
+
+ if (p2)
+ *p2++ = 0;
+
+ // Jpath must be explicit
+ if (a || *p == 0 || *p == '[' || IsNum(p)) {
+ // Analyse intermediate array processing
+ if (SetArrayOptions(g, p, i, Nodes[i - 1].Key))
+ return true;
+
+ } else if (*p == '*') {
+ // Return JSON
+ Nodes[i].Op = OP_XX;
+ } else {
+ Nodes[i].Key = p;
+ Nodes[i].Op = OP_EXIST;
+ } // endif's
+
+ } // endfor i, p
+
+ Nod = i;
+
+fin:
+ MulVal = AllocateValue(g, Value);
+ Parsed = true;
+ return false;
+} // end of ParseJpath
+
+/***********************************************************************/
+/* Get Jpath converted to Mongo path. */
+/***********************************************************************/
+char *JSONCOL::GetJpath(PGLOBAL g, bool proj)
+{
+ if (Jpath) {
+ char *p1, *p2, *mgopath;
+ int i = 0;
+
+ if (strcmp(Jpath, "*")) {
+ p1 = Jpath;
+ if (*p1 == '$') p1++;
+ if (*p1 == '.') p1++;
+ mgopath = PlugDup(g, p1);
+ } else
+ return NULL;
- } // endfor i, p
+ for (p1 = p2 = mgopath; *p1; p1++)
+ if (i) { // Inside []
+ if (isdigit(*p1)) {
+ if (!proj)
+ *p2++ = *p1;
+
+ } else if (*p1 == ']' && i == 1) {
+ if (proj && p1[1] == '.')
+ p1++;
+
+ i = 0;
+ } else if (*p1 == '.' && i == 2) {
+ if (!proj)
+ *p2++ = '.';
+
+ i = 0;
+ } else if (!proj)
+ return NULL;
+
+ } else switch (*p1) {
+ case ':':
+ case '.':
+ if (isdigit(p1[1]))
+ i = 2;
+
+ *p2++ = '.';
+ break;
+ case '[':
+ if (*p2 != '.')
+ *p2++ = '.';
+
+ i = 1;
+ break;
+ case '*':
+ if (*(p2 - 1) == '.' && !*(p1 + 1)) {
+ p2--; // Suppress last :*
+ break;
+ } // endif p2
+
+ default:
+ *p2++ = *p1;
+ break;
+ } // endswitch p1;
+
+ *p2 = 0;
+ return mgopath;
+ } else
+ return NULL;
- fin:
- MulVal = AllocateValue(g, Value);
- Parsed = true;
- return false;
- } // end of ParseJpath
+} // end of GetJpath
/***********************************************************************/
/* MakeJson: Serialize the json item and set value to it. */
/***********************************************************************/
PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
- {
- if (Value->IsTypeNum()) {
+{
+ if (Value->IsTypeNum()) {
strcpy(g->Message, "Cannot make Json for a numeric column");
Value->Reset();
} else
@@ -1171,7 +1373,8 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
case TYPE_INTG:
case TYPE_BINT:
case TYPE_DBL:
- vp->SetValue_pval(val->GetValue());
+ case TYPE_DTM:
+ vp->SetValue_pval(val->GetValue());
break;
case TYPE_BOOL:
if (vp->IsTypeNum())
@@ -1190,11 +1393,14 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
// } // endif Type
default:
- vp->Reset();
- } // endswitch Type
+ vp->Reset();
+ vp->SetNull(true);
+ } // endswitch Type
- } else
- vp->Reset();
+ } else {
+ vp->Reset();
+ vp->SetNull(true);
+ } // endif val
} // end of SetJsonValue
@@ -1207,8 +1413,8 @@ void JSONCOL::ReadColumn(PGLOBAL g)
Value->SetValue_pval(GetColumnValue(g, Tjp->Row, 0));
// Set null when applicable
- if (Nullable)
- Value->SetNull(Value->IsZero());
+ if (!Nullable)
+ Value->SetNull(false);
} // end of ReadColumn
@@ -1289,8 +1495,8 @@ PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
if (!(jvp = arp->GetValue((Nodes[n].Rx = Nodes[n].Nx)))) {
strcpy(g->Message, "Logical error expanding array");
- longjmp(g->jumper[g->jump_level], 666);
- } // endif jvp
+ throw 666;
+ } // endif jvp
if (n < Nod - 1 && jvp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvp->GetJson(), n + 1));
@@ -1343,8 +1549,9 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
} else
SetJsonValue(g, MulVal, jvp, n);
- if (!MulVal->IsZero()) {
- switch (op) {
+// if (!MulVal->IsZero()) {
+ if (!MulVal->IsNull()) {
+ switch (op) {
case OP_CNC:
if (Nodes[n].CncVal) {
val[0] = Nodes[n].CncVal;
@@ -1369,7 +1576,7 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (err)
vp->Reset();
- } // endif Zero
+ } // endif Null
} while (Tjp->NextSame > nextsame);
@@ -1475,8 +1682,8 @@ void JSONCOL::WriteColumn(PGLOBAL g)
{
if (Xpd && Tjp->Pretty < 2) {
strcpy(g->Message, "Cannot write expanded column when Pretty is not 2");
- longjmp(g->jumper[g->jump_level], 666);
- } // endif Xpd
+ throw 666;
+ } // endif Xpd
/*********************************************************************/
/* Check whether this node must be written. */
@@ -1510,8 +1717,8 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (!(jsp = ParseJson(G, s, (int)strlen(s)))) {
strcpy(g->Message, s);
- longjmp(g->jumper[g->jump_level], 666);
- } // endif jsp
+ throw 666;
+ } // endif jsp
if (arp) {
if (Nod > 1 && Nodes[Nod-2].Op == OP_EQ)
@@ -1533,6 +1740,7 @@ void JSONCOL::WriteColumn(PGLOBAL g)
// Passthru
case TYPE_DATE:
case TYPE_INT:
+ case TYPE_TINY:
case TYPE_SHORT:
case TYPE_BIGINT:
case TYPE_DOUBLE:
@@ -1655,54 +1863,66 @@ int TDBJSON::MakeDocument(PGLOBAL g)
if (!jsp && g->Message[0])
return RC_FX;
- objpath = PlugDup(g, Objname);
+ if ((objpath = PlugDup(g, Objname))) {
+ if (*objpath == '$') objpath++;
+ if (*objpath == '.') objpath++;
+
+ /*********************************************************************/
+ /* Find the table in the tree structure. */
+ /*********************************************************************/
+ for (; jsp && objpath; objpath = p) {
+ if ((p = strchr(objpath, Sep)))
+ *p++ = 0;
+
+ if (*objpath != '[' && !IsNum(objpath)) {
+ // objpass is a key
+ if (jsp->GetType() != TYPE_JOB) {
+ strcpy(g->Message, "Table path does not match the json file");
+ return RC_FX;
+ } // endif Type
+
+ key = objpath;
+ objp = jsp->GetObject();
+ arp = NULL;
+ val = objp->GetValue(key);
+
+ if (!val || !(jsp = val->GetJson())) {
+ sprintf(g->Message, "Cannot find object key %s", key);
+ return RC_FX;
+ } // endif val
- /*********************************************************************/
- /* Find the table in the tree structure. */
- /*********************************************************************/
- for (; jsp && objpath; objpath = p) {
- if ((p = strchr(objpath, ':')))
- *p++ = 0;
-
- if (*objpath != '[') { // objpass is a key
- if (jsp->GetType() != TYPE_JOB) {
- strcpy(g->Message, "Table path does not match the json file");
- return RC_FX;
- } // endif Type
-
- key = objpath;
- objp = jsp->GetObject();
- arp = NULL;
- val = objp->GetValue(key);
-
- if (!val || !(jsp = val->GetJson())) {
- sprintf(g->Message, "Cannot find object key %s", key);
- return RC_FX;
- } // endif val
-
- } else if (objpath[strlen(objpath)-1] == ']') {
- if (jsp->GetType() != TYPE_JAR) {
- strcpy(g->Message, "Table path does not match the json file");
- return RC_FX;
- } // endif Type
-
- arp = jsp->GetArray();
- objp = NULL;
- i = atoi(objpath+1) - B;
- val = arp->GetValue(i);
-
- if (!val) {
- sprintf(g->Message, "Cannot find array value %d", i);
- return RC_FX;
- } // endif val
+ } else {
+ if (*objpath == '[') {
+ // Old style
+ if (objpath[strlen(objpath) - 1] != ']') {
+ sprintf(g->Message, "Invalid Table path %s", Objname);
+ return RC_FX;
+ } else
+ objpath++;
- } else {
- sprintf(g->Message, "Invalid Table path %s", Objname);
- return RC_FX;
- } // endif objpath
+ } // endif objpath
+
+ if (jsp->GetType() != TYPE_JAR) {
+ strcpy(g->Message, "Table path does not match the json file");
+ return RC_FX;
+ } // endif Type
+
+ arp = jsp->GetArray();
+ objp = NULL;
+ i = atoi(objpath) - B;
+ val = arp->GetValue(i);
- jsp = val->GetJson();
- } // endfor objpath
+ if (!val) {
+ sprintf(g->Message, "Cannot find array value %d", i);
+ return RC_FX;
+ } // endif val
+
+ } // endif
+
+ jsp = val->GetJson();
+ } // endfor objpath
+
+ } // endif objpath
if (jsp && jsp->GetType() == TYPE_JAR)
Doc = jsp->GetArray();
@@ -1860,8 +2080,11 @@ bool TDBJSON::OpenDB(PGLOBAL g)
return true;
} // endswitch Jmode
- Use = USE_OPEN;
- return false;
+ if (Xcol)
+ To_Filter = NULL; // Imcompatible
+
+ Use = USE_OPEN;
+ return false;
} // end of OpenDB
/***********************************************************************/
@@ -1871,7 +2094,7 @@ int TDBJSON::ReadDB(PGLOBAL)
{
int rc;
- N++;
+ N++;
if (NextSame) {
SameRow = NextSame;
@@ -1983,6 +2206,7 @@ TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp)
{
Topt = tdp->GetTopt();
Db = (char*)tdp->GetDB();
+ Dsn = (char*)tdp->Uri;
} // end of TDBJCL constructor
/***********************************************************************/
@@ -1990,7 +2214,7 @@ TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp)
/***********************************************************************/
PQRYRES TDBJCL::GetResult(PGLOBAL g)
{
- return JSONColumns(g, Db, Topt, false);
+ return JSONColumns(g, Db, Dsn, Topt, false);
} // end of GetResult
/* --------------------------- End of json --------------------------- */
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index 924ce387900..9ca03ddbc83 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -1,7 +1,7 @@
/*************** tabjson H Declares Source Code File (.H) **************/
-/* Name: tabjson.h Version 1.1 */
+/* Name: tabjson.h Version 1.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
/* */
/* This file contains the JSON classes declares. */
/***********************************************************************/
@@ -32,12 +32,15 @@ typedef struct _jnode {
/***********************************************************************/
/* JSON table. */
/***********************************************************************/
-class JSONDEF : public DOSDEF { /* Table description */
+class DllExport JSONDEF : public DOSDEF { /* Table description */
friend class TDBJSON;
friend class TDBJSN;
friend class TDBJCL;
- friend PQRYRES JSONColumns(PGLOBAL, char*, PTOS, bool);
- public:
+ friend PQRYRES JSONColumns(PGLOBAL, char*, char*, PTOS, bool);
+#if defined(MONGO_SUPPORT)
+ friend class MGOFAM;
+#endif // MONGO_SUPPORT
+public:
// Constructor
JSONDEF(void);
@@ -51,13 +54,21 @@ class JSONDEF : public DOSDEF { /* Table description */
protected:
// Members
JMODE Jmode; /* MODE_OBJECT by default */
- char *Objname; /* Name of first level object */
- char *Xcol; /* Name of expandable column */
+ PCSZ Objname; /* Name of first level object */
+ PCSZ Xcol; /* Name of expandable column */
int Limit; /* Limit of multiple values */
int Pretty; /* Depends on file structure */
int Level; /* Used for catalog table */
- int Base; /* Tne array index base */
+ int Base; /* The array index base */
bool Strict; /* Strict syntax checking */
+ char Sep; /* The Jpath separator */
+ const char *Uri; /* MongoDB connection URI */
+#if defined(MONGO_SUPPORT)
+ PCSZ Collname; /* External collection name */
+ PCSZ Schema; /* External schema (DB) name */
+ PSZ Options; /* Colist ; filter */
+ bool Pipe; /* True if Colist is a pipeline */
+#endif // MONGO_SUPPORT
}; // end of JSONDEF
/* -------------------------- TDBJSN class --------------------------- */
@@ -66,9 +77,12 @@ class JSONDEF : public DOSDEF { /* Table description */
/* This is the JSN Access Method class declaration. */
/* The table is a DOS file, each record being a JSON object. */
/***********************************************************************/
-class TDBJSN : public TDBDOS {
+class DllExport TDBJSN : public TDBDOS {
friend class JSONCOL;
friend class JSONDEF;
+#if defined(MONGO_SUPPORT)
+ friend class MGOFAM;
+#endif // MONGO_SUPPORT
public:
// Constructor
TDBJSN(PJDEF tdp, PTXF txfp);
@@ -87,6 +101,8 @@ public:
virtual PCOL InsertSpecialColumn(PCOL colp);
virtual int RowNumber(PGLOBAL g, bool b = FALSE)
{return (b) ? M : N;}
+ virtual bool CanBeFiltered(void)
+ {return Txfp->GetAmType() == TYPE_AM_MGO || !Xcol;}
// Database routines
virtual int Cardinality(PGLOBAL g);
@@ -107,8 +123,8 @@ public:
PJSON Val; // The value of the current row
PJCOL Colp; // The multiple column
JMODE Jmode; // MODE_OBJECT by default
- char *Objname; // The table object name
- char *Xcol; // Name of expandable column
+ PCSZ Objname; // The table object name
+ PCSZ Xcol; // Name of expandable column
int Fpos; // The current row index
int N; // The current Rownum
int M; // Index of multiple value
@@ -118,6 +134,7 @@ public:
int SameRow; // Same row nb
int Xval; // Index of expandable array
int B; // Array index base
+ char Sep; // The Jpath separator
bool Strict; // Strict syntax checking
bool Comma; // Row has final comma
}; // end of class TDBJSN
@@ -127,9 +144,10 @@ public:
/***********************************************************************/
/* Class JSONCOL: JSON access method column descriptor. */
/***********************************************************************/
-class JSONCOL : public DOSCOL {
+class DllExport JSONCOL : public DOSCOL {
friend class TDBJSN;
friend class TDBJSON;
+ friend class MGOFAM;
public:
// Constructors
JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i);
@@ -139,20 +157,21 @@ class JSONCOL : public DOSCOL {
virtual int GetAmType(void) {return Tjp->GetAmType();}
// Methods
- virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
- bool ParseJpath(PGLOBAL g);
- virtual void ReadColumn(PGLOBAL g);
- virtual void WriteColumn(PGLOBAL g);
+ virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
+ bool ParseJpath(PGLOBAL g);
+ char *GetJpath(PGLOBAL g, bool proj);
+ virtual void ReadColumn(PGLOBAL g);
+ virtual void WriteColumn(PGLOBAL g);
protected:
- bool CheckExpand(PGLOBAL g, int i, PSZ nm, bool b);
- bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm);
- PVAL GetColumnValue(PGLOBAL g, PJSON row, int i);
- PVAL ExpandArray(PGLOBAL g, PJAR arp, int n);
- PVAL CalculateArray(PGLOBAL g, PJAR arp, int n);
- PVAL MakeJson(PGLOBAL g, PJSON jsp);
- void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n);
- PJSON GetRow(PGLOBAL g);
+ bool CheckExpand(PGLOBAL g, int i, PSZ nm, bool b);
+ bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm);
+ PVAL GetColumnValue(PGLOBAL g, PJSON row, int i);
+ PVAL ExpandArray(PGLOBAL g, PJAR arp, int n);
+ PVAL CalculateArray(PGLOBAL g, PJAR arp, int n);
+ PVAL MakeJson(PGLOBAL g, PJSON jsp);
+ void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n);
+ PJSON GetRow(PGLOBAL g);
// Default constructor not to be used
JSONCOL(void) {}
@@ -165,7 +184,8 @@ class JSONCOL : public DOSCOL {
JNODE *Nodes; // The intermediate objects
int Nod; // The number of intermediate objects
int Xnod; // Index of multiple values
- bool Xpd; // True for expandable column
+ char Sep; // The Jpath separator
+ bool Xpd; // True for expandable column
bool Parsed; // True when parsed
}; // end of class JSONCOL
@@ -174,7 +194,7 @@ class JSONCOL : public DOSCOL {
/***********************************************************************/
/* This is the JSON Access Method class declaration. */
/***********************************************************************/
-class TDBJSON : public TDBJSN {
+class DllExport TDBJSON : public TDBJSN {
friend class JSONDEF;
friend class JSONCOL;
public:
@@ -221,7 +241,7 @@ class TDBJSON : public TDBJSN {
/***********************************************************************/
/* This is the class declaration for the JSON catalog table. */
/***********************************************************************/
-class TDBJCL : public TDBCAT {
+class DllExport TDBJCL : public TDBCAT {
public:
// Constructor
TDBJCL(PJDEF tdp);
@@ -233,4 +253,5 @@ class TDBJCL : public TDBCAT {
// Members
PTOS Topt;
char *Db;
+ char *Dsn;
}; // end of class TDBJCL
diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp
index 916449be6c6..61aefc93082 100644
--- a/storage/connect/table.cpp
+++ b/storage/connect/table.cpp
@@ -47,6 +47,7 @@ TDB::TDB(PTABDEF tdp) : Tdb_No(++Tnum)
To_Orig = NULL;
To_Filter = NULL;
To_CondFil = NULL;
+ Cond = NULL;
Next = NULL;
Name = (tdp) ? tdp->GetName() : NULL;
To_Table = NULL;
@@ -68,6 +69,7 @@ TDB::TDB(PTDB tdbp) : Tdb_No(++Tnum)
To_Orig = tdbp;
To_Filter = NULL;
To_CondFil = NULL;
+ Cond = NULL;
Next = NULL;
Name = tdbp->Name;
To_Table = tdbp->To_Table;
@@ -97,7 +99,7 @@ CHARSET_INFO *TDB::data_charset(void)
/***********************************************************************/
/* Return the datapath of the DB this table belongs to. */
/***********************************************************************/
-PSZ TDB::GetPath(void)
+PCSZ TDB::GetPath(void)
{
return To_Def->GetPath();
} // end of GetPath
@@ -297,7 +299,7 @@ bool TDB::SetRecpos(PGLOBAL g, int)
return true;
} // end of SetRecpos
-void TDB::Print(PGLOBAL g, FILE *f, uint n)
+void TDB::Printf(PGLOBAL g, FILE *f, uint n)
{
PCOL cp;
char m[64];
@@ -313,16 +315,16 @@ void TDB::Print(PGLOBAL g, FILE *f, uint n)
fprintf(f, "%s Columns (deg=%d):\n", m, tp->Degree);
for (cp = tp->Columns; cp; cp = cp->GetNext())
- cp->Print(g, f, n);
+ cp->Printf(g, f, n);
} /* endfor tp */
- } // end of Print
+ } // end of Printf
-void TDB::Print(PGLOBAL, char *ps, uint)
+void TDB::Prints(PGLOBAL, char *ps, uint)
{
sprintf(ps, "R%d.%s", Tdb_No, Name);
- } // end of Print
+ } // end of Prints
/* -------------------------- class TDBASE --------------------------- */
diff --git a/storage/connect/tabmac.cpp b/storage/connect/tabmac.cpp
index bbaba591540..a28b5d7108c 100644
--- a/storage/connect/tabmac.cpp
+++ b/storage/connect/tabmac.cpp
@@ -329,7 +329,7 @@ void MACCOL::ReadColumn(PGLOBAL g)
n = 0;
break;
default:
- p = "";
+ p = PlugDup(g, "");
} // endswitch Flag
} else switch (Flag) {
diff --git a/storage/connect/tabmgo.cpp b/storage/connect/tabmgo.cpp
new file mode 100644
index 00000000000..37a0e44debc
--- /dev/null
+++ b/storage/connect/tabmgo.cpp
@@ -0,0 +1,1480 @@
+/************** tabmgo C++ Program Source Code File (.CPP) *************/
+/* PROGRAM NAME: tabmgo Version 1.0 */
+/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* This program are the MongoDB class DB execution routines. */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Include relevant sections of the MariaDB header file. */
+/***********************************************************************/
+#include <my_global.h>
+
+/***********************************************************************/
+/* Include application header files: */
+/* global.h is header containing all global declarations. */
+/* plgdbsem.h is header containing the DB application declarations. */
+/* tdbdos.h is header containing the TDBDOS declarations. */
+/* json.h is header containing the JSON classes declarations. */
+/***********************************************************************/
+#include "global.h"
+#include "plgdbsem.h"
+#include "xtable.h"
+#include "maputil.h"
+#include "filamtxt.h"
+#include "tabext.h"
+#include "tabmgo.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 */
+
+/***********************************************************************/
+/* MGOColumns: construct the result blocks containing the description */
+/* of all the columns of a document contained inside MongoDB. */
+/***********************************************************************/
+PQRYRES MGOColumns(PGLOBAL g, char *db, 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;
+ 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, 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
+
+/***********************************************************************/
+/* Class used to get the columns of a mongo collection. */
+/***********************************************************************/
+// 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
+
+/***********************************************************************/
+/* Class used to get the columns of a mongo collection. */
+/***********************************************************************/
+int MGODISC::GetColumns(PGLOBAL g, char *db, 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 = GetStringTableOption(g, topt, "Connect", "mongodb://localhost:27017");
+ 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->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
+
+ if (tdp->Colist) {
+ char *p = (char*)strchr(tdp->Colist, ';');
+
+ if (p) {
+ *p++ = 0;
+ tdp->Filter = *p ? p : NULL;
+ } // endif p
+
+ } // endif Colist
+
+ 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->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)
+{
+ if (!doc || bson_iter_init(iter, doc)) {
+ const char *key;
+ char colname[65];
+ char fmt[129];
+ bool newcol;
+
+ while (bson_iter_next(iter)) {
+ key = bson_iter_key(iter);
+ newcol = true;
+
+ 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);
+
+ bcol.Cbn = false;
+
+ if (BSON_ITER_HOLDS_UTF8(iter)) {
+ bcol.Type = TYPE_STRING;
+ bcol.Len = strlen(bson_iter_utf8(iter, NULL));
+ } else if (BSON_ITER_HOLDS_INT32(iter)) {
+ bcol.Type = TYPE_INT;
+ bcol.Len = 11; // bson_iter_int32(iter)
+ } else if (BSON_ITER_HOLDS_INT64(iter)) {
+ bcol.Type = TYPE_BIGINT;
+ bcol.Len = 22; // bson_iter_int64(iter)
+ } else if (BSON_ITER_HOLDS_DOUBLE(iter)) {
+ bcol.Type = TYPE_DOUBLE;
+ bcol.Len = 12;
+ bcol.Scale = 6; // bson_iter_double(iter)
+ } else if (BSON_ITER_HOLDS_DATE_TIME(iter)) {
+ bcol.Type = TYPE_DATE;
+ bcol.Len = 19; // bson_iter_date_time(iter)
+ } else if (BSON_ITER_HOLDS_BOOL(iter)) {
+ bcol.Type = TYPE_TINY;
+ bcol.Len = 1;
+ } else if (BSON_ITER_HOLDS_OID(iter)) {
+ bcol.Type = TYPE_STRING;
+ bcol.Len = 24; // bson_iter_oid(iter)
+ } else if (BSON_ITER_HOLDS_DECIMAL128(iter)) {
+ bcol.Type = TYPE_DECIM;
+ bcol.Len = 32; // bson_iter_decimal128(iter, &dec)
+ } else if (BSON_ITER_HOLDS_DOCUMENT(iter)) {
+ if (lvl < 0)
+ continue;
+ else if (lvl <= k) {
+ bcol.Type = TYPE_STRING;
+ bcol.Len = 512;
+ } else {
+ bson_iter_t child;
+
+ if (bson_iter_recurse(iter, &child))
+ if (FindInDoc(g, &child, NULL, colname, fmt, i, k + 1, false))
+ return true;
+
+ newcol = false;
+ } // endif lvl
+
+ } else if (BSON_ITER_HOLDS_ARRAY(iter)) {
+ if (lvl < 0)
+ continue;
+ else if (lvl <= k) {
+ bcol.Type = TYPE_STRING;
+ bcol.Len = 512;
+ } else {
+ bson_t *arr;
+ bson_iter_t itar;
+ const uint8_t *data = NULL;
+ uint32_t len = 0;
+
+ bson_iter_array(iter, &len, &data);
+ arr = bson_new_from_data(data, len);
+
+ if (FindInDoc(g, &itar, arr, colname, fmt, i, k + 1, !all))
+ return true;
+
+ newcol = false;
+ } // endif lvl
+
+ } // 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 (b)
+ break; // Test only first element of arrays
+
+ } // endwhile iter
+
+ } // endif doc
+
+ return false;
+} // end of FindInDoc
+
+/* -------------------------- Class MGODEF --------------------------- */
+
+MGODEF::MGODEF(void)
+{
+ Uri = NULL;
+ Colist = NULL;
+ Filter = NULL;
+ Level = 0;
+ Base = 0;
+ Pipe = false;
+} // end of MGODEF constructor
+
+/***********************************************************************/
+/* DefineAM: define specific AM block values. */
+/***********************************************************************/
+bool MGODEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
+{
+ if (EXTDEF::DefineAM(g, "MGO", poff))
+ return true;
+ else if (!Tabschema)
+ Tabschema = GetStringCatInfo(g, "Dbname", "*");
+
+ Uri = GetStringCatInfo(g, "Connect", "mongodb://localhost:27017");
+ Colist = GetStringCatInfo(g, "Colist", NULL);
+ Filter = GetStringCatInfo(g, "Filter", NULL);
+ Base = GetIntCatInfo("Base", 0) ? 1 : 0;
+ Pipe = GetBoolCatInfo("Pipeline", false);
+ return false;
+} // end of DefineAM
+
+/***********************************************************************/
+/* GetTable: makes a new Table Description Block. */
+/***********************************************************************/
+PTDB MGODEF::GetTable(PGLOBAL g, MODE m)
+{
+ //if (Catfunc == FNC_COL)
+ // return new(g)TDBGOL(this);
+
+ return new(g) TDBMGO(this);
+} // end of GetTable
+
+/* --------------------------- Class INCOL --------------------------- */
+
+/***********************************************************************/
+/* Add a column in the column list. */
+/***********************************************************************/
+void INCOL::AddCol(PGLOBAL g, PCOL colp, char *jp)
+{
+ char *p;
+ PKC kp, kcp;
+
+ if ((p = strchr(jp, '.'))) {
+ PINCOL icp;
+
+ *p = 0;
+
+ for (kp = Klist; kp; kp = kp->Next)
+ if (kp->Incolp && !strcmp(jp, kp->Key))
+ break;
+
+ if (!kp) {
+ icp = new(g) INCOL;
+ kcp = (PKC)PlugSubAlloc(g, NULL, sizeof(KEYCOL));
+ kcp->Next = NULL;
+ kcp->Incolp = icp;
+ kcp->Colp = NULL;
+ kcp->Key = PlugDup(g, jp);
+
+ if (Klist) {
+ for (kp = Klist; kp->Next; kp = kp->Next);
+
+ kp->Next = kcp;
+ } else
+ Klist = kcp;
+
+ } else
+ icp = kp->Incolp;
+
+ *p = '.';
+ icp->AddCol(g, colp, p + 1);
+ } else {
+ kcp = (PKC)PlugSubAlloc(g, NULL, sizeof(KEYCOL));
+
+ kcp->Next = NULL;
+ kcp->Incolp = NULL;
+ kcp->Colp = colp;
+ kcp->Key = jp;
+
+ if (Klist) {
+ for (kp = Klist; kp->Next; kp = kp->Next);
+
+ kp->Next = kcp;
+ } else
+ Klist = kcp;
+
+ } // endif jp
+
+} // end of AddCol
+
+/* --------------------------- Class TDBMGO -------------------------- */
+
+/***********************************************************************/
+/* Implementation of the TDBMGO class. */
+/***********************************************************************/
+TDBMGO::TDBMGO(PMGODEF tdp) : TDBEXT(tdp)
+{
+ G = NULL;
+ Uri = NULL;
+ Pool = NULL;
+ Client = NULL;
+ Database = NULL;
+ Collection = NULL;
+ Cursor = NULL;
+ Query = NULL;
+ Opts = NULL;
+ Fpc = NULL;
+ Cnd = NULL;
+
+ if (tdp) {
+ Uristr = tdp->Uri;
+ Db_name = tdp->Tabschema;
+ Coll_name = tdp->Tabname;
+ Options = tdp->Colist;
+ Filter = tdp->Filter;
+ B = tdp->Base ? 1 : 0;
+ Pipe = tdp->Pipe && Options != NULL;
+ } else {
+ Uristr = NULL;
+ Db_name = NULL;
+ Coll_name = NULL;
+ Options = NULL;
+ Filter = NULL;
+ B = 0;
+ Pipe = false;
+ } // endif tdp
+
+ Fpos = -1;
+ N = 0;
+ Done = false;
+} // end of TDBMGO standard constructor
+
+TDBMGO::TDBMGO(TDBMGO *tdbp) : TDBEXT(tdbp)
+{
+ G = tdbp->G;
+ 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;
+ Filter = tdbp->Filter;
+ B = tdbp->B;
+ Fpos = tdbp->Fpos;
+ N = tdbp->N;
+ Done = tdbp->Done;
+ Pipe = tdbp->Pipe;
+} // end of TDBMGO copy constructor
+
+// Used for update
+PTDB TDBMGO::Clone(PTABS t)
+{
+ PTDB tp;
+ PMGOCOL cp1, cp2;
+ PGLOBAL g = t->G;
+
+ tp = new(g) TDBMGO(this);
+
+ for (cp1 = (PMGOCOL)Columns; cp1; cp1 = (PMGOCOL)cp1->GetNext())
+ if (!cp1->IsSpecial()) {
+ cp2 = new(g) MGOCOL(cp1, tp); // Make a copy
+ NewPointer(t, cp1, cp2);
+ } // endif cp1
+
+ return tp;
+} // end of Clone
+
+/***********************************************************************/
+/* Allocate JSN column description block. */
+/***********************************************************************/
+PCOL TDBMGO::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
+{
+ PMGOCOL colp = new(g) MGOCOL(g, cdp, this, cprec, n);
+
+ colp->Mbuf = (char*)PlugSubAlloc(g, NULL, colp->Long + 1);
+ return colp;
+ //return (colp->ParseJpath(g)) ? NULL : colp;
+} // end of MakeCol
+
+/***********************************************************************/
+/* InsertSpecialColumn: Put a special column ahead of the column list.*/
+/***********************************************************************/
+PCOL TDBMGO::InsertSpecialColumn(PCOL colp)
+{
+ if (!colp->IsSpecial())
+ return NULL;
+
+ colp->SetNext(Columns);
+ Columns = colp;
+ return colp;
+} // end of InsertSpecialColumn
+
+/***********************************************************************/
+/* MONGO Cardinality: returns table size in number of rows. */
+/***********************************************************************/
+int TDBMGO::Cardinality(PGLOBAL g)
+{
+ if (!g)
+ return 1;
+ else if (Cardinal < 0)
+ if (!Init(g)) {
+ bson_t *query;
+ const char *jf = NULL;
+
+ if (Pipe)
+ return 10;
+ else if (Filter)
+ jf = Filter;
+
+ if (jf) {
+ query = bson_new_from_json((const uint8_t *)jf, -1, &Error);
+
+ if (!query) {
+ htrc("Wrong filter: %s", Error.message);
+ return 10;
+ } // endif Query
+
+ } else
+ query = bson_new();
+
+ Cardinal = (int)mongoc_collection_count(Collection,
+ MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error);
+
+ if (Cardinal < 0) {
+ htrc("Collection count: %s", Error.message);
+ Cardinal = 10;
+ } // endif Cardinal
+
+ bson_destroy(query);
+ } else
+ return 10;
+
+ return Cardinal;
+} // end of Cardinality
+
+/***********************************************************************/
+/* MONGO GetMaxSize: returns collection size estimate. */
+/***********************************************************************/
+int TDBMGO::GetMaxSize(PGLOBAL g)
+{
+ if (MaxSize < 0)
+ MaxSize = Cardinality(g);
+
+ return MaxSize;
+} // end of GetMaxSize
+
+/***********************************************************************/
+/* Init: initialize MongoDB processing. */
+/***********************************************************************/
+bool TDBMGO::Init(PGLOBAL g)
+{
+ if (Done)
+ return false;
+
+ G = g;
+
+ if (Options && !Pipe) {
+ char *p = (char*)strchr(Options, ';');
+
+ if (p) {
+ *p++ = 0;
+
+ if (p)
+ Filter = p;
+
+ } // endif p
+
+ } // endif Options
+
+ Uri = mongoc_uri_new(Uristr);
+
+ if (!Uri) {
+ sprintf(g->Message, "Failed to parse URI: \"%s\"", Uristr);
+ return true;
+ } // endif Uri
+
+ // Create a new client pool instance
+ Pool = mongoc_client_pool_new(Uri);
+ mongoc_client_pool_set_error_api(Pool, 2);
+
+ // Register the application name so we can track it in the profile logs
+ // on the server. This can also be done from the URI.
+ mongoc_client_pool_set_appname(Pool, "Connect");
+
+ // Create a new client instance
+ Client = mongoc_client_pool_pop(Pool);
+ //Client = mongoc_client_new(uristr);
+
+ if (!Client) {
+ sprintf(g->Message, "Failed to get Client");
+ return true;
+ } // endif Client
+
+ //mongoc_client_set_error_api(Client, 2);
+
+ // Register the application name so we can track it in the profile logs
+ // on the server. This can also be done from the URI.
+ //mongoc_client_set_appname(Client, "Connect");
+
+ // Get a handle on the database Db_name and collection Coll_name
+ // Database = mongoc_client_get_database(Client, Db_name);
+ // Collection = mongoc_database_get_collection(Database, Coll_name);
+ Collection = mongoc_client_get_collection(Client, Db_name, Coll_name);
+
+ if (!Collection) {
+ sprintf(g->Message, "Failed to get Collection %s.%s", Db_name, Coll_name);
+ return true;
+ } // endif Collection
+
+ Done = true;
+ return false;
+} // end of Init
+
+/***********************************************************************/
+/* On update the filter can be made by Cond_Push after MakeCursor. */
+/***********************************************************************/
+void TDBMGO::SetFilter(PFIL fp)
+{
+ To_Filter = fp;
+
+ if (fp && Cursor && Cnd != Cond) {
+ mongoc_cursor_t *cursor = MakeCursor(G);
+
+ if (cursor) {
+ mongoc_cursor_destroy(Cursor);
+ Cursor = cursor;
+ } else
+ htrc("SetFilter: %s\n", G->Message);
+
+ } // endif Cursor
+
+} // end of SetFilter
+
+/***********************************************************************/
+/* OpenDB: Data Base open routine for MONGO access method. */
+/***********************************************************************/
+mongoc_cursor_t *TDBMGO::MakeCursor(PGLOBAL g)
+{
+ const char *p;
+ bool b = false, id = (Mode != MODE_READ), all = false;
+ mongoc_cursor_t *cursor;
+ PCOL cp;
+ PSTRG s = NULL;
+
+ if (Options && !stricmp(Options, "all")) {
+ Options = NULL;
+ all = true;
+ } // endif Options
+
+ for (cp = Columns; cp; cp = cp->GetNext())
+ if (!strcmp(cp->GetName(), "_id"))
+ id = true;
+ else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*"))
+ all = true;
+
+ if (Pipe) {
+ if (trace)
+ htrc("Pipeline: %s\n", Options);
+
+ p = strrchr(Options, ']');
+
+ if (!p) {
+ strcpy(g->Message, "Missing ] in pipeline");
+ return NULL;
+ } else
+ *(char*)p = 0;
+
+ s = new(g) STRING(g, 1023, (PSZ)Options);
+
+ if (To_Filter) {
+ s->Append(",{\"$match\":");
+
+ if (To_Filter->MakeSelector(g, s, true)) {
+ strcpy(g->Message, "Failed making selector");
+ return NULL;
+ } else
+ s->Append('}');
+
+ To_Filter = NULL; // Not needed anymore
+ } // endif To_Filter
+
+ if (!all) {
+ // Project list
+ if (Columns) {
+ s->Append(",{\"$project\":{\"");
+
+ if (!id)
+ s->Append("_id\":0,\"");
+
+ for (cp = Columns; cp; cp = cp->GetNext()) {
+ if (b)
+ s->Append(",\"");
+ else
+ b = true;
+
+ s->Append(((PMGOCOL)cp)->GetProjPath(g));
+ s->Append("\":1");
+ } // endfor cp
+
+ s->Append("}}");
+ } else
+ s->Append(",{\"$project\":{\"_id\":1}}");
+
+ } // endif all
+
+ s->Append("]}");
+ s->Resize(s->GetLength() + 1);
+ p = s->GetStr();
+
+ if (trace)
+ htrc("New Pipeline: %s\n", p);
+
+ Query = bson_new_from_json((const uint8_t *)p, -1, &Error);
+
+ if (!Query) {
+ sprintf(g->Message, "Wrong pipeline: %s", Error.message);
+ return NULL;
+ } // endif Query
+
+ cursor = mongoc_collection_aggregate(Collection, MONGOC_QUERY_NONE,
+ Query, NULL, NULL);
+
+ if (mongoc_cursor_error(cursor, &Error)) {
+ sprintf(g->Message, "Mongo aggregate Failure: %s", Error.message);
+ return NULL;
+ } // endif cursor
+
+ } else {
+ if (Filter || To_Filter) {
+ if (trace) {
+ if (Filter)
+ htrc("Filter: %s\n", Filter);
+
+ if (To_Filter) {
+ char buf[512];
+
+ To_Filter->Prints(g, buf, 511);
+ htrc("To_Filter: %s\n", buf);
+ } // endif To_Filter
+
+ } // endif trace
+
+ s = new(g) STRING(g, 1023, (PSZ)Filter);
+
+ if (To_Filter) {
+ if (Filter)
+ s->Append(',');
+
+ if (To_Filter->MakeSelector(g, s, true)) {
+ strcpy(g->Message, "Failed making selector");
+ return NULL;
+ } // endif Selector
+
+ To_Filter = NULL; // Not needed anymore
+ } // endif To_Filter
+
+ if (trace)
+ htrc("selector: %s\n", s->GetStr());
+
+ s->Resize(s->GetLength() + 1);
+ Query = bson_new_from_json((const uint8_t *)s->GetStr(), -1, &Error);
+
+ if (!Query) {
+ sprintf(g->Message, "Wrong filter: %s", Error.message);
+ return NULL;
+ } // endif Query
+
+ } else
+ Query = bson_new();
+
+ if (!all) {
+ if (Options && *Options) {
+ if (trace)
+ htrc("options=%s\n", Options);
+
+ p = Options;
+ } else if (Columns) {
+ // Projection list
+ if (s)
+ s->Set("{\"projection\":{\"");
+ else
+ s = new(g) STRING(g, 511, "{\"projection\":{\"");
+
+ if (!id)
+ s->Append("_id\":0,\"");
+
+ for (cp = Columns; cp; cp = cp->GetNext()) {
+ if (b)
+ s->Append(",\"");
+ else
+ b = true;
+
+ s->Append(((PMGOCOL)cp)->GetProjPath(g));
+ s->Append("\":1");
+ } // endfor cp
+
+ s->Append("}}");
+ s->Resize(s->GetLength() + 1);
+ p = s->GetStr();
+ } else {
+ // count(*) ?
+ p = "{\"projection\":{\"_id\":1}}";
+ } // endif Options
+
+ Opts = bson_new_from_json((const uint8_t *)p, -1, &Error);
+
+ if (!Opts) {
+ sprintf(g->Message, "Wrong options: %s", Error.message);
+ return NULL;
+ } // endif Opts
+
+ } // endif all
+
+ cursor = mongoc_collection_find_with_opts(Collection, Query, Opts, NULL);
+ } // endif Pipe
+
+ return cursor;
+} // end of MakeCursor
+
+/***********************************************************************/
+/* OpenDB: Data Base open routine for MONGO access method. */
+/***********************************************************************/
+bool TDBMGO::OpenDB(PGLOBAL g)
+{
+ if (Use == USE_OPEN) {
+ /*******************************************************************/
+ /* Table already open replace it at its beginning. */
+ /*******************************************************************/
+ mongoc_cursor_t *cursor = mongoc_cursor_clone(Cursor);
+
+ mongoc_cursor_destroy(Cursor);
+ Cursor = cursor;
+ Fpos = -1;
+ return false;
+ } // endif Use
+
+ /*********************************************************************/
+ /* First opening. */
+ /*********************************************************************/
+ if (Pipe && Mode != MODE_READ) {
+ strcpy(g->Message, "Pipeline tables are read only");
+ return true;
+ } // endif Pipe
+
+ if (Init(g))
+ return true;
+
+ if (Mode == MODE_DELETE && !Next) {
+ // Delete all documents
+ Query = bson_new();
+
+ if (!mongoc_collection_remove(Collection, MONGOC_REMOVE_NONE,
+ Query, NULL, &Error)) {
+ sprintf(g->Message, "Mongo remove all: %s", Error.message);
+ return true;
+ } // endif remove
+
+ } else if (Mode == MODE_INSERT)
+ MakeColumnGroups(g);
+ else if (!(Cursor = MakeCursor(g)))
+ return true;
+
+ return false;
+} // end of OpenDB
+
+/***********************************************************************/
+/* Data Base indexed read routine for ODBC access method. */
+/***********************************************************************/
+bool TDBMGO::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
+{
+ strcpy(g->Message, "MONGO tables are not indexable");
+ return true;
+} // end of ReadKey
+
+/***********************************************************************/
+/* ReadDB: Get next document from a collection. */
+/***********************************************************************/
+int TDBMGO::ReadDB(PGLOBAL g)
+{
+ int rc = RC_OK;
+
+ if (mongoc_cursor_next(Cursor, &Document)) {
+
+ if (trace > 1) {
+ bson_iter_t iter;
+ ShowDocument(&iter, Document, "");
+ } else if (trace == 1) {
+ char *str = bson_as_json(Document, NULL);
+ htrc("%s\n", str);
+ bson_free(str);
+ } // endif trace
+
+ } else if (mongoc_cursor_error(Cursor, &Error)) {
+ sprintf(g->Message, "Mongo Cursor Failure: %s", Error.message);
+ rc = RC_FX;
+ } else {
+ //mongoc_cursor_destroy(Cursor);
+ rc = RC_EF;
+ } // endif's Cursor
+
+ return rc;
+} // end of ReadDB
+
+/***********************************************************************/
+/* Use to trace restaurants document contains. */
+/***********************************************************************/
+void TDBMGO::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k)
+{
+ if (!doc || bson_iter_init(iter, doc)) {
+ const char *key;
+
+ while (bson_iter_next(iter)) {
+ key = bson_iter_key(iter);
+ htrc("Found element key: \"%s\"\n", key);
+
+ if (BSON_ITER_HOLDS_UTF8(iter))
+ htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL));
+ else if (BSON_ITER_HOLDS_INT32(iter))
+ htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter));
+ else if (BSON_ITER_HOLDS_INT64(iter))
+ htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter));
+ else if (BSON_ITER_HOLDS_DOUBLE(iter))
+ htrc("%s.%s=%g\n", k, key, bson_iter_double(iter));
+ else if (BSON_ITER_HOLDS_DATE_TIME(iter))
+ htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter));
+ else if (BSON_ITER_HOLDS_OID(iter)) {
+ char str[25];
+
+ bson_oid_to_string(bson_iter_oid(iter), str);
+ htrc("%s.%s=%s\n", k, key, str);
+ } else if (BSON_ITER_HOLDS_DECIMAL128(iter)) {
+ char *str = NULL;
+ bson_decimal128_t dec;
+
+ bson_iter_decimal128(iter, &dec);
+ bson_decimal128_to_string(&dec, str);
+ htrc("%s.%s=%s\n", k, key, str);
+ } else if (BSON_ITER_HOLDS_DOCUMENT(iter)) {
+ bson_iter_t child;
+
+ if (bson_iter_recurse(iter, &child))
+ ShowDocument(&child, NULL, key);
+
+ } else if (BSON_ITER_HOLDS_ARRAY(iter)) {
+ bson_t *arr;
+ bson_iter_t itar;
+ const uint8_t *data = NULL;
+ uint32_t len = 0;
+
+ bson_iter_array(iter, &len, &data);
+ arr = bson_new_from_data(data, len);
+ ShowDocument(&itar, arr, key);
+ } // endif's
+
+ } // endwhile bson_iter_next
+
+ } // endif bson_iter_init
+
+} // end of ShowDocument
+
+/***********************************************************************/
+/* Group columns for inserting or updating. */
+/***********************************************************************/
+void TDBMGO::MakeColumnGroups(PGLOBAL g)
+{
+ Fpc = new(g) INCOL;
+
+ for (PCOL colp = Columns; colp; colp = colp->GetNext())
+ if (!colp->IsSpecial())
+ Fpc->AddCol(g, colp, ((PMGOCOL)colp)->Jpath);
+
+} // end of MakeColumnGroups
+
+/***********************************************************************/
+/* DocWrite. */
+/***********************************************************************/
+bool TDBMGO::DocWrite(PGLOBAL g, PINCOL icp)
+{
+ for (PKC kp = icp->Klist; kp; kp = kp->Next)
+ if (kp->Incolp) {
+ BSON_APPEND_DOCUMENT_BEGIN(&icp->Child, kp->Key, &kp->Incolp->Child);
+
+ if (DocWrite(g, kp->Incolp))
+ return true;
+
+ bson_append_document_end(&icp->Child, &kp->Incolp->Child);
+ } else if (((PMGOCOL)kp->Colp)->AddValue(g, &icp->Child, kp->Key, false))
+ return true;
+
+ return false;
+} // end of DocWrite
+
+/***********************************************************************/
+/* WriteDB: Data Base write routine for DOS access method. */
+/***********************************************************************/
+int TDBMGO::WriteDB(PGLOBAL g)
+{
+ int rc = RC_OK;
+
+ if (Mode == MODE_INSERT) {
+ bson_init(&Fpc->Child);
+
+ if (DocWrite(g, Fpc))
+ return RC_FX;
+
+ if (trace) {
+ char *str = bson_as_json(&Fpc->Child, NULL);
+ htrc("Inserting: %s\n", str);
+ bson_free(str);
+ } // endif trace
+
+ if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE,
+ &Fpc->Child, NULL, &Error)) {
+ sprintf(g->Message, "Mongo insert: %s", Error.message);
+ rc = RC_FX;
+ } // endif insert
+
+ } else {
+ bool b = false;
+ bson_iter_t iter;
+ bson_t *query = bson_new();
+
+ bson_iter_init(&iter, Document);
+
+ if (bson_iter_find(&iter, "_id")) {
+ if (BSON_ITER_HOLDS_OID(&iter))
+ b = BSON_APPEND_OID(query, "_id", bson_iter_oid(&iter));
+ else if (BSON_ITER_HOLDS_INT32(&iter))
+ b = BSON_APPEND_INT32(query, "_id", bson_iter_int32(&iter));
+ else if (BSON_ITER_HOLDS_INT64(&iter))
+ b = BSON_APPEND_INT64(query, "_id", bson_iter_int64(&iter));
+ else if (BSON_ITER_HOLDS_DOUBLE(&iter))
+ b = BSON_APPEND_DOUBLE(query, "_id", bson_iter_double(&iter));
+ else if (BSON_ITER_HOLDS_UTF8(&iter))
+ b = BSON_APPEND_UTF8(query, "_id", bson_iter_utf8(&iter, NULL));
+
+ } // endif iter
+
+ if (b) {
+ if (trace) {
+ char *str = bson_as_json(query, NULL);
+ htrc("update query: %s\n", str);
+ bson_free(str);
+ } // endif trace
+
+ if (Mode == MODE_UPDATE) {
+ bson_t child;
+ bson_t *update = bson_new();
+
+ BSON_APPEND_DOCUMENT_BEGIN(update, "$set", &child);
+
+ for (PCOL colp = To_SetCols; colp; colp = colp->GetNext())
+ if (((PMGOCOL)colp)->AddValue(g, &child, ((PMGOCOL)colp)->Jpath, true))
+ rc = RC_FX;
+
+ bson_append_document_end(update, &child);
+
+ if (rc == RC_OK)
+ if (!mongoc_collection_update(Collection, MONGOC_UPDATE_NONE,
+ query, update, NULL, &Error)) {
+ sprintf(g->Message, "Mongo update: %s", Error.message);
+ rc = RC_FX;
+ } // endif update
+
+ bson_destroy(update);
+ } else if (!mongoc_collection_remove(Collection,
+ MONGOC_REMOVE_SINGLE_REMOVE, query, NULL, &Error)) {
+ sprintf(g->Message, "Mongo delete: %s", Error.message);
+ rc = RC_FX;
+ } // endif remove
+
+ } else {
+ strcpy(g->Message, "Mongo update: cannot find _id");
+ rc = RC_FX;
+ } // endif b
+
+ bson_destroy(query);
+ } // endif Mode
+
+ return rc;
+} // end of WriteDB
+
+/***********************************************************************/
+/* Data Base delete line routine for ODBC access method. */
+/***********************************************************************/
+int TDBMGO::DeleteDB(PGLOBAL g, int irc)
+{
+ return (irc == RC_OK) ? WriteDB(g) : RC_OK;
+} // end of DeleteDB
+
+/***********************************************************************/
+/* Table close routine for MONGO tables. */
+/***********************************************************************/
+void TDBMGO::CloseDB(PGLOBAL g)
+{
+ if (Query) bson_destroy(Query);
+ if (Opts) bson_destroy(Opts);
+ if (Cursor) mongoc_cursor_destroy(Cursor);
+ if (Collection) mongoc_collection_destroy(Collection);
+ // mongoc_database_destroy(Database);
+ // mongoc_client_destroy(Client);
+ if (Client) mongoc_client_pool_push(Pool, Client);
+ if (Pool) mongoc_client_pool_destroy(Pool);
+ if (Uri) mongoc_uri_destroy(Uri);
+ Done = false;
+} // end of CloseDB
+
+/* ----------------------------- MGOCOL ------------------------------ */
+
+/***********************************************************************/
+/* MGOCOL public constructor. */
+/***********************************************************************/
+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);
+ Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName();
+ Mbuf = NULL;
+} // end of MGOCOL constructor
+
+/***********************************************************************/
+/* MGOCOL constructor used for copying columns. */
+/* tdbp is the pointer to the new table descriptor. */
+/***********************************************************************/
+MGOCOL::MGOCOL(MGOCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
+{
+ Tmgp = col1->Tmgp;
+ Jpath = col1->Jpath;
+ Mbuf = col1->Mbuf;
+} // end of MGOCOL copy constructor
+
+/***********************************************************************/
+/* Get projection path. */
+/***********************************************************************/
+char *MGOCOL::GetProjPath(PGLOBAL g)
+{
+ if (Jpath) {
+ char *p1, *p2, *projpath = PlugDup(g, Jpath);
+ int i = 0;
+
+ for (p1 = p2 = projpath; *p1; p1++)
+ if (*p1 == '.') {
+ if (!i)
+ *p2++ = *p1;
+
+ i = 1;
+ } else if (i) {
+ if (!isdigit(*p1)) {
+ *p2++ = *p1;
+ i = 0;
+ } // endif p1
+
+ } else
+ *p2++ = *p1;
+
+ *p2 = 0;
+ return projpath;
+ } else
+ return NULL;
+
+} // end of GetProjPath
+
+/***********************************************************************/
+/* Mini: used to suppress blanks to json strings. */
+/***********************************************************************/
+char *MGOCOL::Mini(PGLOBAL g, const bson_t *bson, bool b)
+{
+ char *s, *str = NULL;
+ int i, k = 0;
+ bool ok = true;
+
+ if (b)
+ s = str = bson_array_as_json(bson, NULL);
+ else
+ s = str = bson_as_json(bson, NULL);
+
+ for (i = 0; i < Long && s[i]; i++) {
+ switch (s[i]) {
+ case ' ':
+ if (ok) continue;
+ case '"':
+ ok = !ok;
+ default:
+ break;
+ } // endswitch s[i]
+
+ Mbuf[k++] = s[i];
+ } // endfor i
+
+ bson_free(str);
+
+ if (i >= Long) {
+ sprintf(g->Message, "Value too long for column %s", Name);
+ throw(TYPE_AM_MGO);
+ } // endif i
+
+ Mbuf[k] = 0;
+ return Mbuf;
+} // end of Mini
+
+/***********************************************************************/
+/* ReadColumn: */
+/***********************************************************************/
+void MGOCOL::ReadColumn(PGLOBAL g)
+{
+
+ if (!strcmp(Jpath, "*")) {
+ Value->SetValue_psz(Mini(g, Tmgp->Document, false));
+ } else if (bson_iter_init(&Iter, Tmgp->Document) &&
+ bson_iter_find_descendant(&Iter, Jpath, &Desc)) {
+ if (BSON_ITER_HOLDS_UTF8(&Desc))
+ Value->SetValue_psz((PSZ)bson_iter_utf8(&Desc, NULL));
+ else if (BSON_ITER_HOLDS_INT32(&Desc))
+ Value->SetValue(bson_iter_int32(&Desc));
+ else if (BSON_ITER_HOLDS_INT64(&Desc))
+ Value->SetValue(bson_iter_int64(&Desc));
+ else if (BSON_ITER_HOLDS_DOUBLE(&Desc))
+ Value->SetValue(bson_iter_double(&Desc));
+ else if (BSON_ITER_HOLDS_DATE_TIME(&Desc))
+ Value->SetValue(bson_iter_date_time(&Desc) / 1000);
+ else if (BSON_ITER_HOLDS_BOOL(&Desc)) {
+ bool b = bson_iter_bool(&Desc);
+
+ if (Value->IsTypeNum())
+ Value->SetValue(b ? 1 : 0);
+ else
+ Value->SetValue_psz(b ? "true" : "false");
+
+ } else if (BSON_ITER_HOLDS_OID(&Desc)) {
+ char str[25];
+
+ bson_oid_to_string(bson_iter_oid(&Desc), str);
+ Value->SetValue_psz(str);
+ } else if (BSON_ITER_HOLDS_DECIMAL128(&Desc)) {
+ char *str = NULL;
+ bson_decimal128_t dec;
+
+ bson_iter_decimal128(&Desc, &dec);
+ bson_decimal128_to_string(&dec, str);
+ Value->SetValue_psz(str);
+ bson_free(str);
+ } else if (BSON_ITER_HOLDS_DOCUMENT(&Iter)) {
+ bson_t *doc;
+ const uint8_t *data = NULL;
+ uint32_t len = 0;
+
+ bson_iter_document(&Desc, &len, &data);
+
+ if (data) {
+ doc = bson_new_from_data(data, len);
+ Value->SetValue_psz(Mini(g, doc, false));
+ bson_destroy(doc);
+ } else
+ Value->Reset();
+
+ } else if (BSON_ITER_HOLDS_ARRAY(&Iter)) {
+ bson_t *arr;
+ const uint8_t *data = NULL;
+ uint32_t len = 0;
+
+ bson_iter_array(&Desc, &len, &data);
+
+ if (data) {
+ arr = bson_new_from_data(data, len);
+ Value->SetValue_psz(Mini(g, arr, true));
+ bson_destroy(arr);
+ } else {
+ // This is a bug in returning the wrong type
+ // This fix is only for document items
+ bson_t *doc;
+
+ bson_iter_document(&Desc, &len, &data);
+
+ if (data) {
+ doc = bson_new_from_data(data, len);
+ Value->SetValue_psz(Mini(g, doc, false));
+ bson_destroy(doc);
+ } else {
+ //strcpy(g->Message, "bson_iter_array failed (data is null)");
+ //throw(TYPE_AM_MGO);
+ Value->Reset();
+ } // endif data
+
+ } // endif data
+
+ } else
+ Value->Reset();
+
+ } else
+ Value->Reset();
+
+ // Set null when applicable
+ if (Nullable)
+ Value->SetNull(Value->IsZero());
+
+} // end of ReadColumn
+
+/***********************************************************************/
+/* WriteColumn: */
+/***********************************************************************/
+void MGOCOL::WriteColumn(PGLOBAL g)
+{
+ // Check whether this node must be written
+ if (Value != To_Val)
+ Value->SetValue_pval(To_Val, FALSE); // Convert the updated value
+
+} // end of WriteColumn
+
+/***********************************************************************/
+/* AddValue: Add column value to the document to insert or update. */
+/***********************************************************************/
+bool MGOCOL::AddValue(PGLOBAL g, bson_t *doc, char *key, bool upd)
+{
+ bool rc = false;
+
+ if (Value->IsNull()) {
+ if (upd)
+ rc = BSON_APPEND_NULL(doc, key);
+ else
+ return false;
+
+ } else switch (Buf_Type) {
+ case TYPE_STRING:
+ rc = BSON_APPEND_UTF8(doc, key, Value->GetCharValue());
+ break;
+ case TYPE_INT:
+ case TYPE_SHORT:
+ rc = BSON_APPEND_INT32(doc, key, Value->GetIntValue());
+ break;
+ case TYPE_TINY:
+ rc = BSON_APPEND_BOOL(doc, key, Value->GetIntValue());
+ break;
+ case TYPE_BIGINT:
+ rc = BSON_APPEND_INT64(doc, key, Value->GetBigintValue());
+ break;
+ case TYPE_DOUBLE:
+ rc = BSON_APPEND_DOUBLE(doc, key, Value->GetFloatValue());
+ break;
+ case TYPE_DECIM:
+ {bson_decimal128_t dec;
+
+ if (bson_decimal128_from_string(Value->GetCharValue(), &dec))
+ rc = BSON_APPEND_DECIMAL128(doc, key, &dec);
+
+ } break;
+ case TYPE_DATE:
+ rc = BSON_APPEND_DATE_TIME(doc, key, Value->GetBigintValue() * 1000);
+ break;
+ default:
+ sprintf(g->Message, "Type %d not supported yet", Buf_Type);
+ return true;
+ } // endswitch Buf_Type
+
+ if (!rc) {
+ strcpy(g->Message, "Adding value failed");
+ return true;
+ } else
+ return false;
+
+} // end of AddValue
+
+#if 0
+/* ---------------------------TDBGOL class --------------------------- */
+
+/***********************************************************************/
+/* TDBGOL class constructor. */
+/***********************************************************************/
+TDBJCL::TDBJCL(PMGODEF tdp) : TDBCAT(tdp)
+{
+ Topt = tdp->GetTopt();
+ Db = (char*)tdp->GetDB();
+ Dsn = (char*)tdp->Uri;
+} // end of TDBJCL constructor
+
+/***********************************************************************/
+/* GetResult: Get the list the JSON file columns. */
+/***********************************************************************/
+PQRYRES TDBGOL::GetResult(PGLOBAL g)
+{
+ return JSONColumns(g, Db, Dsn, Topt, false);
+} // end of GetResult
+#endif // 0
+
+/* -------------------------- End of mongo --------------------------- */
diff --git a/storage/connect/tabmgo.h b/storage/connect/tabmgo.h
new file mode 100644
index 00000000000..610de367268
--- /dev/null
+++ b/storage/connect/tabmgo.h
@@ -0,0 +1,234 @@
+/**************** tabmgo H Declares Source Code File (.H) **************/
+/* Name: tabmgo.h Version 1.0 */
+/* */
+/* (C) Copyright to the author Olivier BERTRAND 2017 */
+/* */
+/* This file contains the MongoDB classes declares. */
+/***********************************************************************/
+#include "osutil.h"
+#include "block.h"
+#include "colblk.h"
+
+/***********************************************************************/
+/* Include MongoDB library header files. */
+/***********************************************************************/
+#include <bson.h>
+#include <bcon.h>
+#include <mongoc.h>
+
+typedef class MGODEF *PMGODEF;
+typedef class TDBMGO *PTDBMGO;
+typedef class MGOCOL *PMGOCOL;
+typedef class INCOL *PINCOL;
+
+typedef struct _bncol {
+ struct _bncol *Next;
+ char *Name;
+ char *Fmt;
+ int Type;
+ int Len;
+ int Scale;
+ bool Cbn;
+ bool Found;
+} BCOL, *PBCOL;
+
+typedef struct KEYCOL {
+ KEYCOL *Next;
+ PINCOL Incolp;
+ PCOL Colp;
+ char *Key;
+} *PKC;
+
+/***********************************************************************/
+/* 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;
+ TDBMGO *tmgp;
+ int *length;
+ int n, k, lvl;
+ bool all;
+}; // end of MGODISC
+
+/***********************************************************************/
+/* MongoDB table. */
+/***********************************************************************/
+class DllExport MGODEF : public EXTDEF { /* Table description */
+ friend class TDBMGO;
+ friend class MGOFAM;
+ friend class MGODISC;
+ friend PQRYRES MGOColumns(PGLOBAL, char *, PTOS, bool);
+public:
+ // Constructor
+ MGODEF(void);
+
+ // Implementation
+ virtual const char *GetType(void) { return "MONGO"; }
+
+ // Methods
+ virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
+ virtual PTDB GetTable(PGLOBAL g, MODE m);
+
+protected:
+ // Members
+ PCSZ Uri; /* MongoDB connection URI */
+ PCSZ Colist; /* Options list */
+ char *Filter; /* Filtering query */
+ int Level; /* Used for catalog table */
+ int Base; /* The array index base */
+ bool Pipe; /* True is Colist is a pipeline */
+}; // end of MGODEF
+
+/* ------------------------- TDBMGO classes -------------------------- */
+
+/***********************************************************************/
+/* Used when inserting values in a MongoDB collection. */
+/***********************************************************************/
+class INCOL : public BLOCK {
+public:
+ // Constructor
+ INCOL(void) { Klist = NULL; }
+
+ // Methods
+ void AddCol(PGLOBAL g, PCOL colp, char *jp);
+
+ //Members
+ bson_t Child;
+ PKC Klist;
+}; // end of INCOL;
+
+/***********************************************************************/
+/* This is the MongoDB Access Method class declaration. */
+/* The table is a collection, each record being a document. */
+/***********************************************************************/
+class DllExport TDBMGO : public TDBEXT {
+ friend class MGOCOL;
+ friend class MGODEF;
+ friend class MGODISC;
+ friend PQRYRES MGOColumns(PGLOBAL, char *, PTOS, bool);
+public:
+ // Constructor
+ TDBMGO(PMGODEF tdp);
+ TDBMGO(TDBMGO *tdbp);
+
+ // Implementation
+ virtual AMT GetAmType(void) {return TYPE_AM_MGO;}
+ virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMGO(this);}
+
+ // Methods
+ virtual PTDB Clone(PTABS t);
+ virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
+ virtual PCOL InsertSpecialColumn(PCOL colp);
+ virtual void SetFilter(PFIL fp);
+ virtual int RowNumber(PGLOBAL g, bool b = FALSE) {return N;}
+
+ // Database routines
+ virtual int Cardinality(PGLOBAL g);
+ virtual int GetMaxSize(PGLOBAL g);
+ virtual bool OpenDB(PGLOBAL g);
+ virtual int ReadDB(PGLOBAL g);
+ virtual int WriteDB(PGLOBAL g);
+ virtual int DeleteDB(PGLOBAL g, int irc);
+ virtual void CloseDB(PGLOBAL g);
+ virtual bool ReadKey(PGLOBAL g, OPVAL op, const key_range *kr);
+
+protected:
+ bool Init(PGLOBAL g);
+ mongoc_cursor_t *MakeCursor(PGLOBAL g);
+ void ShowDocument(bson_iter_t *i, const bson_t *b, const char *k);
+ void MakeColumnGroups(PGLOBAL g);
+ bool DocWrite(PGLOBAL g, PINCOL icp);
+
+ // Members
+ PGLOBAL G; // Needed by SetFilter
+ mongoc_uri_t *Uri;
+ mongoc_client_pool_t *Pool; // Thread safe client pool
+ mongoc_client_t *Client; // The MongoDB client
+ mongoc_database_t *Database; // The MongoDB database
+ mongoc_collection_t *Collection; // The MongoDB collection
+ mongoc_cursor_t *Cursor;
+ const bson_t *Document;
+ bson_t *Query; // MongoDB cursor filter
+ bson_t *Opts; // MongoDB cursor options
+ bson_error_t Error;
+ PINCOL Fpc; // To insert INCOL classes
+ const Item *Cnd; // The first condition
+ const char *Uristr;
+ const char *Db_name;
+ const char *Coll_name;
+ const char *Options; // The MongoDB options
+ const char *Filter; // The filtering query
+ int Fpos; // The current row index
+ int N; // The current Rownum
+ int B; // Array index base
+ bool Done; // Init done
+ bool Pipe; // True for pipeline
+}; // end of class TDBMGO
+
+/* --------------------------- MGOCOL class -------------------------- */
+
+/***********************************************************************/
+/* Class MGOCOL: MongoDB access method column descriptor. */
+/***********************************************************************/
+class DllExport MGOCOL : public EXTCOL {
+ friend class TDBMGO;
+ friend class FILTER;
+public:
+ // Constructors
+ MGOCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i);
+ MGOCOL(MGOCOL *colp, PTDB tdbp); // Constructor used in copy process
+
+ // Implementation
+ virtual int GetAmType(void) { return Tmgp->GetAmType(); }
+
+ // Methods
+//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
+ virtual void ReadColumn(PGLOBAL g);
+ virtual void WriteColumn(PGLOBAL g);
+ bool AddValue(PGLOBAL g, bson_t *doc, char *key, bool upd);
+
+protected:
+ // Default constructor not to be used
+ MGOCOL(void) {}
+ char *GetProjPath(PGLOBAL g);
+ char *Mini(PGLOBAL g, const bson_t *bson, bool b);
+
+ // Members
+ TDBMGO *Tmgp; // To the MGO table block
+ bson_iter_t Iter; // Used to retrieve column value
+ bson_iter_t Desc; // Descendant iter
+ char *Jpath; // The json path
+ char *Mbuf; // The Mini buffer
+}; // end of class MGOCOL
+
+#if 0
+/***********************************************************************/
+/* This is the class declaration for the MONGO catalog table. */
+/***********************************************************************/
+class DllExport TDBGOL : public TDBCAT {
+public:
+ // Constructor
+ TDBGOL(PMGODEF tdp);
+
+protected:
+ // Specific routines
+ virtual PQRYRES GetResult(PGLOBAL g);
+
+ // Members
+ PTOS Topt;
+ char *Db;
+ char *Dsn;
+}; // end of class TDBGOL
+#endif // 0
diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp
index 78adde81d12..5c41f9094ac 100644
--- a/storage/connect/tabmul.cpp
+++ b/storage/connect/tabmul.cpp
@@ -1,7 +1,7 @@
/************* TabMul C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABMUL */
/* ------------- */
-/* Version 1.8 */
+/* Version 1.9 */
/* */
/* COPYRIGHT: */
/* ---------- */
@@ -44,6 +44,11 @@
#define __MFC_COMPAT__ // To define min/max as macro
#endif
//#include <windows.h>
+#if defined(PATHMATCHSPEC)
+#include "Shlwapi.h"
+//using namespace std;
+#pragma comment(lib,"shlwapi.lib")
+#endif // PATHMATCHSPEC
#else
#if defined(UNIX)
#include <fnmatch.h>
@@ -124,9 +129,10 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
{
#define PFNZ 4096
#define FNSZ (_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT)
- char *pfn[PFNZ];
- char *filename;
- int rc, n = 0;
+ PTDBDIR dirp;
+ PSZ pfn[PFNZ];
+ PSZ filename;
+ int rc, n = 0;
if (trace)
htrc("in InitFileName: fn[]=%d\n", FNSZ);
@@ -141,115 +147,39 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
if (trace)
htrc("InitFileName: fn='%s'\n", filename);
- if (Mul == 1) {
+ if (Mul != 2) {
/*******************************************************************/
/* To_File is a multiple name with special characters */
/*******************************************************************/
-#if defined(__WIN__)
- char drive[_MAX_DRIVE], direc[_MAX_DIR];
- WIN32_FIND_DATA FileData;
- HANDLE hSearch;
-
- _splitpath(filename, drive, direc, NULL, NULL);
-
- // Start searching files in the target directory.
- hSearch = FindFirstFile(filename, &FileData);
-
- if (hSearch == INVALID_HANDLE_VALUE) {
- rc = GetLastError();
-
- if (rc != ERROR_FILE_NOT_FOUND) {
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, GetLastError(), 0,
- (LPTSTR)&filename, sizeof(filename), NULL);
- sprintf(g->Message, MSG(BAD_FILE_HANDLE), filename);
- return true;
- } // endif rc
-
- goto suite;
- } // endif hSearch
+ if (Mul == 1)
+ dirp = new(g) TDBDIR(PlugDup(g, filename));
+ else // Mul == 3 (Subdir)
+ dirp = new(g) TDBSDR(PlugDup(g, filename));
- while (n < PFNZ) {
- if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- strcat(strcat(strcpy(filename, drive), direc), FileData.cFileName);
- pfn[n++] = PlugDup(g, filename);
- } // endif dwFileAttributes
-
- if (!FindNextFile(hSearch, &FileData)) {
- rc = GetLastError();
-
- if (rc != ERROR_NO_MORE_FILES) {
- sprintf(g->Message, MSG(NEXT_FILE_ERROR), rc);
- FindClose(hSearch);
- return true;
- } // endif rc
-
- break;
- } // endif FindNextFile
-
- } // endwhile n
+ if (dirp->OpenDB(g))
+ return true;
- // Close the search handle.
- if (!FindClose(hSearch)) {
- strcpy(g->Message, MSG(SRCH_CLOSE_ERR));
- return true;
- } // endif FindClose
+ if (trace && Mul == 3) {
+ int nf = ((PTDBSDR)dirp)->FindInDir(g);
+ htrc("Number of files = %d\n", nf);
+ } // endif trace
+ while (true)
+ if ((rc = dirp->ReadDB(g)) == RC_OK) {
+#if defined(__WIN__)
+ strcat(strcpy(filename, dirp->Drive), dirp->Direc);
#else // !__WIN__
- struct stat fileinfo;
- char fn[FN_REFLEN], direc[FN_REFLEN], pattern[FN_HEADLEN], ftype[FN_EXTLEN];
- DIR *dir;
- struct dirent *entry;
-
- _splitpath(filename, NULL, direc, pattern, ftype);
- strcat(pattern, ftype);
-
- if (trace)
- htrc("direc=%s pattern=%s ftype=%s\n", direc, pattern, ftype);
-
- // Start searching files in the target directory.
- if (!(dir = opendir(direc))) {
- sprintf(g->Message, MSG(BAD_DIRECTORY), direc, strerror(errno));
-
- if (trace)
- htrc("%s\n", g->Message);
-
- return true;
- } // endif dir
-
- if (trace)
- htrc("dir opened: reading files\n");
-
- while ((entry = readdir(dir)) && n < PFNZ) {
- strcat(strcpy(fn, direc), entry->d_name);
-
- if (trace)
- htrc("%s read\n", fn);
-
- if (lstat(fn, &fileinfo) < 0) {
- sprintf(g->Message, "%s: %s", fn, strerror(errno));
- return true;
- } else if (!S_ISREG(fileinfo.st_mode))
- continue; // Not a regular file (should test for links)
-
- /*******************************************************************/
- /* Test whether the file name matches the table name filter. */
- /*******************************************************************/
- if (fnmatch(pattern, entry->d_name, 0))
- continue; // Not a match
-
- strcat(strcpy(filename, direc), entry->d_name);
- pfn[n++] = PlugDup(g, filename);
-
- if (trace)
- htrc("Adding pfn[%d] %s\n", n, filename);
+ strcpy(filename, dirp->Direc);
+#endif // !__WIN__
+ strcat(strcat(filename, dirp->Fname), dirp->Ftype);
+ pfn[n++] = PlugDup(g, filename);
+ } else
+ break;
- } // endwhile readdir
+ dirp->CloseDB(g);
- // Close the dir handle.
- closedir(dir);
-#endif // !__WIN__
+ if (rc == RC_FX)
+ return true;
} else {
/*******************************************************************/
@@ -297,10 +227,6 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
} // endif Mul
-#if defined(__WIN__)
- suite:
-#endif
-
if (n) {
Filenames = (char**)PlugSubAlloc(g, NULL, n * sizeof(char*));
@@ -581,7 +507,95 @@ void TDBMUL::CloseDB(PGLOBAL g)
} // end of CloseDB
-/* --------------------------- Class DIRDEF -------------------------- */
+#if 0
+/* ------------------------- Class TDBMSD ---------------------------- */
+
+ // Method
+PTDB TDBMSD::Clone(PTABS t)
+{
+ PTDBMSD tp;
+ PGLOBAL g = t->G; // Is this really useful ???
+
+ tp = new(g) TDBMSD(this);
+ tp->Tdbp = Tdbp->Clone(t);
+ tp->Columns = tp->Tdbp->GetColumns();
+ return tp;
+} // end of Clone
+
+PTDB TDBMSD::Duplicate(PGLOBAL g)
+{
+ PTDBMSD tmup = new(g) TDBMSD(this);
+
+ tmup->Tdbp = Tdbp->Duplicate(g);
+ return tmup;
+} // end of Duplicate
+
+/***********************************************************************/
+/* Initializes the table filename list. */
+/* Note: tables created by concatenating the file components without */
+/* specifying the LRECL value (that should be restricted to _MAX_PATH)*/
+/* have a LRECL that is the sum of the lengths of all components. */
+/* This is why we use a big filename array to take care of that. */
+/***********************************************************************/
+bool TDBMSD::InitFileNames(PGLOBAL g)
+{
+#define PFNZ 4096
+#define FNSZ (_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT)
+ PTDBSDR dirp;
+ PSZ pfn[PFNZ];
+ PSZ filename;
+ int rc, n = 0;
+
+ if (trace)
+ htrc("in InitFileName: fn[]=%d\n", FNSZ);
+
+ filename = (char*)PlugSubAlloc(g, NULL, FNSZ);
+
+ // The sub table may need to refer to the Table original block
+ Tdbp->SetTable(To_Table); // Was not set at construction
+
+ PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
+
+ if (trace)
+ htrc("InitFileName: fn='%s'\n", filename);
+
+ dirp = new(g) TDBSDR(filename);
+
+ if (dirp->OpenDB(g))
+ return true;
+
+ while (true)
+ if ((rc = dirp->ReadDB(g)) == RC_OK) {
+#if defined(__WIN__)
+ strcat(strcpy(filename, dirp->Drive), dirp->Direc);
+#else // !__WIN__
+ strcpy(filename, dirp->Direc);
+#endif // !__WIN__
+ strcat(strcat(filename, dirp->Fname), dirp->Ftype);
+ pfn[n++] = PlugDup(g, filename);
+ } else
+ break;
+
+ if (rc == RC_FX)
+ return true;
+
+ if (n) {
+ Filenames = (char**)PlugSubAlloc(g, NULL, n * sizeof(char*));
+
+ for (int i = 0; i < n; i++)
+ Filenames[i] = pfn[i];
+
+ } else {
+ Filenames = (char**)PlugSubAlloc(g, NULL, sizeof(char*));
+ Filenames[0] = NULL;
+ } // endif n
+
+ NumFiles = n;
+ return false;
+} // end of InitFileNames
+#endif // 0
+
+ /* --------------------------- Class DIRDEF -------------------------- */
/***********************************************************************/
/* DefineAM: define specific AM block values from XDB file. */
@@ -589,8 +603,9 @@ void TDBMUL::CloseDB(PGLOBAL g)
bool DIRDEF::DefineAM(PGLOBAL g, LPCSTR, int)
{
Desc = Fn = GetStringCatInfo(g, "Filename", NULL);
- Incl = (GetIntCatInfo("Subdir", 0) != 0);
- Huge = (GetIntCatInfo("Huge", 0) != 0);
+ Incl = GetBoolCatInfo("Subdir", false);
+ Huge = GetBoolCatInfo("Huge", false);
+ Nodir = GetBoolCatInfo("Nodir", true);
return false;
} // end of DefineAM
@@ -616,57 +631,40 @@ PTDB DIRDEF::GetTable(PGLOBAL g, MODE)
/***********************************************************************/
/* TABDIR constructors. */
/***********************************************************************/
-TDBDIR::TDBDIR(PDIRDEF tdp) : TDBASE(tdp)
- {
- To_File = tdp->Fn;
- iFile = 0;
+void TDBDIR::Init(void)
+{
+ iFile = 0;
#if defined(__WIN__)
- memset(&FileData, 0, sizeof(_finddata_t));
- Hsearch = -1;
- *Drive = '\0';
-#else // !__WIN__
- memset(&Fileinfo, 0, sizeof(struct stat));
- Entry = NULL;
- Dir = NULL;
- Done = false;
- *Pattern = '\0';
-#endif // !__WIN__
- *Fpath = '\0';
- *Direc = '\0';
- *Fname = '\0';
- *Ftype = '\0';
- } // end of TDBDIR standard constructor
-
-TDBDIR::TDBDIR(PTDBDIR tdbp) : TDBASE(tdbp)
- {
- To_File = tdbp->To_File;
- iFile = tdbp->iFile;
-#if defined(__WIN__)
- FileData = tdbp->FileData;
- Hsearch = tdbp->Hsearch;
- strcpy(Drive, tdbp->Drive);
+ Dvalp = NULL;
+ memset(&FileData, 0, sizeof(_finddata_t));
+ hSearch = INVALID_HANDLE_VALUE;
+ *Drive = '\0';
#else // !__WIN__
- Fileinfo = tdbp->Fileinfo;
- Entry = tdbp->Entry;
- Dir = tdbp->Dir;
- Done = tdbp->Done;
- strcpy(Pattern, tdbp->Pattern);
+ memset(&Fileinfo, 0, sizeof(struct stat));
+ Entry = NULL;
+ Dir = NULL;
+ Done = false;
+ *Pattern = '\0';
#endif // !__WIN__
- strcpy(Direc, tdbp->Direc);
- strcpy(Fname, tdbp->Fname);
- strcpy(Ftype, tdbp->Ftype);
- } // end of TDBDIR copy constructor
+ *Fpath = '\0';
+ *Direc = '\0';
+ *Fname = '\0';
+ *Ftype = '\0';
+} // end of Init
-// Method
-PTDB TDBDIR::Clone(PTABS t)
- {
- PTDB tp;
- PGLOBAL g = t->G; // Is this really useful ???
+TDBDIR::TDBDIR(PDIRDEF tdp) : TDBASE(tdp)
+{
+ To_File = tdp->Fn;
+ Nodir = tdp->Nodir;
+ Init();
+} // end of TDBDIR standard constructor
- tp = new(g) TDBDIR(this);
- tp->SetColumns(Columns);
- return tp;
- } // end of Clone
+TDBDIR::TDBDIR(PSZ fpat) : TDBASE((PTABDEF)NULL)
+{
+ To_File = fpat;
+ Nodir = true;
+ Init();
+} // end of TDBDIR constructor
/***********************************************************************/
/* Initialize/get the components of the search file pattern. */
@@ -674,18 +672,19 @@ PTDB TDBDIR::Clone(PTABS t)
char* TDBDIR::Path(PGLOBAL g)
{
PCATLG cat = PlgGetCatalog(g);
+ PTABDEF defp = (PTABDEF)To_Def;
#if defined(__WIN__)
if (!*Drive) {
- PlugSetPath(Fpath, To_File, ((PTABDEF)To_Def)->GetPath());
+ PlugSetPath(Fpath, To_File, defp ? defp->GetPath() : NULL);
_splitpath(Fpath, Drive, Direc, Fname, Ftype);
} else
- _makepath(Fpath, Drive, Direc, Fname, Ftype); // Usefull ???
+ _makepath(Fpath, Drive, Direc, Fname, Ftype); // Usefull for TDBSDR
return Fpath;
#else // !__WIN__
if (!Done) {
- PlugSetPath(Fpath, To_File, ((PTABDEF)To_Def)->GetPath());
+ PlugSetPath(Fpath, To_File, defp ? defp->GetPath() : NULL);
_splitpath(Fpath, NULL, Direc, Fname, Ftype);
strcat(strcpy(Pattern, Fname), Ftype);
Done = true;
@@ -709,23 +708,48 @@ PCOL TDBDIR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
int TDBDIR::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0) {
- int n = -1;
+ int rc, n = -1;
#if defined(__WIN__)
- int h;
// Start searching files in the target directory.
- h = _findfirst(Path(g), &FileData);
+ hSearch = FindFirstFile(Path(g), &FileData);
- if (h != -1) {
- for (n = 1;; n++)
- if (_findnext(h, &FileData))
- break;
+ if (hSearch == INVALID_HANDLE_VALUE) {
+ rc = GetLastError();
- // Close the search handle.
- _findclose(h);
- } else
- n = 0;
+ if (rc != ERROR_FILE_NOT_FOUND) {
+ char buf[512];
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), 0, (LPTSTR)&buf, sizeof(buf), NULL);
+ sprintf(g->Message, MSG(BAD_FILE_HANDLE), buf);
+ return -1;
+ } // endif rc
+
+ return 0;
+ } // endif hSearch
+
+ while (true) {
+ if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ n++;
+
+ if (!FindNextFile(hSearch, &FileData)) {
+ rc = GetLastError();
+
+ if (rc != ERROR_NO_MORE_FILES) {
+ sprintf(g->Message, MSG(NEXT_FILE_ERROR), rc);
+ FindClose(hSearch);
+ return -1;
+ } // endif rc
+
+ break;
+ } // endif Next
+
+ } // endwhile
+ // Close the search handle.
+ FindClose(hSearch);
#else // !__WIN__
Path(g);
@@ -791,30 +815,35 @@ int TDBDIR::ReadDB(PGLOBAL g)
int rc = RC_OK;
#if defined(__WIN__)
- if (Hsearch == -1) {
- /*******************************************************************/
- /* Start searching files in the target directory. The use of the */
- /* Path function is required when called from TDBSDR. */
- /*******************************************************************/
- Hsearch = _findfirst(Path(g), &FileData);
-
- if (Hsearch == -1)
- rc = RC_EF;
- else
- iFile++;
-
- } else {
- if (_findnext(Hsearch, &FileData)) {
- // Restore file name and type pattern
- _splitpath(To_File, NULL, NULL, Fname, Ftype);
- rc = RC_EF;
- } else
- iFile++;
-
- } // endif Hsearch
+ do {
+ if (hSearch == INVALID_HANDLE_VALUE) {
+ /*****************************************************************/
+ /* Start searching files in the target directory. The use of */
+ /* the Path function is required when called from TDBSDR. */
+ /*****************************************************************/
+ hSearch = FindFirstFile(Path(g), &FileData);
+
+ if (hSearch == INVALID_HANDLE_VALUE) {
+ rc = RC_EF;
+ break;
+ } else
+ iFile++;
+
+ } else {
+ if (!FindNextFile(hSearch, &FileData)) {
+ // Restore file name and type pattern
+ _splitpath(To_File, NULL, NULL, Fname, Ftype);
+ rc = RC_EF;
+ break;
+ } else
+ iFile++;
+
+ } // endif hSearch
+
+ } while (Nodir && FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
if (rc == RC_OK)
- _splitpath(FileData.name, NULL, NULL, Fname, Ftype);
+ _splitpath(FileData.cFileName, NULL, NULL, Fname, Ftype);
#else // !Win32
rc = RC_NF;
@@ -878,8 +907,8 @@ void TDBDIR::CloseDB(PGLOBAL)
{
#if defined(__WIN__)
// Close the search handle.
- _findclose(Hsearch);
- Hsearch = -1;
+ FindClose(hSearch);
+ hSearch = INVALID_HANDLE_VALUE;
#else // !__WIN__
// Close the DIR handle
if (Dir) {
@@ -895,7 +924,7 @@ void TDBDIR::CloseDB(PGLOBAL)
/***********************************************************************/
/* DIRCOL public constructor. */
/***********************************************************************/
-DIRCOL::DIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ)
+DIRCOL::DIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ)
: COLBLK(cdp, tdbp, i)
{
if (cprec) {
@@ -907,6 +936,7 @@ DIRCOL::DIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ)
} // endif cprec
// Set additional DIR access method information for column.
+ Tdbp = (PTDBDIR)tdbp;
N = cdp->GetOffset();
} // end of DIRCOL constructor
@@ -916,75 +946,84 @@ DIRCOL::DIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ)
/***********************************************************************/
DIRCOL::DIRCOL(DIRCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
{
- N = col1->N;
+ Tdbp = (PTDBDIR)tdbp;
+ N = col1->N;
} // end of DIRCOL copy constructor
+#if defined(__WIN__)
+/***********************************************************************/
+/* Retrieve time information from FileData. */
+/***********************************************************************/
+void DIRCOL::SetTimeValue(PGLOBAL g, FILETIME& ftime)
+{
+ char tsp[24];
+ SYSTEMTIME stp;
+
+ if (FileTimeToSystemTime(&ftime, &stp)) {
+ sprintf(tsp, "%04d-%02d-%02d %02d:%02d:%02d",
+ stp.wYear, stp.wMonth, stp.wDay, stp.wHour, stp.wMinute, stp.wSecond);
+
+ if (Value->GetType() != TYPE_STRING) {
+ if (!Tdbp->Dvalp)
+ Tdbp->Dvalp = AllocateValue(g, TYPE_DATE, 20, 0, false,
+ "YYYY-MM-DD hh:mm:ss");
+
+ Tdbp->Dvalp->SetValue_psz(tsp);
+ Value->SetValue_pval(Tdbp->Dvalp);
+ } else
+ Value->SetValue_psz(tsp);
+
+ } else
+ Value->Reset();
+
+} // end of SetTimeValue
+#endif // __WIN__
+
/***********************************************************************/
/* ReadColumn: what this routine does is to access the information */
/* corresponding to this column and convert it to buffer type. */
/***********************************************************************/
void DIRCOL::ReadColumn(PGLOBAL g)
- {
- PTDBDIR tdbp = (PTDBDIR)To_Tdb;
-
+ {
if (trace)
htrc("DIR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
- Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
+ Name, Tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
/*********************************************************************/
/* Retrieve the information corresponding to the column number. */
/*********************************************************************/
switch (N) {
#if defined(__WIN__)
- case 0: Value->SetValue_psz(tdbp->Drive); break;
+ case 0: Value->SetValue_psz(Tdbp->Drive); break;
#endif // __WIN__
- case 1: Value->SetValue_psz(tdbp->Direc); break;
- case 2: Value->SetValue_psz(tdbp->Fname); break;
- case 3: Value->SetValue_psz(tdbp->Ftype); break;
+ case 1: Value->SetValue_psz(Tdbp->Direc); break;
+ case 2: Value->SetValue_psz(Tdbp->Fname); break;
+ case 3: Value->SetValue_psz(Tdbp->Ftype); break;
#if defined(__WIN__)
- case 4: Value->SetValue((int)tdbp->FileData.attrib); break;
- case 5: Value->SetValue((int)tdbp->FileData.size); break;
- case 6: Value->SetValue((int)tdbp->FileData.time_write); break;
- case 7: Value->SetValue((int)tdbp->FileData.time_create); break;
- case 8: Value->SetValue((int)tdbp->FileData.time_access); break;
+ case 4: Value->SetValue((int)Tdbp->FileData.dwFileAttributes); break;
+ case 5: Value->SetValue((int)Tdbp->FileData.nFileSizeLow); break;
+ case 6: SetTimeValue(g, Tdbp->FileData.ftLastWriteTime); break;
+ case 7: SetTimeValue(g, Tdbp->FileData.ftCreationTime); break;
+ case 8: SetTimeValue(g, Tdbp->FileData.ftLastAccessTime); break;
#else // !__WIN__
- case 4: Value->SetValue((int)tdbp->Fileinfo.st_mode); break;
- case 5: Value->SetValue((int)tdbp->Fileinfo.st_size); break;
- case 6: Value->SetValue((int)tdbp->Fileinfo.st_mtime); break;
- case 7: Value->SetValue((int)tdbp->Fileinfo.st_ctime); break;
- case 8: Value->SetValue((int)tdbp->Fileinfo.st_atime); break;
- case 9: Value->SetValue((int)tdbp->Fileinfo.st_uid); break;
- case 10: Value->SetValue((int)tdbp->Fileinfo.st_gid); break;
+ case 4: Value->SetValue((int)Tdbp->Fileinfo.st_mode); break;
+ case 5: Value->SetValue((int)Tdbp->Fileinfo.st_size); break;
+ case 6: Value->SetValue((int)Tdbp->Fileinfo.st_mtime); break;
+ case 7: Value->SetValue((int)Tdbp->Fileinfo.st_ctime); break;
+ case 8: Value->SetValue((int)Tdbp->Fileinfo.st_atime); break;
+ case 9: Value->SetValue((int)Tdbp->Fileinfo.st_uid); break;
+ case 10: Value->SetValue((int)Tdbp->Fileinfo.st_gid); break;
#endif // !__WIN__
default:
sprintf(g->Message, MSG(INV_DIRCOL_OFST), N);
- longjmp(g->jumper[g->jump_level], GetAmType());
- } // endswitch N
+ throw GetAmType();
+ } // endswitch N
} // end of ReadColumn
/* ------------------------- Class TDBSDR ---------------------------- */
/***********************************************************************/
-/* TABSDR copy constructors. */
-/***********************************************************************/
-TDBSDR::TDBSDR(PTDBSDR tdbp) : TDBDIR(tdbp)
- {
- Sub = tdbp->Sub;
- } // end of TDBSDR copy constructor
-
-// Method
-PTDB TDBSDR::Clone(PTABS t)
- {
- PTDB tp;
- PGLOBAL g = t->G; // Is this really useful ???
-
- tp = new(g) TDBSDR(this);
- tp->SetColumns(Columns);
- return tp;
- } // end of Clone
-
-/***********************************************************************/
/* SDR GetMaxSize: returns the number of retrieved files. */
/***********************************************************************/
int TDBSDR::GetMaxSize(PGLOBAL g)
@@ -998,47 +1037,124 @@ int TDBSDR::GetMaxSize(PGLOBAL g)
} // end of GetMaxSize
/***********************************************************************/
-/* SDR GetMaxSize: returns the number of retrieved files. */
+/* SDR FindInDir: returns the number of retrieved files. */
/***********************************************************************/
int TDBSDR::FindInDir(PGLOBAL g)
{
- int n = 0;
+ int rc, n = 0;
size_t m = strlen(Direc);
// Start searching files in the target directory.
#if defined(__WIN__)
- int h = _findfirst(Path(g), &FileData);
+ HANDLE h;
- if (h != -1) {
- for (n = 1;; n++)
- if (_findnext(h, &FileData))
- break;
+#if defined(PATHMATCHSPEC)
+ if (!*Drive)
+ Path(g);
- // Close the search handle.
- _findclose(h);
- } // endif h
+ _makepath(Fpath, Drive, Direc, "*", "*");
- // Now search files in sub-directories.
- _makepath(Fpath, Drive, Direc, "*", "");
- h = _findfirst(Fpath, &FileData);
+ h = FindFirstFile(Fpath, &FileData);
- if (h != -1) {
- while (true) {
- if (FileData.attrib & _A_SUBDIR && *FileData.name != '.') {
- // Look in the name sub-directory
- strcat(strcat(Direc, FileData.name), "\\");
- n += FindInDir(g);
- Direc[m] = '\0'; // Restore path
- } // endif SUBDIR
+ if (h == INVALID_HANDLE_VALUE) {
+ rc = GetLastError();
- if (_findnext(h, &FileData))
- break;
+ if (rc != ERROR_FILE_NOT_FOUND) {
+ char buf[512];
- } // endwhile
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), 0, (LPTSTR)&buf, sizeof(buf), NULL);
+ sprintf(g->Message, MSG(BAD_FILE_HANDLE), buf);
+ return -1;
+ } // endif rc
- // Close the search handle.
- _findclose(h);
- } // endif h
+ return 0;
+ } // endif h
+
+ while (true) {
+ if ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
+ *FileData.cFileName != '.') {
+ // Look in the name sub-directory
+ strcat(strcat(Direc, FileData.cFileName), "/");
+ n += FindInDir(g);
+ Direc[m] = '\0'; // Restore path
+ } else if (PathMatchSpec(FileData.cFileName, Fpath))
+ n++;
+
+ if (!FindNextFile(h, &FileData)) {
+ rc = GetLastError();
+
+ if (rc != ERROR_NO_MORE_FILES) {
+ sprintf(g->Message, MSG(NEXT_FILE_ERROR), rc);
+ FindClose(h);
+ return -1;
+ } // endif rc
+
+ break;
+ } // endif Next
+
+ } // endwhile
+#else // !PATHMATCHSPEC
+ h = FindFirstFile(Path(g), &FileData);
+
+ if (h == INVALID_HANDLE_VALUE) {
+ rc = GetLastError();
+
+ if (rc != ERROR_FILE_NOT_FOUND) {
+ char buf[512];
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), 0, (LPTSTR)&buf, sizeof(buf), NULL);
+ sprintf(g->Message, MSG(BAD_FILE_HANDLE), buf);
+ return -1;
+ } // endif rc
+
+ return 0;
+ } // endif hSearch
+
+ while (true) {
+ n++;
+
+ if (!FindNextFile(h, &FileData)) {
+ rc = GetLastError();
+
+ if (rc != ERROR_NO_MORE_FILES) {
+ sprintf(g->Message, MSG(NEXT_FILE_ERROR), rc);
+ FindClose(h);
+ return -1;
+ } // endif rc
+
+ break;
+ } // endif Next
+
+ } // endwhile
+
+ // Now search files in sub-directories.
+ _makepath(Fpath, Drive, Direc, "*", ".");
+ h = FindFirstFile(Fpath, &FileData);
+
+ if (h != INVALID_HANDLE_VALUE) {
+ while (true) {
+ if ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
+ *FileData.cFileName != '.') {
+ // Look in the name sub-directory
+ strcat(strcat(Direc, FileData.cFileName), "/");
+ n += FindInDir(g);
+ Direc[m] = '\0'; // Restore path
+ } // endif SUBDIR
+
+ if (!FindNextFile(h, &FileData))
+ break;
+
+ } // endwhile
+
+ } // endif h
+#endif // !PATHMATCHSPEC
+
+ // Close the search handle.
+ FindClose(h);
#else // !__WIN__
int k;
DIR *dir = opendir(Direc);
@@ -1090,7 +1206,7 @@ bool TDBSDR::OpenDB(PGLOBAL g)
Sub->Next = NULL;
Sub->Prev = NULL;
#if defined(__WIN__)
- Sub->H = -1;
+ Sub->H = INVALID_HANDLE_VALUE;
Sub->Len = strlen(Direc);
#else // !__WIN__
Sub->D = NULL;
@@ -1116,18 +1232,22 @@ int TDBSDR::ReadDB(PGLOBAL g)
// Are there more files in sub-directories
retry:
do {
- if (Sub->H == -1) {
- _makepath(Fpath, Drive, Direc, "*", "");
- Sub->H = _findfirst(Fpath, &FileData);
- } else if (_findnext(Sub->H, &FileData)) {
- _findclose(Sub->H);
- Sub->H = -1;
- *FileData.name = '\0';
- } // endif findnext
-
- } while(*FileData.name == '.');
-
- if (Sub->H == -1) {
+ if (Sub->H == INVALID_HANDLE_VALUE) {
+// _makepath(Fpath, Drive, Direc, "*", "."); why was this made?
+ _makepath(Fpath, Drive, Direc, "*", NULL);
+ Sub->H = FindFirstFile(Fpath, &FileData);
+ } else if (!FindNextFile(Sub->H, &FileData)) {
+ FindClose(Sub->H);
+ Sub->H = INVALID_HANDLE_VALUE;
+ *FileData.cFileName= '\0';
+ break;
+ } // endif findnext
+
+ } while(!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
+ (*FileData.cFileName == '.' &&
+ (!FileData.cFileName[1] || FileData.cFileName[1] == '.')));
+
+ if (Sub->H == INVALID_HANDLE_VALUE) {
// No more sub-directories. Are we in a sub-directory?
if (!Sub->Prev)
return rc; // No, all is finished
@@ -1145,17 +1265,17 @@ int TDBSDR::ReadDB(PGLOBAL g)
sup = (PSUBDIR)PlugSubAlloc(g, NULL, sizeof(SUBDIR));
sup->Next = NULL;
sup->Prev = Sub;
- sup->H = -1;
+ sup->H = INVALID_HANDLE_VALUE;
Sub->Next = sup;
} // endif Next
Sub = Sub->Next;
- strcat(strcat(Direc, FileData.name), "\\");
+ strcat(strcat(Direc, FileData.cFileName), "/");
Sub->Len = strlen(Direc);
// Reset Hsearch used by TDBDIR::ReadDB
- _findclose(Hsearch);
- Hsearch = -1;
+ FindClose(hSearch);
+ hSearch = INVALID_HANDLE_VALUE;
goto again;
} // endif H
@@ -1179,7 +1299,8 @@ int TDBSDR::ReadDB(PGLOBAL g)
if (lstat(Fpath, &Fileinfo) < 0) {
sprintf(g->Message, "%s: %s", Fpath, strerror(errno));
rc = RC_FX;
- } else if (S_ISDIR(Fileinfo.st_mode) && *Entry->d_name != '.') {
+ } else if (S_ISDIR(Fileinfo.st_mode) && strcmp(Entry->d_name, ".")
+ && strcmp(Entry->d_name, "..")) {
// Look in the name sub-directory
if (!Sub->Next) {
PSUBDIR sup;
@@ -1423,8 +1544,8 @@ void TDBDHR::CloseDB(PGLOBAL g)
// Close the search handle.
if (!FindClose(Hsearch)) {
strcpy(g->Message, MSG(SRCH_CLOSE_ERR));
- longjmp(g->jumper[g->jump_level], GetAmType());
- } // endif FindClose
+ throw GetAmType();
+ } // endif FindClose
iFile = 0;
Hsearch = INVALID_HANDLE_VALUE;
@@ -1435,8 +1556,8 @@ void TDBDHR::CloseDB(PGLOBAL g)
/***********************************************************************/
/* DHRCOL public constructor. */
/***********************************************************************/
-DHRCOL::DHRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
- : COLBLK(cdp, tdbp, i)
+DHRCOL::DHRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
+ : COLBLK(cdp, tdbp, i)
{
if (cprec) {
Next = cprec->GetNext();
diff --git a/storage/connect/tabmul.h b/storage/connect/tabmul.h
index 51fa7f9000a..8a95a772c41 100644
--- a/storage/connect/tabmul.h
+++ b/storage/connect/tabmul.h
@@ -39,7 +39,7 @@ class DllExport TDBMUL : public TDBASE {
virtual void ResetDB(void);
virtual PTDB Clone(PTABS t);
virtual bool IsSame(PTDB tp) {return tp == (PTDB)Tdbp;}
- virtual PSZ GetFile(PGLOBAL g) {return Tdbp->GetFile(g);}
+ virtual PCSZ GetFile(PGLOBAL g) {return Tdbp->GetFile(g);}
virtual int GetRecpos(void) {return 0;}
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num);
bool InitFileNames(PGLOBAL g);
@@ -69,6 +69,34 @@ class DllExport TDBMUL : public TDBASE {
int iFile; // Index of currently processed file
}; // end of class TDBMUL
+#if 0
+/***********************************************************************/
+/* This is the MSD Access Method class declaration for files that are */
+/* physically split in multiple files having the same format. */
+/* This sub-class also include files of the sub-directories. */
+/***********************************************************************/
+class DllExport TDBMSD : public TDBMUL {
+ //friend class MULCOL;
+public:
+ // Constructor
+ TDBMSD(PTDB tdbp) : TDBMUL(tdbp) {}
+ TDBMSD(PTDBMSD tdbp) : TDBMUL(tdbp) {}
+
+ // Implementation
+ virtual PTDB Duplicate(PGLOBAL g);
+
+ // Methods
+ virtual PTDB Clone(PTABS t);
+ bool InitFileNames(PGLOBAL g);
+
+ // Database routines
+
+protected:
+
+ // Members
+}; // end of class TDBMSD
+#endif
+
/***********************************************************************/
/* Directory listing table. */
/***********************************************************************/
@@ -90,7 +118,8 @@ class DllExport DIRDEF : public TABDEF { /* Directory listing table */
// Members
PSZ Fn; /* Path/Name of file search */
bool Incl; /* true to include sub-directories */
- bool Huge; /* true if files can be larger than 2GB */
+ bool Huge; /* true if files can be larger than 2GB */
+ bool Nodir; /* true to exclude directories */
}; // end of DIRDEF
/***********************************************************************/
@@ -101,18 +130,16 @@ class DllExport DIRDEF : public TABDEF { /* Directory listing table */
/***********************************************************************/
class TDBDIR : public TDBASE {
friend class DIRCOL;
- public:
+ friend class TDBMUL;
+public:
// Constructor
TDBDIR(PDIRDEF tdp);
- TDBDIR(PTDBDIR tdbp);
+ TDBDIR(PSZ fpat);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_DIR;}
- virtual PTDB Duplicate(PGLOBAL g)
- {return (PTDB)new(g) TDBDIR(this);}
// Methods
- virtual PTDB Clone(PTABS t);
virtual int GetRecpos(void) {return iFile;}
// Database routines
@@ -127,14 +154,16 @@ class TDBDIR : public TDBASE {
virtual void CloseDB(PGLOBAL g);
protected:
+ void Init(void);
char *Path(PGLOBAL g);
// Members
PSZ To_File; // Points to file search pathname
int iFile; // Index of currently retrieved file
#if defined(__WIN__)
- _finddata_t FileData; // Find data structure
- intptr_t Hsearch; // Search handle
+ PVAL Dvalp; // Used to retrieve file date values
+ WIN32_FIND_DATA FileData; // Find data structure
+ HANDLE hSearch; // Search handle
char Drive[_MAX_DRIVE]; // Drive name
#else // !__WIN__
struct stat Fileinfo; // File info structure
@@ -147,6 +176,7 @@ class TDBDIR : public TDBASE {
char Direc[_MAX_DIR]; // Search path
char Fname[_MAX_FNAME]; // File name
char Ftype[_MAX_EXT]; // File extention
+ bool Nodir; // Exclude directories from file list
}; // end of class TDBDIR
/***********************************************************************/
@@ -158,17 +188,11 @@ class TDBDIR : public TDBASE {
/***********************************************************************/
class TDBSDR : public TDBDIR {
friend class DIRCOL;
+ friend class TDBMUL;
public:
// Constructors
TDBSDR(PDIRDEF tdp) : TDBDIR(tdp) {Sub = NULL;}
- TDBSDR(PTDBSDR tdbp);
-
- // Implementation
- virtual PTDB Duplicate(PGLOBAL g)
- {return (PTDB)new(g) TDBSDR(this);}
-
- // Methods
- virtual PTDB Clone(PTABS t);
+ TDBSDR(PSZ fpat) : TDBDIR(fpat) {Sub = NULL;}
// Database routines
virtual int GetMaxSize(PGLOBAL g);
@@ -184,7 +208,7 @@ class TDBSDR : public TDBDIR {
struct _Sub_Dir *Next;
struct _Sub_Dir *Prev;
#if defined(__WIN__)
- intptr_t H; // Search handle
+ HANDLE H; // Search handle
#else // !__WIN__
DIR *D;
#endif // !__WIN__
@@ -202,7 +226,7 @@ class TDBSDR : public TDBDIR {
class DIRCOL : public COLBLK {
public:
// Constructors
- DIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "DIR");
+ DIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "DIR");
DIRCOL(DIRCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
@@ -214,7 +238,11 @@ class DIRCOL : public COLBLK {
protected:
// Default constructor not to be used
DIRCOL(void) {}
+#if defined(__WIN__)
+ void SetTimeValue(PGLOBAL g, FILETIME& ftime);
+#endif // __WIN__
// Members
+ PTDBDIR Tdbp; // To DIR table
int N; // Column number
}; // end of class DIRCOL
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 1a715819fc8..bdddcf64ca8 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -68,8 +68,8 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
#endif // _CONSOLE
// Used to check whether a MYSQL table is created on itself
-bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
- const char *db, char *tab, const char *src, int port);
+bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, PCSZ host, PCSZ db,
+ PCSZ tab, PCSZ src, int port);
/***********************************************************************/
/* External function. */
@@ -125,7 +125,7 @@ bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
} // endif server
DBUG_PRINT("info", ("get_server_by_name returned server at %lx",
- (long unsigned int) server));
+ (size_t) server));
// TODO: We need to examine which of these can really be NULL
Hostname = PlugDup(g, server->host);
@@ -183,19 +183,22 @@ bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
/***********************************************************************/
bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
{
+ char *tabn, *pwd, *schema;
+
if ((!strstr(url, "://") && (!strchr(url, '@')))) {
// No :// or @ in connection string. Must be a straight
// connection name of either "server" or "server/table"
// ok, so we do a little parsing, but not completely!
- if ((Tabname= strchr(url, '/'))) {
+ if ((tabn= strchr(url, '/'))) {
// If there is a single '/' in the connection string,
// this means the user is specifying a table name
- *Tabname++= '\0';
+ *tabn++= '\0';
// there better not be any more '/'s !
- if (strchr(Tabname, '/'))
+ if (strchr(tabn, '/'))
return true;
+ Tabname = tabn;
} else
// Otherwise, straight server name,
Tabname = (b) ? GetStringCatInfo(g, "Tabname", Name) : NULL;
@@ -223,7 +226,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
Username += 3;
- if (!(Hostname = strchr(Username, '@'))) {
+ if (!(Hostname = (char*)strchr(Username, '@'))) {
strcpy(g->Message, "No host specified in URL");
return true;
} else {
@@ -231,11 +234,11 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
Server = Hostname;
} // endif Hostname
- if ((Password = strchr(Username, ':'))) {
- *Password++ = 0; // End username
+ if ((pwd = (char*)strchr(Username, ':'))) {
+ *pwd++ = 0; // End username
- // Make sure there isn't an extra / or @
- if ((strchr(Password, '/') || strchr(Hostname, '@'))) {
+ // Make sure there isn't an extra /
+ if (strchr(pwd, '/')) {
strcpy(g->Message, "Syntax error in URL");
return true;
} // endif
@@ -243,8 +246,10 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
// Found that if the string is:
// user:@hostname:port/db/table
// Then password is a null string, so set to NULL
- if ((Password[0] == 0))
- Password = NULL;
+ if ((pwd[0] == 0))
+ Password = NULL;
+ else
+ Password = pwd;
} // endif password
@@ -254,21 +259,23 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
return true;
} // endif
- if ((Tabschema = strchr(Hostname, '/'))) {
- *Tabschema++ = 0;
+ if ((schema = strchr(Hostname, '/'))) {
+ *schema++ = 0;
- if ((Tabname = strchr(Tabschema, '/'))) {
- *Tabname++ = 0;
+ if ((tabn = strchr(schema, '/'))) {
+ *tabn++ = 0;
// Make sure there's not an extra /
- if ((strchr(Tabname, '/'))) {
+ if ((strchr(tabn, '/'))) {
strcpy(g->Message, "Syntax error in URL");
return true;
} // endif /
+ Tabname = tabn;
} // endif TableName
- } // endif database
+ Tabschema = schema;
+ } // endif database
if ((sport = strchr(Hostname, ':')))
*sport++ = 0;
@@ -349,7 +356,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
Portnumber = GetIntCatInfo("Port", GetDefaultPort());
Server = Hostname;
} else {
- char *locdb = Tabschema;
+ PCSZ locdb = Tabschema;
if (ParseURL(g, url))
return true;
@@ -495,11 +502,11 @@ PCOL TDBMYSQL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/* filter should be removed from column list. */
/***********************************************************************/
bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
- {
+{
//char *tk = "`";
char tk = '`';
int len = 0, rank = 0;
- bool b = false, oom = false;
+ bool b = false;
PCOL colp;
//PDBUSER dup = PlgGetUser(g);
@@ -526,13 +533,13 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
if (b)
- oom |= Query->Append(", ");
+ Query->Append(", ");
else
b = true;
- oom |= Query->Append(tk);
- oom |= Query->Append(colp->GetName());
- oom |= Query->Append(tk);
+ Query->Append(tk);
+ Query->Append(colp->GetName());
+ Query->Append(tk);
((PMYCOL)colp)->Rank = rank++;
} // endif colp
@@ -542,22 +549,22 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
// Query '*' from...
// (the use of a char constant minimize the result storage)
if (Isview)
- oom |= Query->Append('*');
+ Query->Append('*');
else
- oom |= Query->Append("'*'");
+ Query->Append("'*'");
} // endif ncol
- oom |= Query->Append(" FROM ");
- oom |= Query->Append(tk);
- oom |= Query->Append(TableName);
- oom |= Query->Append(tk);
+ Query->Append(" FROM ");
+ Query->Append(tk);
+ Query->Append(TableName);
+ Query->Append(tk);
len = Query->GetLength();
if (To_CondFil) {
if (!mx) {
- oom |= Query->Append(" WHERE ");
- oom |= Query->Append(To_CondFil->Body);
+ Query->Append(" WHERE ");
+ Query->Append(To_CondFil->Body);
len = Query->GetLength() + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
@@ -565,25 +572,25 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
} else
len += (mx ? 256 : 1);
- if (oom || Query->Resize(len)) {
+ if (Query->IsTruncated() || Query->Resize(len)) {
strcpy(g->Message, "MakeSelect: Out of memory");
return true;
- } // endif oom
+ } // endif Query
if (trace)
htrc("Query=%s\n", Query->GetStr());
return false;
- } // end of MakeSelect
+} // end of MakeSelect
/***********************************************************************/
/* MakeInsert: make the Insert statement used with MySQL connection. */
/***********************************************************************/
bool TDBMYSQL::MakeInsert(PGLOBAL g)
{
- char *tk = "`";
+ const char *tk = "`";
uint len = 0;
- bool b = false, oom;
+ bool oom, b = false;
PCOL colp;
if (Query)
@@ -622,38 +629,38 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
Query = new(g) STRING(g, len);
if (Delayed)
- oom = Query->Set("INSERT DELAYED INTO ");
+ Query->Set("INSERT DELAYED INTO ");
else
- oom = Query->Set("INSERT INTO ");
+ Query->Set("INSERT INTO ");
- oom |= Query->Append(tk);
- oom |= Query->Append(TableName);
- oom |= Query->Append("` (");
+ Query->Append(tk);
+ Query->Append(TableName);
+ Query->Append("` (");
for (colp = Columns; colp; colp = colp->GetNext()) {
if (b)
- oom |= Query->Append(", ");
+ Query->Append(", ");
else
b = true;
- oom |= Query->Append(tk);
- oom |= Query->Append(colp->GetName());
- oom |= Query->Append(tk);
+ Query->Append(tk);
+ Query->Append(colp->GetName());
+ Query->Append(tk);
} // endfor colp
- oom |= Query->Append(") VALUES (");
+ Query->Append(") VALUES (");
#if defined(MYSQL_PREPARED_STATEMENTS)
if (Prep) {
for (int i = 0; i < Nparm; i++)
- oom |= Query->Append("?,");
+ Query->Append("?,");
Query->RepLast(')');
Query->Trim();
} // endif Prep
#endif // MYSQL_PREPARED_STATEMENTS
- if (oom)
+ if ((oom = Query->IsTruncated()))
strcpy(g->Message, "MakeInsert: Out of memory");
return oom;
@@ -684,18 +691,18 @@ bool TDBMYSQL::MakeCommand(PGLOBAL g)
strlwr(strcpy(name, Name)); // Not a keyword
if ((p = strstr(qrystr, name))) {
- bool oom = Query->Set(Qrystr, p - qrystr);
+ Query->Set(Qrystr, p - qrystr);
if (qtd && *(p-1) == ' ') {
- oom |= Query->Append('`');
- oom |= Query->Append(TableName);
- oom |= Query->Append('`');
+ Query->Append('`');
+ Query->Append(TableName);
+ Query->Append('`');
} else
- oom |= Query->Append(TableName);
+ Query->Append(TableName);
- oom |= Query->Append(Qrystr + (p - qrystr) + strlen(name));
+ Query->Append(Qrystr + (p - qrystr) + strlen(name));
- if (oom) {
+ if (Query->IsTruncated()) {
strcpy(g->Message, "MakeCommand: Out of memory");
return true;
} else
@@ -1096,7 +1103,7 @@ bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
To_CondFil->Body= (char*)PlugSubAlloc(g, NULL, 0);
*To_CondFil->Body= 0;
- if ((To_CondFil = hc->CheckCond(g, To_CondFil, To_CondFil->Cond)))
+ if ((To_CondFil = hc->CheckCond(g, To_CondFil, Cond)))
PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1);
} // endif active_index
@@ -1161,24 +1168,23 @@ int TDBMYSQL::WriteDB(PGLOBAL g)
int rc;
uint len = Query->GetLength();
char buf[64];
- bool oom = false;
// Make the Insert command value list
for (PCOL colp = Columns; colp; colp = colp->GetNext()) {
if (!colp->GetValue()->IsNull()) {
if (colp->GetResultType() == TYPE_STRING ||
colp->GetResultType() == TYPE_DATE)
- oom |= Query->Append_quoted(colp->GetValue()->GetCharString(buf));
+ Query->Append_quoted(colp->GetValue()->GetCharString(buf));
else
- oom |= Query->Append(colp->GetValue()->GetCharString(buf));
+ Query->Append(colp->GetValue()->GetCharString(buf));
} else
- oom |= Query->Append("NULL");
+ Query->Append("NULL");
- oom |= Query->Append(',');
+ Query->Append(',');
} // endfor colp
- if (unlikely(oom)) {
+ if (unlikely(Query->IsTruncated())) {
strcpy(g->Message, "WriteDB: Out of memory");
rc = RC_FX;
} else {
@@ -1186,7 +1192,7 @@ int TDBMYSQL::WriteDB(PGLOBAL g)
Myc.m_Rows = -1; // To execute the query
rc = Myc.ExecSQL(g, Query->GetStr());
Query->Truncate(len); // Restore query
- } // endif oom
+ } // endif Query
return (rc == RC_NF) ? RC_OK : rc; // RC_NF is Ok
} // end of WriteDB
@@ -1234,7 +1240,7 @@ void TDBMYSQL::CloseDB(PGLOBAL g)
/***********************************************************************/
/* MYSQLCOL public constructor. */
/***********************************************************************/
-MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: COLBLK(cdp, tdbp, i)
{
if (cprec) {
@@ -1260,7 +1266,7 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
/***********************************************************************/
/* MYSQLCOL public constructor. */
/***********************************************************************/
-MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
+MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PCSZ am)
: COLBLK(NULL, tdbp, i)
{
const char *chset = get_charset_name(fld->charsetnr);
@@ -1407,8 +1413,8 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
if (rc == RC_EF)
sprintf(g->Message, MSG(INV_DEF_READ), rc);
- longjmp(g->jumper[g->jump_level], 11);
- } else
+ throw 11;
+ } else
tdbp->Fetched = true;
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) {
@@ -1669,7 +1675,7 @@ int TDBMYEXC::WriteDB(PGLOBAL g)
/***********************************************************************/
/* MYXCOL public constructor. */
/***********************************************************************/
-MYXCOL::MYXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+MYXCOL::MYXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: MYSQLCOL(cdp, tdbp, cprec, i, am)
{
// Set additional EXEC MYSQL access method information for column.
@@ -1679,7 +1685,7 @@ MYXCOL::MYXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
/***********************************************************************/
/* MYSQLCOL public constructor. */
/***********************************************************************/
-MYXCOL::MYXCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
+MYXCOL::MYXCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PCSZ am)
: MYSQLCOL(fld, tdbp, i, am)
{
if (trace)
diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h
index 050fa59259b..3c37ae5bf3b 100644
--- a/storage/connect/tabmysql.h
+++ b/storage/connect/tabmysql.h
@@ -86,7 +86,7 @@ class TDBMYSQL : public TDBEXT {
virtual void ResetDB(void) {N = 0;}
virtual int RowNumber(PGLOBAL g, bool b = false);
virtual bool IsView(void) {return Isview;}
- virtual PSZ GetServer(void) {return Server;}
+ virtual PCSZ GetServer(void) {return Server;}
void SetDatabase(LPCSTR db) {Schema = (char*)db;}
// Schema routines
@@ -109,7 +109,7 @@ class TDBMYSQL : public TDBEXT {
// Internal functions
bool MakeSelect(PGLOBAL g, bool mx);
bool MakeInsert(PGLOBAL g);
- int BindColumns(PGLOBAL g);
+ int BindColumns(PGLOBAL g __attribute__((unused)));
virtual bool MakeCommand(PGLOBAL g);
//int MakeUpdate(PGLOBAL g);
//int MakeDelete(PGLOBAL g);
@@ -146,8 +146,8 @@ class MYSQLCOL : public COLBLK {
friend class TDBMYSQL;
public:
// Constructors
- MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "MYSQL");
- MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am = "MYSQL");
+ MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "MYSQL");
+ MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PCSZ am = "MYSQL");
MYSQLCOL(MYSQLCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
@@ -215,8 +215,8 @@ class MYXCOL : public MYSQLCOL {
friend class TDBMYEXC;
public:
// Constructors
- MYXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "MYSQL");
- MYXCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am = "MYSQL");
+ MYXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "MYSQL");
+ MYXCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PCSZ am = "MYSQL");
MYXCOL(MYXCOL *colp, PTDB tdbp); // Constructor used in copy process
// Methods
@@ -242,10 +242,10 @@ class TDBMCL : public TDBCAT {
virtual PQRYRES GetResult(PGLOBAL g);
// Members
- PSZ Host; // Host machine to use
- PSZ Db; // Database to be used by server
- PSZ Tab; // External table name
- PSZ User; // User logon name
- PSZ Pwd; // Password logon info
- int Port; // MySQL port number (0 = default)
+ PCSZ Host; // Host machine to use
+ PCSZ Db; // Database to be used by server
+ PCSZ Tab; // External table name
+ PCSZ User; // User logon name
+ PCSZ Pwd; // Password logon info
+ int Port; // MySQL port number (0 = default)
}; // end of class TDBMCL
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index 488acdd330d..56e5e72efd6 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -1,11 +1,11 @@
/************* Tabodbc C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABODBC */
/* ------------- */
-/* Version 3.1 */
+/* Version 3.2 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2000-2016 */
+/* (C) Copyright to the author Olivier BERTRAND 2000-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -116,47 +116,12 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (EXTDEF::DefineAM(g, am, poff))
return true;
- // Tabname = GetStringCatInfo(g, "Name",
- // (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
- // Tabname = GetStringCatInfo(g, "Tabname", Tabname);
- // Tabschema = GetStringCatInfo(g, "Dbname", NULL);
- // Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
- // Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
- // Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
- //Username = GetStringCatInfo(g, "User", NULL);
- // Password = GetStringCatInfo(g, "Password", NULL);
-
- // if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
- // Read_Only = true;
-
- // Qrystr = GetStringCatInfo(g, "Query_String", "?");
- // Sep = GetStringCatInfo(g, "Separator", NULL);
Catver = GetIntCatInfo("Catver", 2);
- //Xsrc = GetBoolCatInfo("Execsrc", FALSE);
- //Maxerr = GetIntCatInfo("Maxerr", 0);
- //Maxres = GetIntCatInfo("Maxres", 0);
- //Quoted = GetIntCatInfo("Quoted", 0);
Options = ODBConn::noOdbcDialog;
//Options = ODBConn::noOdbcDialog | ODBConn::useCursorLib;
Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT);
Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT);
-
- //if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt)
- // Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch
-
- //if (Catfunc == FNC_COL)
- // Colpat = GetStringCatInfo(g, "Colpat", NULL);
-
- //if (Catfunc == FNC_TABLE)
- // Tabtyp = GetStringCatInfo(g, "Tabtype", NULL);
-
UseCnc = GetBoolCatInfo("UseDSN", false);
-
- // Memory was Boolean, it is now integer
- //if (!(Memory = GetIntCatInfo("Memory", 0)))
- // Memory = GetBoolCatInfo("Memory", false) ? 1 : 0;
-
- //Pseudo = 2; // FILID is Ok but not ROWID
return false;
} // end of DefineAM
@@ -210,59 +175,22 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp)
if (tdp) {
Connect = tdp->Connect;
- //TableName = tdp->Tabname;
- //Schema = tdp->Tabschema;
Ops.User = tdp->Username;
Ops.Pwd = tdp->Password;
- //Catalog = tdp->Tabcat;
- //Srcdef = tdp->Srcdef;
- //Qrystr = tdp->Qrystr;
- //Sep = tdp->GetSep();
- //Options = tdp->Options;
Ops.Cto = tdp->Cto;
Ops.Qto = tdp->Qto;
- //Quoted = MY_MAX(0, tdp->GetQuoted());
- //Rows = tdp->GetElemt();
Catver = tdp->Catver;
- //Memory = tdp->Memory;
- //Scrollable = tdp->Scrollable;
Ops.UseCnc = tdp->UseCnc;
} else {
Connect = NULL;
- //TableName = NULL;
- //Schema = NULL;
Ops.User = NULL;
Ops.Pwd = NULL;
- //Catalog = NULL;
- //Srcdef = NULL;
- //Qrystr = NULL;
- //Sep = 0;
- //Options = 0;
Ops.Cto = DEFAULT_LOGIN_TIMEOUT;
Ops.Qto = DEFAULT_QUERY_TIMEOUT;
- //Quoted = 0;
- //Rows = 0;
Catver = 0;
- //Memory = 0;
- //Scrollable = false;
Ops.UseCnc = false;
} // endif tdp
- //Quote = NULL;
- //Query = NULL;
- //Count = NULL;
-//Where = NULL;
- //MulConn = NULL;
- //DBQ = NULL;
- //Qrp = NULL;
- //Fpos = 0;
- //Curpos = 0;
- //AftRows = 0;
- //CurNum = 0;
- //Rbuf = 0;
- //BufSize = 0;
- //Nparm = 0;
- //Placed = false;
} // end of TDBODBC standard constructor
TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBEXT(tdbp)
@@ -270,32 +198,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBEXT(tdbp)
Ocp = tdbp->Ocp; // is that right ?
Cnp = tdbp->Cnp;
Connect = tdbp->Connect;
- //TableName = tdbp->TableName;
- //Schema = tdbp->Schema;
Ops = tdbp->Ops;
- //Catalog = tdbp->Catalog;
- //Srcdef = tdbp->Srcdef;
- //Qrystr = tdbp->Qrystr;
- //Memory = tdbp->Memory;
- //Scrollable = tdbp->Scrollable;
- //Quote = tdbp->Quote;
- //Query = tdbp->Query;
- //Count = tdbp->Count;
-//Where = tdbp->Where;
- //MulConn = tdbp->MulConn;
- //DBQ = tdbp->DBQ;
- //Options = tdbp->Options;
- //Quoted = tdbp->Quoted;
- //Rows = tdbp->Rows;
- //Fpos = 0;
- //Curpos = 0;
- //AftRows = 0;
- //CurNum = 0;
- //Rbuf = 0;
- //BufSize = tdbp->BufSize;
- //Nparm = tdbp->Nparm;
- //Qrp = tdbp->Qrp;
- //Placed = false;
} // end of TDBODBC copy constructor
// Method
@@ -328,7 +231,7 @@ PCOL TDBODBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/* This used for Multiple(1) tables. Also prepare a connect string */
/* with a place holder to be used by SetFile. */
/***********************************************************************/
-PSZ TDBODBC::GetFile(PGLOBAL g)
+PCSZ TDBODBC::GetFile(PGLOBAL g)
{
if (Connect) {
char *p1, *p2;
@@ -370,7 +273,7 @@ PSZ TDBODBC::GetFile(PGLOBAL g)
/***********************************************************************/
/* Set DBQ and get the new file name into the connect string. */
/***********************************************************************/
-void TDBODBC::SetFile(PGLOBAL g, PSZ fn)
+void TDBODBC::SetFile(PGLOBAL g, PCSZ fn)
{
if (MulConn) {
int n = strlen(MulConn) + strlen(fn) - 1;
@@ -386,155 +289,18 @@ void TDBODBC::SetFile(PGLOBAL g, PSZ fn)
sprintf(Connect, MulConn, fn);
} // endif MultConn
- DBQ = fn;
+ DBQ = (PSZ)fn;
} // end of SetFile
-#if 0
-/******************************************************************/
-/* Convert an UTF-8 string to latin characters. */
-/******************************************************************/
-int TDBODBC::Decode(char *txt, char *buf, size_t n)
-{
- uint dummy_errors;
- uint32 len= copy_and_convert(buf, n, &my_charset_latin1,
- txt, strlen(txt),
- &my_charset_utf8_general_ci,
- &dummy_errors);
- buf[len]= '\0';
- return 0;
-} // end of Decode
-
-/***********************************************************************/
-/* MakeSQL: make the SQL statement use with ODBC connection. */
-/* Note: when implementing EOM filtering, column only used in local */
-/* filter should be removed from column list. */
-/***********************************************************************/
-bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
- {
- char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
- int len;
- bool oom = false, first = true;
- PTABLE tablep = To_Table;
- PCOL colp;
-
- if (Srcdef) {
- if (strstr(Srcdef, "%s")) {
- char *fil;
-
- fil = (To_CondFil) ? To_CondFil->Body : PlugDup(g, "1=1");
- Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil));
- Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil));
- } else
- Query = new(g)STRING(g, 0, Srcdef);
-
- return false;
- } // endif Srcdef
-
- // Allocate the string used to contain the Query
- Query = new(g)STRING(g, 1023, "SELECT ");
-
- if (!cnt) {
- if (Columns) {
- // Normal SQL statement to retrieve results
- for (colp = Columns; colp; colp = colp->GetNext())
- if (!colp->IsSpecial()) {
- if (!first)
- oom |= Query->Append(", ");
- else
- first = false;
-
- // Column name can be encoded in UTF-8
- Decode(colp->GetName(), buf, sizeof(buf));
-
- if (Quote) {
- // Put column name between identifier quotes in case in contains blanks
- oom |= Query->Append(Quote);
- oom |= Query->Append(buf);
- oom |= Query->Append(Quote);
- } else
- oom |= Query->Append(buf);
-
- ((PEXTCOL)colp)->SetRank(++Ncol);
- } // endif colp
-
- } else
- // !Columns can occur for queries such that sql count(*) from...
- // for which we will count the rows from sql * from...
- oom |= Query->Append('*');
-
- } else
- // SQL statement used to retrieve the size of the result
- oom |= Query->Append("count(*)");
-
- oom |= Query->Append(" FROM ");
-
- if (Catalog && *Catalog)
- catp = Catalog;
-
- //if (tablep->GetSchema())
- // schmp = (char*)tablep->GetSchema();
- //else
- if (Schema && *Schema)
- schmp = Schema;
-
- if (catp) {
- oom |= Query->Append(catp);
-
- if (schmp) {
- oom |= Query->Append('.');
- oom |= Query->Append(schmp);
- } // endif schmp
-
- oom |= Query->Append('.');
- } else if (schmp) {
- oom |= Query->Append(schmp);
- oom |= Query->Append('.');
- } // endif schmp
-
- // Table name can be encoded in UTF-8
- Decode(TableName, buf, sizeof(buf));
-
- if (Quote) {
- // Put table name between identifier quotes in case in contains blanks
- oom |= Query->Append(Quote);
- oom |= Query->Append(buf);
- oom |= Query->Append(Quote);
- } else
- oom |= Query->Append(buf);
-
- len = Query->GetLength();
-
- if (To_CondFil) {
- if (Mode == MODE_READ) {
- oom |= Query->Append(" WHERE ");
- oom |= Query->Append(To_CondFil->Body);
- len = Query->GetLength() + 1;
- } else
- len += (strlen(To_CondFil->Body) + 256);
-
- } else
- len += ((Mode == MODE_READX) ? 256 : 1);
-
- if (oom || Query->Resize(len)) {
- strcpy(g->Message, "MakeSQL: Out of memory");
- return true;
- } // endif oom
-
- if (trace)
- htrc("Query=%s\n", Query->GetStr());
-
- return false;
- } // end of MakeSQL
-#endif // 0
-
/***********************************************************************/
/* MakeInsert: make the Insert statement used with ODBC connection. */
/***********************************************************************/
bool TDBODBC::MakeInsert(PGLOBAL g)
{
- char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
+ PCSZ schmp = NULL;
+ char *catp = NULL, buf[NAM_LEN * 3];
int len = 0;
- bool b = false, oom = false;
+ bool oom, b = false;
PTABLE tablep = To_Table;
PCOL colp;
@@ -571,32 +337,32 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
Query = new(g) STRING(g, len, "INSERT INTO ");
if (catp) {
- oom |= Query->Append(catp);
+ Query->Append(catp);
if (schmp) {
- oom |= Query->Append('.');
- oom |= Query->Append(schmp);
+ Query->Append('.');
+ Query->Append(schmp);
} // endif schmp
- oom |= Query->Append('.');
+ Query->Append('.');
} else if (schmp) {
- oom |= Query->Append(schmp);
- oom |= Query->Append('.');
+ Query->Append(schmp);
+ Query->Append('.');
} // endif schmp
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
- oom |= Query->Append(Quote);
- oom |= Query->Append(buf);
- oom |= Query->Append(Quote);
+ Query->Append(Quote);
+ Query->Append(buf);
+ Query->Append(Quote);
} else
- oom |= Query->Append(buf);
+ Query->Append(buf);
- oom |= Query->Append('(');
+ Query->Append('(');
for (colp = Columns; colp; colp = colp->GetNext()) {
if (b)
- oom |= Query->Append(", ");
+ Query->Append(", ");
else
b = true;
@@ -605,20 +371,20 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
- oom |= Query->Append(Quote);
- oom |= Query->Append(buf);
- oom |= Query->Append(Quote);
+ Query->Append(Quote);
+ Query->Append(buf);
+ Query->Append(Quote);
} else
- oom |= Query->Append(buf);
+ Query->Append(buf);
} // endfor colp
- oom |= Query->Append(") VALUES (");
+ Query->Append(") VALUES (");
for (int i = 0; i < Nparm; i++)
- oom |= Query->Append("?,");
+ Query->Append("?,");
- if (oom)
+ if ((oom = Query->IsTruncated()))
strcpy(g->Message, "MakeInsert: Out of memory");
else
Query->RepLast(')');
@@ -646,73 +412,6 @@ bool TDBODBC::BindParameters(PGLOBAL g)
#if 0
/***********************************************************************/
-/* MakeCommand: make the Update or Delete statement to send to the */
-/* MySQL server. Limited to remote values and filtering. */
-/***********************************************************************/
-bool TDBODBC::MakeCommand(PGLOBAL g)
- {
- char *p, *stmt, name[68], *body = NULL, *qc = Ocp->GetQuoteChar();
- char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
- bool qtd = Quoted > 0;
- int i = 0, k = 0;
-
- // Make a lower case copy of the originale query and change
- // back ticks to the data source identifier quoting character
- do {
- qrystr[i] = (Qrystr[i] == '`') ? *qc : tolower(Qrystr[i]);
- } while (Qrystr[i++]);
-
- if (To_CondFil && (p = strstr(qrystr, " where "))) {
- p[7] = 0; // Remove where clause
- Qrystr[(p - qrystr) + 7] = 0;
- body = To_CondFil->Body;
- stmt = (char*)PlugSubAlloc(g, NULL, strlen(qrystr)
- + strlen(body) + 64);
- } else
- stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
-
- // Check whether the table name is equal to a keyword
- // If so, it must be quoted in the original query
- strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
-
- if (strstr(" update delete low_priority ignore quick from ", name)) {
- strlwr(strcat(strcat(strcpy(name, qc), Name), qc));
- k += 2;
- } else
- strlwr(strcpy(name, Name)); // Not a keyword
-
- if ((p = strstr(qrystr, name))) {
- for (i = 0; i < p - qrystr; i++)
- stmt[i] = (Qrystr[i] == '`') ? *qc : Qrystr[i];
-
- stmt[i] = 0;
- k += i + (int)strlen(Name);
-
- if (qtd && *(p - 1) == ' ')
- strcat(strcat(strcat(stmt, qc), TableName), qc);
- else
- strcat(stmt, TableName);
-
- i = (int)strlen(stmt);
-
- do {
- stmt[i++] = (Qrystr[k] == '`') ? *qc : Qrystr[k];
- } while (Qrystr[k++]);
-
- if (body)
- strcat(stmt, body);
-
- } else {
- sprintf(g->Message, "Cannot use this %s command",
- (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
- return true;
- } // endif p
-
- Query = new(g) STRING(g, 0, stmt);
- return (!Query->GetSize());
- } // end of MakeCommand
-
-/***********************************************************************/
/* MakeUpdate: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
char *TDBODBC::MakeUpdate(PGLOBAL g)
@@ -829,35 +528,6 @@ int TDBODBC::Cardinality(PGLOBAL g)
return Cardinal;
} // end of Cardinality
-#if 0
-/***********************************************************************/
-/* ODBC GetMaxSize: returns table size estimate in number of lines. */
-/***********************************************************************/
-int TDBODBC::GetMaxSize(PGLOBAL g)
- {
- if (MaxSize < 0) {
- if (Mode == MODE_DELETE)
- // Return 0 in mode DELETE in case of delete all.
- MaxSize = 0;
- else if (!Cardinality(NULL))
- MaxSize = 10; // To make MySQL happy
- else if ((MaxSize = Cardinality(g)) < 0)
- MaxSize = 12; // So we can see an error occurred
-
- } // endif MaxSize
-
- return MaxSize;
- } // end of GetMaxSize
-
-/***********************************************************************/
-/* Return max size value. */
-/***********************************************************************/
-int TDBODBC::GetProgMax(PGLOBAL g)
- {
- return GetMaxSize(g);
- } // end of GetProgMax
-#endif // 0
-
/***********************************************************************/
/* ODBC Access Method opening routine. */
/* New method now that this routine is called recursively (last table */
@@ -1064,7 +734,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
To_CondFil->Body= (char*)PlugSubAlloc(g, NULL, 0);
*To_CondFil->Body= 0;
- if ((To_CondFil = hc->CheckCond(g, To_CondFil, To_CondFil->Cond)))
+ if ((To_CondFil = hc->CheckCond(g, To_CondFil, Cond)))
PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1);
} // endif active_index
@@ -1097,8 +767,6 @@ int TDBODBC::ReadDB(PGLOBAL g)
if (trace > 1)
htrc("ODBC ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode);
- //htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
- // GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!Query && MakeCommand(g))
@@ -1118,12 +786,6 @@ int TDBODBC::ReadDB(PGLOBAL g)
} // endif Mode
- //if (To_Kindex) {
- // // Direct access of ODBC tables is not implemented yet
- // strcpy(g->Message, MSG(NO_ODBC_DIRECT));
- // return RC_FX;
- // } // endif To_Kindex
-
/*********************************************************************/
/* Now start the reading process. */
/* Here is the place to fetch the line(s). */
@@ -1208,11 +870,6 @@ int TDBODBC::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
void TDBODBC::CloseDB(PGLOBAL g)
{
-//if (To_Kindex) {
-// To_Kindex->Close();
-// To_Kindex = NULL;
-// } // endif
-
if (Ocp)
Ocp->Close();
@@ -1227,20 +884,13 @@ void TDBODBC::CloseDB(PGLOBAL g)
/***********************************************************************/
/* ODBCCOL public constructor. */
/***********************************************************************/
-ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: EXTCOL(cdp, tdbp, cprec, i, am)
{
// Set additional ODBC access method information for column.
-//Crp = NULL;
-//Long = Precision;
-//strcpy(F_Date, cdp->F_Date);
-//To_Val = NULL;
Slen = 0;
StrLen = &Slen;
Sqlbuf = NULL;
-//Bufp = NULL;
-//Blkp = NULL;
-//Rank = 0; // Not known yet
} // end of ODBCCOL constructor
/***********************************************************************/
@@ -1248,17 +898,9 @@ ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
/***********************************************************************/
ODBCCOL::ODBCCOL(void) : EXTCOL()
{
-//Crp = NULL;
-//Buf_Type = TYPE_INT; // This is a count(*) column
-//// Set additional Dos access method information for column.
-//Long = sizeof(int);
-//To_Val = NULL;
Slen = 0;
StrLen = &Slen;
Sqlbuf = NULL;
-//Bufp = NULL;
-//Blkp = NULL;
-//Rank = 1;
} // end of ODBCCOL constructor
/***********************************************************************/
@@ -1267,66 +909,11 @@ ODBCCOL::ODBCCOL(void) : EXTCOL()
/***********************************************************************/
ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{
-//Crp = col1->Crp;
-//Long = col1->Long;
-//strcpy(F_Date, col1->F_Date);
-//To_Val = col1->To_Val;
Slen = col1->Slen;
StrLen = col1->StrLen;
Sqlbuf = col1->Sqlbuf;
-//Bufp = col1->Bufp;
-//Blkp = col1->Blkp;
-//Rank = col1->Rank;
} // end of ODBCCOL copy constructor
-#if 0
-/***********************************************************************/
-/* SetBuffer: prepare a column block for write operation. */
-/***********************************************************************/
-bool ODBCCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
- {
- if (!(To_Val = value)) {
- sprintf(g->Message, MSG(VALUE_ERROR), Name);
- return true;
- } else if (Buf_Type == value->GetType()) {
- // Values are of the (good) column type
- if (Buf_Type == TYPE_DATE) {
- // If any of the date values is formatted
- // output format must be set for the receiving table
- if (GetDomain() || ((DTVAL *)value)->IsFormatted())
- goto newval; // This will make a new value;
-
- } else if (Buf_Type == TYPE_DOUBLE)
- // Float values must be written with the correct (column) precision
- // Note: maybe this should be forced by ShowValue instead of this ?
- value->SetPrec(GetScale());
-
- Value = value; // Directly access the external value
- } else {
- // Values are not of the (good) column type
- if (check) {
- sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name,
- GetTypeName(Buf_Type), GetTypeName(value->GetType()));
- return true;
- } // endif check
-
- newval:
- if (InitValue(g)) // Allocate the matching value block
- return true;
-
- } // endif's Value, Buf_Type
-
- // Because Colblk's have been made from a copy of the original TDB in
- // case of Update, we must reset them to point to the original one.
- if (To_Tdb->GetOrig())
- To_Tdb = (PTDB)To_Tdb->GetOrig();
-
- // Set the Column
- Status = (ok) ? BUF_EMPTY : BUF_NO;
- return false;
- } // end of SetBuffer
-#endif // 0
-
/***********************************************************************/
/* ReadColumn: when SQLFetch is used there is nothing to do as the */
/* column buffer was bind to the record set. This is also the case */
@@ -1715,7 +1302,7 @@ int TDBXDBC::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
/* XSRCCOL public constructor. */
/***********************************************************************/
-XSRCCOL::XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+XSRCCOL::XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: ODBCCOL(cdp, tdbp, cprec, i, am)
{
// Set additional ODBC access method information for column.
diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h
index fcefad5647b..cedcf0f5f77 100644
--- a/storage/connect/tabodbc.h
+++ b/storage/connect/tabodbc.h
@@ -1,7 +1,7 @@
/*************** Tabodbc H Declares Source Code File (.H) **************/
-/* Name: TABODBC.H Version 1.8 */
+/* Name: TABODBC.H Version 1.9 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2000-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2000-2017 */
/* */
/* This file contains the TDBODBC classes declares. */
/***********************************************************************/
@@ -33,14 +33,7 @@ public:
// Implementation
virtual const char *GetType(void) {return "ODBC";}
PSZ GetConnect(void) {return Connect;}
- //PSZ GetTabname(void) {return Tabname;}
- //PSZ GetTabschema(void) {return Tabschema;}
- //PSZ GetTabcat(void) {return Tabcat;}
- //PSZ GetSrcdef(void) {return Srcdef;}
- //char GetSep(void) {return (Sep) ? *Sep : 0;}
- //int GetQuoted(void) {return Quoted;}
int GetCatver(void) {return Catver;}
- //int GetOptions(void) {return Options;}
// Methods
virtual int Indexable(void) {return 2;}
@@ -50,27 +43,7 @@ public:
protected:
// Members
PSZ Connect; /* ODBC connection string */
- //PSZ Tabname; /* External table name */
- //PSZ Tabschema; /* External table schema */
- //PSZ Username; /* User connect name */
- //PSZ Password; /* Password connect info */
- //PSZ Tabcat; /* External table catalog */
- //PSZ Tabtyp; /* Catalog table type */
- //PSZ Colpat; /* Catalog column pattern */
- //PSZ Srcdef; /* The source table SQL definition */
- //PSZ Qchar; /* Identifier quoting character */
- //PSZ Qrystr; /* The original query */
- //PSZ Sep; /* Decimal separator */
int Catver; /* ODBC version for catalog functions */
- //int Options; /* Open connection options */
- //int Cto; /* Open connection timeout */
- //int Qto; /* Query (command) timeout */
- //int Quoted; /* Identifier quoting level */
- //int Maxerr; /* Maxerr for an Exec table */
- //int Maxres; /* Maxres for a catalog table */
- //int Memory; /* Put result set in memory */
- //bool Scrollable; /* Use scrollable cursor */
- //bool Xsrc; /* Execution type */
bool UseCnc; /* Use SQLConnect (!SQLDriverConnect) */
}; // end of ODBCDEF
@@ -96,20 +69,16 @@ class TDBODBC : public TDBEXT {
// Methods
virtual PTDB Clone(PTABS t);
-//virtual int GetRecpos(void);
virtual bool SetRecpos(PGLOBAL g, int recpos);
- virtual PSZ GetFile(PGLOBAL g);
- virtual void SetFile(PGLOBAL g, PSZ fn);
+ virtual PCSZ GetFile(PGLOBAL g);
+ virtual void SetFile(PGLOBAL g, PCSZ fn);
virtual void ResetSize(void);
-//virtual int GetAffectedRows(void) {return AftRows;}
- virtual PSZ GetServer(void) {return "ODBC";}
+ virtual PCSZ GetServer(void) {return "ODBC";}
virtual int Indexable(void) {return 2;}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int Cardinality(PGLOBAL g);
-//virtual int GetMaxSize(PGLOBAL g);
-//virtual int GetProgMax(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
@@ -119,14 +88,8 @@ class TDBODBC : public TDBEXT {
protected:
// Internal functions
-//int Decode(char *utf, char *buf, size_t n);
-//bool MakeSQL(PGLOBAL g, bool cnt);
bool MakeInsert(PGLOBAL g);
-//virtual bool MakeCommand(PGLOBAL g);
-//bool MakeFilter(PGLOBAL g, bool c);
bool BindParameters(PGLOBAL g);
-//char *MakeUpdate(PGLOBAL g);
-//char *MakeDelete(PGLOBAL g);
// Members
ODBConn *Ocp; // Points to an ODBC connection class
@@ -145,15 +108,12 @@ class ODBCCOL : public EXTCOL {
friend class TDBODBC;
public:
// Constructors
- ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "ODBC");
+ ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "ODBC");
ODBCCOL(ODBCCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
virtual int GetAmType(void) {return TYPE_AM_ODBC;}
SQLLEN *GetStrLen(void) {return StrLen;}
-// int GetRank(void) {return Rank;}
-// PVBLK GetBlkp(void) {return Blkp;}
-// void SetCrp(PCOLRES crp) {Crp = crp;}
// Methods
//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
@@ -162,7 +122,6 @@ class ODBCCOL : public EXTCOL {
void AllocateBuffers(PGLOBAL g, int rows);
void *GetBuffer(DWORD rows);
SWORD GetBuflen(void);
-// void Print(PGLOBAL g, FILE *, uint);
protected:
// Constructor for count(*) column
@@ -170,14 +129,8 @@ class ODBCCOL : public EXTCOL {
// Members
TIMESTAMP_STRUCT *Sqlbuf; // To get SQL_TIMESTAMP's
-//PCOLRES Crp; // To storage result
-//void *Bufp; // To extended buffer
-//PVBLK Blkp; // To Value Block
-//char F_Date[12]; // Internal Date format
-//PVAL To_Val; // To value used for Insert
SQLLEN *StrLen; // As returned by ODBC
SQLLEN Slen; // Used with Fetch
-//int Rank; // Rank (position) number in the query
}; // end of class ODBCCOL
/***********************************************************************/
@@ -226,16 +179,14 @@ class XSRCCOL : public ODBCCOL {
friend class TDBXDBC;
public:
// Constructors
- XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "ODBC");
+ XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "ODBC");
XSRCCOL(XSRCCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
-//virtual int GetAmType(void) {return TYPE_AM_ODBC;}
// Methods
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
-// void Print(PGLOBAL g, FILE *, uint);
protected:
// Members
@@ -287,10 +238,10 @@ class TDBOTB : public TDBDRV {
virtual PQRYRES GetResult(PGLOBAL g);
// Members
- char *Dsn; // Points to connection string
- char *Schema; // Points to schema name or NULL
- char *Tab; // Points to ODBC table name or pattern
- char *Tabtyp; // Points to ODBC table type
+ PCSZ Dsn; // Points to connection string
+ PCSZ Schema; // Points to schema name or NULL
+ PCSZ Tab; // Points to ODBC table name or pattern
+ PCSZ Tabtyp; // Points to ODBC table type
ODBCPARM Ops; // Additional parameters
}; // end of class TDBOTB
diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp
index c6d32884417..76a46e6899b 100644
--- a/storage/connect/tabpivot.cpp
+++ b/storage/connect/tabpivot.cpp
@@ -106,214 +106,211 @@ bool PIVAID::SkipColumn(PCOLRES crp, char *skc)
/* Make the Pivot table column list. */
/***********************************************************************/
PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
- {
+{
char *p, *query, *colname, *skc, buf[64];
- int rc, ndif, nblin, w = 0;
+ int ndif, nblin, w = 0;
bool b = false;
PVAL valp;
PQRYRES qrp;
PCOLRES *pcrp, crp, fncrp = NULL;
- // Save stack and allocation environment and prepare error return
- if (g->jump_level == MAX_JUMP) {
- strcpy(g->Message, MSG(TOO_MANY_JUMPS));
- return NULL;
- } // endif jump_level
-
- if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
- goto err;
- } // endif rc
-
- // Are there columns to skip?
- if (Skcol) {
- uint n = strlen(Skcol);
-
- skc = (char*)PlugSubAlloc(g, NULL, n + 2);
- strcpy(skc, Skcol);
- skc[n + 1] = 0;
-
- // Replace ; by nulls in skc
- for (p = strchr(skc, ';'); p; p = strchr(p, ';'))
- *p++ = 0;
-
- } else
- skc = NULL;
-
- if (!Tabsrc && Tabname) {
- // Locate the query
- query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 26);
- sprintf(query, "SELECT * FROM `%s` LIMIT 1", Tabname);
- } else if (!Tabsrc) {
- strcpy(g->Message, MSG(SRC_TABLE_UNDEF));
- return NULL;
- } else
- query = Tabsrc;
-
- // Open a MySQL connection for this table
- if (!Myc.Open(g, Host, Database, User, Pwd, Port)) {
- b = true;
-
- // Returned values must be in their original character set
- if (Myc.ExecSQL(g, "SET character_set_results=NULL", &w) == RC_FX)
- goto err;
- else
- Myc.FreeResult();
-
- } else
- return NULL;
-
- // Send the source command to MySQL
- if (Myc.ExecSQL(g, query, &w) == RC_FX)
- goto err;
-
- // We must have a storage query to get pivot column values
- if (!(Qryp = Myc.GetResult(g, true)))
- goto err;
-
- if (!Fncol) {
- for (crp = Qryp->Colresp; crp; crp = crp->Next)
- if ((!Picol || stricmp(Picol, crp->Name)) && !SkipColumn(crp, skc))
- Fncol = crp->Name;
-
- if (!Fncol) {
- strcpy(g->Message, MSG(NO_DEF_FNCCOL));
- goto err;
- } // endif Fncol
-
- } // endif Fncol
-
- if (!Picol) {
- // Find default Picol as the last one not equal to Fncol
- for (crp = Qryp->Colresp; crp; crp = crp->Next)
- if (stricmp(Fncol, crp->Name) && !SkipColumn(crp, skc))
- Picol = crp->Name;
-
- if (!Picol) {
- strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
- goto err;
- } // endif Picol
-
- } // endif picol
-
- // Prepare the column list
- for (pcrp = &Qryp->Colresp; crp = *pcrp; )
- if (SkipColumn(crp, skc)) {
- // Ignore this column
- *pcrp = crp->Next;
- } else if (!stricmp(Picol, crp->Name)) {
- if (crp->Nulls) {
- sprintf(g->Message, "Pivot column %s cannot be nullable", Picol);
- goto err;
- } // endif Nulls
-
- Rblkp = crp->Kdata;
- *pcrp = crp->Next;
- } else if (!stricmp(Fncol, crp->Name)) {
- fncrp = crp;
- *pcrp = crp->Next;
- } else
- pcrp = &crp->Next;
-
- if (!Rblkp) {
- strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
- goto err;
- } else if (!fncrp) {
- strcpy(g->Message, MSG(NO_DEF_FNCCOL));
- goto err;
- } // endif
-
- if (Tabsrc) {
- Myc.Close();
- b = false;
-
- // Before calling sort, initialize all
- nblin = Qryp->Nblin;
-
- Index.Size = nblin * sizeof(int);
- Index.Sub = TRUE; // Should be small enough
-
- if (!PlgDBalloc(g, NULL, Index))
- return NULL;
-
- Offset.Size = (nblin + 1) * sizeof(int);
- Offset.Sub = TRUE; // Should be small enough
-
- if (!PlgDBalloc(g, NULL, Offset))
- return NULL;
-
- ndif = Qsort(g, nblin);
-
- if (ndif < 0) // error
- return NULL;
-
- } else {
- // The query was limited, we must get pivot column values
- // Returned values must be in their original character set
-// if (Myc.ExecSQL(g, "SET character_set_results=NULL", &w) == RC_FX)
-// goto err;
-
- query = (char*)PlugSubAlloc(g, NULL, 0);
- sprintf(query, "SELECT DISTINCT `%s` FROM `%s`", Picol, Tabname);
- PlugSubAlloc(g, NULL, strlen(query) + 1);
- Myc.FreeResult();
-
- // Send the source command to MySQL
- if (Myc.ExecSQL(g, query, &w) == RC_FX)
- goto err;
-
- // We must have a storage query to get pivot column values
- if (!(qrp = Myc.GetResult(g, true)))
- goto err;
-
- Myc.Close();
- b = false;
-
- // Get the column list
- crp = qrp->Colresp;
- Rblkp = crp->Kdata;
- ndif = qrp->Nblin;
- } // endif Tabsrc
-
- // Allocate the Value used to retieve column names
- if (!(valp = AllocateValue(g, Rblkp->GetType(),
- Rblkp->GetVlen(),
- Rblkp->GetPrec())))
- return NULL;
-
- // Now make the functional columns
- for (int i = 0; i < ndif; i++) {
- if (i) {
- crp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
- memcpy(crp, fncrp, sizeof(COLRES));
- } else
- crp = fncrp;
-
- // Get the value that will be the generated column name
- if (Tabsrc)
- valp->SetValue_pvblk(Rblkp, Pex[Pof[i]]);
- else
- valp->SetValue_pvblk(Rblkp, i);
-
- colname = valp->GetCharString(buf);
- crp->Name = PlugDup(g, colname);
- crp->Flag = 1;
-
- // Add this column
- *pcrp = crp;
- crp->Next = NULL;
- pcrp = &crp->Next;
- } // endfor i
-
- // We added ndif columns and removed 2 (picol and fncol)
- Qryp->Nbcol += (ndif - 2);
- return Qryp;
+ try {
+ // Are there columns to skip?
+ if (Skcol) {
+ uint n = strlen(Skcol);
+
+ skc = (char*)PlugSubAlloc(g, NULL, n + 2);
+ strcpy(skc, Skcol);
+ skc[n + 1] = 0;
+
+ // Replace ; by nulls in skc
+ for (p = strchr(skc, ';'); p; p = strchr(p, ';'))
+ *p++ = 0;
+
+ } else
+ skc = NULL;
+
+ if (!Tabsrc && Tabname) {
+ // Locate the query
+ query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 26);
+ sprintf(query, "SELECT * FROM `%s` LIMIT 1", Tabname);
+ } else if (!Tabsrc) {
+ strcpy(g->Message, MSG(SRC_TABLE_UNDEF));
+ goto err;
+ } else
+ query = (char*)Tabsrc;
+
+ // Open a MySQL connection for this table
+ if (!Myc.Open(g, Host, Database, User, Pwd, Port)) {
+ b = true;
+
+ // Returned values must be in their original character set
+ if (Myc.ExecSQL(g, "SET character_set_results=NULL", &w) == RC_FX)
+ goto err;
+ else
+ Myc.FreeResult();
+
+ } else
+ goto err;
+
+ // Send the source command to MySQL
+ if (Myc.ExecSQL(g, query, &w) == RC_FX)
+ goto err;
+
+ // We must have a storage query to get pivot column values
+ if (!(Qryp = Myc.GetResult(g, true)))
+ goto err;
+
+ if (!Fncol) {
+ for (crp = Qryp->Colresp; crp; crp = crp->Next)
+ if ((!Picol || stricmp(Picol, crp->Name)) && !SkipColumn(crp, skc))
+ Fncol = crp->Name;
+
+ if (!Fncol) {
+ strcpy(g->Message, MSG(NO_DEF_FNCCOL));
+ goto err;
+ } // endif Fncol
+
+ } // endif Fncol
+
+ if (!Picol) {
+ // Find default Picol as the last one not equal to Fncol
+ for (crp = Qryp->Colresp; crp; crp = crp->Next)
+ if (stricmp(Fncol, crp->Name) && !SkipColumn(crp, skc))
+ Picol = crp->Name;
+
+ if (!Picol) {
+ strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
+ goto err;
+ } // endif Picol
+
+ } // endif picol
+
+ // Prepare the column list
+ for (pcrp = &Qryp->Colresp; crp = *pcrp; )
+ if (SkipColumn(crp, skc)) {
+ // Ignore this column
+ *pcrp = crp->Next;
+ } else if (!stricmp(Picol, crp->Name)) {
+ if (crp->Nulls) {
+ sprintf(g->Message, "Pivot column %s cannot be nullable", Picol);
+ goto err;
+ } // endif Nulls
+
+ Rblkp = crp->Kdata;
+ *pcrp = crp->Next;
+ } else if (!stricmp(Fncol, crp->Name)) {
+ fncrp = crp;
+ *pcrp = crp->Next;
+ } else
+ pcrp = &crp->Next;
+
+ if (!Rblkp) {
+ strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
+ goto err;
+ } else if (!fncrp) {
+ strcpy(g->Message, MSG(NO_DEF_FNCCOL));
+ goto err;
+ } // endif
+
+ if (Tabsrc) {
+ Myc.Close();
+ b = false;
+
+ // Before calling sort, initialize all
+ nblin = Qryp->Nblin;
+
+ Index.Size = nblin * sizeof(int);
+ Index.Sub = TRUE; // Should be small enough
+
+ if (!PlgDBalloc(g, NULL, Index))
+ goto err;
+
+ Offset.Size = (nblin + 1) * sizeof(int);
+ Offset.Sub = TRUE; // Should be small enough
+
+ if (!PlgDBalloc(g, NULL, Offset))
+ goto err;
+
+ ndif = Qsort(g, nblin);
+
+ if (ndif < 0) // error
+ goto err;
+
+ } else {
+ // The query was limited, we must get pivot column values
+ // Returned values must be in their original character set
+ // if (Myc.ExecSQL(g, "SET character_set_results=NULL", &w) == RC_FX)
+ // goto err;
+
+ query = (char*)PlugSubAlloc(g, NULL, 0);
+ sprintf(query, "SELECT DISTINCT `%s` FROM `%s`", Picol, Tabname);
+ PlugSubAlloc(g, NULL, strlen(query) + 1);
+ Myc.FreeResult();
+
+ // Send the source command to MySQL
+ if (Myc.ExecSQL(g, query, &w) == RC_FX)
+ goto err;
+
+ // We must have a storage query to get pivot column values
+ if (!(qrp = Myc.GetResult(g, true)))
+ goto err;
+
+ Myc.Close();
+ b = false;
+
+ // Get the column list
+ crp = qrp->Colresp;
+ Rblkp = crp->Kdata;
+ ndif = qrp->Nblin;
+ } // endif Tabsrc
+
+ // Allocate the Value used to retieve column names
+ if (!(valp = AllocateValue(g, Rblkp->GetType(),
+ Rblkp->GetVlen(),
+ Rblkp->GetPrec())))
+ goto err;
+
+ // Now make the functional columns
+ for (int i = 0; i < ndif; i++) {
+ if (i) {
+ crp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
+ memcpy(crp, fncrp, sizeof(COLRES));
+ } else
+ crp = fncrp;
+
+ // Get the value that will be the generated column name
+ if (Tabsrc)
+ valp->SetValue_pvblk(Rblkp, Pex[Pof[i]]);
+ else
+ valp->SetValue_pvblk(Rblkp, i);
+
+ colname = valp->GetCharString(buf);
+ crp->Name = PlugDup(g, colname);
+ crp->Flag = 1;
+
+ // Add this column
+ *pcrp = crp;
+ crp->Next = NULL;
+ pcrp = &crp->Next;
+ } // endfor i
+
+ // We added ndif columns and removed 2 (picol and fncol)
+ Qryp->Nbcol += (ndif - 2);
+ return Qryp;
+ } catch (int n) {
+ if (trace)
+ htrc("Exception %d: %s\n", n, g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
err:
if (b)
Myc.Close();
return NULL;
- } // end of MakePivotColumns
+} // end of MakePivotColumns
/***********************************************************************/
/* PIVAID: Compare routine for sorting pivot column values. */
diff --git a/storage/connect/tabpivot.h b/storage/connect/tabpivot.h
index 07d5c3e456b..6c2d53e9527 100644
--- a/storage/connect/tabpivot.h
+++ b/storage/connect/tabpivot.h
@@ -32,16 +32,16 @@ class PIVAID : public CSORT {
protected:
// Members
MYSQLC Myc; // MySQL connection class
- char *Host; // Host machine to use
- char *User; // User logon info
- char *Pwd; // Password logon info
- char *Database; // Database to be used by server
+ PCSZ Host; // Host machine to use
+ PCSZ User; // User logon info
+ PCSZ Pwd; // Password logon info
+ PCSZ Database; // Database to be used by server
PQRYRES Qryp; // Points to Query result block
- char *Tabname; // Name of source table
- char *Tabsrc; // SQL of source table
- char *Picol; // Pivot column name
- char *Fncol; // Function column name
- char *Skcol; // Skipped columns
+ PCSZ Tabname; // Name of source table
+ PCSZ Tabsrc; // SQL of source table
+ PCSZ Picol; // Pivot column name
+ PCSZ Fncol; // Function column name
+ PCSZ Skcol; // Skipped columns
PVBLK Rblkp; // The value block of the pivot column
int Port; // MySQL port number
}; // end of class PIVAID
diff --git a/storage/connect/tabsys.cpp b/storage/connect/tabsys.cpp
index 2ddd1c3c753..7f0d9881298 100644
--- a/storage/connect/tabsys.cpp
+++ b/storage/connect/tabsys.cpp
@@ -1,9 +1,9 @@
/************* TabSys C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABSYS */
/* ------------- */
-/* Version 2.3 */
+/* Version 2.4 */
/* */
-/* Author Olivier BERTRAND 2004-2015 */
+/* Author Olivier BERTRAND 2004-2017 */
/* */
/* This program are the INI/CFG tables classes. */
/***********************************************************************/
@@ -355,7 +355,7 @@ void TDBINI::CloseDB(PGLOBAL)
/***********************************************************************/
/* INICOL public constructor. */
/***********************************************************************/
-INICOL::INICOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ)
+INICOL::INICOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ)
: COLBLK(cdp, tdbp, i)
{
if (cprec) {
@@ -511,12 +511,12 @@ void INICOL::WriteColumn(PGLOBAL g)
if (strlen(p) > (unsigned)Long) {
sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long);
- longjmp(g->jumper[g->jump_level], 31);
- } else if (Flag == 1) {
+ throw 31;
+ } else if (Flag == 1) {
if (tdbp->Mode == MODE_UPDATE) {
strcpy(g->Message, MSG(NO_SEC_UPDATE));
- longjmp(g->jumper[g->jump_level], 31);
- } else if (*p) {
+ throw 31;
+ } else if (*p) {
tdbp->Section = p;
} else
tdbp->Section = NULL;
@@ -524,8 +524,8 @@ void INICOL::WriteColumn(PGLOBAL g)
return;
} else if (!tdbp->Section) {
strcpy(g->Message, MSG(SEC_NAME_FIRST));
- longjmp(g->jumper[g->jump_level], 31);
- } // endif's
+ throw 31;
+ } // endif's
/*********************************************************************/
/* Updating must be done only when not in checking pass. */
@@ -536,8 +536,8 @@ void INICOL::WriteColumn(PGLOBAL g)
if (!rc) {
sprintf(g->Message, "Error %d writing to %s",
GetLastError(), tdbp->Ifile);
- longjmp(g->jumper[g->jump_level], 31);
- } // endif rc
+ throw 31;
+ } // endif rc
} // endif Status
@@ -769,7 +769,7 @@ int TDBXIN::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
/* XINCOL public constructor. */
/***********************************************************************/
-XINCOL::XINCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+XINCOL::XINCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: INICOL(cdp, tdbp, cprec, i, am)
{
} // end of XINCOL constructor
@@ -837,12 +837,12 @@ void XINCOL::WriteColumn(PGLOBAL g)
if (strlen(p) > (unsigned)Long) {
sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long);
- longjmp(g->jumper[g->jump_level], 31);
- } else if (Flag == 1) {
+ throw 31;
+ } else if (Flag == 1) {
if (tdbp->Mode == MODE_UPDATE) {
strcpy(g->Message, MSG(NO_SEC_UPDATE));
- longjmp(g->jumper[g->jump_level], 31);
- } else if (*p) {
+ throw 31;
+ } else if (*p) {
tdbp->Section = p;
} else
tdbp->Section = NULL;
@@ -851,8 +851,8 @@ void XINCOL::WriteColumn(PGLOBAL g)
} else if (Flag == 2) {
if (tdbp->Mode == MODE_UPDATE) {
strcpy(g->Message, MSG(NO_KEY_UPDATE));
- longjmp(g->jumper[g->jump_level], 31);
- } else if (*p) {
+ throw 31;
+ } else if (*p) {
tdbp->Keycur = p;
} else
tdbp->Keycur = NULL;
@@ -860,8 +860,8 @@ void XINCOL::WriteColumn(PGLOBAL g)
return;
} else if (!tdbp->Section || !tdbp->Keycur) {
strcpy(g->Message, MSG(SEC_KEY_FIRST));
- longjmp(g->jumper[g->jump_level], 31);
- } // endif's
+ throw 31;
+ } // endif's
/*********************************************************************/
/* Updating must be done only when not in checking pass. */
@@ -872,8 +872,8 @@ void XINCOL::WriteColumn(PGLOBAL g)
if (!rc) {
sprintf(g->Message, "Error %d writing to %s",
GetLastError(), tdbp->Ifile);
- longjmp(g->jumper[g->jump_level], 31);
- } // endif rc
+ throw 31;
+ } // endif rc
} // endif Status
diff --git a/storage/connect/tabsys.h b/storage/connect/tabsys.h
index ff1b8335690..0c6017af177 100644
--- a/storage/connect/tabsys.h
+++ b/storage/connect/tabsys.h
@@ -61,8 +61,8 @@ class TDBINI : public TDBASE {
virtual int GetRecpos(void) {return N;}
virtual int GetProgCur(void) {return N;}
//virtual int GetAffectedRows(void) {return 0;}
- virtual PSZ GetFile(PGLOBAL g) {return Ifile;}
- virtual void SetFile(PGLOBAL g, PSZ fn) {Ifile = fn;}
+ virtual PCSZ GetFile(PGLOBAL g) {return Ifile;}
+ virtual void SetFile(PGLOBAL g, PCSZ fn) {Ifile = fn;}
virtual void ResetDB(void) {Seclist = Section = NULL; N = 0;}
virtual void ResetSize(void) {MaxSize = -1; Seclist = NULL;}
virtual int RowNumber(PGLOBAL g, bool b = false) {return N;}
@@ -80,7 +80,7 @@ class TDBINI : public TDBASE {
protected:
// Members
- char *Ifile; // The INI file
+ PCSZ Ifile; // The INI file
char *Seclist; // The section list
char *Section; // The current section
int Seclen; // Length of seclist buffer
@@ -93,7 +93,7 @@ class TDBINI : public TDBASE {
class INICOL : public COLBLK {
public:
// Constructors
- INICOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "INI");
+ INICOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "INI");
INICOL(INICOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
@@ -165,7 +165,7 @@ class TDBXIN : public TDBINI {
class XINCOL : public INICOL {
public:
// Constructors
- XINCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "INI");
+ XINCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "INI");
XINCOL(XINCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp
index 762c61bd1a1..574cef28ea3 100644
--- a/storage/connect/tabutil.cpp
+++ b/storage/connect/tabutil.cpp
@@ -119,7 +119,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
- char *pn, *tn, *fld, *colname, *chset, *fmt, v;
+ PCSZ fmt;
+ char *pn, *tn, *fld, *colname, *chset, v;
int i, n, ncol = sizeof(buftyp) / sizeof(int);
int prec, len, type, scale;
int zconv = GetConvSize();
@@ -227,7 +228,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
fmt = MyDateFmt(fp->type());
prec = len = strlen(fmt);
} else {
- fmt = (char*)fp->option_struct->dateformat;
+ fmt = (PCSZ)fp->option_struct->dateformat;
prec = len = fp->field_length;
} // endif mysql
@@ -314,7 +315,7 @@ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR, int)
strcpy(g->Message, "Missing object table definition");
return true;
} else
- tab = "Noname";
+ tab = PlugDup(g, "Noname");
} else
// Analyze the table name, it may have the format: [dbname.]tabname
@@ -626,7 +627,7 @@ void TDBPRX::RemoveNext(PTABLE tp)
/***********************************************************************/
/* PRXCOL public constructor. */
/***********************************************************************/
-PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: COLBLK(cdp, tdbp, i)
{
if (cprec) {
@@ -741,7 +742,14 @@ void PRXCOL::ReadColumn(PGLOBAL g)
if (Nullable)
Value->SetNull(Value->IsNull());
- } // endif Colp
+ } else {
+ Value->Reset();
+
+ // Set null when applicable
+ if (Nullable)
+ Value->SetNull(true);
+
+ } // endif Colp
} // end of ReadColumn
diff --git a/storage/connect/tabutil.h b/storage/connect/tabutil.h
index 8e56aecff86..62678508ca1 100644
--- a/storage/connect/tabutil.h
+++ b/storage/connect/tabutil.h
@@ -71,7 +71,7 @@ class DllExport TDBPRX : public TDBASE {
virtual int GetRecpos(void) {return Tdbp->GetRecpos();}
virtual void ResetDB(void) {Tdbp->ResetDB();}
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
- virtual PSZ GetServer(void) {return (Tdbp) ? Tdbp->GetServer() : (PSZ)"?";}
+ virtual PCSZ GetServer(void) {return (Tdbp) ? Tdbp->GetServer() : (PSZ)"?";}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
@@ -101,7 +101,7 @@ class DllExport PRXCOL : public COLBLK {
friend class TDBOCCUR;
public:
// Constructors
- PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "PRX");
+ PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "PRX");
PRXCOL(PRXCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp
index 282fb55a43c..533986e44da 100644
--- a/storage/connect/tabvct.cpp
+++ b/storage/connect/tabvct.cpp
@@ -1,11 +1,11 @@
/************* TabVct C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABVCT */
/* ------------- */
-/* Version 3.8 */
+/* Version 3.9 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1999-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 1999-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -174,7 +174,7 @@ bool VCTDEF::Erase(char *filename)
/***********************************************************************/
int VCTDEF::MakeFnPattern(char *fpat)
{
- char pat[8];
+ char pat[16];
#if defined(__WIN__)
char drive[_MAX_DRIVE];
#else
@@ -490,15 +490,15 @@ void VCTCOL::ReadBlock(PGLOBAL g)
#if defined(_DEBUG)
if (!Blk) {
strcpy(g->Message, MSG(TO_BLK_IS_NULL));
- longjmp(g->jumper[g->jump_level], 58);
- } // endif
+ throw 58;
+ } // endif
#endif
/*********************************************************************/
/* Read column block according to used access method. */
/*********************************************************************/
if (txfp->ReadBlock(g, this))
- longjmp(g->jumper[g->jump_level], 6);
+ throw 6;
ColBlk = txfp->CurBlk;
ColPos = -1; // Any invalid position
@@ -518,15 +518,15 @@ void VCTCOL::WriteBlock(PGLOBAL g)
#if defined(_DEBUG)
if (!Blk) {
strcpy(g->Message, MSG(BLK_IS_NULL));
- longjmp(g->jumper[g->jump_level], 56);
- } // endif
+ throw 56;
+ } // endif
#endif
/*******************************************************************/
/* Write column block according to used access method. */
/*******************************************************************/
if (txfp->WriteBlock(g, this))
- longjmp(g->jumper[g->jump_level], 6);
+ throw 6;
Modif = 0;
} // endif Modif
diff --git a/storage/connect/tabvir.cpp b/storage/connect/tabvir.cpp
index 155c71fe268..84b3dd1787b 100644
--- a/storage/connect/tabvir.cpp
+++ b/storage/connect/tabvir.cpp
@@ -1,6 +1,6 @@
/************* tdbvir C++ Program Source Code File (.CPP) **************/
-/* PROGRAM NAME: tdbvir.cpp Version 1.1 */
-/* (C) Copyright to the author Olivier BERTRAND 2014 */
+/* PROGRAM NAME: tdbvir.cpp Version 1.2 */
+/* (C) Copyright to the author Olivier BERTRAND 2014-2017 */
/* This program are the VIR classes DB execution routines. */
/***********************************************************************/
@@ -269,7 +269,7 @@ int TDBVIR::DeleteDB(PGLOBAL g, int)
/***********************************************************************/
/* VIRCOL public constructor. */
/***********************************************************************/
-VIRCOL::VIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ)
+VIRCOL::VIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ)
: COLBLK(cdp, tdbp, i)
{
if (cprec) {
@@ -289,8 +289,8 @@ void VIRCOL::ReadColumn(PGLOBAL g)
{
// This should never be called
sprintf(g->Message, "ReadColumn: Column %s is not virtual", Name);
- longjmp(g->jumper[g->jump_level], TYPE_COLBLK);
- } // end of ReadColumn
+ throw TYPE_COLBLK;
+} // end of ReadColumn
/* ---------------------------TDBVICL class -------------------------- */
diff --git a/storage/connect/tabvir.h b/storage/connect/tabvir.h
index a53aceaeceb..e7313bbae67 100644
--- a/storage/connect/tabvir.h
+++ b/storage/connect/tabvir.h
@@ -76,7 +76,7 @@ class VIRCOL : public COLBLK {
friend class TDBVIR;
public:
// Constructors
- VIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "VIRTUAL");
+ VIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "VIRTUAL");
// Implementation
virtual int GetAmType(void) {return TYPE_AM_VIR;}
diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp
index 4871a1d66dc..335ffce5d7f 100644
--- a/storage/connect/tabwmi.cpp
+++ b/storage/connect/tabwmi.cpp
@@ -27,7 +27,7 @@
/***********************************************************************/
/* Initialize WMI operations. */
/***********************************************************************/
-PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname)
+PWMIUT InitWMI(PGLOBAL g, PCSZ nsp, PCSZ classname)
{
IWbemLocator *loc;
char *p;
@@ -132,7 +132,7 @@ PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname)
/* WMIColumns: constructs the result blocks containing the description */
/* of all the columns of a WMI table of a specified class. */
/***********************************************************************/
-PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info)
+PQRYRES WMIColumns(PGLOBAL g, PCSZ nsp, PCSZ cls, bool info)
{
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_INT, TYPE_INT, TYPE_SHORT};
diff --git a/storage/connect/tabwmi.h b/storage/connect/tabwmi.h
index 6abb85453a1..7a18453374e 100644
--- a/storage/connect/tabwmi.h
+++ b/storage/connect/tabwmi.h
@@ -27,7 +27,7 @@ typedef struct _WMIutil {
/***********************************************************************/
/* Functions used externally. */
/***********************************************************************/
-PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info);
+PQRYRES WMIColumns(PGLOBAL g, PCSZ nsp, PCSZ cls, bool info);
/* -------------------------- WMI classes ---------------------------- */
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 52cf3d3812f..80d4395058e 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -1,9 +1,9 @@
/************* Tabxml C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABXML */
/* ------------- */
-/* Version 2.9 */
+/* Version 3.0 */
/* */
-/* Author Olivier BERTRAND 2007 - 2016 */
+/* Author Olivier BERTRAND 2007 - 2017 */
/* */
/* This program are the XML tables classes using MS-DOM or libxml2. */
/***********************************************************************/
@@ -118,10 +118,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
- char *fn, *op, colname[65], fmt[129], buf[512];
+ char colname[65], fmt[129], buf[512];
int i, j, lvl, n = 0;
int ncol = sizeof(buftyp) / sizeof(int);
bool ok = true;
+ PCSZ fn, op;
PXCL xcol, xcp, fxcp = NULL, pxcp = NULL;
PLVL *lvlp, vp;
PXNODE node = NULL;
@@ -157,7 +158,10 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
tdp = new(g) XMLDEF;
tdp->Fn = fn;
- tdp->Database = SetPath(g, db);
+
+ if (!(tdp->Database = SetPath(g, db)))
+ return NULL;
+
tdp->Tabname = tab;
tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
@@ -359,7 +363,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
skipit:
if (trace)
- htrc("CSVColumns: n=%d len=%d\n", n, length[0]);
+ htrc("XMLColumns: n=%d len=%d\n", n, length[0]);
/*********************************************************************/
/* Allocate the structures used to refer to the result set. */
@@ -448,7 +452,8 @@ XMLDEF::XMLDEF(void)
/***********************************************************************/
bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
- char *defrow, *defcol, buf[10];
+ PCSZ defrow, defcol;
+ char buf[10];
Fn = GetStringCatInfo(g, "Filename", NULL);
Encoding = GetStringCatInfo(g, "Encoding", "UTF-8");
@@ -1314,8 +1319,8 @@ void TDBXML::CloseDB(PGLOBAL g)
Docp->CloseDoc(g, To_Xb);
// This causes a crash in Diagnostics_area::set_error_status
-// longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endif DumpDoc
+// throw TYPE_AM_XML;
+ } // endif DumpDoc
} // endif Changed
@@ -1357,8 +1362,8 @@ void TDBXML::CloseDB(PGLOBAL g)
/***********************************************************************/
/* XMLCOL public constructor. */
/***********************************************************************/
-XMLCOL::XMLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
- : COLBLK(cdp, tdbp, i)
+XMLCOL::XMLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
+ : COLBLK(cdp, tdbp, i)
{
if (cprec) {
Next = cprec->GetNext();
@@ -1637,8 +1642,8 @@ void XMLCOL::ReadColumn(PGLOBAL g)
if (ValNode->GetType() != XML_ELEMENT_NODE &&
ValNode->GetType() != XML_ATTRIBUTE_NODE) {
sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endif type
+ throw TYPE_AM_XML;
+ } // endif type
// Get the Xname value from the XML file
switch (ValNode->GetContent(g, Valbuf, Long + 1)) {
@@ -1648,8 +1653,8 @@ void XMLCOL::ReadColumn(PGLOBAL g)
PushWarning(g, Tdbp);
break;
default:
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endswitch
+ throw TYPE_AM_XML;
+ } // endswitch
Value->SetValue_psz(Valbuf);
} else {
@@ -1699,7 +1704,7 @@ void XMLCOL::WriteColumn(PGLOBAL g)
/* For columns having an Xpath, the Clist must be updated. */
/*********************************************************************/
if (Tdbp->CheckRow(g, Nod || Tdbp->Colname))
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
+ throw TYPE_AM_XML;
/*********************************************************************/
/* Null values are represented by no node. */
@@ -1771,8 +1776,8 @@ void XMLCOL::WriteColumn(PGLOBAL g)
if (ColNode == NULL) {
strcpy(g->Message, MSG(COL_ALLOC_ERR));
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endif ColNode
+ throw TYPE_AM_XML;
+ } // endif ColNode
} // endif ColNode
@@ -1800,8 +1805,8 @@ void XMLCOL::WriteColumn(PGLOBAL g)
if (strlen(p) > (unsigned)Long) {
sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long);
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } else
+ throw TYPE_AM_XML;
+ } else
strcpy(Valbuf, p);
/*********************************************************************/
@@ -1850,8 +1855,8 @@ void XMULCOL::ReadColumn(PGLOBAL g)
if (ValNode->GetType() != XML_ELEMENT_NODE &&
ValNode->GetType() != XML_ATTRIBUTE_NODE) {
sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endif type
+ throw TYPE_AM_XML;
+ } // endif type
// Get the Xname value from the XML file
switch (ValNode->GetContent(g, p, (b ? Long : len))) {
@@ -1936,7 +1941,7 @@ void XMULCOL::WriteColumn(PGLOBAL g)
/* For columns having an Xpath, the Clist must be updated. */
/*********************************************************************/
if (Tdbp->CheckRow(g, Nod))
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
+ throw TYPE_AM_XML;
/*********************************************************************/
/* Find the column and value nodes to update or insert. */
@@ -1985,8 +1990,8 @@ void XMULCOL::WriteColumn(PGLOBAL g)
if (len > 1 && !Tdbp->Xpand) {
sprintf(g->Message, MSG(BAD_VAL_UPDATE), Name);
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } else
+ throw TYPE_AM_XML;
+ } else
ValNode = Nlx->GetItem(g, Tdbp->Nsub, Vxnp);
} else // Inod != Nod
@@ -2027,8 +2032,8 @@ void XMULCOL::WriteColumn(PGLOBAL g)
if (ColNode == NULL) {
strcpy(g->Message, MSG(COL_ALLOC_ERR));
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endif ColNode
+ throw TYPE_AM_XML;
+ } // endif ColNode
} // endif ColNode
@@ -2056,8 +2061,8 @@ void XMULCOL::WriteColumn(PGLOBAL g)
if (strlen(p) > (unsigned)Long) {
sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long);
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } else
+ throw TYPE_AM_XML;
+ } else
strcpy(Valbuf, p);
/*********************************************************************/
@@ -2088,8 +2093,8 @@ void XPOSCOL::ReadColumn(PGLOBAL g)
if (Tdbp->Clist == NULL) {
strcpy(g->Message, MSG(MIS_TAG_LIST));
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endif Clist
+ throw TYPE_AM_XML;
+ } // endif Clist
if ((ValNode = Tdbp->Clist->GetItem(g, Rank, Vxnp))) {
// Get the column value from the XML file
@@ -2100,8 +2105,8 @@ void XPOSCOL::ReadColumn(PGLOBAL g)
PushWarning(g, Tdbp);
break;
default:
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endswitch
+ throw TYPE_AM_XML;
+ } // endswitch
Value->SetValue_psz(Valbuf);
} else {
@@ -2151,15 +2156,15 @@ void XPOSCOL::WriteColumn(PGLOBAL g)
/* For all columns the Clist must be updated. */
/*********************************************************************/
if (Tdbp->CheckRow(g, true))
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
+ throw TYPE_AM_XML;
/*********************************************************************/
/* Find the column and value nodes to update or insert. */
/*********************************************************************/
if (Tdbp->Clist == NULL) {
strcpy(g->Message, MSG(MIS_TAG_LIST));
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } // endif Clist
+ throw TYPE_AM_XML;
+ } // endif Clist
n = Tdbp->Clist->GetLength();
k = Rank;
@@ -2183,8 +2188,8 @@ void XPOSCOL::WriteColumn(PGLOBAL g)
if (strlen(p) > (unsigned)Long) {
sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long);
- longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
- } else
+ throw TYPE_AM_XML;
+ } else
strcpy(Valbuf, p);
/*********************************************************************/
diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h
index 65b353072cb..813f62dde52 100644
--- a/storage/connect/tabxml.h
+++ b/storage/connect/tabxml.h
@@ -31,7 +31,7 @@ class DllExport XMLDEF : public TABDEF { /* Logical table description */
protected:
// Members
- char *Fn; /* Path/Name of corresponding file */
+ PCSZ Fn; /* Path/Name of corresponding file */
char *Encoding; /* New XML table file encoding */
char *Tabname; /* Name of Table node */
char *Rowname; /* Name of first level nodes */
@@ -42,7 +42,7 @@ class DllExport XMLDEF : public TABDEF { /* Logical table description */
char *DefNs; /* Dummy name of default namespace */
char *Attrib; /* Table node attributes */
char *Hdattr; /* Header node attributes */
- char *Entry; /* Zip entry name or pattern */
+ PCSZ Entry; /* Zip entry name or pattern */
int Coltype; /* Default column type */
int Limit; /* Limit of multiple values */
int Header; /* n first rows are header rows */
@@ -74,8 +74,8 @@ class DllExport TDBXML : public TDBASE {
virtual PTDB Clone(PTABS t);
virtual int GetRecpos(void);
virtual int GetProgCur(void) {return N;}
- virtual PSZ GetFile(PGLOBAL g) {return Xfile;}
- virtual void SetFile(PGLOBAL g, PSZ fn) {Xfile = fn;}
+ virtual PCSZ GetFile(PGLOBAL g) {return Xfile;}
+ virtual void SetFile(PGLOBAL g, PCSZ fn) {Xfile = fn;}
virtual void ResetDB(void) {N = 0;}
virtual void ResetSize(void) {MaxSize = -1;}
virtual int RowNumber(PGLOBAL g, bool b = false);
@@ -127,7 +127,7 @@ class DllExport TDBXML : public TDBASE {
bool Void; // True if the file does not exist
bool Zipped; // True if Zipped XML file(s)
bool Mulentries; // True if multiple entries in zip file
- char *Xfile; // The XML file
+ PCSZ Xfile; // The XML file
char *Enc; // New XML table file encoding
char *Tabname; // Name of Table node
char *Rowname; // Name of first level nodes
@@ -138,7 +138,7 @@ class DllExport TDBXML : public TDBASE {
char *DefNs; // Dummy name of default namespace
char *Attrib; // Table node attribut(s)
char *Hdattr; // Header node attribut(s)
- char *Entry; // Zip entry name or pattern
+ PCSZ Entry; // Zip entry name or pattern
int Coltype; // Default column type
int Limit; // Limit of multiple values
int Header; // n first rows are header rows
@@ -155,7 +155,7 @@ class DllExport TDBXML : public TDBASE {
class XMLCOL : public COLBLK {
public:
// Constructors
- XMLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "XML");
+ XMLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "XML");
XMLCOL(XMLCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
diff --git a/storage/connect/tabzip.cpp b/storage/connect/tabzip.cpp
index b91059a3843..c026744dba8 100644
--- a/storage/connect/tabzip.cpp
+++ b/storage/connect/tabzip.cpp
@@ -195,8 +195,8 @@ void TDBZIP::CloseDB(PGLOBAL g)
/***********************************************************************/
/* ZIPCOL public constructor. */
/***********************************************************************/
-ZIPCOL::ZIPCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
- : COLBLK(cdp, tdbp, i)
+ZIPCOL::ZIPCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
+ : COLBLK(cdp, tdbp, i)
{
if (cprec) {
Next = cprec->GetNext();
diff --git a/storage/connect/tabzip.h b/storage/connect/tabzip.h
index dcec3475371..32b15281f81 100644
--- a/storage/connect/tabzip.h
+++ b/storage/connect/tabzip.h
@@ -34,7 +34,7 @@ public:
protected:
// Members
- PSZ target; // The inside file to query
+ PCSZ target; // The inside file to query
}; // end of ZIPDEF
/***********************************************************************/
@@ -68,7 +68,7 @@ protected:
// Members
unzFile zipfile; // The ZIP container file
- PSZ zfn; // The ZIP file name
+ PCSZ zfn; // The ZIP file name
//PSZ target;
unz_file_info64 finfo; // The current file info
char fn[FILENAME_MAX]; // The current file name
@@ -82,7 +82,7 @@ class DllExport ZIPCOL : public COLBLK {
friend class TDBZIP;
public:
// Constructors
- ZIPCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "ZIP");
+ ZIPCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "ZIP");
// Implementation
virtual int GetAmType(void) { return TYPE_AM_ZIP; }
diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp
index 5fefcba5856..5b98f3eb425 100644
--- a/storage/connect/valblk.cpp
+++ b/storage/connect/valblk.cpp
@@ -1,7 +1,7 @@
/************ Valblk C++ Functions Source Code File (.CPP) *************/
-/* Name: VALBLK.CPP Version 2.1 */
+/* Name: VALBLK.CPP Version 2.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */
/* */
/* This file contains the VALBLK and derived classes functions. */
/* Second family is VALBLK, representing simple suballocated arrays */
@@ -138,14 +138,14 @@ PSZ VALBLK::GetCharValue(int)
assert(g);
sprintf(g->Message, MSG(NO_CHAR_FROM), Type);
- longjmp(g->jumper[g->jump_level], Type);
- return NULL;
+ throw Type;
+ return NULL;
} // end of GetCharValue
/***********************************************************************/
/* Set format so formatted dates can be converted on input. */
/***********************************************************************/
-bool VALBLK::SetFormat(PGLOBAL g, PSZ, int, int)
+bool VALBLK::SetFormat(PGLOBAL g, PCSZ, int, int)
{
sprintf(g->Message, MSG(NO_DATE_FMT), Type);
return true;
@@ -206,8 +206,8 @@ void VALBLK::ChkIndx(int n)
if (n < 0 || n >= Nval) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BAD_VALBLK_INDX));
- longjmp(g->jumper[g->jump_level], Type);
- } // endif n
+ throw Type;
+ } // endif n
} // end of ChkIndx
@@ -216,8 +216,8 @@ void VALBLK::ChkTyp(PVAL v)
if (Check && (Type != v->GetType() || Unsigned != v->IsUnsigned())) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(VALTYPE_NOMATCH));
- longjmp(g->jumper[g->jump_level], Type);
- } // endif Type
+ throw Type;
+ } // endif Type
} // end of ChkTyp
@@ -226,8 +226,8 @@ void VALBLK::ChkTyp(PVBLK vb)
if (Check && (Type != vb->GetType() || Unsigned != vb->IsUnsigned())) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(VALTYPE_NOMATCH));
- longjmp(g->jumper[g->jump_level], Type);
- } // endif Type
+ throw Type;
+ } // endif Type
} // end of ChkTyp
@@ -335,15 +335,15 @@ uchar TYPBLK<uchar>::GetTypedValue(PVAL valp)
/* Set one value in a block from a zero terminated string. */
/***********************************************************************/
template <class TYPE>
-void TYPBLK<TYPE>::SetValue(PSZ p, int n)
+void TYPBLK<TYPE>::SetValue(PCSZ p, int n)
{
ChkIndx(n);
if (Check) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BAD_SET_STRING));
- longjmp(g->jumper[g->jump_level], Type);
- } // endif Check
+ throw Type;
+ } // endif Check
bool minus;
ulonglong maxval = MaxVal();
@@ -385,15 +385,15 @@ template <>
ulonglong TYPBLK<ulonglong>::MaxVal(void) {return ULONGLONG_MAX;}
template <>
-void TYPBLK<double>::SetValue(PSZ p, int n)
+void TYPBLK<double>::SetValue(PCSZ p, int n)
{
ChkIndx(n);
if (Check) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BAD_SET_STRING));
- longjmp(g->jumper[g->jump_level], Type);
- } // endif Check
+ throw Type;
+ } // endif Check
Typp[n] = atof(p);
SetNull(n, false);
@@ -403,7 +403,7 @@ void TYPBLK<double>::SetValue(PSZ p, int n)
/* Set one value in a block from an array of characters. */
/***********************************************************************/
template <class TYPE>
-void TYPBLK<TYPE>::SetValue(char *sp, uint len, int n)
+void TYPBLK<TYPE>::SetValue(PCSZ sp, uint len, int n)
{
PGLOBAL& g = Global;
PSZ spz = (PSZ)PlugSubAlloc(g, NULL, 0); // Temporary
@@ -778,7 +778,7 @@ void CHRBLK::SetValue(PVAL valp, int n)
/***********************************************************************/
/* Set one value in a block from a zero terminated string. */
/***********************************************************************/
-void CHRBLK::SetValue(PSZ sp, int n)
+void CHRBLK::SetValue(PCSZ sp, int n)
{
uint len = (sp) ? strlen(sp) : 0;
SetValue(sp, len, n);
@@ -787,7 +787,7 @@ void CHRBLK::SetValue(PSZ sp, int n)
/***********************************************************************/
/* Set one value in a block from an array of characters. */
/***********************************************************************/
-void CHRBLK::SetValue(char *sp, uint len, int n)
+void CHRBLK::SetValue(const char *sp, uint len, int n)
{
char *p = Chrp + n * Long;
@@ -795,8 +795,8 @@ void CHRBLK::SetValue(char *sp, uint len, int n)
if (Check && (signed)len > Long) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(SET_STR_TRUNC));
- longjmp(g->jumper[g->jump_level], Type);
- } // endif Check
+ throw Type;
+ } // endif Check
#endif // _DEBUG
if (sp)
@@ -823,8 +823,8 @@ void CHRBLK::SetValue(PVBLK pv, int n1, int n2)
if (Type != pv->GetType() || Long != ((CHRBLK*)pv)->Long) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BLKTYPLEN_MISM));
- longjmp(g->jumper[g->jump_level], Type);
- } // endif Type
+ throw Type;
+ } // endif Type
if (!(b = pv->IsNull(n2)))
memcpy(Chrp + n1 * Long, ((CHRBLK*)pv)->Chrp + n2 * Long, Long);
@@ -874,8 +874,8 @@ void CHRBLK::SetValues(PVBLK pv, int k, int n)
if (Type != pv->GetType() || Long != ((CHRBLK*)pv)->Long) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BLKTYPLEN_MISM));
- longjmp(g->jumper[g->jump_level], Type);
- } // endif Type
+ throw Type;
+ } // endif Type
#endif // _DEBUG
char *p = ((CHRBLK*)pv)->Chrp;
@@ -1152,7 +1152,7 @@ void STRBLK::SetValue(PVAL valp, int n)
/***********************************************************************/
/* Set one value in a block from a zero terminated string. */
/***********************************************************************/
-void STRBLK::SetValue(PSZ p, int n)
+void STRBLK::SetValue(PCSZ p, int n)
{
if (p) {
if (!Sorted || !n || !Strp[n-1] || strcmp(p, Strp[n-1]))
@@ -1168,7 +1168,7 @@ void STRBLK::SetValue(PSZ p, int n)
/***********************************************************************/
/* Set one value in a block from an array of characters. */
/***********************************************************************/
-void STRBLK::SetValue(char *sp, uint len, int n)
+void STRBLK::SetValue(const char *sp, uint len, int n)
{
PSZ p;
@@ -1316,7 +1316,7 @@ DATBLK::DATBLK(void *mp, int nval) : TYPBLK<int>(mp, nval, TYPE_INT)
/***********************************************************************/
/* Set format so formatted dates can be converted on input. */
/***********************************************************************/
-bool DATBLK::SetFormat(PGLOBAL g, PSZ fmt, int len, int year)
+bool DATBLK::SetFormat(PGLOBAL g, PCSZ fmt, int len, int year)
{
if (!(Dvalp = AllocateValue(g, TYPE_DATE, len, year, false, fmt)))
return true;
@@ -1343,7 +1343,7 @@ char *DATBLK::GetCharString(char *p, int n)
/***********************************************************************/
/* Set one value in a block from a char string. */
/***********************************************************************/
-void DATBLK::SetValue(PSZ p, int n)
+void DATBLK::SetValue(PCSZ p, int n)
{
if (Dvalp) {
// Decode the string according to format
diff --git a/storage/connect/valblk.h b/storage/connect/valblk.h
index c3cad79b234..38a73424985 100644
--- a/storage/connect/valblk.h
+++ b/storage/connect/valblk.h
@@ -91,7 +91,7 @@ class VALBLK : public BLOCK {
virtual char *GetCharString(char *p, int n) = 0;
virtual void ReAlloc(void *mp, int n) {Blkp = mp; Nval = n;}
virtual void Reset(int n) = 0;
- virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
+ virtual bool SetFormat(PGLOBAL g, PCSZ fmt, int len, int year = 0);
virtual void SetPrec(int p) {}
virtual bool IsCi(void) {return false;}
@@ -105,8 +105,8 @@ class VALBLK : public BLOCK {
virtual void SetValue(double, int) {assert(false);}
virtual void SetValue(char, int) {assert(false);}
virtual void SetValue(uchar, int) {assert(false);}
- virtual void SetValue(PSZ, int) {assert(false);}
- virtual void SetValue(char *, uint, int) {assert(false);}
+ virtual void SetValue(PCSZ, int) {assert(false);}
+ virtual void SetValue(const char *, uint, int) {assert(false);}
virtual void SetValue(PVAL valp, int n) = 0;
virtual void SetValue(PVBLK pv, int n1, int n2) = 0;
virtual void SetMin(PVAL valp, int n) = 0;
@@ -165,8 +165,8 @@ class TYPBLK : public VALBLK {
// Methods
using VALBLK::SetValue;
- virtual void SetValue(PSZ sp, int n);
- virtual void SetValue(char *sp, uint len, int n);
+ virtual void SetValue(PCSZ sp, int n);
+ virtual void SetValue(const char *sp, uint len, int n);
virtual void SetValue(short sval, int n)
{Typp[n] = (TYPE)sval; SetNull(n, false);}
virtual void SetValue(ushort sval, int n)
@@ -236,8 +236,8 @@ class CHRBLK : public VALBLK {
// Methods
using VALBLK::SetValue;
- virtual void SetValue(PSZ sp, int n);
- virtual void SetValue(char *sp, uint len, int n);
+ virtual void SetValue(PCSZ sp, int n);
+ virtual void SetValue(const char *sp, uint len, int n);
virtual void SetValue(PVAL valp, int n);
virtual void SetValue(PVBLK pv, int n1, int n2);
virtual void SetMin(PVAL valp, int n);
@@ -290,8 +290,8 @@ class STRBLK : public VALBLK {
// Methods
using VALBLK::SetValue;
- virtual void SetValue(PSZ sp, int n);
- virtual void SetValue(char *sp, uint len, int n);
+ virtual void SetValue(PCSZ sp, int n);
+ virtual void SetValue(const char *sp, uint len, int n);
virtual void SetValue(PVAL valp, int n);
virtual void SetValue(PVBLK pv, int n1, int n2);
virtual void SetMin(PVAL valp, int n);
@@ -322,12 +322,12 @@ class DATBLK : public TYPBLK<int> {
DATBLK(void *mp, int size);
// Implementation
- virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
+ virtual bool SetFormat(PGLOBAL g, PCSZ fmt, int len, int year = 0);
virtual char *GetCharString(char *p, int n);
// Methods
using TYPBLK<int>::SetValue;
- virtual void SetValue(PSZ sp, int n);
+ virtual void SetValue(PCSZ sp, int n);
protected:
// Members
@@ -352,7 +352,7 @@ class PTRBLK : public STRBLK {
// Methods
using STRBLK::SetValue;
using STRBLK::CompVal;
- virtual void SetValue(PSZ p, int n) {Strp[n] = p;}
+ virtual void SetValue(PCSZ p, int n) {Strp[n] = (char*)p;}
virtual int CompVal(int i1, int i2);
protected:
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index ced690e77c0..b488f7aa061 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -1,7 +1,7 @@
/************* Value C++ Functions Source Code File (.CPP) *************/
-/* Name: VALUE.CPP Version 2.6 */
+/* Name: VALUE.CPP Version 2.8 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2016 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2017 */
/* */
/* This file contains the VALUE and derived classes family functions. */
/* These classes contain values of different types. They are used so */
@@ -60,7 +60,7 @@
#define CheckType(V) if (Type != V->GetType()) { \
PGLOBAL& g = Global; \
strcpy(g->Message, MSG(VALTYPE_NOMATCH)); \
- longjmp(g->jumper[g->jump_level], Type); }
+ throw Type;
#else
#define CheckType(V)
#endif
@@ -94,12 +94,12 @@ PSZ strlwr(PSZ s);
/* OUT minus: Set to true if the number is negative */
/* Returned val: The resulting number */
/***********************************************************************/
-ulonglong CharToNumber(char *p, int n, ulonglong maxval,
+ulonglong CharToNumber(const char *p, int n, ulonglong maxval,
bool un, bool *minus, bool *rc)
{
- char *p2;
- uchar c;
- ulonglong val;
+ const char *p2;
+ uchar c;
+ ulonglong val;
if (minus) *minus = false;
if (rc) *rc = false;
@@ -138,9 +138,9 @@ ulonglong CharToNumber(char *p, int n, ulonglong maxval,
/***********************************************************************/
/* GetTypeName: returns the PlugDB internal type name. */
/***********************************************************************/
-PSZ GetTypeName(int type)
+PCSZ GetTypeName(int type)
{
- PSZ name;
+ PCSZ name;
switch (type) {
case TYPE_STRING: name = "CHAR"; break;
@@ -184,9 +184,9 @@ int GetTypeSize(int type, int len)
/***********************************************************************/
/* GetFormatType: returns the FORMAT character(s) according to type. */
/***********************************************************************/
-char *GetFormatType(int type)
+const char *GetFormatType(int type)
{
- char *c = "X";
+ const char *c = "X";
switch (type) {
case TYPE_STRING: c = "C"; break;
@@ -370,7 +370,7 @@ PVAL AllocateValue(PGLOBAL g, void *value, short type, short prec)
/* Allocate a variable Value according to type, length and precision. */
/***********************************************************************/
PVAL AllocateValue(PGLOBAL g, int type, int len, int prec,
- bool uns, PSZ fmt)
+ bool uns, PCSZ fmt)
{
PVAL valp;
@@ -558,6 +558,38 @@ bool VALUE::Compute(PGLOBAL g, PVAL *, int, OPVAL)
return true;
} // end of Compute
+/***********************************************************************/
+/* Make file output of an object value. */
+/***********************************************************************/
+void VALUE::Printf(PGLOBAL g, FILE *f, uint n)
+{
+ char m[64], buf[64];
+
+ memset(m, ' ', n); /* Make margin string */
+ m[n] = '\0';
+
+ if (Null)
+ fprintf(f, "%s<null>\n", m);
+ else
+ fprintf(f, strcat(strcat(GetCharString(buf), "\n"), m));
+
+} /* end of Printf */
+
+/***********************************************************************/
+/* Make string output of an object value. */
+/***********************************************************************/
+void VALUE::Prints(PGLOBAL g, char *ps, uint z)
+{
+ char *p, buf[64];
+
+ if (Null)
+ p = strcpy(buf, "<null>");
+ else
+ p = GetCharString(buf);
+
+ strncpy(ps, p, z);
+} // end of Prints
+
/* -------------------------- Class TYPVAL ---------------------------- */
/***********************************************************************/
@@ -682,7 +714,7 @@ uchar TYPVAL<uchar>::GetTypedValue(PVAL valp)
/* TYPVAL SetValue: convert chars extracted from a line to TYPE value.*/
/***********************************************************************/
template <class TYPE>
-bool TYPVAL<TYPE>::SetValue_char(char *p, int n)
+bool TYPVAL<TYPE>::SetValue_char(const char *p, int n)
{
bool rc, minus;
ulonglong maxval = MaxVal();
@@ -704,7 +736,7 @@ bool TYPVAL<TYPE>::SetValue_char(char *p, int n)
} // end of SetValue
template <>
-bool TYPVAL<double>::SetValue_char(char *p, int n)
+bool TYPVAL<double>::SetValue_char(const char *p, int n)
{
if (p && n > 0) {
char buf[64];
@@ -732,7 +764,7 @@ bool TYPVAL<double>::SetValue_char(char *p, int n)
/* TYPVAL SetValue: fill a typed value from a string. */
/***********************************************************************/
template <class TYPE>
-void TYPVAL<TYPE>::SetValue_psz(PSZ s)
+void TYPVAL<TYPE>::SetValue_psz(PCSZ s)
{
if (s) {
SetValue_char(s, (int)strlen(s));
@@ -1019,12 +1051,12 @@ TYPE TYPVAL<TYPE>::SafeAdd(TYPE n1, TYPE n2)
if ((n2 > 0) && (n < n1)) {
// Overflow
strcpy(g->Message, MSG(FIX_OVFLW_ADD));
- longjmp(g->jumper[g->jump_level], 138);
- } else if ((n2 < 0) && (n > n1)) {
+ throw 138;
+ } else if ((n2 < 0) && (n > n1)) {
// Underflow
strcpy(g->Message, MSG(FIX_UNFLW_ADD));
- longjmp(g->jumper[g->jump_level], 138);
- } // endif's n2
+ throw 138;
+ } // endif's n2
return n;
} // end of SafeAdd
@@ -1047,12 +1079,12 @@ TYPE TYPVAL<TYPE>::SafeMult(TYPE n1, TYPE n2)
if (n > MinMaxVal(true)) {
// Overflow
strcpy(g->Message, MSG(FIX_OVFLW_TIMES));
- longjmp(g->jumper[g->jump_level], 138);
- } else if (n < MinMaxVal(false)) {
+ throw 138;
+ } else if (n < MinMaxVal(false)) {
// Underflow
strcpy(g->Message, MSG(FIX_UNFLW_TIMES));
- longjmp(g->jumper[g->jump_level], 138);
- } // endif's n2
+ throw 138;
+ } // endif's n2
return (TYPE)n;
} // end of SafeMult
@@ -1170,7 +1202,7 @@ bool TYPVAL<TYPE>::Compall(PGLOBAL g, PVAL *vp, int np, OPVAL op)
/* This function assumes that the format matches the value type. */
/***********************************************************************/
template <class TYPE>
-bool TYPVAL<TYPE>::FormatValue(PVAL vp, char *fmt)
+bool TYPVAL<TYPE>::FormatValue(PVAL vp, PCSZ fmt)
{
char *buf = (char*)vp->GetTo_Val(); // Should be big enough
int n = sprintf(buf, fmt, Tval);
@@ -1192,37 +1224,6 @@ bool TYPVAL<TYPE>::SetConstFormat(PGLOBAL g, FORMAT& fmt)
return false;
} // end of SetConstFormat
-/***********************************************************************/
-/* Make file output of a typed object. */
-/***********************************************************************/
-template <class TYPE>
-void TYPVAL<TYPE>::Print(PGLOBAL g, FILE *f, uint n)
- {
- char m[64], buf[12];
-
- memset(m, ' ', n); /* Make margin string */
- m[n] = '\0';
-
- if (Null)
- fprintf(f, "%s<null>\n", m);
- else
- fprintf(f, strcat(strcat(strcpy(buf, "%s"), Fmt), "\n"), m, Tval);
-
- } /* end of Print */
-
-/***********************************************************************/
-/* Make string output of a int object. */
-/***********************************************************************/
-template <class TYPE>
-void TYPVAL<TYPE>::Print(PGLOBAL g, char *ps, uint z)
- {
- if (Null)
- strcpy(ps, "<null>");
- else
- sprintf(ps, Fmt, Tval);
-
- } /* end of Print */
-
/* -------------------------- Class STRING --------------------------- */
/***********************************************************************/
@@ -1361,25 +1362,25 @@ bool TYPVAL<PSZ>::SetValue_pval(PVAL valp, bool chktype)
/***********************************************************************/
/* STRING SetValue: fill string with chars extracted from a line. */
/***********************************************************************/
-bool TYPVAL<PSZ>::SetValue_char(char *p, int n)
+bool TYPVAL<PSZ>::SetValue_char(const char *cp, int n)
{
bool rc = false;
- if (!p || n == 0) {
+ if (!cp || n == 0) {
Reset();
Null = Nullable;
- } else if (p != Strp) {
- rc = n > Len;
+ } else if (cp != Strp) {
+ const char *p = cp + n - 1;
- if ((n = MY_MIN(n, Len))) {
- strncpy(Strp, p, n);
+ for (p; p >= cp; p--, n--)
+ if (*p && *p != ' ')
+ break;
-// for (p = Strp + n - 1; p >= Strp && (*p == ' ' || *p == '\0'); p--) ;
- for (p = Strp + n - 1; p >= Strp; p--)
- if (*p && *p != ' ')
- break;
+ rc = n > Len;
- *(++p) = '\0';
+ if ((n = MY_MIN(n, Len))) {
+ strncpy(Strp, cp, n);
+ Strp[n] = '\0';
if (trace > 1)
htrc(" Setting string to: '%s'\n", Strp);
@@ -1396,7 +1397,7 @@ bool TYPVAL<PSZ>::SetValue_char(char *p, int n)
/***********************************************************************/
/* STRING SetValue: fill string with another string. */
/***********************************************************************/
-void TYPVAL<PSZ>::SetValue_psz(PSZ s)
+void TYPVAL<PSZ>::SetValue_psz(PCSZ s)
{
if (!s) {
Reset();
@@ -1432,8 +1433,8 @@ void TYPVAL<PSZ>::SetValue(int n)
if (k > Len) {
sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len);
- longjmp(g->jumper[g->jump_level], 138);
- } else
+ throw 138;
+ } else
SetValue_psz(buf);
Null = false;
@@ -1486,8 +1487,8 @@ void TYPVAL<PSZ>::SetValue(longlong n)
if (k > Len) {
sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len);
- longjmp(g->jumper[g->jump_level], 138);
- } else
+ throw 138;
+ } else
SetValue_psz(buf);
Null = false;
@@ -1529,8 +1530,8 @@ void TYPVAL<PSZ>::SetValue(double f)
if (k > Len) {
sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len);
- longjmp(g->jumper[g->jump_level], 138);
- } else
+ throw 138;
+ } else
SetValue_psz(buf);
Null = false;
@@ -1559,7 +1560,7 @@ void TYPVAL<PSZ>::SetValue(uchar c)
/***********************************************************************/
void TYPVAL<PSZ>::SetBinValue(void *p)
{
- SetValue_char((char *)p, Len);
+ SetValue_char((const char *)p, Len);
} // end of SetBinValue
/***********************************************************************/
@@ -1654,32 +1655,36 @@ bool TYPVAL<PSZ>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
int i;
for (i = 0; i < np; i++)
- p[i] = vp[i]->GetCharString(val[i]);
-
- switch (op) {
- case OP_CNC:
- assert(np == 1 || np == 2);
-
- if (np == 2)
- SetValue_psz(p[0]);
-
- if ((i = Len - (signed)strlen(Strp)) > 0)
- strncat(Strp, p[np - 1], i);
-
- break;
- case OP_MIN:
- assert(np == 2);
- SetValue_psz((strcmp(p[0], p[1]) < 0) ? p[0] : p[1]);
- break;
- case OP_MAX:
- assert(np == 2);
- SetValue_psz((strcmp(p[0], p[1]) > 0) ? p[0] : p[1]);
- break;
- default:
-// sprintf(g->Message, MSG(BAD_EXP_OPER), op);
- strcpy(g->Message, "Function not supported");
- return true;
- } // endswitch op
+ p[i] = vp[i]->IsNull() ? NULL : vp[i]->GetCharString(val[i]);
+
+ if (p[i]) {
+ switch (op) {
+ case OP_CNC:
+ assert(np == 1 || np == 2);
+
+ if (np == 2)
+ SetValue_psz(p[0]);
+
+ if ((i = Len - (signed)strlen(Strp)) > 0)
+ strncat(Strp, p[np - 1], i);
+
+ break;
+ case OP_MIN:
+ assert(np == 2);
+ SetValue_psz((strcmp(p[0], p[1]) < 0) ? p[0] : p[1]);
+ break;
+ case OP_MAX:
+ assert(np == 2);
+ SetValue_psz((strcmp(p[0], p[1]) > 0) ? p[0] : p[1]);
+ break;
+ default:
+ // sprintf(g->Message, MSG(BAD_EXP_OPER), op);
+ strcpy(g->Message, "Function not supported");
+ return true;
+ } // endswitch op
+
+ Null = false;
+ } // endif p[i]
return false;
} // end of Compute
@@ -1689,7 +1694,7 @@ bool TYPVAL<PSZ>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
/* constructed from its own value formated using the fmt format. */
/* This function assumes that the format matches the value type. */
/***********************************************************************/
-bool TYPVAL<PSZ>::FormatValue(PVAL vp, char *fmt)
+bool TYPVAL<PSZ>::FormatValue(PVAL vp, PCSZ fmt)
{
char *buf = (char*)vp->GetTo_Val(); // Should be big enough
int n = sprintf(buf, fmt, Strp);
@@ -1708,6 +1713,18 @@ bool TYPVAL<PSZ>::SetConstFormat(PGLOBAL, FORMAT& fmt)
return false;
} // end of SetConstFormat
+/***********************************************************************/
+/* Make string output of an object value. */
+/***********************************************************************/
+void TYPVAL<PSZ>::Prints(PGLOBAL g, char *ps, uint z)
+{
+ if (Null)
+ strncpy(ps, "null", z);
+ else
+ strcat(strncat(strncpy(ps, "\"", z), Strp, z-2), "\"");
+
+} // end of Prints
+
/* -------------------------- Class DECIMAL -------------------------- */
/***********************************************************************/
@@ -1797,102 +1814,6 @@ bool DECVAL::GetBinValue(void *buf, int buflen, bool go)
return false;
} // end of GetBinValue
-#if 0
-/***********************************************************************/
-/* DECIMAL SetValue: copy the value of another Value object. */
-/***********************************************************************/
-bool DECVAL::SetValue_pval(PVAL valp, bool chktype)
- {
- if (chktype && (valp->GetType() != Type || valp->GetSize() > Len))
- return true;
-
- char buf[64];
-
- if (!(Null = valp->IsNull() && Nullable))
- strncpy(Strp, valp->GetCharString(buf), Len);
- else
- Reset();
-
- return false;
- } // end of SetValue_pval
-
-/***********************************************************************/
-/* DECIMAL SetValue: fill string with chars extracted from a line. */
-/***********************************************************************/
-bool DECVAL::SetValue_char(char *p, int n)
- {
- bool rc;
-
- if (p && n > 0) {
- rc = n > Len;
-
- if ((n = MY_MIN(n, Len))) {
- strncpy(Strp, p, n);
-
-// for (p = Strp + n - 1; p >= Strp && (*p == ' ' || *p == '\0'); p--) ;
- for (p = Strp + n - 1; p >= Strp; p--)
- if (*p && *p != ' ')
- break;
-
- *(++p) = '\0';
-
- if (trace > 1)
- htrc(" Setting string to: '%s'\n", Strp);
-
- } else
- Reset();
-
- Null = false;
- } else {
- rc = false;
- Reset();
- Null = Nullable;
- } // endif p
-
- return rc;
- } // end of SetValue_char
-
-/***********************************************************************/
-/* DECIMAL SetValue: fill string with another string. */
-/***********************************************************************/
-void DECVAL::SetValue_psz(PSZ s)
- {
- if (s) {
- strncpy(Strp, s, Len);
- Null = false;
- } else {
- Reset();
- Null = Nullable;
- } // endif s
-
- } // end of SetValue_psz
-
-/***********************************************************************/
-/* DECIMAL SetValue: fill string with a string extracted from a block.*/
-/***********************************************************************/
-void DECVAL::SetValue_pvblk(PVBLK blk, int n)
- {
- // STRBLK's can return a NULL pointer
- SetValue_psz(blk->GetCharValue(n));
- } // end of SetValue_pvblk
-
-/***********************************************************************/
-/* DECIMAL SetBinValue: fill string with chars extracted from a line. */
-/***********************************************************************/
-void DECVAL::SetBinValue(void *p)
- {
- SetValue_char((char *)p, Len);
- } // end of SetBinValue
-
-/***********************************************************************/
-/* DECIMAL GetCharString: get string representation of a char value. */
-/***********************************************************************/
-char *DECVAL::GetCharString(char *p)
- {
- return Strp;
- } // end of GetCharString
-#endif // 0
-
/***********************************************************************/
/* DECIMAL compare value with another Value. */
/***********************************************************************/
@@ -1927,32 +1848,6 @@ int DECVAL::CompareValue(PVAL vp)
return (f > n) ? 1 : (f < n) ? (-1) : 0;
} // end of CompareValue
-#if 0
-/***********************************************************************/
-/* FormatValue: This function set vp (a STRING value) to the string */
-/* constructed from its own value formated using the fmt format. */
-/* This function assumes that the format matches the value type. */
-/***********************************************************************/
-bool DECVAL::FormatValue(PVAL vp, char *fmt)
- {
- char *buf = (char*)vp->GetTo_Val(); // Should be big enough
- int n = sprintf(buf, fmt, Strp);
-
- return (n > vp->GetValLen());
- } // end of FormatValue
-
-/***********************************************************************/
-/* DECIMAL SetFormat function (used to set SELECT output format). */
-/***********************************************************************/
-bool DECVAL::SetConstFormat(PGLOBAL g, FORMAT& fmt)
- {
- fmt.Type[0] = 'C';
- fmt.Length = Len;
- fmt.Prec = 0;
- return false;
- } // end of SetConstFormat
-#endif // 0
-
/* -------------------------- Class BINVAL --------------------------- */
/***********************************************************************/
@@ -2110,7 +2005,7 @@ bool BINVAL::SetValue_pval(PVAL valp, bool chktype)
/***********************************************************************/
/* BINVAL SetValue: fill value with chars extracted from a line. */
/***********************************************************************/
-bool BINVAL::SetValue_char(char *p, int n)
+bool BINVAL::SetValue_char(const char *p, int n)
{
bool rc;
@@ -2131,7 +2026,7 @@ bool BINVAL::SetValue_char(char *p, int n)
/***********************************************************************/
/* BINVAL SetValue: fill value with another string. */
/***********************************************************************/
-void BINVAL::SetValue_psz(PSZ s)
+void BINVAL::SetValue_psz(PCSZ s)
{
if (s) {
Len = MY_MIN(Clen, (signed)strlen(s));
@@ -2357,7 +2252,7 @@ bool BINVAL::IsEqual(PVAL vp, bool chktype)
/* constructed from its own value formated using the fmt format. */
/* This function assumes that the format matches the value type. */
/***********************************************************************/
-bool BINVAL::FormatValue(PVAL vp, char *fmt)
+bool BINVAL::FormatValue(PVAL vp, PCSZ fmt)
{
char *buf = (char*)vp->GetTo_Val(); // Should be big enough
int n = sprintf(buf, fmt, Len, Binp);
@@ -2381,7 +2276,7 @@ bool BINVAL::SetConstFormat(PGLOBAL, FORMAT& fmt)
/***********************************************************************/
/* DTVAL public constructor for new void values. */
/***********************************************************************/
-DTVAL::DTVAL(PGLOBAL g, int n, int prec, PSZ fmt)
+DTVAL::DTVAL(PGLOBAL g, int n, int prec, PCSZ fmt)
: TYPVAL<int>((int)0, TYPE_DATE)
{
if (!fmt) {
@@ -2410,7 +2305,7 @@ DTVAL::DTVAL(int n) : TYPVAL<int>(n, TYPE_DATE)
/***********************************************************************/
/* Set format so formatted dates can be converted on input/output. */
/***********************************************************************/
-bool DTVAL::SetFormat(PGLOBAL g, PSZ fmt, int len, int year)
+bool DTVAL::SetFormat(PGLOBAL g, PCSZ fmt, int len, int year)
{
Pdtp = MakeDateFormat(g, fmt, true, true, (year > 9999) ? 1 : 0);
Sdate = (char*)PlugSubAlloc(g, NULL, len + 1);
@@ -2668,7 +2563,11 @@ bool DTVAL::SetValue_pval(PVAL valp, bool chktype)
ndv = ExtractDate(valp->GetCharValue(), Pdtp, DefYear, dval);
MakeDate(NULL, dval, ndv);
- } else
+ } else if (valp->GetType() == TYPE_BIGINT &&
+ !(valp->GetBigintValue() % 1000)) {
+ // Assuming that this timestamp is in milliseconds
+ Tval = valp->GetBigintValue() / 1000;
+ } else
Tval = valp->GetIntValue();
} else
@@ -2682,14 +2581,14 @@ bool DTVAL::SetValue_pval(PVAL valp, bool chktype)
/***********************************************************************/
/* SetValue: convert chars extracted from a line to date value. */
/***********************************************************************/
-bool DTVAL::SetValue_char(char *p, int n)
+bool DTVAL::SetValue_char(const char *p, int n)
{
bool rc= 0;
if (Pdtp) {
- char *p2;
- int ndv;
- int dval[6];
+ const char *p2;
+ int ndv;
+ int dval[6];
if (n > 0) {
// Trim trailing blanks
@@ -2721,11 +2620,11 @@ bool DTVAL::SetValue_char(char *p, int n)
/***********************************************************************/
/* SetValue: convert a char string to date value. */
/***********************************************************************/
-void DTVAL::SetValue_psz(PSZ p)
+void DTVAL::SetValue_psz(PCSZ p)
{
if (Pdtp) {
- int ndv;
- int dval[6];
+ int ndv;
+ int dval[6];
strncpy(Sdate, p, Len);
Sdate[Len] = '\0';
@@ -2815,8 +2714,10 @@ char *DTVAL::ShowValue(char *buf, int len)
strncat(p, "Error", m);
} // endif n
- } else
- p = ""; // DEFAULT VALUE ???
+ } else {
+ p = buf;
+ *p = '\0'; // DEFAULT VALUE ???
+ } // endif Null
return p;
} else
@@ -2881,7 +2782,7 @@ bool DTVAL::WeekNum(PGLOBAL g, int& nval)
/* constructed from its own value formated using the fmt format. */
/* This function assumes that the format matches the value type. */
/***********************************************************************/
-bool DTVAL::FormatValue(PVAL vp, char *fmt)
+bool DTVAL::FormatValue(PVAL vp, PCSZ fmt)
{
char *buf = (char*)vp->GetTo_Val(); // Should be big enough
struct tm tm, *ptm = GetGmTime(&tm);
diff --git a/storage/connect/value.h b/storage/connect/value.h
index 14a568c3549..f771d33dc52 100644
--- a/storage/connect/value.h
+++ b/storage/connect/value.h
@@ -1,7 +1,7 @@
/**************** Value H Declares Source Code File (.H) ***************/
-/* Name: VALUE.H Version 2.2 */
+/* Name: VALUE.H Version 2.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2016 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2017 */
/* */
/* This file contains the VALUE and derived classes declares. */
/***********************************************************************/
@@ -40,14 +40,14 @@ typedef struct _datpar *PDTP; // For DTVAL
/* Utilities used to test types and to allocated values. */
/***********************************************************************/
// Exported functions
-DllExport PSZ GetTypeName(int);
+DllExport PCSZ GetTypeName(int);
DllExport int GetTypeSize(int, int);
#ifdef ODBC_SUPPORT
/* This function is exported for use in OEM table type DLLs */
DllExport int TranslateSQLType(int stp, int prec,
int& len, char& v, bool& w);
#endif
-DllExport char *GetFormatType(int);
+DllExport const char *GetFormatType(int);
DllExport int GetFormatType(char);
DllExport bool IsTypeChar(int type);
DllExport bool IsTypeNum(int type);
@@ -55,8 +55,8 @@ DllExport int ConvertType(int, int, CONV, bool match = false);
DllExport PVAL AllocateValue(PGLOBAL, void *, short, short = 2);
DllExport PVAL AllocateValue(PGLOBAL, PVAL, int = TYPE_VOID, int = 0);
DllExport PVAL AllocateValue(PGLOBAL, int, int len = 0, int prec = 0,
- bool uns = false, PSZ fmt = NULL);
-DllExport ulonglong CharToNumber(char *, int, ulonglong, bool,
+ bool uns = false, PCSZ fmt = NULL);
+DllExport ulonglong CharToNumber(PCSZ, int, ulonglong, bool,
bool *minus = NULL, bool *rc = NULL);
DllExport BYTE OpBmp(PGLOBAL g, OPVAL opc);
@@ -90,8 +90,8 @@ class DllExport VALUE : public BLOCK {
virtual double GetFloatValue(void) = 0;
virtual void *GetTo_Val(void) = 0;
virtual void SetPrec(int prec) {Prec = prec;}
- bool IsNull(void) {return Null;}
- void SetNull(bool b) {Null = b;}
+ bool IsNull(void) {return (Nullable && Null);}
+ void SetNull(bool b) {Null = (Nullable ? b : false);}
bool GetNullable(void) {return Nullable;}
void SetNullable(bool b) {Nullable = b;}
int GetType(void) {return Type;}
@@ -100,8 +100,8 @@ class DllExport VALUE : public BLOCK {
// Methods
virtual bool SetValue_pval(PVAL valp, bool chktype = false) = 0;
- virtual bool SetValue_char(char *p, int n) = 0;
- virtual void SetValue_psz(PSZ s) = 0;
+ virtual bool SetValue_char(const char *p, int n) = 0;
+ virtual void SetValue_psz(PCSZ s) = 0;
virtual void SetValue_bool(bool) {assert(FALSE);}
virtual int CompareValue(PVAL vp) = 0;
virtual BYTE TestValue(PVAL vp);
@@ -121,7 +121,9 @@ class DllExport VALUE : public BLOCK {
virtual char *GetCharString(char *p) = 0;
virtual bool IsEqual(PVAL vp, bool chktype) = 0;
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
- virtual bool FormatValue(PVAL vp, char *fmt) = 0;
+ virtual bool FormatValue(PVAL vp, PCSZ fmt) = 0;
+ virtual void Printf(PGLOBAL g, FILE *, uint);
+ virtual void Prints(PGLOBAL g, char *ps, uint z);
/**
Set value from a non-aligned in-memory value in the machine byte order.
@@ -211,8 +213,8 @@ class DllExport TYPVAL : public VALUE {
// Methods
virtual bool SetValue_pval(PVAL valp, bool chktype);
- virtual bool SetValue_char(char *p, int n);
- virtual void SetValue_psz(PSZ s);
+ virtual bool SetValue_char(const char *p, int n);
+ virtual void SetValue_psz(PCSZ s);
virtual void SetValue_bool(bool b) {Tval = (b) ? 1 : 0;}
virtual int CompareValue(PVAL vp);
virtual void SetValue(char c) {Tval = (TYPE)c; Null = false;}
@@ -232,9 +234,7 @@ class DllExport TYPVAL : public VALUE {
virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
- virtual bool FormatValue(PVAL vp, char *fmt);
- virtual void Print(PGLOBAL g, FILE *, uint);
- virtual void Print(PGLOBAL g, char *, uint);
+ virtual bool FormatValue(PVAL vp, PCSZ fmt);
protected:
static TYPE MinMaxVal(bool b);
@@ -287,8 +287,8 @@ class DllExport TYPVAL<PSZ>: public VALUE {
// Methods
virtual bool SetValue_pval(PVAL valp, bool chktype);
- virtual bool SetValue_char(char *p, int n);
- virtual void SetValue_psz(PSZ s);
+ virtual bool SetValue_char(const char *p, int n);
+ virtual void SetValue_psz(PCSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
virtual void SetValue(char c);
virtual void SetValue(uchar c);
@@ -306,8 +306,9 @@ class DllExport TYPVAL<PSZ>: public VALUE {
virtual char *GetCharString(char *p);
virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
- virtual bool FormatValue(PVAL vp, char *fmt);
+ virtual bool FormatValue(PVAL vp, PCSZ fmt);
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
+ virtual void Prints(PGLOBAL g, char *ps, uint z);
protected:
// Members
@@ -371,8 +372,8 @@ class DllExport BINVAL: public VALUE {
// Methods
virtual bool SetValue_pval(PVAL valp, bool chktype);
- virtual bool SetValue_char(char *p, int n);
- virtual void SetValue_psz(PSZ s);
+ virtual bool SetValue_char(const char *p, int n);
+ virtual void SetValue_psz(PCSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
virtual void SetValue(char c);
virtual void SetValue(uchar c);
@@ -389,7 +390,7 @@ class DllExport BINVAL: public VALUE {
virtual char *ShowValue(char *buf, int);
virtual char *GetCharString(char *p);
virtual bool IsEqual(PVAL vp, bool chktype);
- virtual bool FormatValue(PVAL vp, char *fmt);
+ virtual bool FormatValue(PVAL vp, PCSZ fmt);
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
protected:
@@ -405,18 +406,18 @@ class DllExport BINVAL: public VALUE {
class DllExport DTVAL : public TYPVAL<int> {
public:
// Constructors
- DTVAL(PGLOBAL g, int n, int p, PSZ fmt);
+ DTVAL(PGLOBAL g, int n, int p, PCSZ fmt);
DTVAL(int n);
// Implementation
virtual bool SetValue_pval(PVAL valp, bool chktype);
- virtual bool SetValue_char(char *p, int n);
- virtual void SetValue_psz(PSZ s);
+ virtual bool SetValue_char(const char *p, int n);
+ virtual void SetValue_psz(PCSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
virtual char *GetCharString(char *p);
virtual char *ShowValue(char *buf, int);
- virtual bool FormatValue(PVAL vp, char *fmt);
- bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
+ virtual bool FormatValue(PVAL vp, PCSZ fmt);
+ bool SetFormat(PGLOBAL g, PCSZ fmt, int len, int year = 0);
bool SetFormat(PGLOBAL g, PVAL valp);
bool IsFormatted(void) {return Pdtp != NULL;}
bool MakeTime(struct tm *ptm);
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 15fb71ab88a..9a2fbd83544 100755
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -1,7 +1,7 @@
/***************** Xindex C++ Class Xindex Code (.CPP) *****************/
-/* Name: XINDEX.CPP Version 2.9 */
+/* Name: XINDEX.CPP Version 3.0 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2004-2015 */
+/* (C) Copyright to the author Olivier BERTRAND 2004-2017 */
/* */
/* This file contains the class XINDEX implementation code. */
/***********************************************************************/
@@ -181,23 +181,23 @@ XXBASE::XXBASE(PTDBDOS tbxp, bool b) : CSORT(b),
/***********************************************************************/
/* Make file output of XINDEX contents. */
/***********************************************************************/
-void XXBASE::Print(PGLOBAL, FILE *f, uint n)
+void XXBASE::Printf(PGLOBAL, FILE *f, uint n)
{
char m[64];
memset(m, ' ', n); // Make margin string
m[n] = '\0';
fprintf(f, "%sXINDEX: Tbxp=%p Num=%d\n", m, Tbxp, Num_K);
- } // end of Print
+ } // end of Printf
/***********************************************************************/
/* Make string output of XINDEX contents. */
/***********************************************************************/
-void XXBASE::Print(PGLOBAL, char *ps, uint z)
+void XXBASE::Prints(PGLOBAL, char *ps, uint z)
{
*ps = '\0';
strncat(ps, "Xindex", z);
- } // end of Print
+ } // end of Prints
/* -------------------------- XINDEX Class --------------------------- */
@@ -446,8 +446,8 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
#if 0
if (!dup->Step) {
strcpy(g->Message, MSG(QUERY_CANCELLED));
- longjmp(g->jumper[g->jump_level], 99);
- } // endif Step
+ throw 99;
+ } // endif Step
#endif // 0
/*******************************************************************/
@@ -819,7 +819,7 @@ bool XINDEX::Reorder(PGLOBAL g __attribute__((unused)))
/***********************************************************************/
bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
{
- char *ftype;
+ PCSZ ftype;
char fn[_MAX_PATH];
int n[NZ], nof = (Mul) ? (Ndif + 1) : 0;
int id = -1, size = 0;
@@ -948,7 +948,7 @@ bool XINDEX::Init(PGLOBAL g)
/* Table will be accessed through an index table. */
/* If sorting is required, this will be done later. */
/*********************************************************************/
- char *ftype;
+ PCSZ ftype;
char fn[_MAX_PATH];
int k, n, nv[NZ], id = -1;
bool estim = false;
@@ -965,7 +965,7 @@ bool XINDEX::Init(PGLOBAL g)
// For DBF tables, Cardinality includes bad or soft deleted lines
// that are not included in the index, and can be larger then the
// index size.
- estim = (Tdbp->Ftype == RECFM_DBF);
+ estim = (Tdbp->Ftype == RECFM_DBF || Tdbp->Txfp->GetAmType() == TYPE_AM_ZIP);
n = Tdbp->Cardinality(g); // n is exact table size
} else {
// Variable table not optimized
@@ -1412,7 +1412,7 @@ err:
/***********************************************************************/
bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk)
{
- char *ftype;
+ PCSZ ftype;
char fn[_MAX_PATH];
int nv[NZ], id = -1; // n
//bool estim = false;
@@ -2320,9 +2320,9 @@ XFILE::XFILE(void) : XLOAD()
/***********************************************************************/
bool XFILE::Open(PGLOBAL g, char *filename, int id, MODE mode)
{
- char *pmod;
- bool rc;
- IOFF noff[MAX_INDX];
+ PCSZ pmod;
+ bool rc;
+ IOFF noff[MAX_INDX];
/*********************************************************************/
/* Open the index file according to mode. */
@@ -3032,7 +3032,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
return true;
Klen = Valp->GetClen();
- Keys.Size = n * Klen;
+ Keys.Size = (size_t)n * (size_t)Klen;
if (!PlgDBalloc(g, NULL, Keys)) {
sprintf(g->Message, MSG(KEY_ALLOC_ERROR), Klen, n);
diff --git a/storage/connect/xindex.h b/storage/connect/xindex.h
index 2d10d72722e..339d7e68b75 100644
--- a/storage/connect/xindex.h
+++ b/storage/connect/xindex.h
@@ -200,8 +200,8 @@ class DllExport XXBASE : public CSORT, public BLOCK {
void FreeIndex(void) {PlgDBfree(Index);}
// Methods
- virtual void Print(PGLOBAL g, FILE *f, uint n);
- virtual void Print(PGLOBAL g, char *ps, uint z);
+ virtual void Printf(PGLOBAL g, FILE *f, uint n);
+ virtual void Prints(PGLOBAL g, char *ps, uint z);
virtual bool Init(PGLOBAL g) = 0;
virtual bool Make(PGLOBAL g, PIXDEF sxp) = 0;
#if defined(XMAP)
diff --git a/storage/connect/xobject.cpp b/storage/connect/xobject.cpp
index a0b7849543d..6df3cee14bc 100644
--- a/storage/connect/xobject.cpp
+++ b/storage/connect/xobject.cpp
@@ -1,7 +1,7 @@
/************ Xobject C++ Functions Source Code File (.CPP) ************/
-/* Name: XOBJECT.CPP Version 2.4 */
+/* Name: XOBJECT.CPP Version 2.5 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
/* */
/* This file contains base XOBJECT class functions. */
/* Also here is the implementation of the CONSTANT class. */
@@ -84,7 +84,7 @@ double XOBJECT::GetFloatValue(void)
CONSTANT::CONSTANT(PGLOBAL g, void *value, short type)
{
if (!(Value = AllocateValue(g, value, (int)type)))
- longjmp(g->jumper[g->jump_level], TYPE_CONST);
+ throw TYPE_CONST;
Constant = true;
} // end of CONSTANT constructor
@@ -95,7 +95,7 @@ CONSTANT::CONSTANT(PGLOBAL g, void *value, short type)
CONSTANT::CONSTANT(PGLOBAL g, int n)
{
if (!(Value = AllocateValue(g, &n, TYPE_INT)))
- longjmp(g->jumper[g->jump_level], TYPE_CONST);
+ throw TYPE_CONST;
Constant = true;
} // end of CONSTANT constructor
@@ -117,7 +117,7 @@ void CONSTANT::Convert(PGLOBAL g, int newtype)
{
if (Value->GetType() != newtype)
if (!(Value = AllocateValue(g, Value, newtype)))
- longjmp(g->jumper[g->jump_level], TYPE_CONST);
+ throw TYPE_CONST;
} // end of Convert
@@ -173,18 +173,18 @@ bool CONSTANT::Rephrase(PGLOBAL g, PSZ work)
/***********************************************************************/
/* Make file output of a constant object. */
/***********************************************************************/
-void CONSTANT::Print(PGLOBAL g, FILE *f, uint n)
+void CONSTANT::Printf(PGLOBAL g, FILE *f, uint n)
{
- Value->Print(g, f, n);
- } /* end of Print */
+ Value->Printf(g, f, n);
+ } /* end of Printf */
/***********************************************************************/
/* Make string output of a constant object. */
/***********************************************************************/
-void CONSTANT::Print(PGLOBAL g, char *ps, uint z)
+void CONSTANT::Prints(PGLOBAL g, char *ps, uint z)
{
- Value->Print(g, ps, z);
- } /* end of Print */
+ Value->Prints(g, ps, z);
+ } /* end of Prints */
/* -------------------------- Class STRING --------------------------- */
@@ -192,7 +192,7 @@ void CONSTANT::Print(PGLOBAL g, char *ps, uint z)
/* STRING public constructor for new char values. Alloc Size must be */
/* calculated because PlugSubAlloc rounds up size to multiple of 8. */
/***********************************************************************/
-STRING::STRING(PGLOBAL g, uint n, char *str)
+STRING::STRING(PGLOBAL g, uint n, PCSZ str)
{
G = g;
Length = (str) ? strlen(str) : 0;
@@ -205,10 +205,12 @@ STRING::STRING(PGLOBAL g, uint n, char *str)
Next = GetNext();
Size = Next - Strp;
+ Trc = false;
} else {
// This should normally never happen
Next = NULL;
Size = 0;
+ Trc = true;
} // endif Strp
} // end of STRING constructor
@@ -229,6 +231,7 @@ char *STRING::Realloc(uint len)
if (!p) {
// No more room in Sarea; this is very unlikely
strcpy(G->Message, "No more room in work area");
+ Trc = true;
return NULL;
} // endif p
@@ -243,7 +246,7 @@ char *STRING::Realloc(uint len)
/***********************************************************************/
/* Set a STRING new PSZ value. */
/***********************************************************************/
-bool STRING::Set(PSZ s)
+bool STRING::Set(PCSZ s)
{
if (!s)
return false;
@@ -333,9 +336,9 @@ bool STRING::Append(const char *s, uint ln, bool nq)
} // end of Append
/***********************************************************************/
-/* Append a PSZ to a STRING. */
+/* Append a PCSZ to a STRING. */
/***********************************************************************/
-bool STRING::Append(PSZ s)
+bool STRING::Append(PCSZ s)
{
if (!s)
return false;
@@ -392,11 +395,11 @@ bool STRING::Append(char c)
/***********************************************************************/
/* Append a quoted PSZ to a STRING. */
/***********************************************************************/
-bool STRING::Append_quoted(PSZ s)
+bool STRING::Append_quoted(PCSZ s)
{
bool b = Append('\'');
- if (s) for (char *p = s; !b && *p; p++)
+ if (s) for (const char *p = s; !b && *p; p++)
switch (*p) {
case '\'':
case '\\':
diff --git a/storage/connect/xobject.h b/storage/connect/xobject.h
index 8f6c23c4aeb..bc5912d3054 100644
--- a/storage/connect/xobject.h
+++ b/storage/connect/xobject.h
@@ -112,8 +112,8 @@ class DllExport CONSTANT : public XOBJECT {
{return Value->SetConstFormat(g, fmt);}
void Convert(PGLOBAL g, int newtype);
void SetValue(PVAL vp) {Value = vp;}
- virtual void Print(PGLOBAL g, FILE *, uint);
- virtual void Print(PGLOBAL g, char *, uint);
+ virtual void Printf(PGLOBAL g, FILE *, uint);
+ virtual void Prints(PGLOBAL g, char *, uint);
}; // end of class CONSTANT
/***********************************************************************/
@@ -123,24 +123,25 @@ class DllExport CONSTANT : public XOBJECT {
class DllExport STRING : public BLOCK {
public:
// Constructor
- STRING(PGLOBAL g, uint n, PSZ str = NULL);
+ STRING(PGLOBAL g, uint n, PCSZ str = NULL);
// Implementation
inline int GetLength(void) {return (int)Length;}
inline void SetLength(uint n) {Length = n;}
inline PSZ GetStr(void) {return Strp;}
inline uint32 GetSize(void) {return Size;}
+ inline bool IsTruncated(void) {return Trc;}
// Methods
inline void Reset(void) {*Strp = 0;}
- bool Set(PSZ s);
+ bool Set(PCSZ s);
bool Set(char *s, uint n);
bool Append(const char *s, uint ln, bool nq = false);
- bool Append(PSZ s);
+ bool Append(PCSZ s);
bool Append(STRING &str);
bool Append(char c);
bool Resize(uint n);
- bool Append_quoted(PSZ s);
+ bool Append_quoted(PCSZ s);
inline void Trim(void) {(void)Resize(Length + 1);}
inline void Chop(void) {if (Length) Strp[--Length] = 0;}
inline void RepLast(char c) {if (Length) Strp[Length-1] = c;}
@@ -156,6 +157,7 @@ class DllExport STRING : public BLOCK {
PSZ Strp; // The char string
uint Length; // String length
uint Size; // Allocated size
+ bool Trc; // When truncated
char *Next; // Next alloc position
}; // end of class STRING
diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h
index 4aeea05946a..ebef7a2549a 100644
--- a/storage/connect/xtable.h
+++ b/storage/connect/xtable.h
@@ -33,29 +33,6 @@ class CMD : public BLOCK {
char *Cmd;
}; // end of class CMD
-#if 0
-// Condition filter structure
-class CONDFIL : public BLOCK {
- public:
- // Constructor
- CONDFIL(const Item *cond, uint idx, AMT type)
- {
- Cond = cond; Idx = idx; Type = type; Op = OP_XX;
- Cmds = NULL; All = true; Body = NULL, Having = NULL;
- }
-
- // Members
- const Item *Cond;
- AMT Type;
- uint Idx;
- OPVAL Op;
- PCMD Cmds;
- bool All;
- char *Body;
- char *Having;
-}; // end of class CONDFIL
-#endif // 0
-
typedef class EXTCOL *PEXTCOL;
typedef class CONDFIL *PCFIL;
typedef class TDBCAT *PTDBCAT;
@@ -84,7 +61,6 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
inline PFIL GetFilter(void) {return To_Filter;}
inline PCOL GetSetCols(void) {return To_SetCols;}
inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
- inline void SetFilter(PFIL fp) {To_Filter = fp;}
inline void SetOrig(PTDB txp) {To_Orig = txp;}
inline void SetUse(TUSE n) {Use = n;}
inline void SetCondFil(PCFIL cfp) {To_CondFil = cfp;}
@@ -94,11 +70,14 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
inline void SetColumns(PCOL colp) {Columns = colp;}
inline void SetDegree(int degree) {Degree = degree;}
inline void SetMode(MODE mode) {Mode = mode;}
+ inline const Item *GetCond(void) {return Cond;}
+ inline void SetCond(const Item *cond) {Cond = cond;}
// Properties
virtual AMT GetAmType(void) {return TYPE_AM_ERROR;}
virtual bool IsRemote(void) {return false;}
virtual bool IsIndexed(void) {return false;}
+ virtual void SetFilter(PFIL fp) {To_Filter = fp;}
virtual int GetTdb_No(void) {return Tdb_No;}
virtual PTDB GetNext(void) {return Next;}
virtual PCATLG GetCat(void) {return NULL;}
@@ -110,7 +89,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
virtual bool IsSpecial(PSZ name);
virtual bool IsReadOnly(void) {return Read_Only;}
virtual bool IsView(void) {return FALSE;}
- virtual PSZ GetPath(void);
+ virtual PCSZ GetPath(void);
virtual RECFM GetFtype(void) {return RECFM_NAF;}
virtual bool GetBlockValues(PGLOBAL) { return false; }
virtual int Cardinality(PGLOBAL) {return 0;}
@@ -119,19 +98,20 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
virtual int GetMaxSize(PGLOBAL) = 0;
virtual int GetProgMax(PGLOBAL) = 0;
virtual int GetProgCur(void) {return GetRecpos();}
- virtual PSZ GetFile(PGLOBAL) {return "Not a file";}
- virtual void SetFile(PGLOBAL, PSZ) {}
+ virtual PCSZ GetFile(PGLOBAL) {return "Not a file";}
+ virtual void SetFile(PGLOBAL, PCSZ) {}
virtual void ResetDB(void) {}
virtual void ResetSize(void) {MaxSize = -1;}
virtual int RowNumber(PGLOBAL g, bool b = false);
+ virtual bool CanBeFiltered(void) {return true;}
virtual PTDB Duplicate(PGLOBAL) {return NULL;}
virtual PTDB Clone(PTABS) {return this;}
virtual PTDB Copy(PTABS t);
virtual void PrintAM(FILE *f, char *m)
{fprintf(f, "%s AM(%d)\n", m, GetAmType());}
- virtual void Print(PGLOBAL g, FILE *f, uint n);
- virtual void Print(PGLOBAL g, char *ps, uint z);
- virtual PSZ GetServer(void) = 0;
+ virtual void Printf(PGLOBAL g, FILE *f, uint n);
+ virtual void Prints(PGLOBAL g, char *ps, uint z);
+ virtual PCSZ GetServer(void) = 0;
virtual int GetBadLines(void) {return 0;}
virtual CHARSET_INFO *data_charset(void);
@@ -157,6 +137,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
TUSE Use;
PFIL To_Filter;
PCFIL To_CondFil; // To condition filter structure
+ const Item *Cond; // The condition used to make filters
static int Tnum; // Used to generate Tdb_no's
const int Tdb_No; // GetTdb_No() is always 0 for OPJOIN
PTDB Next; // Next in linearized queries
@@ -187,9 +168,6 @@ class DllExport TDBASE : public TDB {
// Implementation
inline int GetKnum(void) {return Knum;}
-//inline PTABDEF GetDef(void) {return To_Def;}
-//inline PCOL GetSetCols(void) {return To_SetCols;}
-//inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
inline void SetKey_Col(PCOL *cpp) {To_Key_Col = cpp;}
inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;}
inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;}
@@ -201,36 +179,14 @@ class DllExport TDBASE : public TDB {
// Methods
virtual bool IsUsingTemp(PGLOBAL) {return false;}
-//virtual bool IsIndexed(void) {return false;}
-//virtual bool IsSpecial(PSZ name);
virtual PCATLG GetCat(void);
-//virtual PSZ GetPath(void);
virtual void PrintAM(FILE *f, char *m);
-//virtual RECFM GetFtype(void) {return RECFM_NAF;}
-//virtual int GetAffectedRows(void) {return -1;}
-//virtual int GetRecpos(void) = 0;
-//virtual bool SetRecpos(PGLOBAL g, int recpos);
-//virtual bool IsReadOnly(void) {return Read_Only;}
-//virtual bool IsView(void) {return FALSE;}
-//virtual CHARSET_INFO *data_charset(void);
virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);}
-//virtual int GetProgCur(void) {return GetRecpos();}
-//virtual PSZ GetFile(PGLOBAL) {return "Not a file";}
-//virtual int GetRemote(void) {return 0;}
-//virtual void SetFile(PGLOBAL, PSZ) {}
-//virtual void ResetDB(void) {}
-//virtual void ResetSize(void) {MaxSize = -1;}
virtual void RestoreNrec(void) {}
virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox);
- virtual PSZ GetServer(void) {return "Current";}
+ virtual PCSZ GetServer(void) {return "Current";}
// Database routines
-//virtual PCOL ColDB(PGLOBAL g, PSZ name, int num);
-//virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int)
-// {assert(false); return NULL;}
-//virtual PCOL InsertSpecialColumn(PCOL colp);
-//virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
-//virtual void MarkDB(PGLOBAL g, PTDB tdb2);
virtual int MakeIndex(PGLOBAL g, PIXDEF, bool)
{strcpy(g->Message, "Remote index"); return RC_INFO;}
virtual bool ReadKey(PGLOBAL, OPVAL, const key_range *)
@@ -241,18 +197,12 @@ class DllExport TDBASE : public TDB {
"This function should not be called for this table"); return true;}
// Members
-//PTABDEF To_Def; // Points to catalog description block
PXOB *To_Link; // Points to column of previous relations
PCOL *To_Key_Col; // Points to key columns in current file
PKXBASE To_Kindex; // Points to table key index
PIXDEF To_Xdp; // To the index definition block
-//PCOL To_SetCols; // Points to updated columns
RECFM Ftype; // File type: 0-var 1-fixed 2-binary (VCT)
-//int MaxSize; // Max size in number of lines
int Knum; // Size of key arrays
-//bool Read_Only; // True for read only tables
-//const CHARSET_INFO *m_data_charset;
-//const char *csname; // Table charset name
}; // end of class TDBASE
/***********************************************************************/