summaryrefslogtreecommitdiff
path: root/storage/connect
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-12-16 07:47:17 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-12-16 07:47:17 +0200
commit28c89b7151bc3ebd7a3459e85f4c9b5e73529629 (patch)
treece50324e5d1054f59a7178bfdb426189998baf52 /storage/connect
parent745fd4b39f8aff6300682502ed2ddf61ee343866 (diff)
parent8fa759a5762733d9f8a4050437fadcd255ecd1a2 (diff)
downloadmariadb-git-28c89b7151bc3ebd7a3459e85f4c9b5e73529629.tar.gz
Merge 10.4 into 10.5
Diffstat (limited to 'storage/connect')
-rw-r--r--storage/connect/CMakeLists.txt11
-rw-r--r--storage/connect/connect.cc64
-rw-r--r--storage/connect/connect.h2
-rw-r--r--storage/connect/filamzip.cpp2
-rw-r--r--storage/connect/filter.h1
-rw-r--r--storage/connect/ha_connect.cc35
-rw-r--r--storage/connect/inihandl.cpp2
-rw-r--r--storage/connect/javaconn.cpp2
-rw-r--r--storage/connect/mycat.cc115
-rw-r--r--storage/connect/mycat.h4
-rw-r--r--storage/connect/myconn.cpp10
-rw-r--r--storage/connect/plgdbsem.h29
-rw-r--r--storage/connect/reldef.cpp278
-rw-r--r--storage/connect/reldef.h9
-rw-r--r--storage/connect/restget.cpp40
-rw-r--r--storage/connect/tabcmg.cpp23
-rw-r--r--storage/connect/tabdos.cpp23
-rw-r--r--storage/connect/tabdos.h1
-rw-r--r--storage/connect/tabfix.cpp2
-rw-r--r--storage/connect/tabfmt.cpp5
-rw-r--r--storage/connect/tabjson.cpp44
-rw-r--r--storage/connect/tabmysql.cpp9
-rw-r--r--storage/connect/tabrest.cpp112
-rw-r--r--storage/connect/tabrest.h19
-rw-r--r--storage/connect/tabutil.cpp16
-rw-r--r--storage/connect/tabutil.h3
-rw-r--r--storage/connect/tabvct.cpp3
-rw-r--r--storage/connect/tabxml.cpp4
-rw-r--r--storage/connect/xindex.cpp14
-rw-r--r--storage/connect/xtable.h5
30 files changed, 534 insertions, 353 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index e5b0771afb3..4ce5b9c6429 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -314,6 +314,9 @@ ENDIF(CONNECT_WITH_MONGO)
OPTION(CONNECT_WITH_REST "Compile CONNECT storage engine with REST support" ON)
IF(CONNECT_WITH_REST)
+ MESSAGE(STATUS "=====> REST support is ON")
+ SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp tabrest.h)
+ add_definitions(-DREST_SUPPORT)
FIND_PACKAGE(cpprestsdk QUIET)
IF (cpprestsdk_FOUND)
IF(UNIX)
@@ -327,10 +330,10 @@ IF(CONNECT_WITH_REST)
# Comment it out if not needed depending on your cpprestsdk installation.
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
ENDIF(UNIX)
- IF(REST_LIBRARY)
- SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp restget.cpp tabrest.h)
- add_definitions(-DREST_SUPPORT)
- ENDIF()
+# IF(REST_LIBRARY) why this? how about Windows
+ SET(CONNECT_SOURCES ${CONNECT_SOURCES} restget.cpp)
+ add_definitions(-DREST_SOURCE)
+# ENDIF()
ELSE(NOT cpprestsdk_FOUND)
# MESSAGE(STATUS "=====> cpprestsdk package not found")
ENDIF (cpprestsdk_FOUND)
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 28345b85c42..e7681c3bdab 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -566,7 +566,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
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);
+ rc = ((PTDBDOS)tdbp)->GetTxfp()->UpdateSortedRows(g);
switch (rc) {
case RC_FX:
@@ -593,7 +593,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
if (!tdbp->IsRemote()) {
// Make all the eventual indexes
- PTDBDOX tbxp = (PTDBDOX)tdbp;
+ PTDBDOS tbxp = (PTDBDOS)tdbp;
tbxp->ResetKindex(g, NULL);
tbxp->SetKey_Col(NULL);
rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1);
@@ -622,8 +622,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted)
{
PIXDEF xdp;
- PTDBDOX tdbp;
- DOXDEF *dfp;
+ PTDBDOS tdbp;
+ DOSDEF *dfp;
if (!ptdb)
return -1;
@@ -633,9 +633,9 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted)
} else if (ptdb->GetDef()->Indexable() == 3) {
return 1;
} else
- tdbp= (PTDBDOX)ptdb;
+ tdbp= (PTDBDOS)ptdb;
- dfp= (DOXDEF*)tdbp->To_Def;
+ dfp= (DOSDEF*)tdbp->GetDef();
//if (!(k= colp->GetKey()))
// if (colp->GetOpt() >= 2) {
@@ -645,17 +645,17 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted)
// This is a pseudo indexed sorted block optimized column
// return 0;
- if (tdbp->To_Kindex) {
- if (((XXBASE*)tdbp->To_Kindex)->GetID() == id) {
- tdbp->To_Kindex->Reset(); // Same index
- return (tdbp->To_Kindex->IsMul()) ? 2 : 1;
+ if (tdbp->GetKindex()) {
+ if (((XXBASE*)tdbp->GetKindex())->GetID() == id) {
+ tdbp->GetKindex()->Reset(); // Same index
+ return (tdbp->GetKindex()->IsMul()) ? 2 : 1;
} else {
- tdbp->To_Kindex->Close();
- tdbp->To_Kindex= NULL;
+ tdbp->GetKindex()->Close();
+ tdbp->SetKindex(NULL);
} // endif colp
}
- for (xdp= dfp->To_Indx; xdp; xdp= xdp->GetNext())
+ for (xdp= dfp->GetIndx(); xdp; xdp= xdp->GetNext())
if (xdp->GetID() == id)
break;
@@ -677,7 +677,7 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted)
if (tdbp->InitialyzeIndex(g, xdp, sorted))
return 0;
- return (tdbp->To_Kindex->IsMul()) ? 2 : 1;
+ return (tdbp->GetKindex()->IsMul()) ? 2 : 1;
} // end of CntIndexInit
#if defined(WORDS_BIGENDIAN)
@@ -711,7 +711,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
int n, x;
RCODE rc;
XXBASE *xbp;
- PTDBDOX tdbp;
+ PTDBDOS tdbp;
if (!ptdb)
return RC_FX;
@@ -737,12 +737,12 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
goto rnd;
} else
- tdbp= (PTDBDOX)ptdb;
+ tdbp= (PTDBDOS)ptdb;
// Set reference values and index operator
- if (!tdbp->To_Link || !tdbp->To_Kindex) {
+ if (!tdbp->GetLink() || !tdbp->GetKindex()) {
// if (!tdbp->To_Xdp) {
- sprintf(g->Message, "Index not initialized for table %s", tdbp->Name);
+ sprintf(g->Message, "Index not initialized for table %s", tdbp->GetName());
return RC_FX;
#if 0
} // endif !To_Xdp
@@ -755,7 +755,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
#endif // 0
} // endif !To_Kindex
- xbp= (XXBASE*)tdbp->To_Kindex;
+ xbp= (XXBASE*)tdbp->GetKindex();
if (kr) {
char *kp= (char*)kr->key;
@@ -765,13 +765,13 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
PVAL valp;
PCOL colp;
- for (n= 0; n < tdbp->Knum; n++) {
- colp= (PCOL)tdbp->To_Key_Col[n];
+ for (n= 0; n < tdbp->GetKnum(); n++) {
+ colp= (PCOL)tdbp->Key(n);
if (colp->GetColUse(U_NULLS))
kp++; // Skip null byte
- valp= tdbp->To_Link[n]->GetValue();
+ valp= tdbp->Link(n)->GetValue();
if (!valp->IsTypeNum()) {
if (colp->GetColUse(U_VAR)) {
@@ -841,7 +841,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
bool b, rcb;
PVAL valp;
PCOL colp;
- PTDBDOX tdbp;
+ PTDBDOS tdbp;
XXBASE *xbp;
if (!ptdb)
@@ -866,35 +866,35 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
return k[1] - k[0] + 1;
} else
- tdbp= (PTDBDOX)ptdb;
+ tdbp= (PTDBDOS)ptdb;
- if (!tdbp->To_Kindex || !tdbp->To_Link) {
- if (!tdbp->To_Xdp) {
- sprintf(g->Message, "Index not initialized for table %s", tdbp->Name);
+ if (!tdbp->GetKindex() || !tdbp->GetLink()) {
+ if (!tdbp->GetXdp()) {
+ sprintf(g->Message, "Index not initialized for table %s", tdbp->GetName());
DBUG_PRINT("Range", ("%s", g->Message));
return -1;
} else // Dynamic index
- return tdbp->To_Xdp->GetMaxSame(); // TODO a better estimate
+ return tdbp->GetXdp()->GetMaxSame(); // TODO a better estimate
} else
- xbp= (XXBASE*)tdbp->To_Kindex;
+ xbp= (XXBASE*)tdbp->GetKindex();
for (b= false, i= 0; i < 2; i++) {
p= kp= key[i];
if (kp) {
- for (n= 0; n < tdbp->Knum; n++) {
+ for (n= 0; n < tdbp->GetKnum(); n++) {
if (kmap[i] & (key_part_map)(1 << n)) {
if (b == true)
// Cannot do indexing with missing intermediate key
return -1;
- colp= (PCOL)tdbp->To_Key_Col[n];
+ colp= (PCOL)tdbp->Key(n);
if (colp->GetColUse(U_NULLS))
p++; // Skip null byte ???
- valp= tdbp->To_Link[n]->GetValue();
+ valp= tdbp->Link(n)->GetValue();
if (!valp->IsTypeNum()) {
if (colp->GetColUse(U_VAR)) {
diff --git a/storage/connect/connect.h b/storage/connect/connect.h
index 3a60cd40160..d1fc2ea592f 100644
--- a/storage/connect/connect.h
+++ b/storage/connect/connect.h
@@ -46,6 +46,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
bool *incl, key_part_map *kmap);
PGLOBAL CntExit(PGLOBAL g);
+#if 0
/***********************************************************************/
/* Definition of classes XKPDEF, DOXDEF, TDBDOX */
/* These classes purpose is chiefly to access protected items! */
@@ -76,3 +77,4 @@ class XKPDEF: public KPARTDEF {
public:
XKPDEF(const char *name, int n) : KPARTDEF((PSZ)name, n) {}
}; // end of class XKPDEF
+#endif // 0
diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp
index b778c4971e9..e1f18b61ce1 100644
--- a/storage/connect/filamzip.cpp
+++ b/storage/connect/filamzip.cpp
@@ -699,7 +699,7 @@ bool UNZIPUTL::openEntry(PGLOBAL g)
} // endif rc
if (trace(1))
- htrc("Openning entry%s %s\n", fn, (entryopen) ? "oked" : "failed");
+ htrc("Opening entry%s %s\n", fn, (entryopen) ? "oked" : "failed");
return !entryopen;
} // end of openEntry
diff --git a/storage/connect/filter.h b/storage/connect/filter.h
index b0fea3d69e0..c6ab8fddd35 100644
--- a/storage/connect/filter.h
+++ b/storage/connect/filter.h
@@ -48,7 +48,6 @@ class DllExport FILTER : public XOBJECT { /* Filter description block */
PVAL &Val(int i) {return Test[i].Value;}
bool &Conv(int i) {return Test[i].Conv;}
void SetNext(PFIL filp) {Next = filp;}
- bool MakeSelector(PGLOBAL g, PSTRG s);
// Methods
virtual void Reset(void);
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index e098faaf995..4937350839d 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -170,9 +170,9 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.06.0010 June 01, 2019";
+ char version[]= "Version 1.07.0001 November 12, 2019";
#if defined(__WIN__)
- char compver[]= "Version 1.06.0010 " __DATE__ " " __TIME__;
+ char compver[]= "Version 1.07.0001 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !__WIN__
char slash= '/';
@@ -704,9 +704,9 @@ DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir)
used by the default rename_table and delete_table method in
handler.cc.
- For engines that have two file name extentions (separate meta/index file
+ For engines that have two file name extensions (separate meta/index file
and data file), the order of elements is relevant. First element of engine
- file name extentions array should be meta/index file extention. Second
+ file name extensions array should be meta/index file extention. Second
element - data file extention. This order is assumed by
prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued.
@@ -1042,6 +1042,8 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
case TAB_REST:
type = TAB_NIY;
break;
+ default:
+ break;
} // endswitch type
#endif // REST_SUPPORT
@@ -2963,9 +2965,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
case Item_func::GE_FUNC: vop= OP_GE; break;
case Item_func::GT_FUNC: vop= OP_GT; break;
case Item_func::LIKE_FUNC:
- vop= OP_LIKE;
- neg= ((Item_func_opt_neg *)condf)->negated;
- break;
+ vop = OP_LIKE;
+ neg= ((Item_func_like*)condf)->negated;
+ break;
case Item_func::ISNOTNULL_FUNC:
neg= true;
// fall through
@@ -3780,9 +3782,9 @@ int ha_connect::index_init(uint idx, bool sorted)
active_index= MAX_KEY;
rc= HA_ERR_INTERNAL_ERROR;
} else if (tdbp->GetKindex()) {
- if (((PTDBDOX)tdbp)->To_Kindex->GetNum_K()) {
+ if (((PTDBDOS)tdbp)->GetKindex()->GetNum_K()) {
if (tdbp->GetFtype() != RECFM_NAF)
- ((PTDBDOX)tdbp)->GetTxfp()->ResetBuffer(g);
+ ((PTDBDOS)tdbp)->GetTxfp()->ResetBuffer(g);
active_index= idx;
// } else { // Void table
@@ -5626,6 +5628,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case TAB_CSV:
ttp = TAB_REST;
break;
+ default:
+ break;
} // endswitch type
#endif // REST_SUPPORT
} // endif ttp
@@ -6036,7 +6040,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
} // endif !nblin
for (i= 0; !rc && i < qrp->Nblin; i++) {
- typ= len= prec= dec= 0;
+ typ= len= prec= dec= flg= 0;
tm= NOT_NULL_FLAG;
cnm= (char*)"noname";
dft= xtra= key= fmt= tn= NULL;
@@ -6077,6 +6081,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
tm= 0; // Nullable
break;
+ case FLD_FLAG:
+ flg = crp->Kdata->GetIntValue(i);
+ break;
case FLD_FORMAT:
fmt= (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL;
break;
@@ -6207,7 +6214,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
// Now add the field
if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
- fmt, 0, dbf, v))
+ fmt, flg, dbf, v))
rc= HA_ERR_OUT_OF_MEM;
} // endfor i
@@ -7355,14 +7362,14 @@ maria_declare_plugin(connect)
&connect_storage_engine,
"CONNECT",
"Olivier Bertrand",
- "Management of External Data (SQL/NOSQL/MED), including many file formats",
+ "Management of External Data (SQL/NOSQL/MED), including Rest query results",
PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */
- 0x0106, /* version number (1.06) */
+ 0x0107, /* version number (1.07) */
NULL, /* status variables */
connect_system_variables, /* system variables */
- "1.06.0010", /* string version */
+ "1.07.0001", /* string version */
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/connect/inihandl.cpp b/storage/connect/inihandl.cpp
index ab6d5db4f0a..c39c94fb30d 100644
--- a/storage/connect/inihandl.cpp
+++ b/storage/connect/inihandl.cpp
@@ -192,7 +192,7 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section )
}
for (key = section->key; key; key = key->next)
- if (key->name && key->name[0]) {
+ if (key->name[0]) {
fprintf(file, "%s", SVP(key->name));
if (key->value)
diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp
index 5a4fe433121..8dc4add9f49 100644
--- a/storage/connect/javaconn.cpp
+++ b/storage/connect/javaconn.cpp
@@ -142,7 +142,7 @@ bool JAVAConn::Check(jint rc)
s = (jstring)env->CallObjectMethod(exc, tid);
Msg = GetUTFString(s);
} else
- Msg = "Exception occured";
+ Msg = "Exception occurred";
env->ExceptionClear();
} else if (rc < 0) {
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index 411e96e3dc8..f8b3dc03aa5 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -95,7 +95,7 @@
#endif // ZIP_SUPPORT
#if defined(REST_SUPPORT)
#include "tabrest.h"
-#endif // Rest_SUPPORT
+#endif // REST_SUPPORT
#include "mycat.h"
/***********************************************************************/
@@ -104,8 +104,9 @@
#if defined(__WIN__)
extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // !__WIN__
-
-PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
+#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
+bool MongoEnabled(void);
+#endif // JAVA_SUPPORT || CMGO_SUPPORT
/***********************************************************************/
/* Get the plugin directory. */
@@ -347,100 +348,6 @@ uint GetFuncID(const char *func)
return fnc;
} // end of GetFuncID
-/***********************************************************************/
-/* OEMColumn: Get table column info for an OEM table. */
-/***********************************************************************/
-PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info)
- {
- typedef PQRYRES (__stdcall *XCOLDEF) (PGLOBAL, void*, char*, char*, bool);
- const char *module, *subtype;
- char c, soname[_MAX_PATH], getname[40] = "Col";
-#if defined(__WIN__)
- HANDLE hdll; /* Handle to the external DLL */
-#else // !__WIN__
- void *hdll; /* Handle for the loaded shared library */
-#endif // !__WIN__
- XCOLDEF coldef = NULL;
- PQRYRES qrp = NULL;
-
- module = topt->module;
- subtype = topt->subtype;
-
- if (!module || !subtype)
- return NULL;
-
- /*********************************************************************/
- /* Ensure that the .dll doesn't have a path. */
- /* This is done to ensure that only approved dll from the system */
- /* directories are used (to make this even remotely secure). */
- /*********************************************************************/
- if (check_valid_path(module, strlen(module))) {
- strcpy(g->Message, "Module cannot contain a path");
- return NULL;
- } else
- PlugSetPath(soname, module, GetPluginDir());
-
- // The exported name is always in uppercase
- for (int i = 0; ; i++) {
- c = subtype[i];
- getname[i + 3] = toupper(c);
- if (!c) break;
- } // endfor i
-
-#if defined(__WIN__)
- // Load the Dll implementing the table
- if (!(hdll = LoadLibrary(soname))) {
- char buf[256];
- DWORD rc = GetLastError();
-
- sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
- (LPTSTR)buf, sizeof(buf), NULL);
- strcat(strcat(g->Message, ": "), buf);
- return NULL;
- } // endif hDll
-
- // Get the function returning an instance of the external DEF class
- if (!(coldef = (XCOLDEF)GetProcAddress((HINSTANCE)hdll, getname))) {
- sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname);
- FreeLibrary((HMODULE)hdll);
- return NULL;
- } // endif coldef
-#else // !__WIN__
- const char *error = NULL;
-
- // Load the desired shared library
- if (!(hdll = dlopen(soname, RTLD_LAZY))) {
- error = dlerror();
- sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
- return NULL;
- } // endif Hdll
-
- // Get the function returning an instance of the external DEF class
- if (!(coldef = (XCOLDEF)dlsym(hdll, getname))) {
- error = dlerror();
- sprintf(g->Message, MSG(GET_FUNC_ERR), getname, SVP(error));
- dlclose(hdll);
- return NULL;
- } // endif coldef
-#endif // !__WIN__
-
- // Just in case the external Get function does not set error messages
- sprintf(g->Message, "Error getting column info from %s", subtype);
-
- // Get the table column definition
- qrp = coldef(g, topt, tab, db, info);
-
-#if defined(__WIN__)
- FreeLibrary((HMODULE)hdll);
-#else // !__WIN__
- dlclose(hdll);
-#endif // !__WIN__
-
- return qrp;
- } // end of OEMColumns
-
/* ------------------------- Class CATALOG --------------------------- */
/***********************************************************************/
@@ -481,10 +388,10 @@ void MYCAT::Reset(void)
/* GetTableDesc: retrieve a table descriptor. */
/* Look for a table descriptor matching the name and type. */
/***********************************************************************/
-PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
+PTABDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
LPCSTR type, PRELDEF *)
{
- PRELDEF tdp= NULL;
+ PTABDEF tdp= NULL;
if (trace(1))
htrc("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type));
@@ -505,12 +412,12 @@ PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
/* MakeTableDesc: make a table/view description. */
/* Note: caller must check if name already exists before calling it. */
/***********************************************************************/
-PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
+PTABDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
{
TABTYPE tc;
LPCSTR name= (PSZ)PlugDup(g, tablep->GetName());
LPCSTR schema= (PSZ)PlugDup(g, tablep->GetSchema());
- PRELDEF tdp= NULL;
+ PTABDEF tdp= NULL;
if (trace(1))
htrc("MakeTableDesc: name=%s schema=%s am=%s\n",
@@ -578,8 +485,8 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
} // endswitch
// Do make the table/view definition
- if (tdp && tdp->Define(g, this, name, schema, am))
- tdp= NULL;
+ if (tdp && tdp->Define(g, this, name, schema, am))
+ tdp = NULL;
if (trace(1))
htrc("Table %s made\n", am);
@@ -592,7 +499,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
/***********************************************************************/
PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
{
- PRELDEF tdp;
+ PTABDEF tdp;
PTDB tdbp= NULL;
// LPCSTR name= tablep->GetName();
diff --git a/storage/connect/mycat.h b/storage/connect/mycat.h
index 818e535b32d..6473f7a5c11 100644
--- a/storage/connect/mycat.h
+++ b/storage/connect/mycat.h
@@ -102,14 +102,14 @@ class MYCAT : public CATALOG {
// Methods
void Reset(void);
bool StoreIndex(PGLOBAL, PTABDEF) {return false;} // Temporary
- PRELDEF GetTableDesc(PGLOBAL g, PTABLE tablep,
+ PTABDEF GetTableDesc(PGLOBAL g, PTABLE tablep,
LPCSTR type, PRELDEF *prp = NULL);
PTDB GetTable(PGLOBAL g, PTABLE tablep,
MODE mode = MODE_READ, LPCSTR type = NULL);
void ClearDB(PGLOBAL g);
protected:
- PRELDEF MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am);
+ PTABDEF MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am);
// Members
ha_connect *Hc; // The Connect handler
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index 448ee7dc782..e07270aff8a 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -472,7 +472,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
int pt, const char *csname)
{
const char *pipe = NULL;
- uint cto = 10, nrt = 20;
+ //uint cto = 10, nrt = 20;
my_bool my_true= 1;
m_DB = mysql_init(NULL);
@@ -485,11 +485,11 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
if (trace(1))
htrc("MYSQLC Open: m_DB=%.4X size=%d\n", m_DB, (int)sizeof(*m_DB));
- // Removed to do like FEDERATED do
+ // Removed to do like FEDERATED does
//mysql_options(m_DB, MYSQL_READ_DEFAULT_GROUP, "client-mariadb");
- mysql_options(m_DB, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL);
- mysql_options(m_DB, MYSQL_OPT_CONNECT_TIMEOUT, &cto);
- mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt);
+//mysql_options(m_DB, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL);
+//mysql_options(m_DB, MYSQL_OPT_CONNECT_TIMEOUT, &cto);
+//mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt);
//mysql_options(m_DB, MYSQL_OPT_WRITE_TIMEOUT, ...);
#if defined(__WIN__)
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index f10ae209e9d..a40e32bcfb2 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -149,16 +149,22 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_MGO = 194, /* 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 */
- RECFM_VAR = 0, /* Varying length DOS files */
- RECFM_FIX = 1, /* Fixed length DOS files */
- RECFM_BIN = 2, /* Binary DOS files (also fixed) */
- RECFM_VCT = 3, /* VCT formatted files */
- RECFM_ODBC = 4, /* Table accessed via ODBC */
- RECFM_JDBC = 5, /* Table accessed via JDBC */
- RECFM_PLG = 6, /* Table accessed via PLGconn */
- RECFM_DBF = 7}; /* DBase formatted file */
+enum RECFM {RECFM_DFLT = 0, /* Default table type */
+ RECFM_NAF = 1, /* Not a file table */
+ RECFM_OEM = 2, /* OEM table */
+ RECFM_VAR = 3, /* Varying length DOS files */
+ RECFM_FIX = 4, /* Fixed length DOS files */
+ RECFM_BIN = 5, /* Binary DOS files (also fixed) */
+ RECFM_DBF = 6, /* DBase formatted file */
+ RECFM_CSV = 7, /* CSV file */
+ RECFM_FMT = 8, /* FMT formatted file */
+ RECFM_VCT = 9, /* VCT formatted files */
+ RECFM_XML = 10, /* XML formatted files */
+ RECFM_JASON = 11, /* JASON formatted files */
+ RECFM_DIR = 12, /* DIR table */
+ RECFM_ODBC = 13, /* Table accessed via ODBC */
+ RECFM_JDBC = 14, /* Table accessed via JDBC */
+ RECFM_PLG = 15}; /* Table accessed via PLGconn */
enum MISC {DB_TABNO = 1, /* DB routines in Utility Table */
MAX_MULT_KEY = 10, /* Max multiple key number */
@@ -537,7 +543,8 @@ enum XFLD {FLD_NO = 0, /* Not a field definition item */
FLD_FORMAT = 16, /* Field format */
FLD_CAT = 17, /* Table catalog */
FLD_SCHEM = 18, /* Table schema */
- FLD_TABNAME = 19}; /* Column Table name */
+ FLD_TABNAME = 19, /* Column Table name */
+ FLD_FLAG = 20}; /* Field flag (CONNECT specific) */
/***********************************************************************/
/* Result of last SQL noconv query. */
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 8ba8aac3621..ffe5f77661d 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -1,11 +1,11 @@
/************* RelDef CPP Program Source Code File (.CPP) **************/
/* PROGRAM NAME: RELDEF */
/* ------------- */
-/* Version 1.6 */
+/* Version 1.7 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2004-2016 */
+/* (C) Copyright to the author Olivier BERTRAND 2004-2019 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -61,6 +61,102 @@ extern handlerton *connect_hton;
/***********************************************************************/
USETEMP UseTemp(void);
char *GetPluginDir(void);
+PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info);
+
+/***********************************************************************/
+/* OEMColumns: Get table column info for an OEM table. */
+/***********************************************************************/
+PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
+{
+ typedef PQRYRES(__stdcall* XCOLDEF) (PGLOBAL, void*, char*, char*, bool);
+ const char* module, * subtype;
+ char c, soname[_MAX_PATH], getname[40] = "Col";
+#if defined(__WIN__)
+ HANDLE hdll; /* Handle to the external DLL */
+#else // !__WIN__
+ void* hdll; /* Handle for the loaded shared library */
+#endif // !__WIN__
+ XCOLDEF coldef = NULL;
+ PQRYRES qrp = NULL;
+
+ module = topt->module;
+ subtype = topt->subtype;
+
+ if (!module || !subtype)
+ return NULL;
+
+ /*********************************************************************/
+ /* Ensure that the .dll doesn't have a path. */
+ /* This is done to ensure that only approved dll from the system */
+ /* directories are used (to make this even remotely secure). */
+ /*********************************************************************/
+ if (check_valid_path(module, strlen(module))) {
+ strcpy(g->Message, "Module cannot contain a path");
+ return NULL;
+ }
+ else
+ PlugSetPath(soname, module, GetPluginDir());
+
+ // The exported name is always in uppercase
+ for (int i = 0; ; i++) {
+ c = subtype[i];
+ getname[i + 3] = toupper(c);
+ if (!c) break;
+ } // endfor i
+
+#if defined(__WIN__)
+ // Load the Dll implementing the table
+ if (!(hdll = LoadLibrary(soname))) {
+ char buf[256];
+ DWORD rc = GetLastError();
+
+ sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
+ (LPTSTR)buf, sizeof(buf), NULL);
+ strcat(strcat(g->Message, ": "), buf);
+ return NULL;
+ } // endif hDll
+
+// Get the function returning an instance of the external DEF class
+ if (!(coldef = (XCOLDEF)GetProcAddress((HINSTANCE)hdll, getname))) {
+ sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname);
+ FreeLibrary((HMODULE)hdll);
+ return NULL;
+ } // endif coldef
+#else // !__WIN__
+ const char* error = NULL;
+
+ // Load the desired shared library
+ if (!(hdll = dlopen(soname, RTLD_LAZY))) {
+ error = dlerror();
+ sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
+ return NULL;
+ } // endif Hdll
+
+// Get the function returning an instance of the external DEF class
+ if (!(coldef = (XCOLDEF)dlsym(hdll, getname))) {
+ error = dlerror();
+ sprintf(g->Message, MSG(GET_FUNC_ERR), getname, SVP(error));
+ dlclose(hdll);
+ return NULL;
+ } // endif coldef
+#endif // !__WIN__
+
+ // Just in case the external Get function does not set error messages
+ sprintf(g->Message, "Error getting column info from %s", subtype);
+
+ // Get the table column definition
+ qrp = coldef(g, topt, tab, db, info);
+
+#if defined(__WIN__)
+ FreeLibrary((HMODULE)hdll);
+#else // !__WIN__
+ dlclose(hdll);
+#endif // !__WIN__
+
+ return qrp;
+} // end of OEMColumns
/* --------------------------- Class RELDEF -------------------------- */
@@ -208,6 +304,7 @@ TABDEF::TABDEF(void)
{
Schema = NULL;
Desc = NULL;
+ Recfm = RECFM_DFLT;
Catfunc = FNC_NO;
Card = 0;
Elemt = 0;
@@ -221,11 +318,40 @@ TABDEF::TABDEF(void)
} // end of TABDEF constructor
/***********************************************************************/
+/* Return the table format. */
+/***********************************************************************/
+RECFM TABDEF::GetTableFormat(const char* type)
+{
+ RECFM recfm = Recfm;
+
+ if (recfm == RECFM_DFLT) {
+ // Default format depends on the table type
+ TABTYPE tc = (Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
+
+ switch (tc) {
+ case TAB_DOS: recfm = RECFM_VAR; break;
+ case TAB_CSV: recfm = RECFM_CSV; break;
+ case TAB_FMT: recfm = RECFM_FMT; break;
+ case TAB_FIX: recfm = RECFM_FIX; break;
+ case TAB_BIN: recfm = RECFM_BIN; break;
+ case TAB_VEC: recfm = RECFM_VCT; break;
+ case TAB_DBF: recfm = RECFM_DBF; break;
+ case TAB_XML: recfm = RECFM_XML; break;
+ case TAB_DIR: recfm = RECFM_DIR; break;
+ default: recfm = RECFM_NAF; break;
+ } // endswitch type
+
+ } // endif recfm
+
+ return recfm;
+} // end of GetTableFormat
+
+/***********************************************************************/
/* Define: initialize the table definition block from XDB file. */
/***********************************************************************/
bool TABDEF::Define(PGLOBAL g, PCATLG cat,
LPCSTR name, LPCSTR schema, LPCSTR am)
- {
+{
int poff = 0;
Hc = ((MYCAT*)cat)->GetHandler();
@@ -243,13 +369,17 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat,
NULL;
csname = GetStringCatInfo(g, "Table_charset", NULL);
- // Get The column definitions
- if ((poff = GetColCatInfo(g)) < 0)
- return true;
+ // Do the definition of AM specific fields
+ if (DefineAM(g, am, 0))
+ return true;
- // Do the definition of AM specific fields
- return DefineAM(g, am, poff);
- } // end of Define
+ // Get The column definitions
+ if (stricmp(am, "OEM") && GetColCatInfo(g) < 0)
+ return true;
+
+ Hc->tshp = NULL; // TO BE CHECKED
+ return false;
+} // end of Define
/***********************************************************************/
/* This function returns the database data path. */
@@ -264,71 +394,71 @@ PCSZ TABDEF::GetPath(void)
/***********************************************************************/
int TABDEF::GetColCatInfo(PGLOBAL g)
{
- char *type= GetStringCatInfo(g, "Type", "*");
+ char *type = GetStringCatInfo(g, "Type", "*");
char c, fty, eds;
int i, n, loff, poff, nof, nlg;
- void *field= NULL;
- TABTYPE tc;
- PCOLDEF cdp, lcdp= NULL, tocols= NULL;
+ void *field = NULL;
+ RECFM trf;
+ PCOLDEF cdp, lcdp = NULL, tocols= NULL;
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
memset(pcf, 0, sizeof(COLINFO));
- // Get a unique char identifier for type
- tc= (Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
+ // Get the table format
+ trf = GetTableFormat(type);
// 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= (trf == RECFM_DBF) ? 1 : (trf == RECFM_XML || trf == RECFM_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;
+ loff = (trf == RECFM_DBF || trf == RECFM_DIR) ? 1 : (trf == RECFM_XML) ? -1 : 0;
#endif // !__WIN__
while (true) {
- // Default Offset depends on table type
- switch (tc) {
- case TAB_DOS:
- case TAB_FIX:
- case TAB_BIN:
- case TAB_VEC:
- case TAB_DBF:
+ // Default Offset depends on table format
+ switch (trf ) {
+ case RECFM_VAR:
+ case RECFM_FIX:
+ case RECFM_BIN:
+ case RECFM_VCT:
+ case RECFM_DBF:
poff= loff + nof; // Default next offset
nlg= MY_MAX(nlg, poff); // Default lrecl
break;
- case TAB_CSV:
- case TAB_FMT:
+ case RECFM_CSV:
+ case RECFM_FMT:
nlg+= nof;
- case TAB_DIR:
- case TAB_XML:
+ case RECFM_DIR:
+ case RECFM_XML:
poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1);
break;
- case TAB_INI:
- case TAB_MAC:
- case TAB_TBL:
- case TAB_XCL:
- case TAB_OCCUR:
- case TAB_PRX:
- case TAB_OEM:
+ //case RECFM_INI:
+ //case RECFM_MAC:
+ //case RECFM_TBL:
+ //case RECFM_XCL:
+ //case RECFM_OCCUR:
+ //case RECFM_PRX:
+ case RECFM_OEM:
poff = 0; // Offset represents an independant flag
break;
- default: // VCT PLG ODBC JDBC MYSQL WMI...
+ default: // PLG ODBC JDBC MYSQL WMI...
poff = 0; // NA
break;
- } // endswitch tc
+ } // endswitch trf
// do {
field= Hc->GetColumnOption(g, field, pcf);
// } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
- if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
+ if (trf == RECFM_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
// DBF date format defaults to 'YYYMMDD'
pcf->Datefmt= "YYYYMMDD";
pcf->Length= 8;
- } // endif tc
+ } // endif trf
if (!field)
break;
@@ -341,10 +471,10 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
else
loff= cdp->GetOffset();
- switch (tc) {
- case TAB_VEC:
+ switch (trf ) {
+ case RECFM_VCT:
cdp->SetOffset(0); // Not to have shift
- case TAB_BIN:
+ case RECFM_BIN:
// BIN/VEC are packed by default
if (nof) {
// Field width is the internal representation width
@@ -395,7 +525,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
default:
break;
- } // endswitch tc
+ } // endswitch trf
if (lcdp)
lcdp->SetNext(cdp);
@@ -413,21 +543,15 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
if (GetDefType() == TYPE_AM_DOS) {
int ending, recln= 0;
- // Was commented because sometimes ending is 0 even when
- // not specified (for instance if quoted is specified)
-// if ((ending= Hc->GetIntegerOption("Ending")) < 0) {
- if ((ending= Hc->GetIntegerOption("Ending")) <= 0) {
- ending= (tc == TAB_BIN || tc == TAB_VEC) ? 0 : CRLF;
- Hc->SetIntegerOption("Ending", ending);
- } // endif ending
+ ending = Hc->GetIntegerOption("Ending");
// Calculate the default record size
- switch (tc) {
- case TAB_FIX:
- case TAB_BIN:
+ switch (trf ) {
+ case RECFM_FIX:
+ case RECFM_BIN:
recln= nlg + ending; // + length of line ending
break;
- case TAB_VEC:
+ case RECFM_VCT:
recln= nlg;
// if ((k= (pak < 0) ? 8 : pak) > 1)
@@ -436,18 +560,18 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
// recln= ((recln + k - 1) / k) * k;
break;
- case TAB_DOS:
- case TAB_DBF:
+ case RECFM_VAR:
+ case RECFM_DBF:
recln= nlg;
break;
- case TAB_CSV:
- case TAB_FMT:
+ case RECFM_CSV:
+ case RECFM_FMT:
// The number of separators (assuming an extra one can exist)
// recln= poff * ((qotd) ? 3 : 1); to be investigated
recln= nlg + poff * 3; // To be safe
default:
break;
- } // endswitch tc
+ } // endswitch trf
// lrecl must be at least recln to avoid buffer overflow
if (trace(1))
@@ -461,7 +585,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
if (trace(1))
htrc("Lrecl set to %d\n", recln);
- } // endif Lrecl
+ } // endif TYPE
// Attach the column definition to the tabdef
SetCols(tocols);
@@ -500,7 +624,8 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
return NULL;
} else
// PlugSetPath(soname, Module, GetPluginDir()); // Crashes on Fedora
- strncat(strcpy(soname, GetPluginDir()), Module, _MAX_PATH);
+ strncat(strcpy(soname, GetPluginDir()), Module,
+ sizeof(soname) - strlen(soname) - 1);
#if defined(__WIN__)
// Is the DLL already loaded?
@@ -596,10 +721,6 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
cat->Cbuf = (char*)PlugSubAlloc(g, NULL, cat->Cblen);
} // endif Cbuf
- // Here "OEM" should be replace by a more useful value
- if (xdefp->Define(g, cat, Name, Schema, "OEM"))
- return NULL;
-
// Ok, return external block
return xdefp;
} // end of GetXdef
@@ -622,7 +743,7 @@ bool OEMDEF::DeleteTableFile(PGLOBAL g)
/***********************************************************************/
bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
{
- Module = GetStringCatInfo(g, "Module", "");
+ Module = GetStringCatInfo(g, "Module", "");
Subtype = GetStringCatInfo(g, "Subtype", Module);
if (!*Module)
@@ -632,7 +753,13 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
+ strlen(Subtype) + 3);
sprintf(desc, "%s(%s)", Module, Subtype);
Desc = desc;
- return false;
+
+ // If define block not here yet, get it now
+ if (!Pxdef && !(Pxdef = GetXdef(g)))
+ return true; // Error
+
+ // Here "OEM" should be replace by a more useful value
+ return Pxdef->Define(g, Cat, Name, Schema, Subtype);
} // end of DefineAM
/***********************************************************************/
@@ -640,7 +767,6 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
/***********************************************************************/
PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
{
- RECFM rfm;
PTDB tdbp = NULL;
// If define block not here yet, get it now
@@ -653,18 +779,10 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
/*********************************************************************/
if (!(tdbp = Pxdef->GetTable(g, mode)))
return NULL;
- else
- rfm = tdbp->GetFtype();
-
- if (rfm == RECFM_NAF)
- return tdbp;
- else if (rfm == RECFM_OEM) {
- if (Multiple)
- tdbp = new(g) TDBMUL(tdbp); // No block optimization yet
-
- return tdbp;
- } // endif OEM
+ else if (Multiple && tdbp->GetFtype() == RECFM_OEM)
+ tdbp = new(g) TDBMUL(tdbp); // No block optimization yet
+#if 0
/*********************************************************************/
/* The OEM table is based on a file type (currently DOS+ only) */
/*********************************************************************/
@@ -723,7 +841,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
if (Multiple)
tdbp = new(g) TDBMUL(tdbp);
-
+#endif // 0
return tdbp;
} // end of GetTable
diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h
index f8256a59b3d..73e178ed51c 100644
--- a/storage/connect/reldef.h
+++ b/storage/connect/reldef.h
@@ -84,10 +84,12 @@ public:
void SetNext(PTABDEF tdfp) {Next = tdfp;}
int GetMultiple(void) {return Multiple;}
int GetPseudo(void) {return Pseudo;}
- PCSZ GetPath(void);
+ RECFM GetRecfm(void) {return Recfm;}
+ PCSZ GetPath(void);
//PSZ GetPath(void)
// {return (Database) ? (PSZ)Database : Cat->GetDataPath();}
- bool SepIndex(void) {return GetBoolCatInfo("SepIndex", false);}
+ RECFM GetTableFormat(const char* type);
+ bool SepIndex(void) {return GetBoolCatInfo("SepIndex", false);}
bool IsReadOnly(void) {return Read_Only;}
virtual AMT GetDefType(void) {return TYPE_AM_TAB;}
virtual PIXDEF GetIndx(void) {return NULL;}
@@ -108,7 +110,8 @@ public:
// Members
PCSZ Schema; /* Table schema (for ODBC) */
PCSZ Desc; /* Table description */
- uint Catfunc; /* Catalog function ID */
+ RECFM Recfm; /* File or table format */
+ uint Catfunc; /* Catalog function ID */
int Card; /* (max) number of rows in table */
int Elemt; /* Number of rows in blocks or rowset */
int Sort; /* Table already sorted ??? */
diff --git a/storage/connect/restget.cpp b/storage/connect/restget.cpp
index 6b184ae6926..d85ec6ae693 100644
--- a/storage/connect/restget.cpp
+++ b/storage/connect/restget.cpp
@@ -4,12 +4,6 @@
/***********************************************************************/
#include <cpprest/filestream.h>
#include <cpprest/http_client.h>
-#if defined(MARIADB)
-#include <my_global.h>
-#else
-#include "mini-global.h"
-#define _OS_H_INCLUDED // Prevent os.h to be called
-#endif
using namespace utility::conversions; // String conversions utilities
using namespace web; // Common features like URIs.
@@ -17,24 +11,24 @@ using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features
using namespace concurrency::streams; // Asynchronous streams
-#include "global.h"
+typedef const char* PCSZ;
/***********************************************************************/
/* Make a local copy of the requested file. */
/***********************************************************************/
-int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
+int restGetFile(char *m, bool xt, PCSZ http, PCSZ uri, PCSZ fn)
{
int rc = 0;
- bool xt = trace(515);
auto fileStream = std::make_shared<ostream>();
if (!http || !fn) {
- strcpy(g->Message, "Missing http or filename");
- return 2;
+ //strcpy(g->Message, "Missing http or filename");
+ strcpy(m, "Missing http or filename");
+ return 2;
} // endif
if (xt)
- htrc("restGetFile: fn=%s\n", fn);
+ fprintf(stderr, "restGetFile: fn=%s\n", fn);
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(to_string_t(fn))
@@ -42,7 +36,7 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
*fileStream= outFile;
if (xt)
- htrc("Outfile isopen=%d\n", outFile.is_open());
+ fprintf(stderr, "Outfile isopen=%d\n", outFile.is_open());
// Create http_client to send the request.
http_client client(to_string_t(http));
@@ -58,8 +52,8 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
// Handle response headers arriving.
.then([=](http_response response) {
if (xt)
- htrc("Received response status code:%u\n",
- response.status_code());
+ fprintf(stderr, "Received response status code:%u\n",
+ response.status_code());
// Write response body into the file.
return response.body().read_to_end(fileStream->streambuf());
@@ -68,27 +62,27 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
// Close the file stream.
.then([=](size_t n) {
if (xt)
- htrc("Return size=%u\n", n);
+ fprintf(stderr, "Return size=%zu\n", n);
return fileStream->close();
});
// Wait for all the outstanding I/O to complete and handle any exceptions
try {
- requestTask.wait();
-
if (xt)
- htrc("In Wait\n");
+ fprintf(stderr, "Waiting\n");
+ requestTask.wait();
} catch (const std::exception &e) {
if (xt)
- htrc("Error exception: %s\n", e.what());
- sprintf(g->Message, "Error exception: %s", e.what());
- rc= 1;
+ fprintf(stderr, "Error exception: %s\n", e.what());
+
+ sprintf(m, "Error exception: %s", e.what());
+ rc= 1;
} // end try/catch
if (xt)
- htrc("restget done: rc=%d\n", rc);
+ fprintf(stderr, "restget done: rc=%d\n", rc);
return rc;
} // end of restGetFile
diff --git a/storage/connect/tabcmg.cpp b/storage/connect/tabcmg.cpp
index da1cfd34ac7..b9b7f6e4b60 100644
--- a/storage/connect/tabcmg.cpp
+++ b/storage/connect/tabcmg.cpp
@@ -53,25 +53,30 @@ bool CMGDISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
{
if (!doc || bson_iter_init(iter, doc)) {
const char *key;
- char colname[65];
- char fmt[129];
- bool newcol;
+ char colname[65];
+ char fmt[129];
+ bool newcol;
+ size_t n;
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);
+ n = sizeof(colname) - 1;
+ strncpy(colname, pcn, n);
+ colname[n] = 0;
+ n -= strlen(colname);
+ strncat(strncat(colname, "_", n), key, n - 1);
} else
strcpy(colname, key);
if (pfmt) {
- strncpy(fmt, pfmt, 128);
- fmt[128] = 0;
- strncat(strncat(fmt, ".", 129), key, 129);
+ n = sizeof(fmt) - 1;
+ strncpy(fmt, pfmt, n);
+ fmt[n] = 0;
+ n -= strlen(fmt);
+ strncat(strncat(fmt, ".", n), key, n - 1);
} else
strcpy(fmt, key);
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index b3cb510b5b9..c979d86e9ae 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -45,7 +45,7 @@
#include "global.h"
#include "osutil.h"
#include "plgdbsem.h"
-#include "catalog.h"
+//#include "catalog.h"
#include "mycat.h"
#include "xindex.h"
#include "filamap.h"
@@ -161,7 +161,12 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
//Last = GetIntCatInfo("Last", 0);
Ending = GetIntCatInfo("Ending", CRLF);
- if (Recfm == RECFM_FIX || Recfm == RECFM_BIN) {
+ if (Ending <= 0) {
+ Ending = (Recfm == RECFM_BIN || Recfm == RECFM_VCT) ? 0 : CRLF;
+ SetIntCatInfo("Ending", Ending);
+ } // endif ending
+
+ if (Recfm == RECFM_FIX || Recfm == RECFM_BIN) {
Huge = GetBoolCatInfo("Huge", Cat->GetDefHuge());
Padded = GetBoolCatInfo("Padded", false);
Blksize = GetIntCatInfo("Blksize", 0);
@@ -191,7 +196,8 @@ bool DOSDEF::GetOptFileName(PGLOBAL g, char *filename)
case RECFM_FIX: ftype = ".fop"; break;
case RECFM_BIN: ftype = ".bop"; break;
case RECFM_VCT: ftype = ".vop"; break;
- case RECFM_DBF: ftype = ".dbp"; break;
+ case RECFM_CSV: ftype = ".cop"; break;
+ case RECFM_DBF: ftype = ".dbp"; break;
default:
sprintf(g->Message, MSG(INVALID_FTYPE), Recfm);
return true;
@@ -261,7 +267,8 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break;
- case RECFM_DBF: ftype = ".dbx"; break;
+ case RECFM_CSV: ftype = ".cnx"; break;
+ case RECFM_DBF: ftype = ".dbx"; break;
default:
sprintf(g->Message, MSG(BAD_RECFM_VAL), Recfm);
return true;
@@ -2259,7 +2266,7 @@ int TDBDOS::ReadDB(PGLOBAL g)
/***********************************************************************/
bool TDBDOS::PrepareWriting(PGLOBAL)
{
- if (!Ftype && (Mode == MODE_INSERT || Txfp->GetUseTemp())) {
+ if (Ftype == RECFM_VAR && (Mode == MODE_INSERT || Txfp->GetUseTemp())) {
char *p;
/*******************************************************************/
@@ -2544,7 +2551,8 @@ void DOSCOL::ReadColumn(PGLOBAL g)
/*********************************************************************/
/* For a variable length file, check if the field exists. */
/*********************************************************************/
- if (tdbp->Ftype == RECFM_VAR && strlen(tdbp->To_Line) < (unsigned)Deplac)
+ if ((tdbp->Ftype == RECFM_VAR || tdbp->Ftype == RECFM_CSV)
+ && strlen(tdbp->To_Line) < (unsigned)Deplac)
field = 0;
else if (Dsp)
for(i = 0; i < field; i++)
@@ -2554,7 +2562,8 @@ void DOSCOL::ReadColumn(PGLOBAL g)
switch (tdbp->Ftype) {
case RECFM_VAR:
case RECFM_FIX: // Fixed length text file
- case RECFM_DBF: // Fixed length DBase file
+ case RECFM_CSV: // Variable length CSV or FMT file
+ case RECFM_DBF: // Fixed length DBase file
if (Nod) switch (Buf_Type) {
case TYPE_INT:
case TYPE_SHORT:
diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h
index bdde37adaad..207a1277fce 100644
--- a/storage/connect/tabdos.h
+++ b/storage/connect/tabdos.h
@@ -80,7 +80,6 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
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 */
bool Zipped; /* true for zipped table file */
bool Mulentries; /* true for multiple entries */
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp
index 14afe511640..6fa3f2e6433 100644
--- a/storage/connect/tabfix.cpp
+++ b/storage/connect/tabfix.cpp
@@ -83,7 +83,7 @@ PTDB TDBFIX::Clone(PTABS t)
tp = new(g) TDBFIX(g, this);
- if (Ftype < 2) {
+ if (Ftype == RECFM_VAR || Ftype == RECFM_FIX) {
// File is text
PDOSCOL cp1, cp2;
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 847fd515860..432e297e59a 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -1,11 +1,11 @@
/************* TabFmt C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABFMT */
/* ------------- */
-/* Version 3.9.2 */
+/* Version 3.9.3 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2001 - 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2001 - 2019 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -482,6 +482,7 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (DOSDEF::DefineAM(g, "CSV", poff))
return true;
+ Recfm = RECFM_CSV;
GetCharCatInfo("Separator", ",", buf, sizeof(buf));
Sep = (strlen(buf) == 2 && buf[0] == '\\' && buf[1] == 't') ? '\t' : *buf;
Quoted = GetIntCatInfo("Quoted", -1);
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index a96b7fe46d5..ca126d8c488 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -396,10 +396,11 @@ err:
bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
{
- char *p, *pc = colname + strlen(colname);
- int ars;
- PJOB job;
- PJAR jar;
+ char *p, *pc = colname + strlen(colname);
+ int ars;
+ size_t n;
+ PJOB job;
+ PJAR jar;
if ((valp = jvp ? jvp->GetValue() : NULL)) {
jcol.Type = valp->GetType();
@@ -425,8 +426,10 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
PCSZ k = jrp->GetKey();
if (*k != '$') {
- strncat(strncat(fmt, sep, 128), k, 128);
- strncat(strncat(colname, "_", 64), k, 64);
+ n = sizeof(fmt) - strlen(fmt) -1;
+ strncat(strncat(fmt, sep, n), k, n - strlen(sep));
+ n = sizeof(colname) - strlen(colname) - 1;
+ strncat(strncat(colname, "_", n), k, n - 1);
} // endif Key
if (Find(g, jrp->GetVal(), k, j + 1))
@@ -445,19 +448,26 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
ars = MY_MIN(jar->GetSize(false), 1);
for (int k = 0; k < ars; k++) {
- if (!tdp->Xcol || stricmp(tdp->Xcol, key)) {
- sprintf(buf, "%d", k);
-
- if (tdp->Uri)
- strncat(strncat(fmt, sep, 128), buf, 128);
- else
- strncat(strncat(strncat(fmt, "[", 128), buf, 128), "]", 128);
+ n = sizeof(fmt) - (strlen(fmt) + 1);
- if (all)
- strncat(strncat(colname, "_", 64), buf, 64);
+ if (!tdp->Xcol || stricmp(tdp->Xcol, key)) {
+ sprintf(buf, "%d", k);
- } else
- strncat(fmt, (tdp->Uri ? sep : "[*]"), 128);
+ if (tdp->Uri) {
+ strncat(strncat(fmt, sep, n), buf, n - strlen(sep));
+ } else {
+ strncat(strncat(fmt, "[", n), buf, n - 1);
+ strncat(fmt, "]", n - (strlen(buf) + 1));
+ } // endif uri
+
+ if (all) {
+ n = sizeof(colname) - (strlen(colname) + 1);
+ strncat(strncat(colname, "_", n), buf, n - 1);
+ } // endif all
+
+ } else {
+ strncat(fmt, (tdp->Uri ? sep : "[*]"), n);
+ }
if (Find(g, jar->GetValue(k), "", j))
return true;
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 9d60319a83f..c3197d8b373 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -342,11 +342,13 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
Delayed = !!GetIntCatInfo("Delayed", 0);
} else {
// MYSQL access from a PROXY table
- Tabschema = GetStringCatInfo(g, "Database", Tabschema ? Tabschema : PlugDup(g, "*"));
+ TABLE_SHARE* s;
+
+ Tabschema = GetStringCatInfo(g, "Database", Tabschema ? Tabschema : PlugDup(g, "*"));
Isview = GetBoolCatInfo("View", false);
// We must get other connection parms from the calling table
- Remove_tshp(Cat);
+ s = Remove_tshp(Cat);
url = GetStringCatInfo(g, "Connect", NULL);
if (!url || !*url) {
@@ -365,6 +367,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
} // endif url
Tabname = Name;
+
+ // Needed for column description
+ Restore_tshp(Cat, s);
} // endif am
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) {
diff --git a/storage/connect/tabrest.cpp b/storage/connect/tabrest.cpp
index 9e1a643c89f..f9acbc28ddc 100644
--- a/storage/connect/tabrest.cpp
+++ b/storage/connect/tabrest.cpp
@@ -1,5 +1,5 @@
/*************** Rest C++ Program Source Code File (.CPP) **************/
-/* PROGRAM NAME: Rest Version 1.5 */
+/* PROGRAM NAME: Rest Version 1.6 */
/* (C) Copyright to the author Olivier BERTRAND 2018 - 2019 */
/* This program is the REST Web API support for MariaDB. */
/* When compiled without MARIADB defined, it is the EOM module code. */
@@ -36,17 +36,7 @@
#include "tabfmt.h"
#include "tabrest.h"
-/***********************************************************************/
-/* Get the file from the Web. */
-/***********************************************************************/
-int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn);
-
-#if defined(__WIN__)
-static PCSZ slash = "\\";
-#else // !__WIN__
-static PCSZ slash = "/";
-#define stricmp strcasecmp
-#endif // !__WIN__
+static XGETREST getRestFnc = NULL;
#if !defined(MARIADB)
/***********************************************************************/
@@ -76,6 +66,74 @@ PTABDEF __stdcall GetREST(PGLOBAL g, void *memp)
#endif // !MARIADB
/***********************************************************************/
+/* GetREST: get the external TABDEF from OEM module. */
+/***********************************************************************/
+XGETREST GetRestFunction(PGLOBAL g)
+{
+ if (getRestFnc)
+ return getRestFnc;
+
+#if !defined(REST_SOURCE)
+ if (trace(515))
+ htrc("Looking for GetRest library\n");
+
+#if defined(__WIN__)
+ HANDLE Hdll;
+ const char* soname = "GetRest.dll"; // Module name
+
+ if (!(Hdll = LoadLibrary(soname))) {
+ char buf[256];
+ DWORD rc = GetLastError();
+
+ sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
+ (LPTSTR)buf, sizeof(buf), NULL);
+ strcat(strcat(g->Message, ": "), buf);
+ return NULL;
+ } // endif Hdll
+
+// Get the function returning an instance of the external DEF class
+ if (!(getRestFnc = (XGETREST)GetProcAddress((HINSTANCE)Hdll, "restGetFile"))) {
+ char buf[256];
+ DWORD rc = GetLastError();
+
+ sprintf(g->Message, MSG(PROCADD_ERROR), rc, "restGetFile");
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
+ (LPTSTR)buf, sizeof(buf), NULL);
+ strcat(strcat(g->Message, ": "), buf);
+ FreeLibrary((HMODULE)Hdll);
+ return NULL;
+ } // endif getRestFnc
+#else // !__WIN__
+ void* Hso;
+ const char* error = NULL;
+ const char* soname = "GetRest.so"; // Module name
+
+ // Load the desired shared library
+ if (!(Hso = dlopen(soname, RTLD_LAZY))) {
+ error = dlerror();
+ sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
+ return NULL;
+ } // endif Hdll
+
+// Get the function returning an instance of the external DEF class
+ if (!(getRestFnc = (XGETREST)dlsym(Hso, "restGetFile"))) {
+ error = dlerror();
+ sprintf(g->Message, MSG(GET_FUNC_ERR), "restGetFile", SVP(error));
+ dlclose(Hso);
+ return NULL;
+ } // endif getdef
+#endif // !__WIN__
+#else
+ getRestFnc = restGetFile;
+#endif
+
+ return getRestFnc;
+} // end of GetRestFunction
+
+/***********************************************************************/
/* Return the columns definition to MariaDB. */
/***********************************************************************/
#if defined(MARIADB)
@@ -87,6 +145,10 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
PQRYRES qrp= NULL;
char filename[_MAX_PATH + 1]; // MAX PATH ???
PCSZ http, uri, fn, ftype;
+ XGETREST grf = GetRestFunction(g);
+
+ if (!grf)
+ return NULL;
http = GetStringTableOption(g, tp, "Http", NULL);
uri = GetStringTableOption(g, tp, "Uri", NULL);
@@ -100,11 +162,11 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
// We used the file name relative to recorded datapath
strcat(strcat(strcat(strcpy(filename, "."), slash), db), slash);
- strncat(filename, fn, _MAX_PATH);
+ strncat(filename, fn, _MAX_PATH - strlen(filename));
// Retrieve the file from the web and copy it locally
- if (http && restGetFile(g, http, uri, filename)) {
- // sprintf(g->Message, "Failed to get file at %s", http);
+ if (http && grf(g->Message, trace(515), http, uri, filename)) {
+ // sprintf(g->Message, "Failed to get file at %s", http);
} else if (!stricmp(ftype, "XML"))
qrp = XMLColumns(g, db, tab, tp, info);
else if (!stricmp(ftype, "JSON"))
@@ -124,9 +186,14 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
/***********************************************************************/
bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
- char filename[_MAX_PATH + 1];
+ char filename[_MAX_PATH + 1];
int rc = 0, n;
- LPCSTR ftype;
+ bool xt = trace(515);
+ LPCSTR ftype;
+ XGETREST grf = GetRestFunction(g);
+
+ if (!grf)
+ return true;
#if defined(MARIADB)
ftype = GetStringCatInfo(g, "Type", "JSON");
@@ -135,7 +202,7 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
ftype = GetStringCatInfo(g, "Ftype", "JSON");
#endif // !MARIADB
- if (trace(515))
+ if (xt)
htrc("ftype = %s am = %s\n", ftype, SVP(am));
n = (!stricmp(ftype, "JSON")) ? 1
@@ -154,12 +221,13 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
// We used the file name relative to recorded datapath
//PlugSetPath(filename, Fn, GetPath());
- strncat(strcpy(filename, GetPath()), Fn, _MAX_PATH);
+ strcpy(filename, GetPath());
+ strncat(filename, Fn, _MAX_PATH - strlen(filename));
// Retrieve the file from the web and copy it locally
- rc = restGetFile(g, Http, Uri, filename);
+ rc = grf(g->Message, xt, Http, Uri, filename);
- if (trace(515))
+ if (xt)
htrc("Return from restGetFile: rc=%d\n", rc);
if (rc)
@@ -175,7 +243,7 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (Tdp && Tdp->Define(g, Cat, Name, Schema, "REST"))
Tdp = NULL; // Error occured
- if (trace(515))
+ if (xt)
htrc("Tdp defined\n", rc);
// Return true in case of error
diff --git a/storage/connect/tabrest.h b/storage/connect/tabrest.h
index 1725f256079..d945c97e5f1 100644
--- a/storage/connect/tabrest.h
+++ b/storage/connect/tabrest.h
@@ -5,6 +5,25 @@
/***********************************************************************/
#pragma once
+#if defined(__WIN__)
+static PCSZ slash = "\\";
+#else // !__WIN__
+static PCSZ slash = "/";
+#define stricmp strcasecmp
+#endif // !__WIN__
+
+typedef int(__stdcall* XGETREST) (char*, bool, PCSZ, PCSZ, PCSZ);
+
+/***********************************************************************/
+/* Functions used by REST. */
+/***********************************************************************/
+XGETREST GetRestFunction(PGLOBAL g);
+int restGetFile(char* m, bool x, PCSZ http, PCSZ uri, PCSZ fn);
+#if defined(MARIADB)
+PQRYRES RESTColumns(PGLOBAL g, PTOS tp, char* tab, char* db, bool info);
+#endif // !MARIADB
+
+
/***********************************************************************/
/* Restest table. */
/***********************************************************************/
diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp
index b82e98204dd..8113ee620c3 100644
--- a/storage/connect/tabutil.cpp
+++ b/storage/connect/tabutil.cpp
@@ -59,12 +59,24 @@ int GetConvSize(void);
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */
/* table (PROXY, TBL, XCL, or OCCUR) when used by one of these. */
/************************************************************************/
-void Remove_tshp(PCATLG cat)
+TABLE_SHARE *Remove_tshp(PCATLG cat)
{
- ((MYCAT*)cat)->GetHandler()->tshp = NULL;
+ TABLE_SHARE *s = ((MYCAT*)cat)->GetHandler()->tshp;
+
+ ((MYCAT*)cat)->GetHandler()->tshp = NULL;
+ return s;
} // end of Remove_thsp
/************************************************************************/
+/* Used by MYSQL tables to get MySQL parameters from the calling proxy */
+/* table (PROXY, TBL, XCL, or OCCUR) when used by one of these. */
+/************************************************************************/
+void Restore_tshp(PCATLG cat, TABLE_SHARE *s)
+{
+ ((MYCAT*)cat)->GetHandler()->tshp = s;
+} // end of Restore_thsp
+
+/************************************************************************/
/* GetTableShare: allocates and open a table share. */
/************************************************************************/
TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
diff --git a/storage/connect/tabutil.h b/storage/connect/tabutil.h
index 62678508ca1..c8e7e75106f 100644
--- a/storage/connect/tabutil.h
+++ b/storage/connect/tabutil.h
@@ -18,7 +18,8 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
const char *name, bool& info);
-void Remove_tshp(PCATLG cat);
+TABLE_SHARE *Remove_tshp(PCATLG cat);
+void Restore_tshp(PCATLG cat, TABLE_SHARE *s);
/* -------------------------- PROXY classes -------------------------- */
diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp
index 40d020202ea..0ed466f6ffb 100644
--- a/storage/connect/tabvct.cpp
+++ b/storage/connect/tabvct.cpp
@@ -115,11 +115,14 @@ bool VCTDEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
Recfm = RECFM_VCT;
+ // poff is no more in use; This will have to be revisited
+#if 0
// For packed files the logical record length is calculated in poff
if (poff != Lrecl) {
Lrecl = poff;
SetIntCatInfo("Lrecl", poff);
} // endif poff
+#endif // 0
Padded = false;
Blksize = 0;
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 489fcae303b..062d52679f6 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -241,7 +241,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
more:
if (vp->atp) {
- strncpy(colname, vp->atp->GetName(g), sizeof(colname));
+ size_t z = sizeof(colname) - 1;
+ strncpy(colname, vp->atp->GetName(g), z);
+ colname[z] = 0;
strncat(xcol->Name, colname, XLEN(xcol->Name));
switch (vp->atp->GetText(g, buf, sizeof(buf))) {
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 137e29ab9dd..2421aec9f67 100644
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -660,7 +660,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
/* Not true for DBF tables because of eventual soft deleted lines. */
/* Note: for Num_K = 1 any non null value is Ok. */
/*********************************************************************/
- if (Srtd && !filp && Tdbp->Ftype != RECFM_VAR
+ if (Srtd && !filp && Tdbp->Ftype != RECFM_VAR && Tdbp->Ftype != RECFM_CSV
&& Tdbp->Txfp->GetAmType() != TYPE_AM_DBF) {
Incr = (Num_K > 1) ? To_Rec[1] : Num_K;
PlgDBfree(Record);
@@ -838,7 +838,8 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break;
- case RECFM_DBF: ftype = ".dbx"; break;
+ case RECFM_CSV: ftype = ".cnx"; break;
+ case RECFM_DBF: ftype = ".dbx"; break;
default:
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
return true;
@@ -991,7 +992,8 @@ bool XINDEX::Init(PGLOBAL g)
case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break;
- case RECFM_DBF: ftype = ".dbx"; break;
+ case RECFM_CSV: ftype = ".cnx"; break;
+ case RECFM_DBF: ftype = ".dbx"; break;
default:
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
return true;
@@ -1243,7 +1245,8 @@ bool XINDEX::MapInit(PGLOBAL g)
case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break;
- case RECFM_DBF: ftype = ".dbx"; break;
+ case RECFM_CSV: ftype = ".cnx"; break;
+ case RECFM_DBF: ftype = ".dbx"; break;
default:
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
return true;
@@ -1457,7 +1460,8 @@ bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk)
case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break;
- case RECFM_DBF: ftype = ".dbx"; break;
+ case RECFM_CSV: ftype = ".cnx"; break;
+ case RECFM_DBF: ftype = ".dbx"; break;
default:
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
return true;
diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h
index bc9265e0223..1b499e09047 100644
--- a/storage/connect/xtable.h
+++ b/storage/connect/xtable.h
@@ -173,9 +173,12 @@ class DllExport TDBASE : public TDB {
inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;}
// Properties
- virtual PKXBASE GetKindex(void) {return To_Kindex;}
+ PKXBASE GetKindex(void) {return To_Kindex;}
+ PXOB *GetLink(void) {return To_Link;}
+ PIXDEF GetXdp(void) {return To_Xdp;}
void ResetKindex(PGLOBAL g, PKXBASE kxp);
PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;}
+ PXOB Link(int i) { return (To_Link) ? To_Link[i] : NULL; }
// Methods
virtual bool IsUsingTemp(PGLOBAL) {return false;}