mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- Implemented: The use of Federated servers.
modified: storage/connect/global.h storage/connect/ha_connect.cc storage/connect/plugutil.c storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabtbl.cpp
This commit is contained in:
@@ -244,6 +244,7 @@ DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
|
|||||||
DllExport void *PlugAllocMem(PGLOBAL, uint);
|
DllExport void *PlugAllocMem(PGLOBAL, uint);
|
||||||
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
|
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
|
||||||
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
|
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
|
||||||
|
DllExport char *PlugDup(PGLOBAL g, const char *str);
|
||||||
DllExport void *MakePtr(void *, OFFSET);
|
DllExport void *MakePtr(void *, OFFSET);
|
||||||
DllExport void htrc(char const *fmt, ...);
|
DllExport void htrc(char const *fmt, ...);
|
||||||
|
|
||||||
|
@@ -666,8 +666,7 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
|
|||||||
else if (!stricmp(opname, "Separator"))
|
else if (!stricmp(opname, "Separator"))
|
||||||
opval= (char*)options->separator;
|
opval= (char*)options->separator;
|
||||||
else if (!stricmp(opname, "Connect"))
|
else if (!stricmp(opname, "Connect"))
|
||||||
// opval= (char*)options->connect;
|
opval= (tshp) ? tshp->connect_string.str : table->s->connect_string.str;
|
||||||
opval= table->s->connect_string.str;
|
|
||||||
else if (!stricmp(opname, "Qchar"))
|
else if (!stricmp(opname, "Qchar"))
|
||||||
opval= (char*)options->qchar;
|
opval= (char*)options->qchar;
|
||||||
else if (!stricmp(opname, "Module"))
|
else if (!stricmp(opname, "Module"))
|
||||||
|
@@ -511,6 +511,23 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
|
|||||||
return (memp);
|
return (memp);
|
||||||
} /* end of PlugSubAlloc */
|
} /* end of PlugSubAlloc */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This routine suballocate a copy of the passed string. */
|
||||||
|
/***********************************************************************/
|
||||||
|
char *PlugDup(PGLOBAL g, const char *str)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (str && (len = strlen(str))) {
|
||||||
|
buf = (char*)PlugSubAlloc(g, NULL, len + 1);
|
||||||
|
strcpy(buf, str);
|
||||||
|
} else
|
||||||
|
buf = NULL;
|
||||||
|
|
||||||
|
return(buf);
|
||||||
|
} /* end of PlugDup */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* This routine makes a pointer from an offset to a memory pointer. */
|
/* This routine makes a pointer from an offset to a memory pointer. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -31,7 +31,10 @@
|
|||||||
/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */
|
/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */
|
||||||
/* */
|
/* */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
#define MYSQL_SERVER 1
|
||||||
#include "my_global.h"
|
#include "my_global.h"
|
||||||
|
#include "sql_class.h"
|
||||||
|
#include "sql_servers.h"
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
//#include <windows.h>
|
//#include <windows.h>
|
||||||
#else // !WIN32
|
#else // !WIN32
|
||||||
@@ -64,7 +67,6 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
|
|||||||
#endif // _CONSOLE
|
#endif // _CONSOLE
|
||||||
|
|
||||||
extern "C" int trace;
|
extern "C" int trace;
|
||||||
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
|
|
||||||
|
|
||||||
/* -------------- Implementation of the MYSQLDEF class --------------- */
|
/* -------------- Implementation of the MYSQLDEF class --------------- */
|
||||||
|
|
||||||
@@ -86,6 +88,45 @@ MYSQLDEF::MYSQLDEF(void)
|
|||||||
Delayed = FALSE;
|
Delayed = FALSE;
|
||||||
} // end of MYSQLDEF constructor
|
} // end of MYSQLDEF constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Get connection info from the declared server. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
|
||||||
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
|
MEM_ROOT *mem= thd->mem_root;
|
||||||
|
FOREIGN_SERVER *server, server_buffer;
|
||||||
|
DBUG_ENTER("GetServerInfo");
|
||||||
|
DBUG_PRINT("info", ("server_name %s", server_name));
|
||||||
|
|
||||||
|
if (!server_name || !strlen(server_name)) {
|
||||||
|
DBUG_PRINT("info", ("server_name not defined!"));
|
||||||
|
strcpy(g->Message, "server_name not defined!");
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
} // endif server_name
|
||||||
|
|
||||||
|
// get_server_by_name() clones the server if exists and allocates
|
||||||
|
// copies of strings in the supplied mem_root
|
||||||
|
if (!(server= get_server_by_name(mem, server_name, &server_buffer))) {
|
||||||
|
DBUG_PRINT("info", ("get_server_by_name returned > 0 error condition!"));
|
||||||
|
/* need to come up with error handling */
|
||||||
|
strcpy(g->Message, "get_server_by_name returned > 0 error condition!");
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
} // endif server
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("get_server_by_name returned server at %lx",
|
||||||
|
(long unsigned int) server));
|
||||||
|
|
||||||
|
// TODO: We need to examine which of these can really be NULL
|
||||||
|
Hostname = PlugDup(g, server->host);
|
||||||
|
Database = PlugDup(g, server->db);
|
||||||
|
Username = PlugDup(g, server->username);
|
||||||
|
Password = PlugDup(g, server->password);
|
||||||
|
Portnumber = (server->port) ? server->port : GetDefaultPort();
|
||||||
|
|
||||||
|
DBUG_RETURN(false);
|
||||||
|
} // end of GetServerInfo
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Parse connection string */
|
/* Parse connection string */
|
||||||
/* */
|
/* */
|
||||||
@@ -135,54 +176,25 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
|||||||
if ((!strstr(url, "://") && (!strchr(url, '@')))) {
|
if ((!strstr(url, "://") && (!strchr(url, '@')))) {
|
||||||
// No :// or @ in connection string. Must be a straight
|
// No :// or @ in connection string. Must be a straight
|
||||||
// connection name of either "server" or "server/table"
|
// connection name of either "server" or "server/table"
|
||||||
strcpy(g->Message, "Using Federated server not implemented yet");
|
// ok, so we do a little parsing, but not completely!
|
||||||
return true;
|
if ((Tabname= strchr(url, '/'))) {
|
||||||
#if 0
|
// If there is a single '/' in the connection string,
|
||||||
/* ok, so we do a little parsing, but not completely! */
|
// this means the user is specifying a table name
|
||||||
share->parsed= FALSE;
|
*Tabname++= '\0';
|
||||||
/*
|
|
||||||
If there is a single '/' in the connection string, this means the user is
|
|
||||||
specifying a table name
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((share->table_name= strchr(share->connection_string, '/')))
|
// there better not be any more '/'s !
|
||||||
{
|
if (strchr(Tabname, '/'))
|
||||||
*share->table_name++= '\0';
|
return true;
|
||||||
share->table_name_length= strlen(share->table_name);
|
|
||||||
|
|
||||||
DBUG_PRINT("info",
|
} else
|
||||||
("internal format, parsed table_name "
|
// Otherwise, straight server name,
|
||||||
"share->connection_string: %s share->table_name: %s",
|
// use tablename of federatedx table as remote table name
|
||||||
share->connection_string, share->table_name));
|
Tabname= Name;
|
||||||
|
|
||||||
/*
|
if (trace)
|
||||||
there better not be any more '/'s !
|
htrc("server: %s Tabname: %s", url, Tabname);
|
||||||
*/
|
|
||||||
if (strchr(share->table_name, '/'))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Otherwise, straight server name, use tablename of federatedx table
|
|
||||||
as remote table name
|
|
||||||
*/
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Connection specifies everything but, resort to
|
|
||||||
expecting remote and foreign table names to match
|
|
||||||
*/
|
|
||||||
share->table_name= strmake_root(mem_root, table->s->table_name.str,
|
|
||||||
(share->table_name_length=
|
|
||||||
table->s->table_name.length));
|
|
||||||
DBUG_PRINT("info",
|
|
||||||
("internal format, default table_name "
|
|
||||||
"share->connection_string: %s share->table_name: %s",
|
|
||||||
share->connection_string, share->table_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error_num= get_connection(mem_root, share)))
|
return GetServerInfo(g, url);
|
||||||
goto error;
|
|
||||||
#endif // 0
|
|
||||||
} else {
|
} else {
|
||||||
// URL, parse it
|
// URL, parse it
|
||||||
char *sport, *scheme = url;
|
char *sport, *scheme = url;
|
||||||
@@ -247,7 +259,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
|||||||
if ((sport = strchr(Hostname, ':')))
|
if ((sport = strchr(Hostname, ':')))
|
||||||
*sport++ = 0;
|
*sport++ = 0;
|
||||||
|
|
||||||
Portnumber = (sport && sport[0]) ? atoi(sport) : mysqld_port;
|
Portnumber = (sport && sport[0]) ? atoi(sport) : GetDefaultPort();
|
||||||
|
|
||||||
if (Username[0] == 0)
|
if (Username[0] == 0)
|
||||||
Username = Cat->GetStringCatInfo(g, "User", "*");
|
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||||
@@ -279,12 +291,14 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||||
{
|
{
|
||||||
char *url = Cat->GetStringCatInfo(g, "Connect", NULL);
|
char *url;
|
||||||
|
|
||||||
Desc = "MySQL Table";
|
Desc = "MySQL Table";
|
||||||
|
|
||||||
if (stricmp(am, "MYPRX")) {
|
if (stricmp(am, "MYPRX")) {
|
||||||
// Normal case of specific MYSQL table
|
// Normal case of specific MYSQL table
|
||||||
|
url = Cat->GetStringCatInfo(g, "Connect", NULL);
|
||||||
|
|
||||||
if (!url || !*url) {
|
if (!url || !*url) {
|
||||||
// Not using the connection URL
|
// Not using the connection URL
|
||||||
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
||||||
@@ -293,24 +307,36 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
||||||
Username = Cat->GetStringCatInfo(g, "User", "*");
|
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||||
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
||||||
Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
|
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
|
||||||
} else if (ParseURL(g, url))
|
} else if (ParseURL(g, url))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
Bind = !!Cat->GetIntCatInfo("Bind", 0);
|
Bind = !!Cat->GetIntCatInfo("Bind", 0);
|
||||||
Delayed = !!Cat->GetIntCatInfo("Delayed", 0);
|
Delayed = !!Cat->GetIntCatInfo("Delayed", 0);
|
||||||
} else {
|
} else {
|
||||||
// MYSQL access from a PROXY table, not using URL
|
// MYSQL access from a PROXY table
|
||||||
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
||||||
Tabname = Name;
|
|
||||||
Isview = Cat->GetBoolCatInfo("View", FALSE);
|
Isview = Cat->GetBoolCatInfo("View", FALSE);
|
||||||
|
|
||||||
// We must get connection parms from the calling table
|
// We must get other connection parms from the calling table
|
||||||
Remove_tshp(Cat);
|
Remove_tshp(Cat);
|
||||||
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
url = Cat->GetStringCatInfo(g, "Connect", NULL);
|
||||||
Username = Cat->GetStringCatInfo(g, "User", "*");
|
|
||||||
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
if (!url || !*url) {
|
||||||
Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
|
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
||||||
|
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||||
|
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
||||||
|
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
|
||||||
|
} else {
|
||||||
|
char *locdb = Database;
|
||||||
|
|
||||||
|
if (ParseURL(g, url))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
Database = locdb;
|
||||||
|
} // endif url
|
||||||
|
|
||||||
|
Tabname = Name;
|
||||||
} // endif am
|
} // endif am
|
||||||
|
|
||||||
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
|
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
|
||||||
|
@@ -39,6 +39,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||||||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||||
virtual PTDB GetTable(PGLOBAL g, MODE m);
|
virtual PTDB GetTable(PGLOBAL g, MODE m);
|
||||||
bool ParseURL(PGLOBAL g, char *url);
|
bool ParseURL(PGLOBAL g, char *url);
|
||||||
|
bool GetServerInfo(PGLOBAL g, const char *server_name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
|
@@ -109,11 +109,12 @@ TBLDEF::TBLDEF(void)
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||||
{
|
{
|
||||||
char *tablist, *dbname;
|
char *tablist, *dbname, *def = NULL;
|
||||||
|
|
||||||
Desc = "Table list table";
|
Desc = "Table list table";
|
||||||
tablist = Cat->GetStringCatInfo(g, "Tablist", "");
|
tablist = Cat->GetStringCatInfo(g, "Tablist", "");
|
||||||
dbname = Cat->GetStringCatInfo(g, "Dbname", "*");
|
dbname = Cat->GetStringCatInfo(g, "Dbname", "*");
|
||||||
|
def = Cat->GetStringCatInfo(g, "Srcdef", NULL);
|
||||||
Ntables = 0;
|
Ntables = 0;
|
||||||
|
|
||||||
if (*tablist) {
|
if (*tablist) {
|
||||||
@@ -134,7 +135,7 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
} // endif p
|
} // endif p
|
||||||
|
|
||||||
// Allocate the TBLIST block for that table
|
// Allocate the TBLIST block for that table
|
||||||
tbl = new(g) XTAB(pn);
|
tbl = new(g) XTAB(pn, def);
|
||||||
tbl->SetQualifier(pdb);
|
tbl->SetQualifier(pdb);
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
@@ -231,16 +232,28 @@ PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, PCOL scp)
|
|||||||
bool TDBTBL::InitTableList(PGLOBAL g)
|
bool TDBTBL::InitTableList(PGLOBAL g)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
uint sln;
|
||||||
|
char *scs;
|
||||||
PTABLE tp, tabp;
|
PTABLE tp, tabp;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
PTBLDEF tdp = (PTBLDEF)To_Def;
|
PTBLDEF tdp = (PTBLDEF)To_Def;
|
||||||
|
PCATLG cat = To_Def->GetCat();
|
||||||
|
PHC hc = ((MYCAT*)cat)->GetHandler();
|
||||||
|
|
||||||
|
scs = hc->get_table()->s->connect_string.str;
|
||||||
|
sln = hc->get_table()->s->connect_string.length;
|
||||||
// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
||||||
|
|
||||||
for (n = 0, tp = tdp->Tablep; tp; tp = tp->GetNext()) {
|
for (n = 0, tp = tdp->Tablep; tp; tp = tp->GetNext()) {
|
||||||
if (TestFil(g, To_Filter, tp)) {
|
if (TestFil(g, To_Filter, tp)) {
|
||||||
tabp = new(g) XTAB(tp);
|
tabp = new(g) XTAB(tp);
|
||||||
|
|
||||||
|
if (tabp->GetSrc()) {
|
||||||
|
// Table list is a list of connections
|
||||||
|
hc->get_table()->s->connect_string.str = (char*)tabp->GetName();
|
||||||
|
hc->get_table()->s->connect_string.length = strlen(tabp->GetName());
|
||||||
|
} // endif Src
|
||||||
|
|
||||||
// Get the table description block of this table
|
// Get the table description block of this table
|
||||||
if (!(Tdbp = GetSubTable(g, tabp))) {
|
if (!(Tdbp = GetSubTable(g, tabp))) {
|
||||||
if (++Nbc > Maxerr)
|
if (++Nbc > Maxerr)
|
||||||
@@ -269,6 +282,9 @@ bool TDBTBL::InitTableList(PGLOBAL g)
|
|||||||
|
|
||||||
} // endfor tp
|
} // endfor tp
|
||||||
|
|
||||||
|
hc->get_table()->s->connect_string.str = scs;
|
||||||
|
hc->get_table()->s->connect_string.length = sln;
|
||||||
|
|
||||||
//NumTables = n;
|
//NumTables = n;
|
||||||
To_Filter = NULL; // To avoid doing it several times
|
To_Filter = NULL; // To avoid doing it several times
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
Reference in New Issue
Block a user