diff options
author | Nirbhay Choubey <nirbhay.choubey@oracle.com> | 2012-09-21 23:31:32 +0530 |
---|---|---|
committer | Nirbhay Choubey <nirbhay.choubey@oracle.com> | 2012-09-21 23:31:32 +0530 |
commit | 967fd170f558f2d3e28cc1aede4589324e19d736 (patch) | |
tree | 8606d925ce1d16f6064d5fc27f26ddc14937f2f5 /client/mysql.cc | |
parent | d43185e5037ef51b5cd8fad1261397b6b3f0742e (diff) | |
parent | 600aa420d6bb17a2af779de11926ae1d3c122fd8 (diff) | |
download | mariadb-git-967fd170f558f2d3e28cc1aede4589324e19d736.tar.gz |
Merge of fix for Bug#14645196 from mysql-5.1
Diffstat (limited to 'client/mysql.cc')
-rw-r--r-- | client/mysql.cc | 91 |
1 files changed, 89 insertions, 2 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index 73787ea5eeb..b772fe67cc4 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -242,6 +242,8 @@ static void init_username(); static void add_int_to_prompt(int toadd); static int get_result_width(MYSQL_RES *res); static int get_field_disp_length(MYSQL_FIELD * field); +static int normalize_dbname(const char *line, char *buff, uint buff_size); +static int get_quote_count(const char *line); /* A structure which contains information on the commands this program can understand. */ @@ -4137,8 +4139,23 @@ com_use(String *buffer __attribute__((unused)), char *line) int select_db; bzero(buff, sizeof(buff)); - strmake(buff, line, sizeof(buff) - 1); - tmp= get_arg(buff, 0); + + /* + In case number of quotes exceed 2, we try to get + the normalized db name. + */ + if (get_quote_count(line) > 2) + { + if (normalize_dbname(line, buff, sizeof(buff))) + return put_error(&mysql); + tmp= buff; + } + else + { + strmake(buff, line, sizeof(buff) - 1); + tmp= get_arg(buff, 0); + } + if (!tmp || !*tmp) { put_info("USE must be followed by a database name", INFO_ERROR); @@ -4204,6 +4221,62 @@ com_use(String *buffer __attribute__((unused)), char *line) return 0; } +/** + Normalize database name. + + @param line [IN] The command. + @param buff [OUT] Normalized db name. + @param buff_size [IN] Buffer size. + + @return Operation status + @retval 0 Success + @retval 1 Failure + + @note Sometimes server normilizes the database names + & APIs like mysql_select_db() expect normalized + database names. Since it is difficult to perform + the name conversion/normalization on the client + side, this function tries to get the normalized + dbname (indirectly) from the server. +*/ + +static int +normalize_dbname(const char *line, char *buff, uint buff_size) +{ + MYSQL_RES *res= NULL; + + /* Send the "USE db" commmand to the server. */ + if (mysql_query(&mysql, line)) + return 1; + + /* + Now, get the normalized database name and store it + into the buff. + */ + if (!mysql_query(&mysql, "SELECT DATABASE()") && + (res= mysql_use_result(&mysql))) + { + MYSQL_ROW row= mysql_fetch_row(res); + if (row && row[0]) + { + size_t len= strlen(row[0]); + /* Make sure there is enough room to store the dbname. */ + if ((len > buff_size) || ! memcpy(buff, row[0], len)) + { + mysql_free_result(res); + return 1; + } + } + mysql_free_result(res); + } + + /* Restore the original database. */ + if (current_db && mysql_select_db(&mysql, current_db)) + return 1; + + return 0; +} + static int com_warnings(String *buffer __attribute__((unused)), char *line __attribute__((unused))) @@ -4283,6 +4356,20 @@ char *get_arg(char *line, my_bool get_next_arg) return valid_arg ? start : NullS; } +/* + Number of quotes present in the command's argument. +*/ +static int +get_quote_count(const char *line) +{ + int quote_count; + const char *ptr= line; + + for(quote_count= 0; ptr ++ && *ptr; ptr= strpbrk(ptr, "\"\'`")) + quote_count ++; + + return quote_count; +} static int sql_real_connect(char *host,char *database,char *user,char *password, |