Commit 0b624deb authored by Olivier Bertrand's avatar Olivier Bertrand

Update to version 1.07 (as for MariaDB 10.2)

parent 0043593b
......@@ -40,6 +40,10 @@ user_connect.h valblk.h value.h xindex.h xobject.h xtable.h)
add_definitions( -DMARIADB -DFORCE_INIT_OF_VARS -Dconnect_EXPORTS)
add_definitions( -DHUGE_SUPPORT -DGZ_SUPPORT )
macro(DISABLE_WARNING W)
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-error=${W}")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-${W}" DEBUG)
endmacro()
#
# OS specific C flags, definitions and source files.
......@@ -47,14 +51,15 @@ add_definitions( -DHUGE_SUPPORT -DGZ_SUPPORT )
IF(UNIX)
MY_CHECK_AND_SET_COMPILER_FLAG("-Wall -Wmissing-declarations")
if(NOT WITH_WARNINGS)
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-unused-function")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-unused-variable")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-unused-value")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-parentheses")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-strict-aliasing")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-misleading-indentation")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-format-truncation")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-implicit-fallthrough")
DISABLE_WARNING("unused-function")
DISABLE_WARNING("unused-variable")
DISABLE_WARNING("unused-value")
DISABLE_WARNING("parentheses")
DISABLE_WARNING("strict-aliasing")
DISABLE_WARNING("misleading-indentation")
DISABLE_WARNING("format-truncation")
DISABLE_WARNING("implicit-fallthrough")
DISABLE_WARNING("type-limits")
endif(NOT WITH_WARNINGS)
add_definitions( -DUNIX -DLINUX -DUBUNTU )
......@@ -68,10 +73,6 @@ ELSE(NOT UNIX)
tabwmi.cpp tabwmi.h tabmac.cpp tabmac.h macutil.cpp macutil.h)
# Add exception handling to the CONNECT project)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MD")
SET(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MD")
SET(IPHLPAPI_LIBRARY iphlpapi.lib)
IF(MSVC AND (CMAKE_CXX_COMPILER_ID MATCHES Clang))
# Connect does not work with clang-cl
......@@ -171,7 +172,8 @@ IF(CONNECT_WITH_ODBC)
# the library 'libiodbc' gets compiled with 'sql'h.
# This will also need changes in the sources (e.g. #include <isql.h>).
find_path(ODBC_INCLUDE_DIR sql.h
find_file(ODBC_INCLUDES sql.h
PATHS
/usr/include
/usr/include/odbc
/usr/local/include
......@@ -181,7 +183,7 @@ IF(CONNECT_WITH_ODBC)
#"C:/Program Files/Microsoft SDKs/Windows/v7.0A/include"
#"C:/Program Files/Microsoft SDKs/Windows/v6.0a/include"
#"C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/include"
DOC "Specify the directory containing sql.h."
DOC "Specify the path to sql.h."
)
find_library(ODBC_LIBRARY
......@@ -200,9 +202,10 @@ IF(CONNECT_WITH_ODBC)
DOC "Specify the ODBC driver manager library here."
)
mark_as_advanced(ODBC_LIBRARY ODBC_INCLUDE_DIR)
mark_as_advanced(ODBC_LIBRARY ODBC_INCLUDES)
IF(ODBC_INCLUDE_DIR AND ODBC_LIBRARY)
IF(ODBC_INCLUDES AND ODBC_LIBRARY)
get_filename_component(ODBC_INCLUDE_DIR "${ODBC_INCLUDES}" PATH)
set(CMAKE_REQUIRED_LIBRARIES ${ODBC_LIBRARY})
set(CMAKE_REQUIRED_INCLUDES ${ODBC_INCLUDE_DIR})
CHECK_CXX_SOURCE_COMPILES(
......@@ -316,19 +319,27 @@ OPTION(CONNECT_WITH_REST "Compile CONNECT storage engine with REST support" ON)
IF(CONNECT_WITH_REST)
MESSAGE(STATUS "=====> REST support is ON")
FIND_PACKAGE(cpprestsdk)
SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp tabrest.h)
add_definitions(-DREST_SUPPORT)
FIND_PACKAGE(cpprestsdk QUIET)
IF (cpprestsdk_FOUND)
MESSAGE(STATUS "=====> cpprestsdk found")
IF(UNIX)
# INCLUDE_DIRECTORIES(${CPPRESTSDK_INCLUDE_DIR})
# If needed edit next line to set the path to libcpprest.so
SET(REST_LIBRARY -lcpprest)
MESSAGE (STATUS ${REST_LIBRARY})
ELSE(NOT UNIX)
# Next line sets debug compile mode matching cpprest_2_10d.dll
# when it was binary installed (can be change later in Visual Studio)
# Comment it out if not needed depending on your cpprestsdk installation.
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
ENDIF(UNIX)
SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp restget.cpp tabrest.h)
add_definitions(-DREST_SUPPORT)
# 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")
# MESSAGE(STATUS "=====> cpprestsdk package not found")
ENDIF (cpprestsdk_FOUND)
ENDIF(CONNECT_WITH_REST)
......
......@@ -438,7 +438,7 @@ char *ARRAY::GetStringValue(int n)
/***********************************************************************/
bool ARRAY::Find(PVAL valp)
{
register int n;
int n;
PVAL vp;
if (Type != valp->GetType()) {
......@@ -1042,7 +1042,7 @@ MULAR::MULAR(PGLOBAL g, int n) : CSORT(false)
/***********************************************************************/
int MULAR::Qcompare(int *i1, int *i2)
{
register int i, n = 0;
int i, n = 0;
for (i = 0; i < Narray; i++)
if ((n = Pars[i]->Qcompare(i1, i2)))
......
......@@ -16,7 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/***********************************************************************/
/* Author Olivier BERTRAND bertrandop@gmail.com 2004-2017 */
/* Author Olivier BERTRAND bertrandop@gmail.com 2004-2019 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
......@@ -389,6 +389,9 @@ RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool reset, bool mrr)
try {
for (colp = tdbp->GetColumns(); rc == RC_OK && colp;
colp = colp->GetNext()) {
xtrc(2, "Going to read column %s of table %s\n",
colp->GetName(), tdbp->GetName());
if (reset)
colp->Reset();
......@@ -563,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:
......@@ -590,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);
......@@ -619,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;
......@@ -630,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) {
......@@ -642,16 +645,16 @@ 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;
......@@ -673,7 +676,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)
......@@ -707,7 +710,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;
......@@ -733,12 +736,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
......@@ -751,7 +754,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;
......@@ -761,13 +764,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)) {
......@@ -837,7 +840,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)
......@@ -862,35 +865,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)) {
......
......@@ -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
......@@ -178,9 +178,9 @@ void CSORT::DebugSort(int ph, int n, int *base, int *mid, int *tmp)
/***********************************************************************/
int CSORT::Qsortx(void)
{
register int c;
register int lo, hi, min;
register int i, j, rc = 0;
int c;
int lo, hi, min;
int i, j, rc = 0;
// To do: rc should be checked for being used uninitialized
int *top;
#ifdef DEBTRACE
......@@ -344,7 +344,7 @@ int CSORT::Qsortx(void)
/***********************************************************************/
void CSORT::Qstx(int *base, int *max)
{
register int *i, *j, *jj, *mid, *him, c;
int *i, *j, *jj, *mid, *him, c;
int *tmp;
int lo, hi, rc;
size_t zlo, zhi, cnm;
......@@ -543,9 +543,9 @@ void CSORT::Qstx(int *base, int *max)
/***********************************************************************/
int CSORT::Qsortc(void)
{
register int c;
register int lo, hi, min;
register int i, j, k, m, rc = 0;
int c;
int lo, hi, min;
int i, j, k, m, rc = 0;
// To do: rc should be checked for being used uninitialized
int *max;
#ifdef DEBTRACE
......@@ -720,7 +720,7 @@ int CSORT::Qsortc(void)
/***********************************************************************/
void CSORT::Qstc(int *base, int *max)
{
register int *i, *j, *jj, *lt, *eq, *gt, *mid;
int *i, *j, *jj, *lt, *eq, *gt, *mid;
int c = 0, lo, hi, rc;
size_t zlo, zhi, cnm;
......@@ -907,9 +907,9 @@ void CSORT::Qstc(int *base, int *max)
/***********************************************************************/
void CSORT::Istc(int *base, int *hi, int *max)
{
register int c = 0;
register int *lo;
register int *i, *j;
int c = 0;
int *lo;
int *i, *j;
/*********************************************************************/
/* First put smallest element, which must be in the first THRESH, */
......
......@@ -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= '/';
......@@ -1045,6 +1045,8 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
case TAB_REST:
type = TAB_NIY;
break;
default:
break;
} // endswitch type
#endif // REST_SUPPORT
......@@ -1341,7 +1343,7 @@ char *ha_connect::GetRealString(PCSZ s)
{
char *sv;
if (IsPartitioned() && s && partname && *partname) {
if (IsPartitioned() && s && *partname) {
sv= (char*)PlugSubAlloc(xp->g, NULL, 0);
sprintf(sv, s, partname);
PlugSubAlloc(xp->g, NULL, strlen(sv) + 1);
......@@ -2964,10 +2966,12 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
case Item_func::LE_FUNC: vop= OP_LE; break;
case Item_func::GE_FUNC: vop= OP_GE; break;
case Item_func::GT_FUNC: vop= OP_GT; break;
#if MYSQL_VERSION_ID > 100200
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;
#endif // VERSION_ID > 100200
case Item_func::ISNOTNULL_FUNC:
neg= true;
// fall through
......@@ -3095,7 +3099,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;
......@@ -3125,7 +3129,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;
......@@ -3785,9 +3789,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
......@@ -4503,34 +4507,13 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
case TAB_DIR:
case TAB_ZIP:
case TAB_OEM:
#ifdef NO_EMBEDDED_ACCESS_CHECKS
return false;
#endif
/*
Check FILE_ACL
If table or table->mdl_ticket is NULL - it's a DLL, e.g. CREATE TABLE.
if the table has an MDL_EXCLUSIVE lock - it's a DDL too, e.g. the
insert step of CREATE ... SELECT.
Otherwise it's a DML, the table was normally opened, locked,
privilege were already checked, and table->grant.privilege is set.
With SQL SECURITY DEFINER, table->grant.privilege has definer's privileges.
Unless we're in prelocking mode, in this case table->grant.privilege
is only checked in start_stmt(), not in external_lock().
*/
if (!table || !table->mdl_ticket || table->mdl_ticket->get_type() == MDL_EXCLUSIVE)
return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0);
if ((!quick && thd->lex->requires_prelocking()) || table->grant.privilege & FILE_ACL)
return false;
status_var_increment(thd->status_var.access_denied_errors);
my_error(access_denied_error_code(thd->password), MYF(0),
thd->security_ctx->priv_user, thd->security_ctx->priv_host,
(thd->password ? ER(ER_YES) : ER(ER_NO)));
return true;
if (table && table->pos_in_table_list) // if SELECT
{
Switch_to_definer_security_ctx backup_ctx(thd, table->pos_in_table_list);
return check_global_access(thd, FILE_ACL);
}
else
return check_global_access(thd, FILE_ACL);
case TAB_ODBC:
case TAB_JDBC:
case TAB_MONGO:
......@@ -5653,6 +5636,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
......@@ -6062,7 +6047,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;
......@@ -6102,6 +6087,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (crp->Kdata->GetIntValue(i))
tm= 0; // Nullable
break;
case FLD_FLAG:
flg = crp->Kdata->GetIntValue(i);
break;
case FLD_FORMAT:
fmt= (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL;
......@@ -6233,7 +6221,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
......@@ -7379,14 +7367,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;
......@@ -1196,9 +1196,14 @@ int JDBConn::GetResultSize(PCSZ sql, PCOL colp)
if ((rc = ExecuteQuery(sql)) != RC_OK)
return -1;
if ((rc = Fetch()) > 0)
SetColumnValue(1, NULL, colp->GetValue());
else
if ((rc = Fetch()) > 0) {
try {
SetColumnValue(1, NULL, colp->GetValue());
} catch (...) {
return -4;
} // end catch
} else
return -2;
if ((rc = Fetch()) != 0)
......
......@@ -95,7 +95,7 @@
#endif // ZIP_SUPPORT
#if defined(REST_SUPPORT)
#include "tabrest.h"
#endif // Rest_SUPPORT
#endif // REST_SUPPORT
#include "mycat.h"
/***********************************************************************/
......@@ -107,7 +107,6 @@ extern "C" HINSTANCE s_hModule; // Saved module handle
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
bool MongoEnabled(void);
#endif // JAVA_SUPPORT || CMGO_SUPPORT
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
/***********************************************************************/
/* Get the plugin directory. */
......@@ -349,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 --------------------------- */
/***********************************************************************/
......@@ -483,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));
......@@ -507,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",
......@@ -580,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);
......@@ -594,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();
......
......@@ -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
......
......@@ -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__)
......@@ -879,7 +879,7 @@ MYSQL_FIELD *MYSQLC::GetNextField(void)
PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
{
PCSZ fmt;
char *name, v;
char *name, v= 0;
int n;
bool uns;
PCOLRES *pcrp, crp;
......
......@@ -2279,7 +2279,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
int i, irc;
bool b;
PCSZ fnc = "Unknown";
UWORD n;
UWORD n = 0;
SWORD ncol, len, tp;
SQLULEN crow = 0;
PQRYRES qrp = cap->Qrp;
......
......@@ -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. */
......
This diff is collapsed.
......@@ -84,10 +84,12 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
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 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
// 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 ??? */
......
......@@ -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,26 @@ 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;
extern "C" int restGetFile(char* m, bool xt, PCSZ http, PCSZ uri, PCSZ fn);
/***********************************************************************/
/* 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 +38,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 +54,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 +64,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
......@@ -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);
......
......@@ -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;
......@@ -2257,7 +2264,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;
/*******************************************************************/
......@@ -2542,7 +2549,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++)
......@@ -2552,7 +2560,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:
......
......@@ -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 */
......
......@@ -84,7 +84,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;
......
/************* 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: */
/* ----------------------- */
......@@ -477,6 +477,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);
......
......@@ -394,10 +394,11 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
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();
......@@ -423,8 +424,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))
......@@ -443,19 +446,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;
......
......@@ -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))) {
......
......@@ -605,8 +605,10 @@ bool TDBODBC::OpenDB(PGLOBAL g)
Cnp->InitValue(g);
if ((n = Ocp->GetResultSize(Query->GetStr(), Cnp)) < 0) {
strcpy(g->Message, "Cannot get result size");
return true;
char* msg = PlugDup(g, g->Message);
sprintf(g->Message, "Get result size: %s (rc=%d)", msg, n);
return true;
} else if (n) {
Ocp->m_Rows = n;
......
/*************** Rest C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: Rest Version 1.5 */
/************** tabrest C++ Program Source Code File (.CPP) ************/
/* PROGRAM NAME: tabrest Version 1.7 */
/* (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. */
......@@ -9,13 +9,18 @@
/* Definitions needed by the included files. */
/***********************************************************************/
#if defined(MARIADB)
#include <my_global.h> // All MariaDB stuff
#include <my_global.h> // All MariaDB stuff
#else // !MARIADB OEM module
#include "mini-global.h"
#define _MAX_PATH 260
#if !defined(__WIN__)
#if !defined(REST_SOURCE)
#if defined(__WIN__) || defined(_WINDOWS)
#include <windows.h>
#else // !__WIN__
#define __stdcall
#include <dlfcn.h> // dlopen(), dlclose(), dlsym() ...
#endif // !__WIN__
#endif // !REST_SOURCE
#define _OS_H_INCLUDED // Prevent os.h to be called
#endif // !MARIADB
......@@ -23,7 +28,6 @@
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/* (x)table.h is header containing the TDBASE declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
......@@ -36,17 +40,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)
/***********************************************************************/
......@@ -75,6 +69,74 @@ PTABDEF __stdcall GetREST(PGLOBAL g, void *memp)
} // end of GetREST
#endif // !MARIADB
/***********************************************************************/
/* GetREST: get the external TABDEF from OEM module. */
/***********************************************************************/
XGETREST GetRestFunction(PGLOBAL g)
{
if (getRestFnc)
return getRestFnc;
#if !defined(MARIADB) || !defined(REST_SOURCE)
if (trace(515))
htrc("Looking for GetRest library\n");
#if defined(__WIN__) || defined(_WINDOWS)
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. */
/***********************************************************************/
......@@ -87,6 +149,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 +166,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 +190,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 +206,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 +225,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 +247,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
......
......@@ -5,6 +5,27 @@
/***********************************************************************/
#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);
#if defined(REST_SOURCE)
extern "C" int restGetFile(char* m, bool xt, PCSZ http, PCSZ uri, PCSZ fn);
#endif // REST_SOURCE
#if defined(MARIADB)
PQRYRES RESTColumns(PGLOBAL g, PTOS tp, char* tab, char* db, bool info);
#endif // !MARIADB
/***********************************************************************/
/* Restest table. */
/***********************************************************************/
......
......@@ -59,11 +59,23 @@ 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. */
/************************************************************************/
......
......@@ -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 -------------------------- */
......
......@@ -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;
......
......@@ -240,7 +240,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))) {
......
......@@ -206,6 +206,7 @@ void VALBLK::ChkIndx(int n)
{
if (n < 0 || n >= Nval) {
PGLOBAL& g = Global;
xtrc(1, "ChkIndx: n=%d Nval=%d\n", n, Nval);
strcpy(g->Message, MSG(BAD_VALBLK_INDX));
throw Type;
} // endif n
......@@ -216,7 +217,8 @@ void VALBLK::ChkTyp(PVAL v)
{
if (Check && (Type != v->GetType() || Unsigned != v->IsUnsigned())) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(VALTYPE_NOMATCH));
xtrc(1, "ChkTyp: Type=%d valType=%d\n", Type, v->GetType());
strcpy(g->Message, MSG(VALTYPE_NOMATCH));
throw Type;
} // endif Type
......@@ -511,7 +513,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, int k, int n)
CheckType(pv)
TYPE *lp = ((TYPBLK*)pv)->Typp;
for (register int i = k; i < n; i++) // TODO
for (int i = k; i < n; i++) // TODO
Typp[i] = lp[i];
} // end of SetValues
......@@ -805,7 +807,7 @@ void CHRBLK::SetValue(const char *sp, uint len, int n)
if (Blanks) {
// Suppress eventual ending zero and right fill with blanks
for (register int i = len; i < Long; i++)
for (int i = len; i < Long; i++)
p[i] = ' ';
} else if ((signed)len < Long)
......
This diff is collapsed.
......@@ -272,8 +272,8 @@ void XINDEX::Close(void)
/***********************************************************************/
int XINDEX::Qcompare(int *i1, int *i2)
{
register int k;
register PXCOL kcp;
int k;
PXCOL kcp;
for (kcp = To_KeyCol, k = 0; kcp; kcp = kcp->Next)
if ((k = kcp->Compare(*i1, *i2)))
......@@ -659,7 +659,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);
......@@ -745,7 +745,7 @@ int XINDEX::ColMaxSame(PXCOL kp)
/***********************************************************************/
bool XINDEX::Reorder(PGLOBAL g __attribute__((unused)))
{
register int i, j, k, n;
int i, j, k, n;
bool sorted = true;
PXCOL kcp;
#if 0
......@@ -837,7 +837,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;
......@@ -990,7 +991,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;
......@@ -1870,8 +1874,8 @@ int XINDEX::Fetch(PGLOBAL g)
/***********************************************************************/
int XINDEX::FastFind(void)
{
register int curk, sup, inf, i= 0, k, n = 2;
register PXCOL kp, kcp;
int curk, sup, inf, i= 0, k, n = 2;
PXCOL kp, kcp;
//assert((int)nv == Nval);
......@@ -2209,8 +2213,8 @@ int XINDXS::Fetch(PGLOBAL g)
/***********************************************************************/
int XINDXS::FastFind(void)
{
register int sup, inf, i= 0, n = 2;
register PXCOL kcp = To_KeyCol;
int sup, inf, i= 0, n = 2;
PXCOL kcp = To_KeyCol;
if (Nblk && Op == OP_EQ) {
// Look in block values to find in which block to search
......@@ -3235,7 +3239,7 @@ void KXYCOL::FillValue(PVAL valp)
int KXYCOL::Compare(int i1, int i2)
{
// Do the actual comparison between values.
register int k = Kblp->CompVal(i1, i2);
int k = Kblp->CompVal(i1, i2);
if (trace(4))
htrc("Compare done result=%d\n", k);
......@@ -3250,7 +3254,7 @@ int KXYCOL::CompVal(int i)
{
// Do the actual comparison between numerical values.
if (trace(4)) {
register int k = (int)Kblp->CompVal(Valp, (int)i);
int k = (int)Kblp->CompVal(Valp, (int)i);
htrc("Compare done result=%d\n", k);
return k;
......
......@@ -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;}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment