Commit e4797a99 authored by Olivier Bertrand's avatar Olivier Bertrand

In CONNECT version 1.6.10 NOSQL facility is enhanced by a new way to retrieve NOSQL data.

In addition to files and Mongo collections, JSON as well as XML and CSV data can be retrieved
from the net as answers from REST queries. Because it uses and external package (cpprestsdk)
this is currently available only to MariaDB servers compiled from source.

-- Add the REST support when Microsoft Casablanca package (cpprestsdk) is installed.
-- Also include some changes specific to MariaDB 10.3.
  modified:   storage/connect/CMakeLists.txt

-- Add conditional REST support
-- Added string options HTTP and URI.
-- Added added internal table type TAB_REST.
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/mycat.cc
  modified:   storage/connect/mycat.h
  modified:   storage/connect/plgdbsem.h

-- Fix MDEV-19648 Variable connect_conv_size doesn't change
-- Change Variable wrong block parameter from 8169 to 1.
-- Also change connect_conv_size default value to 1024.
  modified:   storage/connect/ha_connect.cc

-- Avoid possible buffer overflow
-- In particular by the function ShowValue.
  modified:   storage/connect/tabdos.cpp
  modified:   storage/connect/tabfmt.cpp
  modified:   storage/connect/value.cpp
  modified:   storage/connect/value.h

-- Add some cast to avoid some compiler warnings
  modified:   storage/connect/filamdbf.cpp

-- Fix some C++ error
  modified:   storage/connect/javaconn.cpp
  modified:   storage/connect/jmgoconn.cpp
  modified:   storage/connect/plugutil.cpp

-- Miscellaneous Typo and warning suppressing changes
  modified:   storage/connect/connect.cpp
  modified:   storage/connect/connect.h
  modified:   storage/connect/filamvct.cpp
  modified:   storage/connect/inihandl.cpp
  modified:   storage/connect/jsonudf.cpp
  modified:   storage/connect/libdoc.cpp
  modified:   storage/connect/tabjson.cpp
  modified:   storage/connect/tabtbl.cpp
  modified:   storage/connect/tabxml.cpp
  modified:   storage/connect/user_connect.cc
  modified:   storage/connect/user_connect.h

-- Update failing test results and disbling
  modified:   storage/connect/mysql-test/connect/disabled.def
  modified:   storage/connect/mysql-test/connect/r/dir.result
  modified:   storage/connect/mysql-test/connect/r/grant.result
  modified:   storage/connect/mysql-test/connect/r/jdbc.result
  modified:   storage/connect/mysql-test/connect/r/jdbc_postgresql.result
  modified:   storage/connect/mysql-test/connect/r/xml.result
  modified:   storage/connect/mysql-test/connect/r/xml2.result
  modified:   storage/connect/mysql-test/connect/r/xml2_mult.result
  modified:   storage/connect/mysql-test/connect/r/xml_mult.result

-- Add an option
  modified:   storage/connect/mysql-test/connect/t/grant.test
parent 4e583a27
......@@ -11,7 +11,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
SET(CONNECT_PLUGIN_STATIC "connect")
SET(CONNECT_PLUGIN_DYNAMIC "connect")
......@@ -69,6 +69,10 @@ ELSE(NOT UNIX)
# Add exception handling to the CONNECT project)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
SET(IPHLPAPI_LIBRARY iphlpapi.lib)
IF(MSVC AND (CMAKE_CXX_COMPILER_ID MATCHES Clang))
# Connect does not work with clang-cl
RETURN()
ENDIF()
ENDIF(UNIX)
......@@ -109,7 +113,6 @@ IF(CONNECT_WITH_LIBXML2)
FIND_PACKAGE(LibXml2)
IF (LIBXML2_FOUND)
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
SET(ZLIB_LIBRARY "z") # see ZLIB_INCLUDE_DIR below
SET(XML_LIBRARY ${LIBXML2_LIBRARIES})
SET(CONNECT_SOURCES ${CONNECT_SOURCES} libdoc.cpp libdoc.h)
add_definitions(-DLIBXML2_SUPPORT)
......@@ -301,6 +304,24 @@ IF(CONNECT_WITH_MONGO)
ENDIF(CONNECT_WITH_MONGO)
#
# REST
#
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)
IF (cpprestsdk_FOUND)
MESSAGE(STATUS "=====> cpprestsdk found")
SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp restget.cpp tabrest.h)
add_definitions(-DREST_SUPPORT)
ELSE(NOT cpprestsdk_FOUND)
MESSAGE(STATUS "=====> cpprestsdk package not found")
ENDIF (cpprestsdk_FOUND)
ENDIF(CONNECT_WITH_REST)
#
# XMAP
#
......@@ -326,14 +347,6 @@ IF(NOT TARGET connect)
RETURN()
ENDIF()
# Don't link with bundled zlib and systel libxml2 at the same time.
# System libxml2 uses system zlib, might conflict with the bundled one.
IF (XML_LIBRARY AND BUILD_BUNDLED_ZLIB)
GET_PROPERTY(INCS TARGET connect PROPERTY INCLUDE_DIRECTORIES)
LIST(REMOVE_ITEM INCS ${ZLIB_INCLUDE_DIR})
SET_PROPERTY(TARGET connect PROPERTY INCLUDE_DIRECTORIES ${INCS})
ENDIF()
IF(WIN32)
IF (libmongoc-1.0_FOUND)
SET_TARGET_PROPERTIES(connect PROPERTIES LINK_FLAGS
......
......@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/**************** Cnt H Declares Source Code File (.H) *****************/
/* Name: CONNECT.H Version 2.4 */
......
......@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/**
@file ha_connect.cc
......@@ -164,15 +164,15 @@
/***********************************************************************/
/* Initialize the ha_connect static members. */
/***********************************************************************/
#define SZCONV 8192
#define SZCONV 1024 // Default converted text size
#define SZWORK 67108864 // Default work area size 64M
#define SZWMIN 4194304 // Minimum work area size 4M
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
char version[]= "Version 1.06.0009 January 27, 2019";
char version[]= "Version 1.06.0010 June 01, 2019";
#if defined(__WIN__)
char compver[]= "Version 1.06.0009 " __DATE__ " " __TIME__;
char compver[]= "Version 1.06.0010 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !__WIN__
char slash= '/';
......@@ -211,14 +211,14 @@ char *GetUserVariable(PGLOBAL g, const uchar *varname)
{
char buf[1024];
bool b;
THD *thd = current_thd;
CHARSET_INFO *cs = system_charset_info;
String *str = NULL, tmp(buf, sizeof(buf), cs);
HASH uvars = thd->user_vars;
user_var_entry *uvar = (user_var_entry*)my_hash_search(&uvars, varname, 0);
THD *thd= current_thd;
CHARSET_INFO *cs= system_charset_info;
String *str= NULL, tmp(buf, sizeof(buf), cs);
HASH uvars= thd->user_vars;
user_var_entry *uvar= (user_var_entry*)my_hash_search(&uvars, varname, 0);
if (uvar)
str = uvar->val_str(&b, &tmp, NOT_FIXED_DEC);
str= uvar->val_str(&b, &tmp, NOT_FIXED_DEC);
return str ? PlugDup(g, str->ptr()) : NULL;
}; // end of GetUserVariable
......@@ -231,6 +231,9 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
PQRYRES VirColumns(PGLOBAL g, bool info);
PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info);
#if defined(REST_SUPPORT)
PQRYRES RESTColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
#endif // REST_SUPPORT
#if defined(JAVA_SUPPORT)
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ url, PTOS topt, bool info);
#endif // JAVA_SUPPORT
......@@ -352,7 +355,7 @@ static MYSQL_THDVAR_UINT(work_size,
static MYSQL_THDVAR_INT(conv_size,
PLUGIN_VAR_RQCMDARG, // opt
"Size used when converting TEXT columns.",
NULL, NULL, SZCONV, 0, 65500, 8192);
NULL, NULL, SZCONV, 0, 65500, 1);
/**
Type conversion:
......@@ -583,6 +586,8 @@ ha_create_table_option connect_table_option_list[]=
HA_TOPTION_STRING("FILTER", filter),
HA_TOPTION_STRING("OPTION_LIST", oplist),
HA_TOPTION_STRING("DATA_CHARSET", data_charset),
HA_TOPTION_STRING("HTTP", http),
HA_TOPTION_STRING("URI", uri),
HA_TOPTION_NUMBER("LRECL", lrecl, 0, 0, INT_MAX32, 1),
HA_TOPTION_NUMBER("BLOCK_SIZE", elements, 0, 0, INT_MAX32, 1),
//HA_TOPTION_NUMBER("ESTIMATE", estimate, 0, 0, INT_MAX32, 1),
......@@ -991,11 +996,11 @@ static PCONNECT GetUser(THD *thd, PCONNECT xp)
pthread_mutex_unlock(&usrmut);
if (!xp) {
xp = new user_connect(thd);
xp= new user_connect(thd);
if (xp->user_init()) {
delete xp;
xp = NULL;
xp= NULL;
} // endif user_init
} // endif xp
......@@ -1027,6 +1032,19 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
if (type == TAB_UNDEF)
type= pos->srcdef ? TAB_MYSQL : pos->tabname ? TAB_PRX : TAB_DOS;
#if defined(REST_SUPPORT)
else if (pos->http)
switch (type) {
case TAB_JSON:
case TAB_XML:
case TAB_CSV:
type = TAB_REST;
break;
case TAB_REST:
type = TAB_NIY;
break;
} // endswitch type
#endif // REST_SUPPORT
} else
type= TAB_UNDEF;
......@@ -1130,48 +1148,48 @@ PCSZ GetListOption(PGLOBAL g, PCSZ opname, PCSZ oplist, PCSZ def)
return (char*)def;
char key[16], val[256];
char *pv, *pn, *pk = (char*)oplist;
PCSZ opval = def;
char *pv, *pn, *pk= (char*)oplist;
PCSZ opval= def;
int n;
while (*pk == ' ')
pk++;
for (; pk; pk = pn) {
pn = strchr(pk, ',');
pv = strchr(pk, '=');
for (; pk; pk= pn) {
pn= strchr(pk, ',');
pv= strchr(pk, '=');
if (pv && (!pn || pv < pn)) {
n = MY_MIN(static_cast<size_t>(pv - pk), sizeof(key) - 1);
n= MY_MIN(static_cast<size_t>(pv - pk), sizeof(key) - 1);
memcpy(key, pk, n);
while (n && key[n - 1] == ' ')
n--;
key[n] = 0;
key[n]= 0;
while (*(++pv) == ' ');
n = MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
n= MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
memcpy(val, pv, n);
while (n && val[n - 1] == ' ')
n--;
val[n] = 0;
val[n]= 0;
} else {
n = MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
n= MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
memcpy(key, pk, n);
while (n && key[n - 1] == ' ')
n--;
key[n] = 0;
val[0] = 0;
key[n]= 0;
val[0]= 0;
} // endif pv
if (!stricmp(opname, key)) {
opval = PlugDup(g, val);
opval= PlugDup(g, val);
break;
} else if (!pn)
break;
......@@ -1219,9 +1237,13 @@ PCSZ GetStringTableOption(PGLOBAL g, PTOS options, PCSZ opname, PCSZ sdef)
else if (!stricmp(opname, "Colist"))
opval= options->colist;
else if (!stricmp(opname, "Filter"))
opval = options->filter;
opval= options->filter;
else if (!stricmp(opname, "Data_charset"))
opval= options->data_charset;
else if (!stricmp(opname, "Http") || !stricmp(opname, "URL"))
opval = options->http;
else if (!stricmp(opname, "Uri"))
opval = options->uri;
if (!opval && options->oplist)
opval= GetListOption(g, opname, options->oplist);
......@@ -1252,7 +1274,7 @@ bool GetBooleanTableOption(PGLOBAL g, PTOS options, PCSZ opname, bool bdef)
else if (!stricmp(opname, "Header"))
opval= (options->header != 0); // Is Boolean for some table types
else if (!stricmp(opname, "Zipped"))
opval = options->zipped;
opval= options->zipped;
else if (options->oplist)
if ((pv= GetListOption(g, opname, options->oplist)))
opval= (!*pv || *pv == 'y' || *pv == 'Y' || atoi(pv) != 0);
......@@ -1346,8 +1368,8 @@ PCSZ ha_connect::GetStringOption(PCSZ opname, PCSZ sdef)
} else if (!stricmp(opname, "Query_String")) {
// This escapes everything and returns a wrong query
// opval = thd_query_string(table->in_use)->str;
opval = (PCSZ)PlugSubAlloc(xp->g, NULL,
// opval= thd_query_string(table->in_use)->str;
opval= (PCSZ)PlugSubAlloc(xp->g, NULL,
thd_query_string(table->in_use)->length + 1);
strcpy((char*)opval, thd_query_string(table->in_use)->str);
// sprintf((char*)opval, "%s", thd_query_string(table->in_use)->str);
......@@ -1368,7 +1390,7 @@ PCSZ ha_connect::GetStringOption(PCSZ opname, PCSZ sdef)
|| !stricmp(opname, "filename")
|| !stricmp(opname, "optname")
|| !stricmp(opname, "entry")))
opval = GetRealString(opval);
opval= GetRealString(opval);
if (!opval) {
if (sdef && !strcmp(sdef, "*")) {
......@@ -1497,7 +1519,7 @@ PFOS ha_connect::GetFieldOptionStruct(Field *fdp)
void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
{
const char *cp;
char *chset, v = 0;
char *chset, v= 0;
ha_field_option_struct *fop;
Field* fp;
Field* *fldp;
......@@ -1549,7 +1571,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Fieldfmt= NULL;
} // endif fop
chset = (char *)fp->charset()->name;
chset= (char *)fp->charset()->name;
switch (fp->type()) {
case MYSQL_TYPE_BLOB:
......@@ -1817,7 +1839,7 @@ const char *ha_connect::GetTableName(void)
{
const char *path= tshp ? tshp->path.str : table_share->path.str;
const char *name= strrchr(path, slash);
return name ? name+1 : path;
return name ? name + 1 : path;
} // end of GetTableName
char *ha_connect::GetPartName(void)
......@@ -2055,10 +2077,10 @@ bool ha_connect::CheckColumnList(PGLOBAL g)
} catch (int n) {
if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
brc = true;
brc= true;
} catch (const char *msg) {
strcpy(g->Message, msg);
brc = true;
brc= true;
} // end catch
return brc;
......@@ -2185,9 +2207,9 @@ int ha_connect::MakeRecord(char *buf)
rc= fp->store(p, strlen(p), charset, CHECK_FIELD_WARN);
break;
case TYPE_BIN:
p = value->GetCharValue();
charset = &my_charset_bin;
rc = fp->store(p, strlen(p), charset, CHECK_FIELD_WARN);
p= value->GetCharValue();
charset= &my_charset_bin;
rc= fp->store(p, strlen(p), charset, CHECK_FIELD_WARN);
break;
case TYPE_DOUBLE:
rc= fp->store(value->GetFloatValue());
......@@ -2436,7 +2458,7 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
kfp= &table->key_info[active_index];
old_map= dbug_tmp_use_all_columns(table, table->write_set);
for (i = 0; i <= 1; i++) {
for (i= 0; i <= 1; i++) {
if (ranges[i] == NULL)
continue;
......@@ -2547,7 +2569,7 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg)
switch (vop) {
case OP_EQ:
val= " = ";
val= "= ";
break;
case OP_NE:
val= " <> ";
......@@ -2817,7 +2839,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
/***********************************************************************/
PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
{
AMT tty = filp->Type;
AMT tty= filp->Type;
char *body= filp->Body;
char *havg= filp->Having;
unsigned int i;
......@@ -2834,7 +2856,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
if (cond->type() == COND::COND_ITEM) {
char *pb0, *pb1, *pb2, *ph0= 0, *ph1= 0, *ph2= 0;
bool bb = false, bh = false;
bool bb= false, bh= false;
Item_cond *cond_item= (Item_cond *)cond;
if (x)
......@@ -2893,13 +2915,13 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
bb |= filp->Bd;
bh |= filp->Hv;
filp->Bd = filp->Hv = false;
filp->Bd= filp->Hv= false;
} else
return NULL;
if (bb) {
strcpy(pb1, ")");
filp->Bd = bb;
filp->Bd= bb;
} else
*pb0= 0;
......@@ -2907,13 +2929,13 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
if (bb && bh && vop == OP_OR) {
// Cannot or'ed a where clause with a having clause
bb= bh= 0;
*pb0 = 0;
*ph0 = 0;
*pb0= 0;
*ph0= 0;
} else if (bh) {
strcpy(ph1, ")");
filp->Hv= bh;
} else
*ph0 = 0;
*ph0= 0;
} // endif havg
......@@ -2926,7 +2948,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
Item_func *condf= (Item_func *)cond;
Item* *args= condf->arguments();
filp->Bd = filp->Hv = false;
filp->Bd= filp->Hv= false;
if (trace(1))
htrc("Func type=%d argnum=%d\n", condf->functype(),
......@@ -2942,10 +2964,10 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
case Item_func::GT_FUNC: vop= OP_GT; break;
case Item_func::LIKE_FUNC:
vop= OP_LIKE;
neg = ((Item_func_opt_neg *)condf)->negated;
neg= ((Item_func_opt_neg *)condf)->negated;
break;
case Item_func::ISNOTNULL_FUNC:
neg = true;
neg= true;
// fall through
case Item_func::ISNULL_FUNC: vop= OP_NULL; break;
case Item_func::IN_FUNC: vop= OP_IN; /* fall through */
......@@ -3003,12 +3025,12 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
} else {
bool h;
fnm = filp->Chk(pField->field->field_name, &h);
fnm= filp->Chk(pField->field->field_name, &h);
if (h && i && !ishav)
return NULL; // Having should be col VOP arg
else
ishav = h;
ishav= h;
} // endif's
......@@ -3059,7 +3081,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
if (!x) {
const char *p;
char *s = (ishav) ? havg : body;
char *s= (ishav) ? havg : body;
uint j, k, n;
// Append the value to the filter
......@@ -3116,37 +3138,37 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
strcat(s, "'}");
break;
default:
j = strlen(s);
s[j++] = '\'';
p = res->ptr();
n = res->length();
j= strlen(s);
s[j++]= '\'';
p= res->ptr();
n= res->length();
for (k = 0; k < n; k++) {
for (k= 0; k < n; k++) {
if (p[k] == '\'')
s[j++] = '\'';
s[j++]= '\'';
s[j++] = p[k];
s[j++]= p[k];
} // endfor k
s[j++] = '\'';
s[j] = 0;
s[j++]= '\'';
s[j]= 0;
} // endswitch field type
} else {
j = strlen(s);
s[j++] = '\'';
p = res->ptr();
n = res->length();
j= strlen(s);
s[j++]= '\'';
p= res->ptr();
n= res->length();
for (k = 0; k < n; k++) {
for (k= 0; k < n; k++) {
if (p[k] == '\'')
s[j++] = '\'';
s[j++]= '\'';
s[j++] = p[k];
s[j++]= p[k];
} // endfor k
s[j++] = '\'';
s[j] = 0;
s[j++]= '\'';
s[j]= 0;
} // endif tty
break;
......@@ -3170,7 +3192,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
} // endif's Type
if (!x) {
char *s = (ishav) ? havg : body;
char *s= (ishav) ? havg : body;
if (!i)
strcat(s, GetValStr(vop, neg));
......@@ -3184,11 +3206,11 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
} // endfor i
if (x)
filp->Op = vop;
filp->Op= vop;
else if (ishav)
filp->Hv = true;
filp->Hv= true;
else
filp->Bd = true;
filp->Bd= true;
} else {
if (trace(1))
......@@ -3238,21 +3260,21 @@ const COND *ha_connect::cond_push(const COND *cond)
PCFIL filp;
int rc;
if ((filp = tdbp->GetCondFil()) && tdbp->GetCond() == cond &&
if ((filp= tdbp->GetCondFil()) && tdbp->GetCond() == cond &&
filp->Idx == active_index && filp->Type == tty)
goto fin;
filp = new(g) CONDFIL(active_index, tty);
rc = filp->Init(g, this);
filp= new(g) CONDFIL(active_index, tty);
rc= filp->Init(g, this);
if (rc == RC_INFO) {
filp->Having = (char*)PlugSubAlloc(g, NULL, 256);
*filp->Having = 0;
filp->Having= (char*)PlugSubAlloc(g, NULL, 256);
*filp->Having= 0;
} else if (rc == RC_FX)
goto fin;
filp->Body = (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
*filp->Body = 0;
filp->Body= (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
*filp->Body= 0;
if (CheckCond(g, filp, cond)) {
if (filp->Having && strlen(filp->Having) > 255)
......@@ -3266,7 +3288,7 @@ const COND *ha_connect::cond_push(const COND *cond)
if (!x)
PlugSubAlloc(g, NULL, strlen(filp->Body) + 1);
else
cond = NULL; // Does this work?
cond= NULL; // Does this work?
tdbp->SetCondFil(filp);
} else if (x && cond)
......@@ -3316,8 +3338,8 @@ ha_rows ha_connect::records()
int ha_connect::check(THD* thd, HA_CHECK_OPT* check_opt)
{
int rc = HA_ADMIN_OK;
PGLOBAL g = ((table && table->in_use) ? GetPlug(table->in_use, xp) :
int rc= HA_ADMIN_OK;
PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) :
(xp) ? xp->g : NULL);
DBUG_ENTER("ha_connect::check");
......@@ -3327,32 +3349,32 @@ int ha_connect::check(THD* thd, HA_CHECK_OPT* check_opt)
// Do not close the table if it was opened yet (possible?)
if (IsOpened()) {
if (IsPartitioned() && CheckColumnList(g)) // map can have been changed
rc = HA_ADMIN_CORRUPT;
rc= HA_ADMIN_CORRUPT;
else if (tdbp->OpenDB(g)) // Rewind table
rc = HA_ADMIN_CORRUPT;
rc= HA_ADMIN_CORRUPT;
} else if (xp->CheckQuery(valid_query_id)) {
tdbp = NULL; // Not valid anymore
tdbp= NULL; // Not valid anymore
if (OpenTable(g, false))
rc = HA_ADMIN_CORRUPT;
rc= HA_ADMIN_CORRUPT;
} else // possible?
DBUG_RETURN(HA_ADMIN_INTERNAL_ERROR);
if (rc == HA_ADMIN_OK) {
TABTYPE type = GetTypeID(GetStringOption("Type", "*"));
TABTYPE type= GetTypeID(GetStringOption("Type", "*"));
if (IsFileType(type)) {
if (check_opt->flags & T_MEDIUM) {
// TO DO
do {
if ((rc = CntReadNext(g, tdbp)) == RC_FX)
if ((rc= CntReadNext(g, tdbp)) == RC_FX)
break;
} while (rc != RC_EF);
rc = (rc == RC_EF) ? HA_ADMIN_OK : HA_ADMIN_CORRUPT;
rc= (rc == RC_EF) ? HA_ADMIN_OK : HA_ADMIN_CORRUPT;
} else if (check_opt->flags & T_EXTEND) {
// TO DO
} // endif's flags
......@@ -3380,7 +3402,7 @@ bool ha_connect::get_error_message(int error, String* buf)
DBUG_ENTER("ha_connect::get_error_message");
if (xp && xp->g) {
PGLOBAL g = xp->g;
PGLOBAL g= xp->g;
if (trace(1))
htrc("GEM(%d): %s\n", error, g->Message);
......@@ -3489,32 +3511,32 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT*)
try {
// Ignore error on the opt file
dup->Check &= ~CHK_OPT;
tdbp = GetTDB(g);
tdbp= GetTDB(g);
dup->Check |= CHK_OPT;
if (tdbp && !tdbp->IsRemote()) {
bool dop = IsTypeIndexable(GetRealType(NULL));
bool dox = (tdbp->GetDef()->Indexable() == 1);
bool dop= IsTypeIndexable(GetRealType(NULL));
bool dox= (tdbp->GetDef()->Indexable() == 1);
if ((rc = ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) {
if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) {
if (rc == RC_INFO) {
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
rc = 0;
rc= 0;
} else
rc = HA_ERR_CRASHED_ON_USAGE; // Table must be repaired
rc= HA_ERR_CRASHED_ON_USAGE; // Table must be repaired
} // endif rc
} else if (!tdbp)
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
} catch (int n) {
if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
} catch (const char *msg) {
strcpy(g->Message, msg);
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
} // end catch
if (rc)
......@@ -4214,7 +4236,7 @@ int ha_connect::rnd_pos(uchar *buf, uchar *pos)
tdbp->SetFilter(NULL);
rc= rnd_next(buf);
} else {
PGLOBAL g = GetPlug((table) ? table->in_use : NULL, xp);
PGLOBAL g= GetPlug((table) ? table->in_use : NULL, xp);
// strcpy(g->Message, "Not supported by this table type");
my_message(ER_ILLEGAL_HA, g->Message, MYF(0));
rc= HA_ERR_INTERNAL_ERROR;
......@@ -4298,12 +4320,12 @@ int ha_connect::info(uint flag)
} else
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
if (!(tdbp = GetTDB(g))) {
if (!(tdbp= GetTDB(g))) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif tdbp
valid_info = false;
valid_info= false;
} // endif tdbp
if (!valid_info) {
......@@ -4446,6 +4468,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
case TAB_XML:
case TAB_INI:
case TAB_VEC:
case TAB_REST:
case TAB_JSON:
if (options->filename && *options->filename) {
if (!quick) {
......@@ -4582,13 +4605,13 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
// newmode= MODE_UPDATE; // To be checked
// break;
case SQLCOM_DELETE_MULTI:
*cras = true;
*cras= true;
case SQLCOM_DELETE:
case SQLCOM_TRUNCATE:
newmode= MODE_DELETE;
break;
case SQLCOM_UPDATE_MULTI:
*cras = true;
*cras= true;
case SQLCOM_UPDATE:
newmode= MODE_UPDATE;
break;
......@@ -4616,7 +4639,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
break;
// } // endif partitioned
case SQLCOM_REPAIR: // TODO implement it
newmode = MODE_UPDATE;
newmode= MODE_UPDATE;
break;
default:
htrc("Unsupported sql_command=%d\n", thd_sql_command(thd));
......@@ -4731,15 +4754,15 @@ int ha_connect::start_stmt(THD *thd, thr_lock_type lock_type)
if (CloseTable(g)) {
// Make error a warning to avoid crash
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
rc = 0;
rc= 0;
} // endif Close
locked = 0;
xmod = MODE_ANY; // For info commands
locked= 0;
xmod= MODE_ANY; // For info commands
DBUG_RETURN(rc);
} // endif MODE_ANY
newmode = CheckMode(g, thd, newmode, &chk, &cras);
newmode= CheckMode(g, thd, newmode, &chk, &cras);
if (newmode == MODE_ERROR)
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
......@@ -4815,7 +4838,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
DBUG_RETURN(0);
} else if (g->Xchk) {
if (!tdbp) {
if (!(tdbp = GetTDB(g))) {
if (!(tdbp= GetTDB(g))) {
// DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
DBUG_RETURN(0);
......@@ -4952,7 +4975,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
int ha_connect::check_stmt(PGLOBAL g, MODE newmode, bool cras)
{
int rc = 0;
int rc= 0;
DBUG_ENTER("ha_connect::check_stmt");
// If this is the start of a new query, cleanup the previous one
......@@ -5039,7 +5062,7 @@ THR_LOCK_DATA **ha_connect::store_lock(THD *,
{
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
lock.type=lock_type;
*to++ = &lock;
*to++= &lock;
return to;
}
......@@ -5316,7 +5339,7 @@ static bool add_field(String *sql, const char *field_name, int typ, int len,
int dec, char *key, uint tm, const char *rem, char *dft,
char *xtra, char *fmt, int flag, bool dbf, char v)
{
char var = (len > 255) ? 'V' : v;
char var= (len > 255) ? 'V' : v;
bool q, error= false;
const char *type= PLGtoMYSQLtype(typ, dbf, var);
......@@ -5360,9 +5383,9 @@ static bool add_field(String *sql, const char *field_name, int typ, int len,
error|= sql->append(" DEFAULT ");
if (typ == TYPE_DATE)
q = (strspn(dft, "0123456789 -:/") == strlen(dft));
q= (strspn(dft, "0123456789 -:/") == strlen(dft));
else
q = !IsTypeNum(typ);
q= !IsTypeNum(typ);
if (q) {
error|= sql->append("'");
......@@ -5514,13 +5537,13 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
PCSZ fncn= "?";
PCSZ user, fn, db, host, pwd, sep, tbl, src;
PCSZ col, ocl, rnk, pic, fcl, skc, zfn;
char *tab, *dsn, *shm, *dpath;
char *tab, *dsn, *shm, *dpath, *url;
#if defined(__WIN__)
PCSZ nsp= NULL, cls= NULL;
#endif // __WIN__
//int hdr, mxe;
int port = 0, mxr = 0, rc = 0, mul = 0, lrecl = 0;
//PCSZ tabtyp = NULL;
int port= 0, mxr= 0, rc= 0, mul= 0, lrecl= 0;
//PCSZ tabtyp= NULL;
#if defined(ODBC_SUPPORT)
POPARM sop= NULL;
PCSZ ucnc= NULL;
......@@ -5530,7 +5553,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if defined(JAVA_SUPPORT)
PJPARM sjp= NULL;
PCSZ driver= NULL;
char *url= NULL;
#endif // JAVA_SUPPORT
uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
bool bif, ok= false, dbf= false;
......@@ -5550,7 +5572,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
String sql(buf, sizeof(buf), system_charset_info);
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
user= host= pwd= tbl= src= col= ocl= pic= fcl= skc= rnk= zfn= dsn= NULL;
user = host = pwd = tbl = src = col = ocl = pic = fcl = skc = rnk = zfn = NULL;
dsn = url = NULL;
// Get the useful create options
ttp= GetTypeID(topt->type);
......@@ -5561,7 +5584,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
fncn= topt->catfunc;
fnc= GetFuncID(fncn);
sep= topt->separator;
mul = (int)topt->multiple;
mul= (int)topt->multiple;
tbl= topt->tablist;
col= topt->colist;
......@@ -5584,7 +5607,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // __WIN__
port= atoi(GetListOption(g, "port", topt->oplist, "0"));
#if defined(ODBC_SUPPORT)
// tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL);
// tabtyp= GetListOption(g, "Tabtype", topt->oplist, NULL);
mxr= atoi(GetListOption(g,"maxres", topt->oplist, "0"));
cto= atoi(GetListOption(g,"ConnectTimeout", topt->oplist, "-1"));
qto= atoi(GetListOption(g,"QueryTimeout", topt->oplist, "-1"));
......@@ -5599,7 +5622,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0"));
#endif // PROMPT_OK
#if defined(ZIP_SUPPORT)
zfn = GetListOption(g, "Zipfile", topt->oplist, NULL);
zfn= GetListOption(g, "Zipfile", topt->oplist, NULL);
#endif // ZIP_SUPPORT
} else {
host= "localhost";
......@@ -5612,14 +5635,24 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
try {
// Check table type
if (ttp == TAB_UNDEF) {
topt->type = (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
ttp = GetTypeID(topt->type);
topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
ttp= GetTypeID(topt->type);
sprintf(g->Message, "No table_type. Was set to %s", topt->type);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
} else if (ttp == TAB_NIY) {
sprintf(g->Message, "Unsupported table type %s", topt->type);
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
goto err;
#if defined(REST_SUPPORT)
} else if (topt->http) {
switch (ttp) {
case TAB_JSON:
case TAB_XML:
case TAB_CSV:
ttp = TAB_REST;
break;
} // endswitch type
#endif // REST_SUPPORT
} // endif ttp
if (!tab) {
......@@ -5629,39 +5662,39 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (!tbl) {
strcpy(g->Message, "Missing table list");
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
goto err;
} // endif tbl
tab = PlugDup(g, tbl);
tab= PlugDup(g, tbl);
if ((p = strchr(tab, ',')))
*p = 0;
if ((p= strchr(tab, ',')))
*p= 0;
if ((p = strchr(tab, '.'))) {
*p = 0;
db = tab;
tab = p + 1;
if ((p= strchr(tab, '.'))) {
*p= 0;
db= tab;
tab= p + 1;
} // endif p
} else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL)))
tab = (char*)table_s->table_name.str; // Default value
tab= (char*)table_s->table_name.str; // Default value
} // endif tab
switch (ttp) {
#if defined(ODBC_SUPPORT)
case TAB_ODBC:
dsn = strz(g, create_info->connect_string);
dsn= strz(g, create_info->connect_string);
if (fnc & (FNC_DSN | FNC_DRIVER)) {
ok = true;
ok= true;
#if defined(PROMPT_OK)
} else if (!stricmp(thd->main_security_ctx.host, "localhost")
&& cop == 1) {
if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) {
if ((dsn= ODBCCheckConnection(g, dsn, cop)) != NULL) {
thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn));
ok = true;
ok= true;
} // endif dsn
#endif // PROMPT_OK
......@@ -5669,13 +5702,13 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
sprintf(g->Message, "Missing %s connection string", topt->type);
} else {
// Store ODBC additional parameters
sop = (POPARM)PlugSubAlloc(g, NULL, sizeof(ODBCPARM));
sop->User = (char*)user;
sop->Pwd = (char*)pwd;
sop->Cto = cto;
sop->Qto = qto;
sop->UseCnc = cnc;
ok = true;
sop= (POPARM)PlugSubAlloc(g, NULL, sizeof(ODBCPARM));
sop->User= (char*)user;
sop->Pwd= (char*)pwd;
sop->Cto= cto;
sop->Qto= qto;
sop->UseCnc= cnc;
ok= true;
} // endif's
supfnc |= (FNC_TABLE | FNC_DSN | FNC_DRIVER);
......@@ -5684,31 +5717,31 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if defined(JAVA_SUPPORT)
case TAB_JDBC:
if (fnc & FNC_DRIVER) {
ok = true;
} else if (!(url = strz(g, create_info->connect_string))) {
ok= true;
} else if (!(url= strz(g, create_info->connect_string))) {
strcpy(g->Message, "Missing URL");
} else {
// Store JDBC additional parameters
int rc;
PJDBCDEF jdef = new(g) JDBCDEF();
PJDBCDEF jdef= new(g) JDBCDEF();
jdef->SetName(create_info->alias);
sjp = (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM));
sjp->Driver = driver;
// sjp->Properties = prop;
sjp->Fsize = 0;
sjp->Scrollable = false;
if ((rc = jdef->ParseURL(g, url, false)) == RC_OK) {
sjp->Url = url;
sjp->User = (char*)user;
sjp->Pwd = (char*)pwd;
ok = true;
sjp= (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM));
sjp->Driver= driver;
// sjp->Properties= prop;
sjp->Fsize= 0;
sjp->Scrollable= false;
if ((rc= jdef->ParseURL(g, url, false)) == RC_OK) {
sjp->Url= url;
sjp->User= (char*)user;
sjp->Pwd= (char*)pwd;
ok= true;
} else if (rc == RC_NF) {
if (jdef->GetTabname())
tab = (char*)jdef->GetTabname();
tab= (char*)jdef->GetTabname();
ok = jdef->SetParms(sjp);
ok= jdef->SetParms(sjp);
} // endif rc
} // endif's
......@@ -5717,7 +5750,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
break;
#endif // JAVA_SUPPORT
case TAB_DBF:
dbf = true;
dbf= true;
// fall through
case TAB_CSV:
if (!fn && fnc != FNC_NO)
......@@ -5725,55 +5758,55 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
else if (sep && strlen(sep) > 1)
sprintf(g->Message, "Invalid separator %s", sep);
else
ok = true;
ok= true;
break;
case TAB_MYSQL:
ok = true;
ok= true;
if (create_info->connect_string.str &&
create_info->connect_string.length) {
PMYDEF mydef = new(g) MYSQLDEF();
PMYDEF mydef= new(g) MYSQLDEF();
dsn = strz(g, create_info->connect_string);
dsn= strz(g, create_info->connect_string);
mydef->SetName(create_info->alias);
if (!mydef->ParseURL(g, dsn, false)) {
if (mydef->GetHostname())
host = mydef->GetHostname();
host= mydef->GetHostname();
if (mydef->GetUsername())
user = mydef->GetUsername();
user= mydef->GetUsername();
if (mydef->GetPassword())
pwd = mydef->GetPassword();
pwd= mydef->GetPassword();
if (mydef->GetTabschema())
db = mydef->GetTabschema();
db= mydef->GetTabschema();
if (mydef->GetTabname())
tab = (char*)mydef->GetTabname();
tab= (char*)mydef->GetTabname();
if (mydef->GetPortnumber())
port = mydef->GetPortnumber();
port= mydef->GetPortnumber();
} else
ok = false;
ok= false;
} else if (!user)
user = "root";
user= "root";
if (ok && CheckSelf(g, table_s, host, db, tab, src, port))
ok = false;
ok= false;
break;
#if defined(__WIN__)
case TAB_WMI:
ok = true;
ok= true;
break;
#endif // __WIN__
case TAB_PIVOT:
supfnc = FNC_NO;
supfnc= FNC_NO;
case TAB_PRX:
case TAB_TBL:
case TAB_XCL:
......@@ -5782,12 +5815,12 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
(!db || !stricmp(db, table_s->db.str)))
sprintf(g->Message, "A %s table cannot refer to itself", topt->type);
else
ok = true;
ok= true;
break;
case TAB_OEM:
if (topt->module && topt->subtype)
ok = true;
ok= true;
else
strcpy(g->Message, "Missing OEM module or subtype");
......@@ -5796,24 +5829,33 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case TAB_XML:
#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT
case TAB_JSON:
dsn = strz(g, create_info->connect_string);
dsn= strz(g, create_info->connect_string);
if (!fn && !zfn && !mul && !dsn)
sprintf(g->Message, "Missing %s file name", topt->type);
else
ok = true;
ok= true;
break;
#if defined(JAVA_SUPPORT)
case TAB_MONGO:
if (!topt->tabname)
topt->tabname = tab;
topt->tabname= tab;
ok = true;
ok= true;
break;
#endif // JAVA_SUPPORT
case TAB_VIR:
#if defined(REST_SUPPORT)
case TAB_REST:
if (!topt->http)
sprintf(g->Message, "Missing %s HTTP address", topt->type);
else
ok = true;
break;
#endif // REST_SUPPORT
case TAB_VIR:
ok= true;
break;
default:
sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
......@@ -5824,12 +5866,12 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (ok && !(supfnc & fnc)) {
sprintf(g->Message, "Unsupported catalog function %s for table type %s",
fncn, topt->type);
ok = false;
ok= false;
} // endif supfnc
if (src && fnc != FNC_NO) {
strcpy(g->Message, "Cannot make catalog table from srcdef");
ok = false;
ok= false;
} // endif src
if (ok) {
......@@ -5837,23 +5879,23 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
char *dft, *xtra, *key, *fmt;
int i, len, prec, dec, typ, flg;
if (!(dpath = SetPath(g, table_s->db.str))) {
rc = HA_ERR_INTERNAL_ERROR;
if (!(dpath= SetPath(g, table_s->db.str))) {
rc= HA_ERR_INTERNAL_ERROR;
goto err;
} // endif dpath
if (src && ttp != TAB_PIVOT && ttp != TAB_ODBC && ttp != TAB_JDBC) {
qrp = SrcColumns(g, host, db, user, pwd, src, port);
qrp= SrcColumns(g, host, db, user, pwd, src, port);
if (qrp && ttp == TAB_OCCUR)
if (OcrSrcCols(g, qrp, col, ocl, rnk)) {
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
goto err;
} // endif OcrSrcCols
} else switch (ttp) {
case TAB_DBF:
qrp = DBFColumns(g, dpath, fn, fnc == FNC_COL);
qrp= DBFColumns(g, dpath, fn, fnc == FNC_COL);
break;
#if defined(ODBC_SUPPORT)
case TAB_ODBC:
......@@ -5861,21 +5903,21 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case FNC_NO:
case FNC_COL:
if (src) {
qrp = ODBCSrcCols(g, dsn, (char*)src, sop);
src = NULL; // for next tests
qrp= ODBCSrcCols(g, dsn, (char*)src, sop);
src= NULL; // for next tests
} else
qrp = ODBCColumns(g, dsn, shm, tab, NULL,
qrp= ODBCColumns(g, dsn, shm, tab, NULL,
mxr, fnc == FNC_COL, sop);
break;
case FNC_TABLE:
qrp = ODBCTables(g, dsn, shm, tab, NULL, mxr, true, sop);
qrp= ODBCTables(g, dsn, shm, tab, NULL, mxr, true, sop);
break;
case FNC_DSN:
qrp = ODBCDataSources(g, mxr, true);
qrp= ODBCDataSources(g, mxr, true);
break;
case FNC_DRIVER:
qrp = ODBCDrivers(g, mxr, true);
qrp= ODBCDrivers(g, mxr, true);
break;
default:
sprintf(g->Message, "invalid catfunc %s", fncn);
......@@ -5890,23 +5932,23 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case FNC_NO:
case FNC_COL:
if (src) {
qrp = JDBCSrcCols(g, (char*)src, sjp);
src = NULL; // for next tests
qrp= JDBCSrcCols(g, (char*)src, sjp);
src= NULL; // for next tests
} else
qrp = JDBCColumns(g, shm, tab, NULL, mxr, fnc == FNC_COL, sjp);
qrp= JDBCColumns(g, shm, tab, NULL, mxr, fnc == FNC_COL, sjp);
break;
case FNC_TABLE:
// qrp = JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp);
qrp = JDBCTables(g, shm, tab, NULL, mxr, true, sjp);
// qrp= JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp);
qrp= JDBCTables(g, shm, tab, NULL, mxr, true, sjp);
break;
#if 0
case FNC_DSN:
qrp = JDBCDataSources(g, mxr, true);
qrp= JDBCDataSources(g, mxr, true);
break;
#endif // 0
case FNC_DRIVER:
qrp = JDBCDrivers(g, mxr, true);
qrp= JDBCDrivers(g, mxr, true);
break;
default:
sprintf(g->Message, "invalid catfunc %s", fncn);
......@@ -5916,56 +5958,61 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
break;
#endif // JAVA_SUPPORT
case TAB_MYSQL:
qrp = MyColumns(g, thd, host, db, user, pwd, tab,
qrp= MyColumns(g, thd, host, db, user, pwd, tab,
NULL, port, fnc == FNC_COL);
break;
case TAB_CSV:
qrp = CSVColumns(g, dpath, topt, fnc == FNC_COL);
qrp= CSVColumns(g, dpath, topt, fnc == FNC_COL);
break;
#if defined(__WIN__)
case TAB_WMI:
qrp = WMIColumns(g, nsp, cls, fnc == FNC_COL);
qrp= WMIColumns(g, nsp, cls, fnc == FNC_COL);
break;
#endif // __WIN__
case TAB_PRX:
case TAB_TBL:
case TAB_XCL:
case TAB_OCCUR:
bif = fnc == FNC_COL;
qrp = TabColumns(g, thd, db, tab, bif);
bif= fnc == FNC_COL;
qrp= TabColumns(g, thd, db, tab, bif);
if (!qrp && bif && fnc != FNC_COL) // tab is a view
qrp = MyColumns(g, thd, host, db, user, pwd, tab, NULL, port, false);
qrp= MyColumns(g, thd, host, db, user, pwd, tab, NULL, port, false);
if (qrp && ttp == TAB_OCCUR && fnc != FNC_COL)
if (OcrColumns(g, qrp, col, ocl, rnk)) {
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
goto err;
} // endif OcrColumns
break;
case TAB_PIVOT:
qrp = PivotColumns(g, tab, src, pic, fcl, skc, host, db, user, pwd, port);
qrp= PivotColumns(g, tab, src, pic, fcl, skc, host, db, user, pwd, port);
break;
case TAB_VIR:
qrp = VirColumns(g, fnc == FNC_COL);
qrp= VirColumns(g, fnc == FNC_COL);
break;
case TAB_JSON:
qrp = JSONColumns(g, db, dsn, topt, fnc == FNC_COL);
qrp= JSONColumns(g, db, dsn, topt, fnc == FNC_COL);
break;
#if defined(JAVA_SUPPORT)
case TAB_MONGO:
url = strz(g, create_info->connect_string);
qrp = MGOColumns(g, db, url, topt, fnc == FNC_COL);
url= strz(g, create_info->connect_string);
qrp= MGOColumns(g, db, url, topt, fnc == FNC_COL);
break;
#endif // JAVA_SUPPORT
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
case TAB_XML:
qrp = XMLColumns(g, (char*)db, tab, topt, fnc == FNC_COL);
qrp= XMLColumns(g, (char*)db, tab, topt, fnc == FNC_COL);
break;
#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT
#if defined(REST_SUPPORT)
case TAB_REST:
qrp = RESTColumns(g, topt, tab, (char *)db, fnc == FNC_COL);
break;
#endif // REST_SUPPORT
case TAB_OEM:
qrp = OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL);
qrp= OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL);
break;
default:
strcpy(g->Message, "System error during assisted discovery");
......@@ -5973,33 +6020,33 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
} // endswitch ttp
if (!qrp) {
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
goto err;
} // endif !qrp
if (fnc != FNC_NO || src || ttp == TAB_PIVOT) {
// Catalog like table
for (crp = qrp->Colresp; !rc && crp; crp = crp->Next) {
cnm = (ttp == TAB_PIVOT) ? crp->Name : encode(g, crp->Name);
typ = crp->Type;
len = crp->Length;
dec = crp->Prec;
flg = crp->Flag;
v = (crp->Kdata->IsUnsigned()) ? 'U' : crp->Var;
tm = (crp->Kdata->IsNullable()) ? 0 : NOT_NULL_FLAG;
for (crp= qrp->Colresp; !rc && crp; crp= crp->Next) {
cnm= (ttp == TAB_PIVOT) ? crp->Name : encode(g, crp->Name);
typ= crp->Type;
len= crp->Length;
dec= crp->Prec;
flg= crp->Flag;
v= (crp->Kdata->IsUnsigned()) ? 'U' : crp->Var;
tm= (crp->Kdata->IsNullable()) ? 0 : NOT_NULL_FLAG;
if (!len && typ == TYPE_STRING)
len = 256; // STRBLK's have 0 length
len= 256; // STRBLK's have 0 length
// Now add the field
if (add_field(&sql, cnm, typ, len, dec, NULL, tm,
NULL, NULL, NULL, NULL, flg, dbf, v))
rc = HA_ERR_OUT_OF_MEM;
rc= HA_ERR_OUT_OF_MEM;
} // endfor crp
} else {
char *schem = NULL;
char *tn = NULL;
char *schem= NULL;
char *tn= NULL;
// Not a catalog table
if (!qrp->Nblin) {
......@@ -6008,57 +6055,57 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
else
strcpy(g->Message, "Fail to retrieve columns");
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
goto err;
} // endif !nblin
for (i = 0; !rc && i < qrp->Nblin; i++) {
typ = len = prec = dec = 0;
tm = NOT_NULL_FLAG;
cnm = (char*)"noname";
dft = xtra = key = fmt = tn = NULL;
v = ' ';
rem = NULL;
for (i= 0; !rc && i < qrp->Nblin; i++) {
typ= len= prec= dec= 0;
tm= NOT_NULL_FLAG;
cnm= (char*)"noname";
dft= xtra= key= fmt= tn= NULL;
v= ' ';
rem= NULL;
for (crp = qrp->Colresp; crp; crp = crp->Next)
for (crp= qrp->Colresp; crp; crp= crp->Next)
switch (crp->Fld) {
case FLD_NAME:
if (ttp == TAB_PRX ||
(ttp == TAB_CSV && topt->data_charset &&
(!stricmp(topt->data_charset, "UTF8") ||
!stricmp(topt->data_charset, "UTF-8"))))
cnm = crp->Kdata->GetCharValue(i);
cnm= crp->Kdata->GetCharValue(i);
else
cnm = encode(g, crp->Kdata->GetCharValue(i));
cnm= encode(g, crp->Kdata->GetCharValue(i));
break;
case FLD_TYPE:
typ = crp->Kdata->GetIntValue(i);
v = (crp->Nulls) ? crp->Nulls[i] : 0;
typ= crp->Kdata->GetIntValue(i);
v= (crp->Nulls) ? crp->Nulls[i] : 0;
break;
case FLD_TYPENAME:
tn = crp->Kdata->GetCharValue(i);
tn= crp->Kdata->GetCharValue(i);
break;
case FLD_PREC:
// PREC must be always before LENGTH
len = prec = crp->Kdata->GetIntValue(i);
len= prec= crp->Kdata->GetIntValue(i);
break;
case FLD_LENGTH:
len = crp->Kdata->GetIntValue(i);
len= crp->Kdata->GetIntValue(i);
break;
case FLD_SCALE:
dec = (!crp->Kdata->IsNull(i)) ? crp->Kdata->GetIntValue(i) : -1;
dec= (!crp->Kdata->IsNull(i)) ? crp->Kdata->GetIntValue(i) : -1;
break;
case FLD_NULL:
if (crp->Kdata->GetIntValue(i))
tm = 0; // Nullable
tm= 0; // Nullable
break;
case FLD_FORMAT:
fmt = (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL;
fmt= (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL;
break;
case FLD_REM:
rem = crp->Kdata->GetCharValue(i);
rem= crp->Kdata->GetCharValue(i);
break;
// case FLD_CHARSET:
// No good because remote table is already translated
......@@ -6067,19 +6114,19 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
// break;
case FLD_DEFAULT:
dft = crp->Kdata->GetCharValue(i);
dft= crp->Kdata->GetCharValue(i);
break;
case FLD_EXTRA:
xtra = crp->Kdata->GetCharValue(i);
xtra= crp->Kdata->GetCharValue(i);
// Auto_increment is not supported yet
if (!stricmp(xtra, "AUTO_INCREMENT"))
xtra = NULL;
xtra= NULL;
break;
case FLD_KEY:
if (ttp == TAB_VIR)
key = crp->Kdata->GetCharValue(i);
key= crp->Kdata->GetCharValue(i);
break;
case FLD_SCHEM:
......@@ -6088,10 +6135,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (schem && stricmp(schem, crp->Kdata->GetCharValue(i))) {
sprintf(g->Message,
"Several %s tables found, specify DBNAME", tab);
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
goto err;
} else if (!schem)
schem = crp->Kdata->GetCharValue(i);
schem= crp->Kdata->GetCharValue(i);
} // endif ttp
#endif // ODBC_SUPPORT || JAVA_SUPPORT
......@@ -6102,10 +6149,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if defined(ODBC_SUPPORT)
if (ttp == TAB_ODBC) {
int plgtyp;
bool w = false; // Wide character type
bool w= false; // Wide character type
// typ must be PLG type, not SQL type
if (!(plgtyp = TranslateSQLType(typ, dec, prec, v, w))) {
if (!(plgtyp= TranslateSQLType(typ, dec, prec, v, w))) {
if (GetTypeConv() == TPC_SKIP) {
// Skip this column
sprintf(g->Message, "Column %s skipped (unsupported type %d)",
......@@ -6114,12 +6161,12 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
continue;
} else {
sprintf(g->Message, "Unsupported SQL type %d", typ);
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
goto err;
} // endif type_conv
} else
typ = plgtyp;
typ= plgtyp;
switch (typ) {
case TYPE_STRING:
......@@ -6134,10 +6181,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
prec += (dec + 2); // To be safe
break;
case TYPE_DECIM:
prec = len;
prec= len;
break;
default:
dec = 0;
dec= 0;
} // endswitch typ
} else
......@@ -6147,7 +6194,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
int plgtyp;
// typ must be PLG type, not SQL type
if (!(plgtyp = TranslateJDBCType(typ, tn, dec, prec, v))) {
if (!(plgtyp= TranslateJDBCType(typ, tn, dec, prec, v))) {
if (GetTypeConv() == TPC_SKIP) {
// Skip this column
sprintf(g->Message, "Column %s skipped (unsupported type %d)",
......@@ -6156,12 +6203,12 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
continue;
} else {
sprintf(g->Message, "Unsupported SQL type %d", typ);
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
goto err;
} // endif type_conv
} else
typ = plgtyp;
typ= plgtyp;
switch (typ) {
case TYPE_DOUBLE:
......@@ -6170,43 +6217,43 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
prec += (dec + 2); // To be safe
break;
default:
dec = 0;
dec= 0;
} // endswitch typ
} else
#endif // ODBC_SUPPORT
// Make the arguments as required by add_fields
if (typ == TYPE_DOUBLE)
prec = len;
prec= len;
if (typ == TYPE_DATE)
prec = 0;
prec= 0;
// Now add the field
if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
fmt, 0, dbf, v))
rc = HA_ERR_OUT_OF_MEM;
rc= HA_ERR_OUT_OF_MEM;
} // endfor i
} // endif fnc
if (!rc)
rc = init_table_share(thd, table_s, create_info, &sql);
rc= init_table_share(thd, table_s, create_info, &sql);
//g->jump_level--;
//PopUser(xp);
//return rc;
} else {
rc = HA_ERR_UNSUPPORTED;
rc= HA_ERR_UNSUPPORTED;
} // endif ok
} catch (int n) {
if (trace(1))
htrc("Exception %d: %s\n", n, g->Message);
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
} catch (const char *msg) {
strcpy(g->Message, msg);
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
} // end catch
err:
......@@ -6274,8 +6321,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
TABTYPE type;
TABLE *st= table; // Probably unuseful
THD *thd= ha_thd();
LEX_STRING cnc = table_arg->s->connect_string;
#ifdef WITH_PARTITION_STORAGE_ENGINE
LEX_STRING cnc= table_arg->s->connect_string;
#if defined(WITH_PARTITION_STORAGE_ENGINE)
partition_info *part_info= table_arg->part_info;
#else // !WITH_PARTITION_STORAGE_ENGINE
#define part_info 0
......@@ -6401,7 +6448,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
host= mydef->GetHostname();
if (mydef->GetTabschema())
db = mydef->GetTabschema();
db= mydef->GetTabschema();
if (mydef->GetTabname())
tab= mydef->GetTabname();
......@@ -6484,7 +6531,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif type JSON
if (type == TAB_CSV) {
const char *sep = options->separator;
const char *sep= options->separator;
if (sep && strlen(sep) > 1) {
sprintf(g->Message, "Invalid separator %s", sep);
......@@ -6685,15 +6732,15 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (options->zipped) {
// Check whether the zip entry must be made from a file
PCSZ fn = GetListOption(g, "Load", options->oplist, NULL);
PCSZ fn= GetListOption(g, "Load", options->oplist, NULL);
if (fn) {
char zbuf[_MAX_PATH], buf[_MAX_PATH], dbpath[_MAX_PATH];
PCSZ entry = GetListOption(g, "Entry", options->oplist, NULL);
PCSZ a = GetListOption(g, "Append", options->oplist, "NO");
bool append = *a == '1' || *a == 'Y' || *a == 'y' || !stricmp(a, "ON");
PCSZ m = GetListOption(g, "Mulentries", options->oplist, "NO");
bool mul = *m == '1' || *m == 'Y' || *m == 'y' || !stricmp(m, "ON");
PCSZ entry= GetListOption(g, "Entry", options->oplist, NULL);
PCSZ a= GetListOption(g, "Append", options->oplist, "NO");
bool append= *a == '1' || *a == 'Y' || *a == 'y' || !stricmp(a, "ON");
PCSZ m= GetListOption(g, "Mulentries", options->oplist, "NO");
bool mul= *m == '1' || *m == 'Y' || *m == 'y' || !stricmp(m, "ON");
if (!entry && !mul) {
my_message(ER_UNKNOWN_ERROR, "Missing entry name", MYF(0));
......@@ -6761,7 +6808,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (SetDataPath(g, table_arg->s->db.str)) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc = HA_ERR_INTERNAL_ERROR;
rc= HA_ERR_INTERNAL_ERROR;
} else if (cat) {
if (part_info)
strncpy(partname,
......@@ -7103,7 +7150,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
/*
ALTER TABLE tbl_name CONVERT TO CHARACTER SET .. and
ALTER TABLE table_name DEFAULT CHARSET = .. most likely
ALTER TABLE table_name DEFAULT CHARSET= .. most likely
change column charsets and so not supported in-place through
old API.
......@@ -7335,7 +7382,7 @@ maria_declare_plugin(connect)
0x0106, /* version number (1.06) */
NULL, /* status variables */
connect_system_variables, /* system variables */
"1.06.0009", /* string version */
"1.06.0010", /* string version */
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
}
maria_declare_plugin_end;
......@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/** @file ha_connect.h
Author Olivier Bertrand
......@@ -32,6 +32,10 @@
/****************************************************************************/
#include "mycat.h"
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
bool MongoEnabled(void);
#endif // JAVA_SUPPORT || CMGO_SUPPORT
/****************************************************************************/
/* Structures used to pass info between CONNECT and ha_connect. */
/****************************************************************************/
......
......@@ -16,7 +16,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*/
#include "my_global.h"
......@@ -194,7 +194,7 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section )
}
for (key = section->key; key; key = key->next)
if (key->name[0]) {
if (key->name && key->name[0]) {
fprintf(file, "%s", SVP(key->name));
if (key->value)
......
......@@ -272,7 +272,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
if (MakeSelector(g, filp, s)) {
strcpy(g->Message, "Failed making selector");
return NULL;
return true;
} else
s->Append('}');
......@@ -340,7 +340,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
if (MakeSelector(g, filp, s)) {
strcpy(g->Message, "Failed making selector");
return NULL;
return true;
} // endif Selector
tdbp->SetFilter(NULL); // Not needed anymore
......@@ -813,4 +813,3 @@ PSZ JMgoConn::GetColumnValue(PSZ path)
return fld;
} // end of GetColumnValue
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
/* PROGRAM NAME: jsonudf Version 1.7 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2018 */
/* PROGRAM NAME: jsonudf Version 1.8 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2019 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
......@@ -1686,7 +1686,7 @@ static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
} // endif *s
if (n < 1)
return "Key";
return (PCSZ) "Key";
if (!b) {
if ((p = (PSZ)PlgDBSubAlloc(g, NULL, n + 1))) {
......@@ -1703,7 +1703,7 @@ static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
return s;
} // endif count
return "Key";
return (PCSZ) "Key";
} // end of MakeKey
/*********************************************************************************/
......
......@@ -1035,7 +1035,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, PCSZ name, PXNODE np)
// If name has the format m[n] only m is taken as node name
if ((p = strchr(pn, '[')))
p = BufAlloc(g, pn, p - pn);
p = BufAlloc(g, pn, int(p - pn));
else
p = pn;
......
......@@ -11,14 +11,14 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/*************** Mycat CC Program Source Code File (.CC) ***************/
/* PROGRAM NAME: MYCAT */
/* ------------- */
/* Version 1.6 */
/* Version 1.7 */
/* */
/* Author: Olivier Bertrand 2012 - 2018 */
/* Author: Olivier Bertrand 2012 - 2019 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
......@@ -93,6 +93,9 @@
#if defined(ZIP_SUPPORT)
#include "tabzip.h"
#endif // ZIP_SUPPORT
#if defined(REST_SUPPORT)
#include "tabrest.h"
#endif // REST_SUPPORT
#include "mycat.h"
/***********************************************************************/
......@@ -181,6 +184,7 @@ bool IsFileType(TABTYPE type)
case TAB_INI:
case TAB_VEC:
case TAB_JSON:
case TAB_REST:
// case TAB_ZIP:
isfile= true;
break;
......@@ -488,8 +492,8 @@ PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
printf("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type));
// If not specified get the type of this table
if (!type)
type= Hc->GetStringOption("Type","*");
//if (!type)
// type= Hc->GetStringOption("Type","*");
return MakeTableDesc(g, tablep, type);
} // end of GetTableDesc
......@@ -501,8 +505,8 @@ PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
{
TABTYPE tc;
LPCSTR name = (PSZ)PlugDup(g, tablep->GetName());
LPCSTR schema = (PSZ)PlugDup(g, tablep->GetSchema());
LPCSTR name= (PSZ)PlugDup(g, tablep->GetName());
LPCSTR schema= (PSZ)PlugDup(g, tablep->GetSchema());
PRELDEF tdp= NULL;
if (trace(1))
......@@ -512,7 +516,11 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
/*********************************************************************/
/* Get a unique enum identifier for types. */
/*********************************************************************/
tc= GetTypeID(am);
if (!am) {
tc = Hc->GetRealType();
am = Hc->GetStringOption("Type", "*");
} else
tc = GetTypeID(am);
switch (tc) {
case TAB_FIX:
......@@ -549,8 +557,11 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
case TAB_VIR: tdp= new(g) VIRDEF; break;
case TAB_JSON: tdp= new(g) JSONDEF; break;
#if defined(ZIP_SUPPORT)
case TAB_ZIP: tdp = new(g) ZIPDEF; break;
case TAB_ZIP: tdp= new(g) ZIPDEF; break;
#endif // ZIP_SUPPORT
#if defined(REST_SUPPORT)
case TAB_REST: tdp= new(g) RESTDEF; break;
#endif // REST_SUPPORT
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
case TAB_MONGO:
if (MongoEnabled()) {
......
......@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/**************** MYCAT H Declares Source Code File (.H) ***************/
/* Name: MYCAT.H Version 2.3 */
......@@ -50,6 +50,8 @@ struct ha_table_option_struct {
const char *filter;
const char *oplist;
const char *data_charset;
const char *http;
const char *uri;
ulonglong lrecl;
ulonglong elements;
//ulonglong estimate;
......
......@@ -82,6 +82,7 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
TAB_JDBC = 26, /* Table accessed via JDBC */
TAB_ZIP = 27, /* ZIP file info table */
TAB_MONGO = 28, /* Table retrieved from MongoDB */
TAB_REST = 29, /* Table retrieved from Rest query */
TAB_NIY = 30}; /* Table not implemented yet */
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
......@@ -400,6 +401,7 @@ typedef class VCTDEF *PVCTDEF;
typedef class PIVOTDEF *PPIVOTDEF;
typedef class DOMDEF *PDOMDEF;
typedef class DIRDEF *PDIRDEF;
typedef class RESTDEF *PRESTDEF;
typedef class OEMDEF *POEMDEF;
typedef class COLCRT *PCOLCRT;
typedef class COLDEF *PCOLDEF;
......
/************* Restget C++ Program Source Code File (.CPP) *************/
/* Adapted from the sample program of the Casablanca tutorial. */
/* Copyright Olivier Bertrand 2019. */
/***********************************************************************/
#include <cpprest/filestream.h>
#include <cpprest/http_client.h>
#if defined(MARIADB)
#include <my_global.h>
#else
#include "mini_global.h"
#endif
using namespace utility::conversions; // String conversions utilities
using namespace web; // Common features like URIs.
using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features
using namespace concurrency::streams; // Asynchronous streams
#include "global.h"
/***********************************************************************/
/* Make a local copy of the requested file. */
/***********************************************************************/
int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
{
int rc= 0;
auto fileStream= std::make_shared<ostream>();
if (!http || !fn) {
strcpy(g->Message, "Missing http or filename");
return 2;
} // endif
//std::string sfn(fn);
//auto wfn= to_string_t(sfn);
//rc= 0;
// Open stream to output file.
pplx::task<void> requestTask=
fstream::open_ostream(to_string_t(fn))
.then([=](ostream outFile) {
*fileStream= outFile;
// Create http_client to send the request.
http_client client(to_string_t(http));
if (uri)
{
// Build request URI and start the request.
uri_builder builder(to_string_t(uri));
return client.request(methods::GET, builder.to_string());
}
else
return client.request(methods::GET);
})
// Handle response headers arriving.
.then([=](http_response response) {
#if defined(DEVELOPMENT)
fprintf(stderr, "Received response status code:%u\n",
response.status_code());
#endif // DEVELOPMENT
// Write response body into the file.
return response.body().read_to_end(fileStream->streambuf());
})
// Close the file stream.
.then([=](size_t) { return fileStream->close(); });
// Wait for all the outstanding I/O to complete and handle any exceptions
try
{
requestTask.wait();
}
catch (const std::exception &e)
{
#if defined(DEVELOPMENT)
fprintf(stderr, "Error exception: %s\n", e.what());
#endif // DEVELOPMENT
sprintf(g->Message, "Error exception: %s", e.what());
rc= 1;
} // end try/catch
return rc;
} // end of restGetFile
\ No newline at end of file
......@@ -641,7 +641,9 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
Cnp->InitValue(g);
if ((n = Jcp->GetResultSize(Query->GetStr(), Cnp)) < 0) {
sprintf(g->Message, "Cannot get result size rc=%d", n);
char* msg = PlugDup(g, g->Message);
sprintf(g->Message, "Get result size: %s (rc=%d)", msg, n);
return true;
} else if (n) {
Jcp->m_Rows = n;
......
......@@ -572,7 +572,7 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Sep = *GetStringCatInfo(g, "Separator", ".");
Accept = GetBoolCatInfo("Accept", false);
// Don't use url as uri when called from REST OEM module
// Don't use url as MONGO uri when called from REST
if (stricmp(am, "REST") && (Uri = GetStringCatInfo(g, "Connect", NULL))) {
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
Collname = GetStringCatInfo(g, "Name",
......
/*************** Rest C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: Rest Version 1.3 */
/* (C) Copyright to the author Olivier BERTRAND 2018 - 2019 */
/* This program is the REST OEM (Web API support) module definition. */
/***********************************************************************/
/***********************************************************************/
/* Definitions needed by the included files. */
/***********************************************************************/
#include <my_global.h> // All MariaDB stuff
/***********************************************************************/
/* 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"
#include "xtable.h"
#include "filamtxt.h"
#include "plgxml.h"
#include "tabdos.h"
#include "tabfmt.h"
#include "tabjson.h"
#include "tabrest.h"
#include "tabxml.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__
/***********************************************************************/
/* Return the columns definition to MariaDB. */
/***********************************************************************/
PQRYRES RESTColumns(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
{
PQRYRES qrp= NULL;
char filename[_MAX_PATH];
PCSZ http, uri, fn, ftype;
http= GetStringTableOption(g, tp, "Http", NULL);
uri= GetStringTableOption(g, tp, "Uri", NULL);
fn= GetStringTableOption(g, tp, "Filename", "rest.json");
ftype = GetStringTableOption(g, tp, "Type", "JSON");
// We used the file name relative to recorded datapath
strcat(strcat(strcat(strcpy(filename, "."), slash), db), slash);
strncat(filename, fn, _MAX_PATH);
// 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);
} else if (!stricmp(ftype, "XML"))
qrp= XMLColumns(g, db, tab, tp, info);
else if (!stricmp(ftype, "JSON"))
qrp= JSONColumns(g, db, NULL, tp, info);
else if (!stricmp(ftype, "CSV"))
qrp= CSVColumns(g, NULL, tp, info);
else
sprintf(g->Message, "Usupported file type %s", ftype);
return qrp;
} // end of RESTColumns
/* -------------------------- Class RESTDEF -------------------------- */
/***********************************************************************/
/* DefineAM: define specific AM block values. */
/***********************************************************************/
bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
char filename[_MAX_PATH];
TABTYPE type= GetTypeID(am);
switch (type) {
case TAB_JSON:
case TAB_XML:
case TAB_CSV:
break;
default:
sprintf(g->Message, "Unsupported REST table type %s", am);
return true;
} // endswitch type
Http= GetStringCatInfo(g, "Http", NULL);
Uri= GetStringCatInfo(g, "Uri", NULL);
Fn= GetStringCatInfo(g, "Filename", "rest.json");
// We used the file name relative to recorded datapath
PlugSetPath(filename, Fn, GetPath());
// Retrieve the file from the web and copy it locally
if (Http && restGetFile(g, Http, Uri, filename)) {}
else if (type == TAB_JSON)
Tdp= new (g) JSONDEF;
else if (type == TAB_XML)
Tdp= new (g) XMLDEF;
else if (type == TAB_CSV)
Tdp= new (g) CSVDEF;
else
sprintf(g->Message, "Unsupported REST table type %s", am);
// Do make the table/view definition
if (Tdp && Tdp->Define(g, Cat, Name, Schema, "REST"))
Tdp= NULL; // Error occured
// Return true in case of error
return (Tdp == NULL);
} // end of DefineAM
/***********************************************************************/
/* GetTable: makes a new Table Description Block. */
/***********************************************************************/
PTDB RESTDEF::GetTable(PGLOBAL g, MODE m)
{
if (m != MODE_READ && m != MODE_READX) {
strcpy(g->Message, "REST tables are currently read only");
return NULL;
} // endif m
return Tdp->GetTable(g, m); // Leave file type do the job
} // end of GetTable
/* ---------------------- End of Class RESTDEF ----------------------- */
/*************** TabRest H Declares Source Code File (.H) **************/
/* Name: tabrest.h Version 1.0 */
/* (C) Copyright to the author Olivier BERTRAND 2019 */
/* This file contains the common tabrest classes declares. */
/***********************************************************************/
#pragma once
/***********************************************************************/
/* Restest table. */
/***********************************************************************/
class RESTDEF : public TABDEF { /* Table description */
public:
// Constructor
RESTDEF(void) { Tdp = NULL; Http = Uri = Fn = NULL; }
// Implementation
virtual const char *GetType(void) { return "REST"; }
// Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
protected:
// Members
PRELDEF Tdp;
PCSZ Http; /* Web connection HTTP */
PCSZ Uri; /* Web connection URI */
PCSZ Fn; /* The intermediate file name */
}; // end of class RESTDEF
......@@ -232,7 +232,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
{
int n;
uint sln;
char *scs;
const char *scs;
PTABLE tp, tabp;
PCOL colp;
PTBLDEF tdp = (PTBLDEF)To_Def;
......@@ -281,7 +281,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
} // endfor tp
hc->get_table()->s->connect_string.str = scs;
hc->get_table()->s->connect_string.str = (char*)scs;
hc->get_table()->s->connect_string.length = sln;
//NumTables = n;
......
......@@ -1880,7 +1880,7 @@ void XMULCOL::ReadColumn(PGLOBAL g)
if (N > Tdbp->Limit) {
N = Tdbp->Limit;
sprintf(g->Message, "Mutiple values limited to %d", Tdbp->Limit);
sprintf(g->Message, "Multiple values limited to %d", Tdbp->Limit);
PushWarning(g, Tdbp);
} // endif N
......
......@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/**
@file user_connect.cc
......
......@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/** @file user_connect.h
......
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