mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- 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
This commit is contained in:
@@ -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
|
||||
#
|
||||
|
@@ -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,7 +162,8 @@
|
||||
/***********************************************************************/
|
||||
/* 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";
|
||||
|
||||
@@ -162,13 +171,25 @@ extern "C" {
|
||||
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,10 +210,35 @@ 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
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -256,21 +302,29 @@ ha_create_table_option connect_field_option_list[]=
|
||||
/***********************************************************************/
|
||||
/* Push G->Message as a MySQL warning. */
|
||||
/***********************************************************************/
|
||||
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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
@@ -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,12 +185,29 @@ 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)
|
||||
} 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
|
||||
crp->Kdata->SetValue(type, i);
|
||||
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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,27 +212,43 @@ 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:
|
||||
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;
|
||||
|
@@ -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];
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
/**********************************************************************/
|
||||
|
@@ -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
|
||||
|
@@ -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;}
|
||||
|
Reference in New Issue
Block a user