Commit fe3cbcdf authored by Olivier Bertrand's avatar Olivier Bertrand

- 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
parent 5c5834b0
...@@ -264,6 +264,17 @@ int main() { ...@@ -264,6 +264,17 @@ int main() {
ENDIF(UNIX) ENDIF(UNIX)
ENDIF(CONNECT_WITH_ODBC) 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 # Plugin definition
# #
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
The ha_connect engine is a stubbed storage engine that enables to create tables 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 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, 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 ODBC tables retrieving data from other DBMS having an ODBC server, and even
virtual tables. virtual tables.
...@@ -53,14 +54,21 @@ ...@@ -53,14 +54,21 @@
@note @note
It was written also from the Brian's ha_example handler and contains parts 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 @note
When you create an CONNECT table, the MySQL Server creates a table .frm 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 (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 name as is customary with MySQL.
of what occurs, here is an example select that would do a scan of an entire For file based tables, if a file name is not specified, this is an inward
table: 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 @code
ha-connect::open ha-connect::open
...@@ -154,7 +162,8 @@ ...@@ -154,7 +162,8 @@
/***********************************************************************/ /***********************************************************************/
/* Initialize the ha_connect static members. */ /* Initialize the ha_connect static members. */
/***********************************************************************/ /***********************************************************************/
//efine CONNECT_INI "connect.ini" #define SZCONV 8192
extern "C" { extern "C" {
char version[]= "Version 1.02.0002 March 16, 2014"; char version[]= "Version 1.02.0002 March 16, 2014";
...@@ -162,13 +171,25 @@ extern "C" { ...@@ -162,13 +171,25 @@ extern "C" {
char msglang[]; // Default message language char msglang[]; // Default message language
#endif #endif
int trace= 0; // The general trace value int trace= 0; // The general trace value
int xconv= 0; // The type conversion option
int zconv= SZCONV; // The text conversion size
} // extern "C" } // extern "C"
static int xtrace= 0; #if defined(XMAP)
bool xmap= false;
#endif // XMAP
ulong ha_connect::num= 0; ulong ha_connect::num= 0;
//int DTVAL::Shift= 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. */ /* Utility functions. */
/***********************************************************************/ /***********************************************************************/
...@@ -189,11 +210,36 @@ static void update_connect_xtrace(MYSQL_THD thd, ...@@ -189,11 +210,36 @@ static void update_connect_xtrace(MYSQL_THD thd,
struct st_mysql_sys_var *var, struct st_mysql_sys_var *var,
void *var_ptr, const void *save) 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 } // 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) CREATE TABLE option list (table options)
...@@ -256,23 +302,31 @@ ha_create_table_option connect_field_option_list[]= ...@@ -256,23 +302,31 @@ ha_create_table_option connect_field_option_list[]=
/***********************************************************************/ /***********************************************************************/
/* Push G->Message as a MySQL warning. */ /* 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; PHC phc;
THD *thd; THD *thd;
MYCAT *cat= (MYCAT*)tdbp->GetDef()->GetCat(); MYCAT *cat= (MYCAT*)tdbp->GetDef()->GetCat();
Sql_condition::enum_warning_level wlvl;
if (!cat || !(phc= cat->GetHandler()) || !phc->GetTable() || if (!cat || !(phc= cat->GetHandler()) || !phc->GetTable() ||
!(thd= (phc->GetTable())->in_use)) !(thd= (phc->GetTable())->in_use))
return true; return true;
//push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); PushWarning(g, thd, level);
wlvl= (Sql_condition::enum_warning_level)level;
push_warning(thd, wlvl, 0, g->Message);
return false; return false;
} // end of PushWarning } // end of PushWarning
#ifdef HAVE_PSI_INTERFACE #ifdef HAVE_PSI_INTERFACE
static PSI_mutex_key con_key_mutex_CONNECT_SHARE_mutex; static PSI_mutex_key con_key_mutex_CONNECT_SHARE_mutex;
...@@ -865,6 +919,7 @@ PFOS ha_connect::GetFieldOptionStruct(Field *fdp) ...@@ -865,6 +919,7 @@ PFOS ha_connect::GetFieldOptionStruct(Field *fdp)
void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
{ {
const char *cp; const char *cp;
char *chset, v;
ha_field_option_struct *fop; ha_field_option_struct *fop;
Field* fp; Field* fp;
Field* *fldp; Field* *fldp;
...@@ -913,6 +968,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) ...@@ -913,6 +968,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Fieldfmt= NULL; pcf->Fieldfmt= NULL;
} // endif fop } // endif fop
chset = (char *)fp->charset()->name;
v = (!strcmp(chset, "binary")) ? 'B' : 0;
switch (fp->type()) { switch (fp->type()) {
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VARCHAR:
...@@ -920,7 +978,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) ...@@ -920,7 +978,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Flags |= U_VAR; pcf->Flags |= U_VAR;
/* no break */ /* no break */
default: default:
pcf->Type= MYSQLtoPLG(fp->type()); pcf->Type= MYSQLtoPLG(fp->type(), &v);
break; break;
} // endswitch SQL type } // endswitch SQL type
...@@ -3850,6 +3908,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -3850,6 +3908,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
PCOLRES crp; PCOLRES crp;
PCONNECT xp= NULL; PCONNECT xp= NULL;
PGLOBAL g= GetPlug(thd, xp); PGLOBAL g= GetPlug(thd, xp);
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
PTOS topt= table_s->option_struct; PTOS topt= table_s->option_struct;
char buf[1024]; char buf[1024];
String sql(buf, sizeof(buf), system_charset_info); String sql(buf, sizeof(buf), system_charset_info);
...@@ -3986,8 +4046,6 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -3986,8 +4046,6 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (create_info->connect_string.str) { if (create_info->connect_string.str) {
int len= create_info->connect_string.length; int len= create_info->connect_string.length;
PMYDEF mydef= new(g) MYSQLDEF(); PMYDEF mydef= new(g) MYSQLDEF();
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
dsn= (char*)PlugSubAlloc(g, NULL, len + 1); dsn= (char*)PlugSubAlloc(g, NULL, len + 1);
strncpy(dsn, create_info->connect_string.str, len); strncpy(dsn, create_info->connect_string.str, len);
...@@ -4070,8 +4128,6 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -4070,8 +4128,6 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (ok) { if (ok) {
char *cnm, *rem, *dft, *xtra; char *cnm, *rem, *dft, *xtra;
int i, len, prec, dec, typ, flg; int i, len, prec, dec, typ, flg;
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
if (cat) if (cat)
cat->SetDataPath(g, table_s->db.str); cat->SetDataPath(g, table_s->db.str);
...@@ -4121,7 +4177,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -4121,7 +4177,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
#endif // ODBC_SUPPORT #endif // ODBC_SUPPORT
#if defined(MYSQL_SUPPORT) #if defined(MYSQL_SUPPORT)
case TAB_MYSQL: 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); NULL, port, fnc == FNC_COL);
break; break;
#endif // MYSQL_SUPPORT #endif // MYSQL_SUPPORT
...@@ -4141,7 +4197,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -4141,7 +4197,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
qrp= TabColumns(g, thd, db, tab, bif); qrp= TabColumns(g, thd, db, tab, bif);
if (!qrp && bif && fnc != FNC_COL) // tab is a view 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 (qrp && ttp == TAB_OCCUR && fnc != FNC_COL)
if (OcrColumns(g, qrp, col, ocl, rnk)) { if (OcrColumns(g, qrp, col, ocl, rnk)) {
...@@ -4232,6 +4288,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -4232,6 +4288,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
break; break;
case FLD_EXTRA: 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;
break; break;
default: default:
break; // Ignore break; // Ignore
...@@ -5157,12 +5218,57 @@ bool ha_connect::check_if_incompatible_data(HA_CREATE_INFO *info, ...@@ -5157,12 +5218,57 @@ bool ha_connect::check_if_incompatible_data(HA_CREATE_INFO *info,
struct st_mysql_storage_engine connect_storage_engine= struct st_mysql_storage_engine connect_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION }; { MYSQL_HANDLERTON_INTERFACE_VERSION };
// Tracing: 0 no, 1 yes, >1 more tracing
static MYSQL_SYSVAR_INT(xtrace, xtrace, static MYSQL_SYSVAR_INT(xtrace, xtrace,
PLUGIN_VAR_RQCMDARG, "Console trace value.", PLUGIN_VAR_RQCMDARG, "Console trace value.",
NULL, update_connect_xtrace, 0, 0, INT_MAX, 1); 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[]= { static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(xtrace), MYSQL_SYSVAR(xtrace),
MYSQL_SYSVAR(conv_size),
MYSQL_SYSVAR(type_conv),
#if defined(XMAP)
MYSQL_SYSVAR(indx_map),
#endif // XMAP
NULL NULL
}; };
......
...@@ -47,9 +47,12 @@ ...@@ -47,9 +47,12 @@
#include "myconn.h" #include "myconn.h"
extern "C" int trace; extern "C" int trace;
extern "C" int zconv;
extern MYSQL_PLUGIN_IMPORT uint mysqld_port; extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port; extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port;
DllExport void PushWarning(PGLOBAL, THD*, int level = 1);
// Returns the current used port // Returns the current used port
uint GetDefaultPort(void) uint GetDefaultPort(void)
{ {
...@@ -61,7 +64,7 @@ uint GetDefaultPort(void) ...@@ -61,7 +64,7 @@ uint GetDefaultPort(void)
/* of a MySQL table or view. */ /* of a MySQL table or view. */
/* info = TRUE to get catalog column informations. */ /* 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 *user, const char *pwd,
const char *table, const char *colpat, const char *table, const char *colpat,
int port, bool info) int port, bool info)
...@@ -75,7 +78,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -75,7 +78,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA, FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA,
FLD_CHARSET}; FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0}; 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 i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0; int len, type, prec, rc, k = 0;
PQRYRES qrp; PQRYRES qrp;
...@@ -144,23 +147,24 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -144,23 +147,24 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
/**********************************************************************/ /**********************************************************************/
/* Now get the results into blocks. */ /* Now get the results into blocks. */
/**********************************************************************/ /**********************************************************************/
for (i = 0; i < n; i++) { for (i = 0; i < n; /*i++*/) {
if ((rc = myc.Fetch(g, -1) == RC_FX)) { if ((rc = myc.Fetch(g, -1)) == RC_FX) {
myc.Close(); myc.Close();
return NULL; return NULL;
} else if (rc == RC_NF) } else if (rc == RC_EF)
break; break;
// Get column name // Get column name
fld = myc.GetCharField(0); colname = myc.GetCharField(0);
crp = qrp->Colresp; // Column_Name crp = qrp->Colresp; // Column_Name
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(colname, i);
// Get type, type name, precision, unsigned and zerofill // Get type, type name, precision, unsigned and zerofill
chset = myc.GetCharField(2);
fld = myc.GetCharField(1); fld = myc.GetCharField(1);
prec = 0; prec = 0;
len = 0; len = 0;
v = 0; v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
*uns = 0; *uns = 0;
*zero = 0; *zero = 0;
...@@ -181,12 +185,29 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -181,12 +185,29 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
} // endswitch nf } // endswitch nf
if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) { 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(); myc.Close();
return NULL; return NULL;
} else if (type == TYPE_STRING) } 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); len = min(len, 4096);
} // endif type
qrp->Nblin++; qrp->Nblin++;
crp = crp->Next; // Data_Type crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i); crp->Kdata->SetValue(type, i);
...@@ -241,8 +262,10 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -241,8 +262,10 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(fld, i);
crp = crp->Next; // New (charset) crp = crp->Next; // New (charset)
fld = myc.GetCharField(2); fld = chset;
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(fld, i);
i++; // Can be skipped
} // endfor i } // endfor i
#if 0 #if 0
......
...@@ -34,7 +34,7 @@ typedef class MYSQLC *PMYC; ...@@ -34,7 +34,7 @@ typedef class MYSQLC *PMYC;
/***********************************************************************/ /***********************************************************************/
/* Prototypes of info functions. */ /* 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 *user, const char *pwd,
const char *table, const char *colpat, const char *table, const char *colpat,
int port, bool info); int port, bool info);
......
/************** MyUtil C++ Program Source Code File (.CPP) **************/ /************** MyUtil C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: MYUTIL */ /* PROGRAM NAME: MYUTIL */
/* ------------- */ /* ------------- */
/* Version 1.1 */ /* Version 1.2 */
/* */ /* */
/* Author Olivier BERTRAND 2013 */ /* Author Olivier BERTRAND 2014 */
/* */ /* */
/* WHAT THIS PROGRAM DOES: */ /* WHAT THIS PROGRAM DOES: */
/* ----------------------- */ /* ----------------------- */
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "myutil.h" #include "myutil.h"
#define DLL_EXPORT // Items are exported from this DLL #define DLL_EXPORT // Items are exported from this DLL
extern "C" int xconv;
/************************************************************************/ /************************************************************************/
/* Convert from MySQL type name to PlugDB type number */ /* Convert from MySQL type name to PlugDB type number */
/************************************************************************/ /************************************************************************/
...@@ -38,8 +40,7 @@ int MYSQLtoPLG(char *typname, char *var) ...@@ -38,8 +40,7 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_INT; type = TYPE_INT;
else if (!stricmp(typname, "smallint")) else if (!stricmp(typname, "smallint"))
type = TYPE_SHORT; type = TYPE_SHORT;
else if (!stricmp(typname, "char") || !stricmp(typname, "varchar") || else if (!stricmp(typname, "char") || !stricmp(typname, "varchar"))
!stricmp(typname, "text") || !stricmp(typname, "blob"))
type = TYPE_STRING; type = TYPE_STRING;
else if (!stricmp(typname, "double") || !stricmp(typname, "float") || else if (!stricmp(typname, "double") || !stricmp(typname, "float") ||
!stricmp(typname, "real")) !stricmp(typname, "real"))
...@@ -54,7 +55,20 @@ int MYSQLtoPLG(char *typname, char *var) ...@@ -54,7 +55,20 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_BIGINT; type = TYPE_BIGINT;
else if (!stricmp(typname, "tinyint")) else if (!stricmp(typname, "tinyint"))
type = TYPE_TINY; 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; type = TYPE_ERROR;
if (var) { if (var) {
...@@ -71,9 +85,11 @@ int MYSQLtoPLG(char *typname, char *var) ...@@ -71,9 +85,11 @@ int MYSQLtoPLG(char *typname, char *var)
else if (!stricmp(typname, "year")) else if (!stricmp(typname, "year"))
*var = 'Y'; *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 // This is to make the difference between CHAR and VARCHAR
*var = 'V'; *var = 'V';
else if (type == TYPE_ERROR && xconv == 2)
*var = 'K';
else else
*var = 0; *var = 0;
...@@ -196,27 +212,43 @@ int MYSQLtoPLG(int mytype, char *var) ...@@ -196,27 +212,43 @@ int MYSQLtoPLG(int mytype, char *var)
#if !defined(ALPHA) #if !defined(ALPHA)
case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA) #endif // !ALPHA)
case MYSQL_TYPE_STRING:
type = TYPE_STRING;
break;
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_STRING: if (var) {
switch (xconv) {
case 1:
if (*var != 'B') {
// This is a TEXT column
type = TYPE_STRING; type = TYPE_STRING;
*var = 'X';
} else
type = TYPE_ERROR;
break; break;
case 2:
*var = 'K'; // Skip
default:
type = TYPE_ERROR;
} // endswitch xconv
return type;
} // endif var
default: default:
type = TYPE_ERROR; type = TYPE_ERROR;
} // endswitch mytype } // endswitch mytype
if (var) switch (mytype) { if (var) switch (mytype) {
// This is to make the difference between CHAR and VARCHAR // This is to make the difference between CHAR and VARCHAR
case MYSQL_TYPE_VAR_STRING:
#if !defined(ALPHA) #if !defined(ALPHA)
case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA) #endif // !ALPHA)
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_VAR_STRING: *var = 'V'; break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB: *var = 'V'; break;
// This is to make the difference between temporal values // This is to make the difference between temporal values
case MYSQL_TYPE_TIMESTAMP: *var = 'S'; break; case MYSQL_TYPE_TIMESTAMP: *var = 'S'; break;
case MYSQL_TYPE_DATE: *var = 'D'; break; case MYSQL_TYPE_DATE: *var = 'D'; break;
......
...@@ -16,6 +16,7 @@ my_bool CloseFileHandle(HANDLE h) ...@@ -16,6 +16,7 @@ my_bool CloseFileHandle(HANDLE h)
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h>
extern FILE *debug; extern FILE *debug;
...@@ -176,8 +177,10 @@ char *_fullpath(char *absPath, const char *relPath, size_t maxLength) ...@@ -176,8 +177,10 @@ char *_fullpath(char *absPath, const char *relPath, size_t maxLength)
strncpy(absPath, relPath, maxLength); strncpy(absPath, relPath, maxLength);
} else if(*relPath == '~') { } else if(*relPath == '~') {
// get the path to the home directory // get the path to the home directory
// Fixme struct passwd *pw = getpwuid_r(getuid());
strncpy(absPath, relPath, maxLength); const char *homedir = pw->pw_dir;
strcat(strcat(strncpy(absPath, homedir, maxLength), "/"), relPath);
} else { } else {
char buff[2*_MAX_PATH]; char buff[2*_MAX_PATH];
......
...@@ -1134,9 +1134,12 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) ...@@ -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) MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
: COLBLK(NULL, tdbp, i) : COLBLK(NULL, tdbp, i)
{ {
const char *chset = get_charset_name(fld->charsetnr);
char v = (!strcmp(chset, "binary")) ? 'B' : 0;
Name = fld->name; Name = fld->name;
Precision = Long = fld->length; Precision = Long = fld->length;
Buf_Type = MYSQLtoPLG(fld->type); Buf_Type = MYSQLtoPLG(fld->type, &v);
strcpy(Format.Type, GetFormatType(Buf_Type)); strcpy(Format.Type, GetFormatType(Buf_Type));
Format.Length = Long; Format.Length = Long;
Format.Prec = fld->decimals; Format.Prec = fld->decimals;
...@@ -1615,5 +1618,5 @@ TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp) ...@@ -1615,5 +1618,5 @@ TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp)
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBMCL::GetResult(PGLOBAL g) 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 } // end of GetResult
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include "ha_connect.h" #include "ha_connect.h"
extern "C" int trace; extern "C" int trace;
extern "C" int zconv;
/************************************************************************/ /************************************************************************/
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */ /* 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, ...@@ -129,7 +130,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET}; FLD_REM, FLD_NO, FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32}; 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 i, n, ncol = sizeof(buftyp) / sizeof(int);
int prec, len, type, scale; int prec, len, type, scale;
bool mysql; bool mysql;
...@@ -176,21 +177,37 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -176,21 +177,37 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
/**********************************************************************/ /**********************************************************************/
/* Now get the results into blocks. */ /* 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; fp= *field;
// Get column name // Get column name
crp = qrp->Colresp; // Column_Name crp = qrp->Colresp; // Column_Name
fld = (char *)fp->field_name; colname = (char *)fp->field_name;
crp->Kdata->SetValue(fld, i); crp->Kdata->SetValue(colname, i);
v = 0;
chset = (char *)fp->charset()->name;
v = (!strcmp(chset, "binary")) ? 'B' : 0;
if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) { 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; qrp = NULL;
break; break;
} // endif type } // 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 = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i); crp->Kdata->SetValue(type, i);
...@@ -198,8 +215,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -198,8 +215,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp->Nulls[i] = 'Z'; crp->Nulls[i] = 'Z';
else if (fp->flags & UNSIGNED_FLAG) else if (fp->flags & UNSIGNED_FLAG)
crp->Nulls[i] = 'U'; crp->Nulls[i] = 'U';
else else // X means TEXT field
crp->Nulls[i] = v; crp->Nulls[i] = (v == 'X') ? 'V' : v;
crp = crp->Next; // Type_Name crp = crp->Next; // Type_Name
crp->Kdata->SetValue(GetTypeName(type), i); crp->Kdata->SetValue(GetTypeName(type), i);
...@@ -214,7 +231,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -214,7 +231,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
prec = len = fp->field_length; prec = len = fp->field_length;
} // endif mysql } // endif mysql
} else { } else if (v != 'X') {
if (type == TYPE_DECIM) if (type == TYPE_DECIM)
prec = ((Field_new_decimal*)fp)->precision; prec = ((Field_new_decimal*)fp)->precision;
else else
...@@ -223,7 +240,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -223,7 +240,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
len = fp->char_length(); len = fp->char_length();
fmt = NULL; fmt = NULL;
} // endif type } else
prec = len = zconv;
crp = crp->Next; // Precision crp = crp->Next; // Precision
crp->Kdata->SetValue(prec, i); crp->Kdata->SetValue(prec, i);
...@@ -259,6 +277,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, ...@@ -259,6 +277,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
// Add this item // Add this item
qrp->Nblin++; qrp->Nblin++;
i++; // Can be skipped
} // endfor field } // endfor field
/**********************************************************************/ /**********************************************************************/
......
...@@ -61,6 +61,9 @@ ...@@ -61,6 +61,9 @@
/***********************************************************************/ /***********************************************************************/
extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */ extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
extern "C" int trace; extern "C" int trace;
#if defined(XMAP)
extern bool xmap;
#endif // XMAP
/***********************************************************************/ /***********************************************************************/
/* Last two parameters are true to enable type checking, and last one */ /* Last two parameters are true to enable type checking, and last one */
...@@ -811,12 +814,16 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) ...@@ -811,12 +814,16 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
return rc; return rc;
} // end of SaveIndex } // end of SaveIndex
#if !defined(XMAP)
/***********************************************************************/ /***********************************************************************/
/* Init: Open and Initialize a Key Index. */ /* Init: Open and Initialize a Key Index. */
/***********************************************************************/ /***********************************************************************/
bool XINDEX::Init(PGLOBAL g) bool XINDEX::Init(PGLOBAL g)
{ {
#if defined(XMAP)
if (xmap)
return MapInit(g);
#endif // XMAP
/*********************************************************************/ /*********************************************************************/
/* Table will be accessed through an index table. */ /* Table will be accessed through an index table. */
/* If sorting is required, this will be done later. */ /* If sorting is required, this will be done later. */
...@@ -1053,11 +1060,11 @@ err: ...@@ -1053,11 +1060,11 @@ err:
return true; return true;
} // end of Init } // end of Init
#else // XMAP #if defined(XMAP)
/***********************************************************************/ /***********************************************************************/
/* Init: Open and Initialize a Key Index. */ /* 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. */ /* Table will be accessed through an index table. */
...@@ -1259,7 +1266,7 @@ bool XINDEX::Init(PGLOBAL g) ...@@ -1259,7 +1266,7 @@ bool XINDEX::Init(PGLOBAL g)
err: err:
Close(); Close();
return true; return true;
} // end of Init } // end of MapInit
#endif // XMAP #endif // XMAP
/***********************************************************************/ /***********************************************************************/
...@@ -2848,7 +2855,8 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m) ...@@ -2848,7 +2855,8 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
} // endif n[1] } // endif n[1]
Ndf = n[0]; Ndf = n[0];
IsSorted = colp->GetOpt() < 0; //IsSorted = colp->GetOpt() < 0;
IsSorted = false;
return m + Bkeys.Size + Keys.Size + Koff.Size; return m + Bkeys.Size + Keys.Size + Koff.Size;
} // end of MapInit } // end of MapInit
#endif // XMAP #endif // XMAP
......
...@@ -192,6 +192,9 @@ class DllExport XXBASE : public CSORT, public BLOCK { ...@@ -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, FILE *f, uint n);
virtual void Print(PGLOBAL g, char *ps, uint z); virtual void Print(PGLOBAL g, char *ps, uint z);
virtual bool Init(PGLOBAL g) = 0; 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 MaxRange(void) {return 1;}
virtual int Fetch(PGLOBAL g) = 0; virtual int Fetch(PGLOBAL g) = 0;
virtual bool NextVal(bool eq) {return true;} virtual bool NextVal(bool eq) {return true;}
...@@ -248,6 +251,9 @@ class DllExport XINDEX : public XXBASE { ...@@ -248,6 +251,9 @@ class DllExport XINDEX : public XXBASE {
// Methods // Methods
virtual void Reset(void); virtual void Reset(void);
virtual bool Init(PGLOBAL g); virtual bool Init(PGLOBAL g);
#if defined(XMAP)
virtual bool MapInit(PGLOBAL g);
#endif // XMAP
virtual int Qcompare(int *, int *); virtual int Qcompare(int *, int *);
virtual int Fetch(PGLOBAL g); virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk); virtual int FastFind(int nk);
...@@ -403,6 +409,9 @@ class DllExport XXROW : public XXBASE { ...@@ -403,6 +409,9 @@ class DllExport XXROW : public XXBASE {
// Methods // Methods
virtual bool Init(PGLOBAL g); virtual bool Init(PGLOBAL g);
#if defined(XMAP)
virtual bool MapInit(PGLOBAL g) {return true;}
#endif // XMAP
virtual int Fetch(PGLOBAL g); virtual int Fetch(PGLOBAL g);
virtual int FastFind(int nk); virtual int FastFind(int nk);
virtual int MaxRange(void) {return 1;} virtual int MaxRange(void) {return 1;}
......
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