diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 16:19:18 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 16:19:18 +0200 |
commit | ee92b2114d4b46e09f32821cb7667de47fcc6390 (patch) | |
tree | 85b9f5cc7b6a53be5b0dce0e4fefb2174774f131 /storage/federatedx | |
parent | 32ee15d851f3099d401b28321a1ae46dd36ef8ef (diff) | |
download | mariadb-git-ee92b2114d4b46e09f32821cb7667de47fcc6390.tar.gz |
assisted discovery in federatedx
Diffstat (limited to 'storage/federatedx')
-rw-r--r-- | storage/federatedx/ha_federatedx.cc | 103 | ||||
-rw-r--r-- | storage/federatedx/ha_federatedx.h | 2 |
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); |