summaryrefslogtreecommitdiff
path: root/sql/sql_servers.cc
diff options
context:
space:
mode:
authorunknown <acurtis/antony@xiphis.org/ltamd64.xiphis.org>2007-03-24 01:18:19 -0700
committerunknown <acurtis/antony@xiphis.org/ltamd64.xiphis.org>2007-03-24 01:18:19 -0700
commit99c5c28c3cc9eb417f4ca12f606c5abcf6b02a19 (patch)
treef23ab8b69e00d10ca3921fb21bb3cc8904908d19 /sql/sql_servers.cc
parentcb5b56c8efc1752d6768547a6f0517455cdbe7e2 (diff)
downloadmariadb-git-99c5c28c3cc9eb417f4ca12f606c5abcf6b02a19.tar.gz
BUG#26257 New Federated Server Functionality Doesn't support differently named tables
* Modified Federated memory allocation to use MEM_ROOT * Modified sql_servers and federated to allocate share connection parameters to use MEM_ROOT * Modified Federated to allow tablename in addition to server name * Implicit flushing of tables using altered/dropped server name * Added tests to prove new functionality works Contributors to this patch: Patrick Galbraith, Antony Curtis mysql-test/r/federated_server.result: BUG #26257 New Federated Server Functionality Doesn't support differently named tables New test results mysql-test/t/federated_server.test: BUG #26257 New Federated Server Functionality Doesn't support differently named tables New test which ensures that one can use the new 'create server' functionality and have tables point to the correct table, using CONNECTION='server', CONNECTION="server/tablename" and CONNECTION="mysql://...url" sql/mysql_priv.h: BUG #26257 New Federated Server Functionality Doesn't support differently named tables new function: close_cached_connection_tables() sql/sql_base.cc: BUG #26257 New Federated Server Functionality Doesn't support differently named tables new function: close_cached_connection_tables() closes all open tables which match connection string provides functionality to allow flushing of altered/dropped server names. sql/sql_servers.cc: BUG #26257 New Federated Server Functionality Doesn't support differently named tables * Added function clone_server() to allocate a new server for use by get_server_by_name() when creating a federated table * Now using MEM_ROOT allocation (mark and sweep) to account for meta data parameters being allocated properly, particularly with regards to to SERVER object. Also cleans up code allocating share. * Tables using the old definition of server name are now flushed on successful execution of ALTER/DROP SERVER. style: fixed some line-wrapping sql/sql_servers.h: BUG #26257 New Federated Server Functionality Doesn't support differently named tables * change in prototype to get_server_by_name() caller can now provide mem_root which strings will be copied in to. storage/federated/ha_federated.cc: BUG #26257 New Federated Server Functionality Doesn't support differently named tables * Simplified share and share member memory allocaton to use MEM_ROOT * Modified parse_url to parse table names along with server names storage/federated/ha_federated.h: BUG #26257 New Federated Server Functionality Doesn't support differently named tables * Added MEM_ROOT share member
Diffstat (limited to 'sql/sql_servers.cc')
-rw-r--r--sql/sql_servers.cc110
1 files changed, 97 insertions, 13 deletions
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index 9b01a1b6889..71e141b0514 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -16,6 +16,21 @@
/*
The servers are saved in the system table "servers"
+
+ Currently, when the user performs an ALTER SERVER or a DROP SERVER
+ operation, it will cause all open tables which refer to the named
+ server connection to be flushed. This may cause some undesirable
+ behaviour with regard to currently running transactions. It is
+ expected that the DBA knows what s/he is doing when s/he performs
+ the ALTER SERVER or DROP SERVER operation.
+
+ TODO:
+ It is desirable for us to implement a callback mechanism instead where
+ callbacks can be registered for specific server protocols. The callback
+ will be fired when such a server name has been created/altered/dropped
+ or when statistics are to be gathered such as how many actual connections.
+ Storage engines etc will be able to make use of the callback so that
+ currently running transactions etc will not be disrupted.
*/
#include "mysql_priv.h"
@@ -557,6 +572,8 @@ int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
int error;
TABLE_LIST tables;
TABLE *table;
+ LEX_STRING name= { server_options->server_name,
+ server_options->server_name_length };
DBUG_ENTER("drop_server");
DBUG_PRINT("info", ("server name server->server_name %s",
@@ -578,14 +595,16 @@ int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
goto end;
}
- error= delete_server_record(table,
- server_options->server_name,
- server_options->server_name_length);
+ error= delete_server_record(table, name.str, name.length);
- /*
- Perform a reload so we don't have a 'hole' in our mem_root
- */
- servers_load(thd, &tables);
+ /* close the servers table before we call closed_cached_connection_tables */
+ close_thread_tables(thd);
+
+ if (close_cached_connection_tables(thd, TRUE, &name))
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR, "Server connection in use");
+ }
end:
rw_unlock(&THR_LOCK_servers);
@@ -975,6 +994,8 @@ int alter_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
{
int error= ER_FOREIGN_SERVER_DOESNT_EXIST;
FOREIGN_SERVER *altered, *existing;
+ LEX_STRING name= { server_options->server_name,
+ server_options->server_name_length };
DBUG_ENTER("alter_server");
DBUG_PRINT("info", ("server_options->server_name %s",
server_options->server_name));
@@ -982,8 +1003,8 @@ int alter_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
rw_wrlock(&THR_LOCK_servers);
if (!(existing= (FOREIGN_SERVER *) hash_search(&servers_cache,
- (byte*) server_options->server_name,
- server_options->server_name_length)))
+ (byte*) name.str,
+ name.length)))
goto end;
altered= (FOREIGN_SERVER *)alloc_root(&mem,
@@ -993,6 +1014,15 @@ int alter_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
error= update_server(thd, existing, altered);
+ /* close the servers table before we call closed_cached_connection_tables */
+ close_thread_tables(thd);
+
+ if (close_cached_connection_tables(thd, FALSE, &name))
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR, "Server connection in use");
+ }
+
end:
DBUG_PRINT("info", ("error returned %d", error));
rw_unlock(&THR_LOCK_servers);
@@ -1143,6 +1173,12 @@ void servers_free(bool end)
DBUG_ENTER("servers_free");
if (!hash_inited(&servers_cache))
DBUG_VOID_RETURN;
+ if (!end)
+ {
+ free_root(&mem, MYF(MY_MARK_BLOCKS_FREE));
+ my_hash_reset(&servers_cache);
+ DBUG_VOID_RETURN;
+ }
rwlock_destroy(&THR_LOCK_servers);
free_root(&mem,MYF(0));
hash_free(&servers_cache);
@@ -1151,6 +1187,51 @@ void servers_free(bool end)
/*
+ SYNOPSIS
+
+ clone_server(MEM_ROOT *mem_root, FOREIGN_SERVER *orig, FOREIGN_SERVER *buff)
+
+ Create a clone of FOREIGN_SERVER. If the supplied mem_root is of
+ thd->mem_root then the copy is automatically disposed at end of statement.
+
+ NOTES
+
+ ARGS
+ MEM_ROOT pointer (strings are copied into this mem root)
+ FOREIGN_SERVER pointer (made a copy of)
+ FOREIGN_SERVER buffer (if not-NULL, this pointer is returned)
+
+ RETURN VALUE
+ FOREIGN_SEVER pointer (copy of one supplied FOREIGN_SERVER)
+*/
+
+static FOREIGN_SERVER *clone_server(MEM_ROOT *mem, const FOREIGN_SERVER *server,
+ FOREIGN_SERVER *buffer)
+{
+ DBUG_ENTER("sql_server.cc:clone_server");
+
+ if (!buffer)
+ buffer= (FOREIGN_SERVER *) alloc_root(mem, sizeof(FOREIGN_SERVER));
+
+ buffer->server_name= strmake_root(mem, server->server_name,
+ server->server_name_length);
+ buffer->port= server->port;
+ buffer->server_name_length= server->server_name_length;
+
+ /* TODO: We need to examine which of these can really be NULL */
+ buffer->db= server->db ? strdup_root(mem, server->db) : NULL;
+ buffer->scheme= server->scheme ? strdup_root(mem, server->scheme) : NULL;
+ buffer->username= server->username? strdup_root(mem, server->username): NULL;
+ buffer->password= server->password? strdup_root(mem, server->password): NULL;
+ buffer->socket= server->socket ? strdup_root(mem, server->socket) : NULL;
+ buffer->owner= server->owner ? strdup_root(mem, server->owner) : NULL;
+ buffer->host= server->host ? strdup_root(mem, server->host) : NULL;
+
+ DBUG_RETURN(buffer);
+}
+
+
+/*
SYNOPSIS
get_server_by_name()
@@ -1163,11 +1244,11 @@ void servers_free(bool end)
*/
-FOREIGN_SERVER *get_server_by_name(const char *server_name)
+FOREIGN_SERVER *get_server_by_name(MEM_ROOT *mem, const char *server_name,
+ FOREIGN_SERVER *buff)
{
- ulong error_num=0;
uint server_name_length;
- FOREIGN_SERVER *server= 0;
+ FOREIGN_SERVER *server;
DBUG_ENTER("get_server_by_name");
DBUG_PRINT("info", ("server_name %s", server_name));
@@ -1176,7 +1257,6 @@ FOREIGN_SERVER *get_server_by_name(const char *server_name)
if (! server_name || !strlen(server_name))
{
DBUG_PRINT("info", ("server_name not defined!"));
- error_num= 1;
DBUG_RETURN((FOREIGN_SERVER *)NULL);
}
@@ -1190,6 +1270,10 @@ FOREIGN_SERVER *get_server_by_name(const char *server_name)
server_name, server_name_length));
server= (FOREIGN_SERVER *) NULL;
}
+ /* otherwise, make copy of server */
+ else
+ server= clone_server(mem, server, buff);
+
DBUG_PRINT("info", ("unlocking servers_cache"));
rw_unlock(&THR_LOCK_servers);
DBUG_RETURN(server);