summaryrefslogtreecommitdiff
path: root/storage/federatedx
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-04-09 16:19:18 +0200
committerSergei Golubchik <sergii@pisem.net>2013-04-09 16:19:18 +0200
commitee92b2114d4b46e09f32821cb7667de47fcc6390 (patch)
tree85b9f5cc7b6a53be5b0dce0e4fefb2174774f131 /storage/federatedx
parent32ee15d851f3099d401b28321a1ae46dd36ef8ef (diff)
downloadmariadb-git-ee92b2114d4b46e09f32821cb7667de47fcc6390.tar.gz
assisted discovery in federatedx
Diffstat (limited to 'storage/federatedx')
-rw-r--r--storage/federatedx/ha_federatedx.cc103
-rw-r--r--storage/federatedx/ha_federatedx.h2
2 files changed, 87 insertions, 18 deletions
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index 1d298cf283d..81b57034e66 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -426,6 +426,7 @@ int federatedx_db_init(void *p)
federatedx_hton->savepoint_release= ha_federatedx::savepoint_release;
federatedx_hton->commit= ha_federatedx::commit;
federatedx_hton->rollback= ha_federatedx::rollback;
+ federatedx_hton->discover_table_structure= ha_federatedx::discover_assisted;
federatedx_hton->create= federatedx_create_handler;
federatedx_hton->flags= HTON_ALTER_NOT_SUPPORTED;
@@ -516,15 +517,16 @@ err:
}
-static int parse_url_error(FEDERATEDX_SHARE *share, TABLE *table, int error_num)
+static int parse_url_error(FEDERATEDX_SHARE *share, TABLE_SHARE *table_s,
+ int error_num)
{
char buf[FEDERATEDX_QUERY_BUFFER_SIZE];
int buf_len;
DBUG_ENTER("ha_federatedx parse_url_error");
- buf_len= min(table->s->connect_string.length,
+ buf_len= min(table_s->connect_string.length,
FEDERATEDX_QUERY_BUFFER_SIZE-1);
- strmake(buf, table->s->connect_string.str, buf_len);
+ strmake(buf, table_s->connect_string.str, buf_len);
my_error(error_num, MYF(0), buf);
DBUG_RETURN(error_num);
}
@@ -646,8 +648,8 @@ error:
*/
-static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table,
- uint table_create_flag)
+static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share,
+ TABLE_SHARE *table_s, uint table_create_flag)
{
uint error_num= (table_create_flag ?
ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE :
@@ -657,11 +659,11 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table,
share->port= 0;
share->socket= 0;
DBUG_PRINT("info", ("share at %lx", (long unsigned int) share));
- DBUG_PRINT("info", ("Length: %u", (uint) table->s->connect_string.length));
- DBUG_PRINT("info", ("String: '%.*s'", (int) table->s->connect_string.length,
- table->s->connect_string.str));
- share->connection_string= strmake_root(mem_root, table->s->connect_string.str,
- table->s->connect_string.length);
+ DBUG_PRINT("info", ("Length: %u", (uint) table_s->connect_string.length));
+ DBUG_PRINT("info", ("String: '%.*s'", (int) table_s->connect_string.length,
+ table_s->connect_string.str));
+ share->connection_string= strmake_root(mem_root, table_s->connect_string.str,
+ table_s->connect_string.length);
DBUG_PRINT("info",("parse_url alloced share->connection_string %lx",
(long unsigned int) share->connection_string));
@@ -714,9 +716,9 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table,
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= strmake_root(mem_root, table_s->table_name.str,
(share->table_name_length=
- table->s->table_name.length));
+ table_s->table_name.length));
DBUG_PRINT("info",
("internal format, default table_name "
"share->connection_string: %s share->table_name: %s",
@@ -730,7 +732,7 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table,
{
share->parsed= TRUE;
// Add a null for later termination of table name
- share->connection_string[table->s->connect_string.length]= 0;
+ share->connection_string[table_s->connect_string.length]= 0;
share->scheme= share->connection_string;
DBUG_PRINT("info",("parse_url alloced share->scheme: %lx",
(ulong) share->scheme));
@@ -817,7 +819,7 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table,
DBUG_RETURN(0);
error:
- DBUG_RETURN(parse_url_error(share, table, error_num));
+ DBUG_RETURN(parse_url_error(share, table_s, error_num));
}
/*****************************************************************************
@@ -1583,7 +1585,7 @@ static FEDERATEDX_SHARE *get_share(const char *table_name, TABLE *table)
tmp_share.share_key= table_name;
tmp_share.share_key_length= strlen(table_name);
- if (parse_url(&mem_root, &tmp_share, table, 0))
+ if (parse_url(&mem_root, &tmp_share, table->s, 0))
goto error;
/* TODO: change tmp_share.scheme to LEX_STRING object */
@@ -3350,7 +3352,7 @@ int ha_federatedx::create(const char *name, TABLE *table_arg,
federatedx_io *tmp_io= NULL;
DBUG_ENTER("ha_federatedx::create");
- if ((retval= parse_url(thd->mem_root, &tmp_share, table_arg, 1)))
+ if ((retval= parse_url(thd->mem_root, &tmp_share, table_arg->s, 1)))
goto error;
/* loopback socket connections hang due to LOCK_open mutex */
@@ -3572,6 +3574,71 @@ int ha_federatedx::rollback(handlerton *hton, MYSQL_THD thd, bool all)
DBUG_RETURN(return_val);
}
+
+/*
+ Federated supports assisted discovery, like
+ CREATE TABLE t1 CONNECTION="mysql://joe:pass@192.168.1.111/federated/t1";
+ but not a fully automatic discovery where a table magically appear
+ on any use (like, on SELECT * from t1).
+*/
+int ha_federatedx::discover_assisted(handlerton *hton, THD* thd,
+ TABLE_SHARE *table_s, HA_CREATE_INFO *info)
+{
+ int error= HA_ERR_NO_CONNECTION;
+ FEDERATEDX_SHARE tmp_share;
+ CHARSET_INFO *cs= system_charset_info;
+ MYSQL mysql;
+ char buf[1024];
+ String query(buf, sizeof(buf), cs);
+ MYSQL_RES *res;
+ MYSQL_ROW rdata;
+ ulong *rlen;
+
+ if (parse_url(thd->mem_root, &tmp_share, table_s, 1))
+ return HA_WRONG_CREATE_OPTION;
+
+ mysql_init(&mysql);
+ mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, cs->csname);
+
+ if (!mysql_real_connect(&mysql, tmp_share.hostname, tmp_share.username,
+ tmp_share.password, tmp_share.database,
+ tmp_share.port, tmp_share.socket, 0))
+ goto err1;
+
+ if (mysql_real_query(&mysql, STRING_WITH_LEN("SET SQL_MODE=NO_TABLE_OPTIONS")))
+ goto err1;
+
+ query.copy(STRING_WITH_LEN("SHOW CREATE TABLE "), cs);
+ append_ident(&query, tmp_share.table_name,
+ tmp_share.table_name_length, ident_quote_char);
+
+ if (mysql_real_query(&mysql, query.ptr(), query.length()))
+ goto err1;
+
+ if (!((res= mysql_store_result(&mysql))))
+ goto err1;
+
+ if (!(rdata= mysql_fetch_row(res)) || !((rlen= mysql_fetch_lengths(res))))
+ goto err2;
+
+ query.copy(rdata[1], rlen[1], cs);
+ query.append(STRING_WITH_LEN(" CONNECTION=\""), cs);
+ query.append(table_s->connect_string.str, table_s->connect_string.length, cs);
+ query.append('"');
+
+ error= table_s->init_from_sql_statement_string(thd, true,
+ query.ptr(), query.length());
+
+err2:
+ mysql_free_result(res);
+err1:
+ if (error)
+ my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), mysql_error(&mysql));
+ mysql_close(&mysql);
+ return error;
+}
+
+
struct st_mysql_storage_engine federatedx_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
@@ -3585,10 +3652,10 @@ maria_declare_plugin(federatedx)
PLUGIN_LICENSE_GPL,
federatedx_db_init, /* Plugin Init */
federatedx_done, /* Plugin Deinit */
- 0x0200 /* 2.0 */,
+ 0x0201 /* 2.1 */,
NULL, /* status variables */
NULL, /* system variables */
- "2.0", /* string version */
+ "2.1", /* string version */
MariaDB_PLUGIN_MATURITY_BETA /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h
index 66eb4061ec3..44c20b6703a 100644
--- a/storage/federatedx/ha_federatedx.h
+++ b/storage/federatedx/ha_federatedx.h
@@ -297,6 +297,8 @@ private:
static int savepoint_release(handlerton *hton, MYSQL_THD thd, void *sv);
static int commit(handlerton *hton, MYSQL_THD thd, bool all);
static int rollback(handlerton *hton, MYSQL_THD thd, bool all);
+ static int discover_assisted(handlerton *, THD*, TABLE_SHARE *,
+ HA_CREATE_INFO *);
bool append_stmt_insert(String *query);