summaryrefslogtreecommitdiff
path: root/storage/connect
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2014-03-30 22:52:54 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2014-03-30 22:52:54 +0200
commitfe3cbcdffa6d419bcc3658fb6dda9ea371b19d35 (patch)
tree350473c8efff19ee2c6edc266a454b78c43558e1 /storage/connect
parent5c5834b09123f46b2807dcf76872846a2185bf8a (diff)
downloadmariadb-git-fe3cbcdffa6d419bcc3658fb6dda9ea371b19d35.tar.gz
- Add system variables type_conv and conv_size. This addresses the eventual
conversion from TEXT to VARCHAR in PROXY and MYSQL tables. modified: storage/connect/ha_connect.cc storage/connect/myconn.cpp storage/connect/myconn.h storage/connect/myutil.cpp storage/connect/tabmysql.cpp storage/connect/tabutil.cpp - Add the xmap system variable addressing whether file mapping should be used to handle indexing. modified: storage/connect/CMakeLists.txt storage/connect/ha_connect.cc storage/connect/xindex.cpp storage/connect/xindex.h - Do take care of ~ in Linux version of _fullpath (not tested yet) modified: storage/connect/osutil.c
Diffstat (limited to 'storage/connect')
-rw-r--r--storage/connect/CMakeLists.txt13
-rw-r--r--storage/connect/ha_connect.cc154
-rw-r--r--storage/connect/myconn.cpp47
-rw-r--r--storage/connect/myconn.h2
-rw-r--r--storage/connect/myutil.cpp72
-rw-r--r--storage/connect/osutil.c7
-rw-r--r--storage/connect/tabmysql.cpp7
-rw-r--r--storage/connect/tabutil.cpp39
-rwxr-xr-xstorage/connect/xindex.cpp18
-rw-r--r--storage/connect/xindex.h9
10 files changed, 291 insertions, 77 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 143ab0c621f..f8db000a486 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -123,7 +123,7 @@ IF(WIN32)
# /MP option of the Microsoft compiler does not work well with COM #import
string(REPLACE "/MP" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
string(REPLACE "/MP" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-
+
OPTION(CONNECT_WITH_MSXML "Compile CONNECT storage engine with MSXML support" ON)
IF(CONNECT_WITH_MSXML)
find_library(MSXML_LIBRARY
@@ -264,6 +264,17 @@ int main() {
ENDIF(UNIX)
ENDIF(CONNECT_WITH_ODBC)
+
+#
+# XMAP
+#
+
+OPTION(CONNECT_WITH_XMAP "Compile CONNECT storage engine with index file mapping support" ON)
+
+IF(CONNECT_WITH_XMAP)
+ add_definitions(-DXMAP)
+ENDIF(CONNECT_WITH_XMAP)
+
#
# Plugin definition
#
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index b0b8aeb8c0d..8b532413e10 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -20,6 +20,7 @@
The ha_connect engine is a stubbed storage engine that enables to create tables
based on external data. Principally they are based on plain files of many
different types, but also on collections of such files, collection of tables,
+ local or remote MySQL/MariaDB tables retrieved via MySQL API,
ODBC tables retrieving data from other DBMS having an ODBC server, and even
virtual tables.
@@ -53,14 +54,21 @@
@note
It was written also from the Brian's ha_example handler and contains parts
- of it that are there but not currently used, such as table variables.
+ of it that are there, such as table and system variables.
@note
When you create an CONNECT table, the MySQL Server creates a table .frm
(format) file in the database directory, using the table name as the file
- name as is customary with MySQL. No other files are created. To get an idea
- of what occurs, here is an example select that would do a scan of an entire
- table:
+ name as is customary with MySQL.
+ For file based tables, if a file name is not specified, this is an inward
+ table. An empty file is made in the current data directory that you can
+ populate later like for other engine tables. This file modified on ALTER
+ and is deleted when dropping the table.
+ If a file name is specified, this in an outward table. The specified file
+ will be used as representing the table data and will not be modified or
+ deleted on command such as ALTER or DROP.
+ To get an idea of what occurs, here is an example select that would do
+ a scan of an entire table:
@code
ha-connect::open
@@ -154,21 +162,34 @@
/***********************************************************************/
/* Initialize the ha_connect static members. */
/***********************************************************************/
-//efine CONNECT_INI "connect.ini"
+#define SZCONV 8192
+
extern "C" {
char version[]= "Version 1.02.0002 March 16, 2014";
#if defined(XMSG)
- char msglang[]; // Default message language
+ char msglang[]; // Default message language
#endif
int trace= 0; // The general trace value
+ int xconv= 0; // The type conversion option
+ int zconv= SZCONV; // The text conversion size
} // extern "C"
-static int xtrace= 0;
+#if defined(XMAP)
+ bool xmap= false;
+#endif // XMAP
ulong ha_connect::num= 0;
//int DTVAL::Shift= 0;
+/* CONNECT system variables */
+static int xtrace= 0;
+static int conv_size= SZCONV;
+static ulong type_conv= 0;
+#if defined(XMAP)
+static my_bool indx_map= 0;
+#endif // XMAP
+
/***********************************************************************/
/* Utility functions. */
/***********************************************************************/
@@ -189,11 +210,36 @@ static void update_connect_xtrace(MYSQL_THD thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save)
{
- xtrace= *(int *)save;
-//xtrace= *(int *)var_ptr= *(int *)save;
+ xtrace= *(int *)var_ptr= *(int *)save;
} // end of update_connect_xtrace
- handlerton *connect_hton;
+static void update_connect_zconv(MYSQL_THD thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save)
+{
+ zconv= *(int *)var_ptr= *(int *)save;
+} // end of update_connect_zconv
+
+static void update_connect_xconv(MYSQL_THD thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save)
+{
+ xconv= (int)(*(ulong *)var_ptr= *(ulong *)save);
+} // end of update_connect_xconv
+
+#if defined(XMAP)
+static void update_connect_xmap(MYSQL_THD thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save)
+{
+ xmap= (bool)(*(my_bool *)var_ptr= *(my_bool *)save);
+} // end of update_connect_xmap
+#endif // XMAP
+
+/***********************************************************************/
+/* The CONNECT handlerton object. */
+/***********************************************************************/
+handlerton *connect_hton;
/**
CREATE TABLE option list (table options)
@@ -256,23 +302,31 @@ ha_create_table_option connect_field_option_list[]=
/***********************************************************************/
/* Push G->Message as a MySQL warning. */
/***********************************************************************/
-bool PushWarning(PGLOBAL g, PTDBASE tdbp, int level)
+void PushWarning(PGLOBAL g, THD *thd, int level)
{
+ if (thd) {
+ Sql_condition::enum_warning_level wlvl;
+
+ wlvl= (Sql_condition::enum_warning_level)level;
+ push_warning(thd, wlvl, 0, g->Message);
+ } else
+ htrc("%s\n", g->Message);
+
+ } // end of PushWarning
+
+bool PushWarning(PGLOBAL g, PTDBASE tdbp, int level)
+{
PHC phc;
THD *thd;
MYCAT *cat= (MYCAT*)tdbp->GetDef()->GetCat();
- Sql_condition::enum_warning_level wlvl;
-
if (!cat || !(phc= cat->GetHandler()) || !phc->GetTable() ||
!(thd= (phc->GetTable())->in_use))
return true;
-//push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
- wlvl= (Sql_condition::enum_warning_level)level;
- push_warning(thd, wlvl, 0, g->Message);
+ PushWarning(g, thd, level);
return false;
- } // end of PushWarning
+} // end of PushWarning
#ifdef HAVE_PSI_INTERFACE
static PSI_mutex_key con_key_mutex_CONNECT_SHARE_mutex;
@@ -865,6 +919,7 @@ PFOS ha_connect::GetFieldOptionStruct(Field *fdp)
void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
{
const char *cp;
+ char *chset, v;
ha_field_option_struct *fop;
Field* fp;
Field* *fldp;
@@ -913,6 +968,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Fieldfmt= NULL;
} // endif fop
+ chset = (char *)fp->charset()->name;
+ v = (!strcmp(chset, "binary")) ? 'B' : 0;
+
switch (fp->type()) {
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VARCHAR:
@@ -920,7 +978,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Flags |= U_VAR;
/* no break */
default:
- pcf->Type= MYSQLtoPLG(fp->type());
+ pcf->Type= MYSQLtoPLG(fp->type(), &v);
break;
} // endswitch SQL type
@@ -3850,6 +3908,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
PCOLRES crp;
PCONNECT xp= NULL;
PGLOBAL g= GetPlug(thd, xp);
+ PDBUSER dup= PlgGetUser(g);
+ PCATLG cat= (dup) ? dup->Catalog : NULL;
PTOS topt= table_s->option_struct;
char buf[1024];
String sql(buf, sizeof(buf), system_charset_info);
@@ -3986,8 +4046,6 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (create_info->connect_string.str) {
int len= create_info->connect_string.length;
PMYDEF mydef= new(g) MYSQLDEF();
- PDBUSER dup= PlgGetUser(g);
- PCATLG cat= (dup) ? dup->Catalog : NULL;
dsn= (char*)PlugSubAlloc(g, NULL, len + 1);
strncpy(dsn, create_info->connect_string.str, len);
@@ -4070,8 +4128,6 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (ok) {
char *cnm, *rem, *dft, *xtra;
int i, len, prec, dec, typ, flg;
- PDBUSER dup= PlgGetUser(g);
- PCATLG cat= (dup) ? dup->Catalog : NULL;
if (cat)
cat->SetDataPath(g, table_s->db.str);
@@ -4121,7 +4177,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
#endif // ODBC_SUPPORT
#if defined(MYSQL_SUPPORT)
case TAB_MYSQL:
- qrp= MyColumns(g, host, db, user, pwd, tab,
+ qrp= MyColumns(g, thd, host, db, user, pwd, tab,
NULL, port, fnc == FNC_COL);
break;
#endif // MYSQL_SUPPORT
@@ -4141,7 +4197,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
qrp= TabColumns(g, thd, db, tab, bif);
if (!qrp && bif && fnc != FNC_COL) // tab is a view
- qrp= MyColumns(g, 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)) {
@@ -4232,6 +4288,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
break;
case FLD_EXTRA:
xtra= crp->Kdata->GetCharValue(i);
+
+ // Auto_increment is not supported yet
+ if (!stricmp(xtra, "AUTO_INCREMENT"))
+ xtra= NULL;
+
break;
default:
break; // Ignore
@@ -5157,12 +5218,57 @@ bool ha_connect::check_if_incompatible_data(HA_CREATE_INFO *info,
struct st_mysql_storage_engine connect_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+// Tracing: 0 no, 1 yes, >1 more tracing
static MYSQL_SYSVAR_INT(xtrace, xtrace,
PLUGIN_VAR_RQCMDARG, "Console trace value.",
NULL, update_connect_xtrace, 0, 0, INT_MAX, 1);
+// Size used when converting TEXT columns to VARCHAR
+static MYSQL_SYSVAR_INT(conv_size, conv_size,
+ PLUGIN_VAR_RQCMDARG, "Size used when converting TEXT columns.",
+ NULL, update_connect_zconv, SZCONV, 0, 65500, 1);
+
+/**
+ Type conversion:
+ no: Unsupported types -> TYPE_ERROR
+ yes: TEXT -> VARCHAR
+ skip: skip unsupported type columns in Discovery
+*/
+const char *xconv_names[]=
+{
+ "NO", "YES", "SKIP", NullS
+};
+
+TYPELIB xconv_typelib=
+{
+ array_elements(xconv_names) - 1, "xconv_typelib",
+ xconv_names, NULL
+};
+
+static MYSQL_SYSVAR_ENUM(
+ type_conv, // name
+ type_conv, // varname
+ PLUGIN_VAR_RQCMDARG, // opt
+ "Unsupported types conversion.", // comment
+ NULL, // check
+ update_connect_xconv, // update function
+ 0, // def (no)
+ &xconv_typelib); // typelib
+
+#if defined(XMAP)
+// Using file mapping for indexes if true
+static MYSQL_SYSVAR_BOOL(indx_map, indx_map, PLUGIN_VAR_RQCMDARG,
+ "Using file mapping for indexes",
+ NULL, update_connect_xmap, 0);
+#endif // XMAP
+
static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(xtrace),
+ MYSQL_SYSVAR(conv_size),
+ MYSQL_SYSVAR(type_conv),
+#if defined(XMAP)
+ MYSQL_SYSVAR(indx_map),
+#endif // XMAP
NULL
};
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index 3d0a3d86136..e8b72cd3643 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -47,9 +47,12 @@
#include "myconn.h"
extern "C" int trace;
+extern "C" int zconv;
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port;
+DllExport void PushWarning(PGLOBAL, THD*, int level = 1);
+
// Returns the current used port
uint GetDefaultPort(void)
{
@@ -61,7 +64,7 @@ uint GetDefaultPort(void)
/* of a MySQL table or view. */
/* info = TRUE to get catalog column informations. */
/************************************************************************/
-PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
+PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
const char *user, const char *pwd,
const char *table, const char *colpat,
int port, bool info)
@@ -75,7 +78,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA,
FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
- char *fld, *fmt, v, cmd[128], uns[16], zero[16];
+ char *fld, *colname, *chset, *fmt, v, cmd[128], uns[16], zero[16];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0;
PQRYRES qrp;
@@ -144,23 +147,24 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
/**********************************************************************/
/* Now get the results into blocks. */
/**********************************************************************/
- for (i = 0; i < n; i++) {
- if ((rc = myc.Fetch(g, -1) == RC_FX)) {
+ for (i = 0; i < n; /*i++*/) {
+ if ((rc = myc.Fetch(g, -1)) == RC_FX) {
myc.Close();
return NULL;
- } else if (rc == RC_NF)
+ } else if (rc == RC_EF)
break;
// Get column name
- fld = myc.GetCharField(0);
+ colname = myc.GetCharField(0);
crp = qrp->Colresp; // Column_Name
- crp->Kdata->SetValue(fld, i);
+ crp->Kdata->SetValue(colname, i);
// Get type, type name, precision, unsigned and zerofill
+ chset = myc.GetCharField(2);
fld = myc.GetCharField(1);
prec = 0;
len = 0;
- v = 0;
+ v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
*uns = 0;
*zero = 0;
@@ -181,11 +185,28 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
} // endswitch nf
if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) {
- sprintf(g->Message, "Unsupported column type %s", cmd);
+ if (v == 'K') {
+ // Skip this column
+ sprintf(g->Message, "Column %s skipped (unsupported type %s)",
+ colname, cmd);
+ PushWarning(g, thd);
+ continue;
+ } // endif v
+
+ sprintf(g->Message, "Column %s unsupported type %s", colname, cmd);
myc.Close();
return NULL;
- } else if (type == TYPE_STRING)
- len = min(len, 4096);
+ } else if (type == TYPE_STRING) {
+ if (v == 'X') {
+ len = zconv;
+ sprintf(g->Message, "Column %s converted to varchar(%d)",
+ colname, len);
+ PushWarning(g, thd);
+ v = 'V';
+ } else
+ len = min(len, 4096);
+
+ } // endif type
qrp->Nblin++;
crp = crp->Next; // Data_Type
@@ -241,8 +262,10 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
crp->Kdata->SetValue(fld, i);
crp = crp->Next; // New (charset)
- fld = myc.GetCharField(2);
+ fld = chset;
crp->Kdata->SetValue(fld, i);
+
+ i++; // Can be skipped
} // endfor i
#if 0
diff --git a/storage/connect/myconn.h b/storage/connect/myconn.h
index 856b6c73ef3..5bfa58ffb0c 100644
--- a/storage/connect/myconn.h
+++ b/storage/connect/myconn.h
@@ -34,7 +34,7 @@ typedef class MYSQLC *PMYC;
/***********************************************************************/
/* Prototypes of info functions. */
/***********************************************************************/
-PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
+PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
const char *user, const char *pwd,
const char *table, const char *colpat,
int port, bool info);
diff --git a/storage/connect/myutil.cpp b/storage/connect/myutil.cpp
index ea694389eaf..0d9a1e2fe16 100644
--- a/storage/connect/myutil.cpp
+++ b/storage/connect/myutil.cpp
@@ -1,9 +1,9 @@
/************** MyUtil C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: MYUTIL */
/* ------------- */
-/* Version 1.1 */
+/* Version 1.2 */
/* */
-/* Author Olivier BERTRAND 2013 */
+/* Author Olivier BERTRAND 2014 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -26,6 +26,8 @@
#include "myutil.h"
#define DLL_EXPORT // Items are exported from this DLL
+extern "C" int xconv;
+
/************************************************************************/
/* Convert from MySQL type name to PlugDB type number */
/************************************************************************/
@@ -38,8 +40,7 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_INT;
else if (!stricmp(typname, "smallint"))
type = TYPE_SHORT;
- else if (!stricmp(typname, "char") || !stricmp(typname, "varchar") ||
- !stricmp(typname, "text") || !stricmp(typname, "blob"))
+ else if (!stricmp(typname, "char") || !stricmp(typname, "varchar"))
type = TYPE_STRING;
else if (!stricmp(typname, "double") || !stricmp(typname, "float") ||
!stricmp(typname, "real"))
@@ -54,7 +55,20 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_BIGINT;
else if (!stricmp(typname, "tinyint"))
type = TYPE_TINY;
- else
+ else if (!stricmp(typname, "text") && var) {
+ switch (xconv) {
+ case 1:
+ type = TYPE_STRING;
+ *var = 'X';
+ break;
+ case 2:
+ *var = 'K';
+ default:
+ type = TYPE_ERROR;
+ } // endswitch xconv
+
+ return type;
+ } else
type = TYPE_ERROR;
if (var) {
@@ -71,9 +85,11 @@ int MYSQLtoPLG(char *typname, char *var)
else if (!stricmp(typname, "year"))
*var = 'Y';
- } else if (type == TYPE_STRING && stricmp(typname, "char"))
+ } else if (type == TYPE_STRING && !stricmp(typname, "varchar"))
// This is to make the difference between CHAR and VARCHAR
*var = 'V';
+ else if (type == TYPE_ERROR && xconv == 2)
+ *var = 'K';
else
*var = 0;
@@ -196,34 +212,50 @@ int MYSQLtoPLG(int mytype, char *var)
#if !defined(ALPHA)
case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA)
+ case MYSQL_TYPE_STRING:
+ type = TYPE_STRING;
+ break;
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
- case MYSQL_TYPE_STRING:
- type = TYPE_STRING;
- break;
+ if (var) {
+ switch (xconv) {
+ case 1:
+ if (*var != 'B') {
+ // This is a TEXT column
+ type = TYPE_STRING;
+ *var = 'X';
+ } else
+ type = TYPE_ERROR;
+
+ break;
+ case 2:
+ *var = 'K'; // Skip
+ default:
+ type = TYPE_ERROR;
+ } // endswitch xconv
+
+ return type;
+ } // endif var
+
default:
type = TYPE_ERROR;
} // endswitch mytype
if (var) switch (mytype) {
// This is to make the difference between CHAR and VARCHAR
- case MYSQL_TYPE_VAR_STRING:
#if !defined(ALPHA)
case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA)
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_TINY_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- case MYSQL_TYPE_LONG_BLOB: *var = 'V'; break;
+ case MYSQL_TYPE_VAR_STRING: *var = 'V'; break;
// This is to make the difference between temporal values
- case MYSQL_TYPE_TIMESTAMP: *var = 'S'; break;
- case MYSQL_TYPE_DATE: *var = 'D'; break;
- case MYSQL_TYPE_DATETIME: *var = 'A'; break;
- case MYSQL_TYPE_YEAR: *var = 'Y'; break;
- case MYSQL_TYPE_TIME: *var = 'T'; break;
- default: *var = 0;
+ case MYSQL_TYPE_TIMESTAMP: *var = 'S'; break;
+ case MYSQL_TYPE_DATE: *var = 'D'; break;
+ case MYSQL_TYPE_DATETIME: *var = 'A'; break;
+ case MYSQL_TYPE_YEAR: *var = 'Y'; break;
+ case MYSQL_TYPE_TIME: *var = 'T'; break;
+ default: *var = 0;
} // endswitch mytype
return type;
diff --git a/storage/connect/osutil.c b/storage/connect/osutil.c
index af5faa5b13b..32debe02107 100644
--- a/storage/connect/osutil.c
+++ b/storage/connect/osutil.c
@@ -16,6 +16,7 @@ my_bool CloseFileHandle(HANDLE h)
#include <sys/stat.h>
#include <ctype.h>
#include <fcntl.h>
+#include <pwd.h>
extern FILE *debug;
@@ -176,8 +177,10 @@ char *_fullpath(char *absPath, const char *relPath, size_t maxLength)
strncpy(absPath, relPath, maxLength);
} else if(*relPath == '~') {
// get the path to the home directory
- // Fixme
- strncpy(absPath, relPath, maxLength);
+ struct passwd *pw = getpwuid_r(getuid());
+ const char *homedir = pw->pw_dir;
+
+ strcat(strcat(strncpy(absPath, homedir, maxLength), "/"), relPath);
} else {
char buff[2*_MAX_PATH];
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 692cad9b9ff..2bebad276c6 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -1134,9 +1134,12 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
: COLBLK(NULL, tdbp, i)
{
+ const char *chset = get_charset_name(fld->charsetnr);
+ char v = (!strcmp(chset, "binary")) ? 'B' : 0;
+
Name = fld->name;
Precision = Long = fld->length;
- Buf_Type = MYSQLtoPLG(fld->type);
+ Buf_Type = MYSQLtoPLG(fld->type, &v);
strcpy(Format.Type, GetFormatType(Buf_Type));
Format.Length = Long;
Format.Prec = fld->decimals;
@@ -1615,5 +1618,5 @@ TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp)
/***********************************************************************/
PQRYRES TDBMCL::GetResult(PGLOBAL g)
{
- return MyColumns(g, Host, Db, User, Pwd, Tab, NULL, Port, false);
+ return MyColumns(g, NULL, Host, Db, User, Pwd, Tab, NULL, Port, false);
} // end of GetResult
diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp
index 6d83852ccb8..b5203b90df9 100644
--- a/storage/connect/tabutil.cpp
+++ b/storage/connect/tabutil.cpp
@@ -55,6 +55,7 @@
#include "ha_connect.h"
extern "C" int trace;
+extern "C" int zconv;
/************************************************************************/
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */
@@ -129,7 +130,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
- char *fld, *fmt, v;
+ char *fld, *colname, *chset, *fmt, v;
int i, n, ncol = sizeof(buftyp) / sizeof(int);
int prec, len, type, scale;
bool mysql;
@@ -176,21 +177,37 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
/**********************************************************************/
/* Now get the results into blocks. */
/**********************************************************************/
- for (i = 0, field= s->field; *field; i++, field++) {
+ for (i = 0, field= s->field; *field; field++) {
fp= *field;
// Get column name
crp = qrp->Colresp; // Column_Name
- fld = (char *)fp->field_name;
- crp->Kdata->SetValue(fld, i);
- v = 0;
+ colname = (char *)fp->field_name;
+ crp->Kdata->SetValue(colname, i);
+
+ chset = (char *)fp->charset()->name;
+ v = (!strcmp(chset, "binary")) ? 'B' : 0;
if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) {
- sprintf(g->Message, "Unsupported column type %s", GetTypeName(type));
+ if (v == 'K') {
+ // Skip this column
+ sprintf(g->Message, "Column %s skipped (unsupported type)", colname);
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ continue;
+ } // endif v
+
+ sprintf(g->Message, "Column %s unsupported type", colname);
qrp = NULL;
break;
} // endif type
+ if (v == 'X') {
+ len = zconv;
+ sprintf(g->Message, "Column %s converted to varchar(%d)",
+ colname, len);
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ } // endif v
+
crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i);
@@ -198,8 +215,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp->Nulls[i] = 'Z';
else if (fp->flags & UNSIGNED_FLAG)
crp->Nulls[i] = 'U';
- else
- crp->Nulls[i] = v;
+ else // X means TEXT field
+ crp->Nulls[i] = (v == 'X') ? 'V' : v;
crp = crp->Next; // Type_Name
crp->Kdata->SetValue(GetTypeName(type), i);
@@ -214,7 +231,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
prec = len = fp->field_length;
} // endif mysql
- } else {
+ } else if (v != 'X') {
if (type == TYPE_DECIM)
prec = ((Field_new_decimal*)fp)->precision;
else
@@ -223,7 +240,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
len = fp->char_length();
fmt = NULL;
- } // endif type
+ } else
+ prec = len = zconv;
crp = crp->Next; // Precision
crp->Kdata->SetValue(prec, i);
@@ -259,6 +277,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
// Add this item
qrp->Nblin++;
+ i++; // Can be skipped
} // endfor field
/**********************************************************************/
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 1adf9f20465..e3321fd14a9 100755
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -61,6 +61,9 @@
/***********************************************************************/
extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
extern "C" int trace;
+#if defined(XMAP)
+extern bool xmap;
+#endif // XMAP
/***********************************************************************/
/* Last two parameters are true to enable type checking, and last one */
@@ -811,12 +814,16 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
return rc;
} // end of SaveIndex
-#if !defined(XMAP)
/***********************************************************************/
/* Init: Open and Initialize a Key Index. */
/***********************************************************************/
bool XINDEX::Init(PGLOBAL g)
{
+#if defined(XMAP)
+ if (xmap)
+ return MapInit(g);
+#endif // XMAP
+
/*********************************************************************/
/* Table will be accessed through an index table. */
/* If sorting is required, this will be done later. */
@@ -1053,11 +1060,11 @@ err:
return true;
} // end of Init
-#else // XMAP
+#if defined(XMAP)
/***********************************************************************/
/* Init: Open and Initialize a Key Index. */
/***********************************************************************/
-bool XINDEX::Init(PGLOBAL g)
+bool XINDEX::MapInit(PGLOBAL g)
{
/*********************************************************************/
/* Table will be accessed through an index table. */
@@ -1259,7 +1266,7 @@ bool XINDEX::Init(PGLOBAL g)
err:
Close();
return true;
- } // end of Init
+ } // end of MapInit
#endif // XMAP
/***********************************************************************/
@@ -2848,7 +2855,8 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
} // endif n[1]
Ndf = n[0];
- IsSorted = colp->GetOpt() < 0;
+//IsSorted = colp->GetOpt() < 0;
+ IsSorted = false;
return m + Bkeys.Size + Keys.Size + Koff.Size;
} // end of MapInit
#endif // XMAP
diff --git a/storage/connect/xindex.h b/storage/connect/xindex.h
index ac886673b68..2f7a29bc246 100644
--- a/storage/connect/xindex.h
+++ b/storage/connect/xindex.h
@@ -192,6 +192,9 @@ class DllExport XXBASE : public CSORT, public BLOCK {
virtual void Print(PGLOBAL g, FILE *f, uint n);
virtual void Print(PGLOBAL g, char *ps, uint z);
virtual bool Init(PGLOBAL g) = 0;
+#if defined(XMAP)
+ virtual bool MapInit(PGLOBAL g) = 0;
+#endif // XMAP
virtual int MaxRange(void) {return 1;}
virtual int Fetch(PGLOBAL g) = 0;
virtual bool NextVal(bool eq) {return true;}
@@ -248,6 +251,9 @@ class DllExport XINDEX : public XXBASE {
// Methods
virtual void Reset(void);
virtual bool Init(PGLOBAL g);
+#if defined(XMAP)
+ virtual bool MapInit(PGLOBAL g);
+#endif // XMAP
virtual int Qcompare(int *, int *);
virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk);
@@ -403,6 +409,9 @@ class DllExport XXROW : public XXBASE {
// Methods
virtual bool Init(PGLOBAL g);
+#if defined(XMAP)
+ virtual bool MapInit(PGLOBAL g) {return true;}
+#endif // XMAP
virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk);
virtual int MaxRange(void) {return 1;}