summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/connect/global.h1
-rw-r--r--storage/connect/ha_connect.cc3
-rw-r--r--storage/connect/plugutil.c17
-rw-r--r--storage/connect/tabmysql.cpp144
-rw-r--r--storage/connect/tabmysql.h1
-rw-r--r--storage/connect/tabtbl.cpp20
6 files changed, 123 insertions, 63 deletions
diff --git a/storage/connect/global.h b/storage/connect/global.h
index 303078f5a18..3702f050501 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -244,6 +244,7 @@ DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
DllExport void *PlugAllocMem(PGLOBAL, uint);
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
+DllExport char *PlugDup(PGLOBAL g, const char *str);
DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...);
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index e28ac90a9ce..ab002488620 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -666,8 +666,7 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
else if (!stricmp(opname, "Separator"))
opval= (char*)options->separator;
else if (!stricmp(opname, "Connect"))
-// opval= (char*)options->connect;
- opval= table->s->connect_string.str;
+ opval= (tshp) ? tshp->connect_string.str : table->s->connect_string.str;
else if (!stricmp(opname, "Qchar"))
opval= (char*)options->qchar;
else if (!stricmp(opname, "Module"))
diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c
index e8098bb2512..7910f1ea318 100644
--- a/storage/connect/plugutil.c
+++ b/storage/connect/plugutil.c
@@ -512,6 +512,23 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
} /* 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. */
/***********************************************************************/
void *MakePtr(void *memp, OFFSET offset)
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 1a19b4cbf33..3af5904eee4 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -31,7 +31,10 @@
/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */
/* */
/************************************************************************/
+#define MYSQL_SERVER 1
#include "my_global.h"
+#include "sql_class.h"
+#include "sql_servers.h"
#if defined(WIN32)
//#include <windows.h>
#else // !WIN32
@@ -64,7 +67,6 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
#endif // _CONSOLE
extern "C" int trace;
-extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
/* -------------- Implementation of the MYSQLDEF class --------------- */
@@ -87,6 +89,45 @@ MYSQLDEF::MYSQLDEF(void)
} // 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 */
/* */
/* SYNOPSIS */
@@ -135,54 +176,25 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
if ((!strstr(url, "://") && (!strchr(url, '@')))) {
// No :// or @ in connection string. Must be a straight
// connection name of either "server" or "server/table"
- strcpy(g->Message, "Using Federated server not implemented yet");
- return true;
-#if 0
- /* ok, so we do a little parsing, but not completely! */
- share->parsed= FALSE;
- /*
- 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, '/')))
- {
- *share->table_name++= '\0';
- share->table_name_length= strlen(share->table_name);
-
- DBUG_PRINT("info",
- ("internal format, parsed table_name "
- "share->connection_string: %s share->table_name: %s",
- share->connection_string, share->table_name));
-
- /*
- there better not be any more '/'s !
- */
- 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)))
- goto error;
-#endif // 0
+ // ok, so we do a little parsing, but not completely!
+ if ((Tabname= strchr(url, '/'))) {
+ // If there is a single '/' in the connection string,
+ // this means the user is specifying a table name
+ *Tabname++= '\0';
+
+ // there better not be any more '/'s !
+ if (strchr(Tabname, '/'))
+ return true;
+
+ } else
+ // Otherwise, straight server name,
+ // use tablename of federatedx table as remote table name
+ Tabname= Name;
+
+ if (trace)
+ htrc("server: %s Tabname: %s", url, Tabname);
+
+ return GetServerInfo(g, url);
} else {
// URL, parse it
char *sport, *scheme = url;
@@ -247,7 +259,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
if ((sport = strchr(Hostname, ':')))
*sport++ = 0;
- Portnumber = (sport && sport[0]) ? atoi(sport) : mysqld_port;
+ Portnumber = (sport && sport[0]) ? atoi(sport) : GetDefaultPort();
if (Username[0] == 0)
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)
{
- char *url = Cat->GetStringCatInfo(g, "Connect", NULL);
+ char *url;
Desc = "MySQL Table";
if (stricmp(am, "MYPRX")) {
// Normal case of specific MYSQL table
+ url = Cat->GetStringCatInfo(g, "Connect", NULL);
+
if (!url || !*url) {
// Not using the connection URL
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);
Username = Cat->GetStringCatInfo(g, "User", "*");
Password = Cat->GetStringCatInfo(g, "Password", NULL);
- Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
+ Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
} else if (ParseURL(g, url))
return TRUE;
Bind = !!Cat->GetIntCatInfo("Bind", 0);
Delayed = !!Cat->GetIntCatInfo("Delayed", 0);
} else {
- // MYSQL access from a PROXY table, not using URL
+ // MYSQL access from a PROXY table
Database = Cat->GetStringCatInfo(g, "Database", "*");
- Tabname = Name;
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);
- Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
- Username = Cat->GetStringCatInfo(g, "User", "*");
- Password = Cat->GetStringCatInfo(g, "Password", NULL);
- Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
+ url = Cat->GetStringCatInfo(g, "Connect", NULL);
+
+ if (!url || !*url) {
+ 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
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h
index 24f8c4cdef2..16e2d650229 100644
--- a/storage/connect/tabmysql.h
+++ b/storage/connect/tabmysql.h
@@ -39,6 +39,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
bool ParseURL(PGLOBAL g, char *url);
+ bool GetServerInfo(PGLOBAL g, const char *server_name);
protected:
// Members
diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp
index 89acc53fd4a..6b90b3861aa 100644
--- a/storage/connect/tabtbl.cpp
+++ b/storage/connect/tabtbl.cpp
@@ -109,11 +109,12 @@ TBLDEF::TBLDEF(void)
/**************************************************************************/
bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
- char *tablist, *dbname;
+ char *tablist, *dbname, *def = NULL;
Desc = "Table list table";
tablist = Cat->GetStringCatInfo(g, "Tablist", "");
dbname = Cat->GetStringCatInfo(g, "Dbname", "*");
+ def = Cat->GetStringCatInfo(g, "Srcdef", NULL);
Ntables = 0;
if (*tablist) {
@@ -134,7 +135,7 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
} // endif p
// Allocate the TBLIST block for that table
- tbl = new(g) XTAB(pn);
+ tbl = new(g) XTAB(pn, def);
tbl->SetQualifier(pdb);
if (trace)
@@ -231,16 +232,28 @@ PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, PCOL scp)
bool TDBTBL::InitTableList(PGLOBAL g)
{
int n;
+ uint sln;
+ char *scs;
PTABLE tp, tabp;
PCOL colp;
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());
for (n = 0, tp = tdp->Tablep; tp; tp = tp->GetNext()) {
if (TestFil(g, To_Filter, 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
if (!(Tdbp = GetSubTable(g, tabp))) {
if (++Nbc > Maxerr)
@@ -269,6 +282,9 @@ bool TDBTBL::InitTableList(PGLOBAL g)
} // endfor tp
+ hc->get_table()->s->connect_string.str = scs;
+ hc->get_table()->s->connect_string.length = sln;
+
//NumTables = n;
To_Filter = NULL; // To avoid doing it several times
return FALSE;