diff options
author | unknown <patg@govinda.patg.net> | 2006-12-08 22:30:18 -0500 |
---|---|---|
committer | unknown <patg@govinda.patg.net> | 2006-12-08 22:30:18 -0500 |
commit | 00080b90f7dee841732c8e740c580bd35be7f963 (patch) | |
tree | d4e2024ed0a048aebabc053293f04f67c25d5a55 /storage/federated | |
parent | 9e82f299e526ceafd0deb105f0487681406b1be8 (diff) | |
parent | 715e63ae98d12d7b4121f3499739e9852a37907b (diff) | |
download | mariadb-git-00080b90f7dee841732c8e740c580bd35be7f963.tar.gz |
Merge pgalbraith@bk-internal.mysql.com:/home/bk/mysql-5.1-arch
into govinda.patg.net:/home/patg/mysql-build/mysql-5.1-arch-wl3031-merge
mysql-test/lib/init_db.sql:
Auto merged
mysql-test/r/1st.result:
Auto merged
mysql-test/r/connect.result:
Auto merged
mysql-test/r/information_schema.result:
Auto merged
mysql-test/r/mysql.result:
Auto merged
mysql-test/r/mysqlcheck.result:
Auto merged
mysql-test/r/show_check.result:
Auto merged
mysql-test/r/system_mysql_db.result:
Auto merged
scripts/mysql_create_system_tables.sh:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/mysqld.cc:
Auto merged
sql/share/errmsg.txt:
Auto merged
sql/sql_lex.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
storage/federated/ha_federated.cc:
Auto merged
mysql-test/r/sp.result:
WL# 3031
More fun with error codes. These error codes vary in the result files because new error codes have been added
mysql-test/r/sp_gis.result:
WL# 3031
More fun with error codes. These error codes vary in the result files because new error codes have been added
Diffstat (limited to 'storage/federated')
-rw-r--r-- | storage/federated/ha_federated.cc | 310 | ||||
-rw-r--r-- | storage/federated/ha_federated.h | 8 |
2 files changed, 231 insertions, 87 deletions
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 7330a19b791..397922e6e51 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -381,8 +381,8 @@ static handler *federated_create_handler(handlerton *hton, static byte *federated_get_key(FEDERATED_SHARE *share, uint *length, my_bool not_used __attribute__ ((unused))) { - *length= share->connect_string_length; - return (byte*) share->scheme; + *length= share->share_key_length; + return (byte*) share->share_key; } /* @@ -549,13 +549,14 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num) int buf_len; DBUG_ENTER("ha_federated parse_url_error"); - if (share->scheme) + if (share->connection_string) { DBUG_PRINT("info", - ("error: parse_url. Returning error code %d freeing share->scheme 0x%lx", - error_num, (long) share->scheme)); - my_free((gptr) share->scheme, MYF(0)); - share->scheme= 0; + ("error: parse_url. Returning error code %d \ + freeing share->connection_string %lx", + error_num, (long unsigned int) share->connection_string)); + my_free((gptr) share->connection_string, MYF(0)); + share->connection_string= 0; } buf_len= min(table->s->connect_string.length, FEDERATED_QUERY_BUFFER_SIZE-1); @@ -563,6 +564,77 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num) my_error(error_num, MYF(0), buf); DBUG_RETURN(error_num); } +/* + retrieve server object which contains server meta-data + from the system table given a server's name, set share + connection parameter members +*/ +int get_connection(FEDERATED_SHARE *share) +{ + int error_num= ER_FOREIGN_SERVER_DOESNT_EXIST; + char error_buffer[FEDERATED_QUERY_BUFFER_SIZE]; + FOREIGN_SERVER *server; + MYSQL *mysql_conn; + MYSQL_RES *result= 0; + MYSQL_ROW row; + DBUG_ENTER("ha_federated::get_connection"); + + if (!(server= + get_server_by_name(share->connection_string))) + { + DBUG_PRINT("info", ("get_server_by_name returned > 0 error condition!")); + /* need to come up with error handling */ + error_num=1; + goto error; + } + DBUG_PRINT("info", ("get_server_by_name returned server at %lx", (long unsigned int) server)); + + /* + Most of these should never be empty strings, error handling will + need to be implemented. Also, is this the best way to set the share + members? Is there some allocation needed? In running this code, it works + except there are errors in the trace file of the share being overrun + at the address of the share. + */ + if (server->server_name) + share->server_name= server->server_name; + share->server_name_length= server->server_name_length ? + server->server_name_length : 0; + if (server->username) + share->username= server->username; + if (server->password) + share->password= server->password; + if (server->db) + share->database= server->db; + + share->port= server->port ? server->port : MYSQL_PORT; + + if (server->host) + share->hostname= server->host; + if (server->socket) + share->socket= server->socket; + else if (strcmp(share->hostname, my_localhost) == 0) + share->socket= my_strdup(MYSQL_UNIX_ADDR, MYF(0)); + if (server->scheme) + share->scheme= server->scheme; + else + share->scheme= NULL; + + DBUG_PRINT("info", ("share->username %s", share->username)); + DBUG_PRINT("info", ("share->password %s", share->password)); + DBUG_PRINT("info", ("share->hostname %s", share->hostname)); + DBUG_PRINT("info", ("share->database %s", share->database)); + DBUG_PRINT("info", ("share->port %d", share->port)); + DBUG_PRINT("info", ("share->socket %s", share->socket)); + DBUG_RETURN(0); + +error: + my_sprintf(error_buffer, + (error_buffer, "server name: '%s' doesn't exist!", + share->connection_string)); + my_error(error_num, MYF(0), error_buffer); + DBUG_RETURN(error_num); +} /* Parse connection info from table->s->connect_string @@ -576,22 +648,39 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num) DESCRIPTION Populates the share with information about the connection to the foreign database that will serve as the data source. - This string must be specified (currently) in the "comment" field, + This string must be specified (currently) in the "CONNECTION" field, listed in the CREATE TABLE statement. This string MUST be in the format of any of these: - scheme://username:password@hostname:port/database/table - scheme://username@hostname/database/table - scheme://username@hostname:port/database/table - scheme://username:password@hostname/database/table + CONNECTION="scheme://username:password@hostname:port/database/table" + CONNECTION="scheme://username@hostname/database/table" + CONNECTION="scheme://username@hostname:port/database/table" + CONNECTION="scheme://username:password@hostname/database/table" + + _OR_ + + CONNECTION="connection name" + + An Example: - mysql://joe:joespass@192.168.1.111:9308/federated/testtable + CREATE TABLE t1 (id int(32)) + ENGINE="FEDERATED" + CONNECTION="mysql://joe:joespass@192.168.1.111:9308/federated/testtable"; + + CREATE TABLE t2 ( + id int(4) NOT NULL auto_increment, + name varchar(32) NOT NULL, + PRIMARY KEY(id) + ) ENGINE="FEDERATED" CONNECTION="my_conn"; ***IMPORTANT*** - Currently, only "mysql://" is supported. + Currently, the Federated Storage Engine only supports connecting to another + MySQL Database ("scheme" of "mysql"). Connections using JDBC as well as + other connectors are in the planning stage. + 'password' and 'port' are both optional. @@ -611,87 +700,126 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, share->port= 0; share->socket= 0; + DBUG_PRINT("info", ("share at %lx", (long unsigned int) share)); DBUG_PRINT("info", ("Length: %d", table->s->connect_string.length)); - DBUG_PRINT("info", ("String: '%.*s'", table->s->connect_string.length, + DBUG_PRINT("info", ("String: '%.*s'", table->s->connect_string.length, table->s->connect_string.str)); - share->scheme= my_strndup(table->s->connect_string.str, - table->s->connect_string.length, - MYF(0)); - - share->connect_string_length= table->s->connect_string.length; - DBUG_PRINT("info",("parse_url alloced share->scheme 0x%lx", (long) share->scheme)); - - /* - remove addition of null terminator and store length - for each string in share - */ - if (!(share->username= strstr(share->scheme, "://"))) - goto error; - share->scheme[share->username - share->scheme]= '\0'; - - if (strcmp(share->scheme, "mysql") != 0) - goto error; - - share->username+= 3; + share->connection_string= my_strndup((const byte*)table->s-> + connect_string.str, + table->s->connect_string.length, + MYF(0)); + + // Add a null for later termination of table name + share->connection_string[table->s->connect_string.length]= 0; + DBUG_PRINT("info",("parse_url alloced share->connection_string %lx", + (long unsigned int) share->connection_string)); + + DBUG_PRINT("info",("share->connection_string %s",share->connection_string)); + /* No delimiters, must be a straight connection name */ + if ( (!strchr(share->connection_string, '/')) && + (!strchr(share->connection_string, '@')) && + (!strchr(share->connection_string, ';'))) + { - if (!(share->hostname= strchr(share->username, '@'))) - goto error; - - share->username[share->hostname - share->username]= '\0'; - share->hostname++; + DBUG_PRINT("info", + ("share->connection_string %s internal format \ + share->connection_string %lx", + share->connection_string, + (long unsigned int) share->connection_string)); - if ((share->password= strchr(share->username, ':'))) - { - share->username[share->password - share->username]= '\0'; - share->password++; - share->username= share->username; - /* make sure there isn't an extra / or @ */ - if ((strchr(share->password, '/') || strchr(share->hostname, '@'))) + share->parsed= FALSE; + if ((error_num= get_connection(share))) goto error; + /* - Found that if the string is: - user:@hostname:port/database/table - Then password is a null string, so set to NULL + connection specifies everything but, resort to + expecting remote and foreign table names to match */ - if ((share->password[0] == '\0')) - share->password= NULL; + share->table_name= table->s->table_name.str; + share->table_name_length= table->s->table_name.length; + share->table_name[share->table_name_length]= '\0'; } else - share->username= share->username; + { + share->parsed= TRUE; + // Add a null for later termination of table name + share->connection_string[table->s->connect_string.length]= 0; + share->scheme= share->connection_string; + DBUG_PRINT("info",("parse_url alloced share->scheme %lx", + (long unsigned int) share->scheme)); - /* make sure there isn't an extra / or @ */ - if ((strchr(share->username, '/')) || (strchr(share->hostname, '@'))) - goto error; + /* + remove addition of null terminator and store length + for each string in share + */ + if (!(share->username= strstr(share->scheme, "://"))) + goto error; + share->scheme[share->username - share->scheme]= '\0'; - if (!(share->database= strchr(share->hostname, '/'))) - goto error; - share->hostname[share->database - share->hostname]= '\0'; - share->database++; + if (strcmp(share->scheme, "mysql") != 0) + goto error; - if ((share->sport= strchr(share->hostname, ':'))) - { - share->hostname[share->sport - share->hostname]= '\0'; - share->sport++; - if (share->sport[0] == '\0') - share->sport= NULL; + share->username+= 3; + + if (!(share->hostname= strchr(share->username, '@'))) + goto error; + + share->username[share->hostname - share->username]= '\0'; + share->hostname++; + + if ((share->password= strchr(share->username, ':'))) + { + share->username[share->password - share->username]= '\0'; + share->password++; + share->username= share->username; + /* make sure there isn't an extra / or @ */ + if ((strchr(share->password, '/') || strchr(share->hostname, '@'))) + goto error; + /* + Found that if the string is: +user:@hostname:port/db/table +Then password is a null string, so set to NULL + */ + if ((share->password[0] == '\0')) + share->password= NULL; + } else - share->port= atoi(share->sport); - } + share->username= share->username; - if (!(share->table_name= strchr(share->database, '/'))) - goto error; - share->database[share->table_name - share->database]= '\0'; - share->table_name++; + /* make sure there isn't an extra / or @ */ + if ((strchr(share->username, '/')) || (strchr(share->hostname, '@'))) + goto error; - share->table_name_length= strlen(share->table_name); - - /* make sure there's not an extra / */ - if ((strchr(share->table_name, '/'))) - goto error; + if (!(share->database= strchr(share->hostname, '/'))) + goto error; + share->hostname[share->database - share->hostname]= '\0'; + share->database++; - if (share->hostname[0] == '\0') - share->hostname= NULL; + if ((share->sport= strchr(share->hostname, ':'))) + { + share->hostname[share->sport - share->hostname]= '\0'; + share->sport++; + if (share->sport[0] == '\0') + share->sport= NULL; + else + share->port= atoi(share->sport); + } + + if (!(share->table_name= strchr(share->database, '/'))) + goto error; + share->database[share->table_name - share->database]= '\0'; + share->table_name++; + share->table_name_length= strlen(share->table_name); + + /* make sure there's not an extra / */ + if ((strchr(share->table_name, '/'))) + goto error; + + if (share->hostname[0] == '\0') + share->hostname= NULL; + + } if (!share->port) { if (strcmp(share->hostname, my_localhost) == 0) @@ -702,7 +830,7 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, DBUG_PRINT("info", ("scheme: %s username: %s password: %s \ - hostname: %s port: %d database: %s tablename: %s", + hostname: %s port: %d db: %s tablename: %s", share->scheme, share->username, share->password, share->hostname, share->port, share->database, share->table_name)); @@ -713,7 +841,6 @@ error: DBUG_RETURN(parse_url_error(share, table, error_num)); } - /***************************************************************************** ** FEDERATED tables *****************************************************************************/ @@ -1313,14 +1440,16 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) pthread_mutex_lock(&federated_mutex); + tmp_share.share_key= table_name; + tmp_share.share_key_length= strlen(table_name); if (parse_url(&tmp_share, table, 0)) goto error; /* TODO: change tmp_share.scheme to LEX_STRING object */ if (!(share= (FEDERATED_SHARE *) hash_search(&federated_open_tables, - (byte*) tmp_share.scheme, + (byte*) tmp_share.share_key, tmp_share. - connect_string_length))) + share_key_length))) { query.set_charset(system_charset_info); query.append(STRING_WITH_LEN("SELECT ")); @@ -1367,7 +1496,8 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) error: pthread_mutex_unlock(&federated_mutex); - my_free((gptr) tmp_share.scheme, MYF(MY_ALLOW_ZERO_PTR)); + my_free((gptr) tmp_share.connection_string, MYF(MY_ALLOW_ZERO_PTR)); + tmp_share.connection_string= 0; my_free((gptr) share, MYF(MY_ALLOW_ZERO_PTR)); return NULL; } @@ -1387,8 +1517,14 @@ static int free_share(FEDERATED_SHARE *share) if (!--share->use_count) { hash_delete(&federated_open_tables, (byte*) share); - my_free((gptr) share->scheme, MYF(MY_ALLOW_ZERO_PTR)); - my_free((gptr) share->socket, MYF(MY_ALLOW_ZERO_PTR)); + if (share->parsed) + my_free((gptr) share->socket, MYF(MY_ALLOW_ZERO_PTR)); + /*if (share->connection_string) + { + */ + my_free((gptr) share->connection_string, MYF(MY_ALLOW_ZERO_PTR)); + share->connection_string= 0; + /*}*/ thr_lock_delete(&share->lock); VOID(pthread_mutex_destroy(&share->mutex)); my_free((gptr) share, MYF(0)); @@ -2697,7 +2833,9 @@ int ha_federated::create(const char *name, TABLE *table_arg, if (!(retval= parse_url(&tmp_share, table_arg, 1))) retval= check_foreign_data_source(&tmp_share, 1); - my_free((gptr) tmp_share.scheme, MYF(MY_ALLOW_ZERO_PTR)); + /* free this because strdup created it in parse_url */ + my_free((gptr) tmp_share.connection_string, MYF(MY_ALLOW_ZERO_PTR)); + tmp_share.connection_string= 0; DBUG_RETURN(retval); } diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h index d1b485d63e2..63399e71bcd 100644 --- a/storage/federated/ha_federated.h +++ b/storage/federated/ha_federated.h @@ -43,6 +43,9 @@ The example implements the minimum of what you will probably need. */ typedef struct st_federated_share { + bool parsed; + /* this key is unique db/tablename */ + const char *share_key; /* the primary select query to be used in rnd_init */ @@ -50,6 +53,8 @@ typedef struct st_federated_share { /* remote host info, parse_url supplies */ + char *server_name; + char *connection_string; char *scheme; char *connect_string; char *hostname; @@ -60,8 +65,9 @@ typedef struct st_federated_share { char *table; char *socket; char *sport; + int share_key_length; ushort port; - uint table_name_length, connect_string_length, use_count; + uint table_name_length, server_name_length, connect_string_length, use_count; pthread_mutex_t mutex; THR_LOCK lock; } FEDERATED_SHARE; |