diff options
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sql_db.cc | 91 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 19 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 5 |
5 files changed, 115 insertions, 2 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2992f11ef65..c0371d1e90c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -472,6 +472,7 @@ int mysqld_show_logs(THD *thd); void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild); int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1); int mysqld_show_create(THD *thd, TABLE_LIST *table_list); +int mysqld_show_create_db(THD *thd, const char *dbname); void mysqld_list_processes(THD *thd,const char *user,bool verbose); int mysqld_show_status(THD *thd); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 63edebd4ac7..7e82e1433b9 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -106,7 +106,7 @@ static int load_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn) for( ; (le[0]=='\r' || le[0]=='\n') ; le++); if (!strcmp(ln,"default-character-set") && val && val[0]) { - thd->db_charset=get_charset_by_name(val, MYF(0)); + create->table_charset=get_charset_by_name(val, MYF(0)); } goto cnt; break; @@ -568,3 +568,92 @@ bool mysql_change_db(THD *thd,const char *name) DBUG_RETURN(0); } + + +int mysqld_show_create_db(THD *thd,const char *name) +{ + int length, db_length; + char *dbname=my_strdup((char*) name,MYF(MY_WME)); + char path[FN_REFLEN]; + uint db_access; + HA_CREATE_INFO create; + CONVERT *convert=thd->convert_set; + + DBUG_ENTER("mysql_show_create_db"); + + if (!dbname || !(db_length=strip_sp(dbname))) + { + x_free(dbname); /* purecov: inspected */ + send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ + DBUG_RETURN(1); /* purecov: inspected */ + } + + if ((db_length > NAME_LEN) || check_db_name(dbname)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, dbname); + x_free(dbname); + DBUG_RETURN(1); + } + + if (test_all_bits(thd->master_access,DB_ACLS)) + db_access=DB_ACLS; + else + db_access= (acl_get(thd->host,thd->ip,(char*) &thd->remote.sin_addr, + thd->priv_user,dbname) | + thd->master_access); + if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) + { + net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, + thd->priv_user, + thd->host_or_ip, + dbname); + mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), + thd->priv_user, + thd->host_or_ip, + dbname); + my_free(dbname,MYF(0)); + DBUG_RETURN(1); + } + + (void) sprintf(path,"%s/%s",mysql_data_home,dbname); + length=unpack_dirname(path,path); // Convert if not unix + if (length && path[length-1] == FN_LIBCHAR) + path[length-1]=0; // remove ending '\' + if (access(path,F_OK)) + { + net_printf(&thd->net,ER_BAD_DB_ERROR,dbname); + my_free(dbname,MYF(0)); + DBUG_RETURN(1); + } + + strcat(path,"/"); + unpack_dirname(path,path); + strcat(path,MY_DB_OPT_FILE); + bzero(&create,sizeof(create)); + load_db_opt(thd,name,&create,path); + + List<Item> field_list; + field_list.push_back(new Item_empty_string("Database",NAME_LEN)); + field_list.push_back(new Item_empty_string("Create Database",1024)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + String *packet = &thd->packet; + packet->length(0); + net_store_data(packet, convert, name); + sprintf(path, "CREATE DATABASE %s", name); + if (create.table_charset) + { + strcat(path," DEFAULT CHARACTER SET "); + strcat(path,create.table_charset->name); + } + net_store_data(packet, convert, path); + + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) + DBUG_RETURN(1); + + send_eof(&thd->net); + + DBUG_RETURN(0); +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 7234a7a92ff..470230c0999 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -42,6 +42,7 @@ enum enum_sql_command { SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS, SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, + SQLCOM_SHOW_CREATE_DB, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, SQLCOM_GRANT, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 43cb056ffc8..e006855105c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2335,7 +2335,7 @@ mysql_execute_command(void) net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); break; } - if (check_access(thd,DROP_ACL,lex->name,0,1)) + if (check_access(thd,ALTER_ACL,lex->name,0,1)) break; if (thd->locked_tables || thd->active_transaction()) { @@ -2345,6 +2345,23 @@ mysql_execute_command(void) res=mysql_alter_db(thd,lex->name,&lex->create_info,0); break; } + case SQLCOM_SHOW_CREATE_DB: + { + if (!strip_sp(lex->name) || check_db_name(lex->name)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); + break; + } + if (check_access(thd,DROP_ACL,lex->name,0,1)) + break; + if (thd->locked_tables || thd->active_transaction()) + { + send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); + goto error; + } + res=mysqld_show_create_db(thd,lex->name); + break; + } case SQLCOM_CREATE_FUNCTION: if (check_access(thd,INSERT_ACL,"mysql",0,1)) break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e96c72ab04b..160bc253dc9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2851,6 +2851,11 @@ show_param: lex->grant_user=$3; lex->grant_user->password.str=NullS; } + | CREATE DATABASE ident + { + Lex->sql_command=SQLCOM_SHOW_CREATE_DB; + Lex->name=$3.str; + } | CREATE TABLE_SYM table_ident { Lex->sql_command = SQLCOM_SHOW_CREATE; |