ALTER DATABASE DEFAULT CHARACTER SET latin1;

parent a3d8e086
......@@ -289,7 +289,8 @@ inline THD *_current_thd(void)
#define prepare_execute(A) ((A)->command == COM_EXECUTE)
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent);
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags);
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists);
......
......@@ -31,6 +31,96 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
const char *db, const char *path,
uint level);
/*
Create database options file:
Currently databse default charset is only stored there.
*/
static int write_db_opt(THD *thd, char *db, HA_CREATE_INFO *create, char *fn)
{
register File file;
char buf[256]; // Should be enough
int error=0;
if ((file=my_create(fn,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
{
sprintf(buf,"default-character-set=%s\n",
(create && create->table_charset) ?
create->table_charset->name : "DEFAULT");
if (my_write(file,(byte*)buf,strlen(buf),MYF(MY_NABP+MY_WME)))
{
// QQ : should we send more suitable error message?
my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
error = -1;
goto exit;
}
my_close(file,MYF(0));
}
else
{
// QQ : should we send more suitable error message?
my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
error = -1;
goto exit;
}
exit:
return error;
}
/*
Load database options file:
*/
static int load_db_opt(THD *thd,char *fn)
{
register File file;
char buf[256]="";
if ((file=my_open(fn,O_RDWR|O_BINARY,MYF(MY_WME))) >= 0)
{
int nbytes=my_read(file,(byte*)buf,sizeof(buf)-1,MYF(0));
if ( nbytes >= 0 )
{
char *ln=buf;
char *pe=buf+nbytes;
buf[nbytes]='\0';
for ( ln=buf; ln<pe; )
{
char *le,*val;
for ( le=ln, val=0 ; le<pe ; le++ )
{
switch(le[0])
{
case '=':
le[0]='\0';
val=le+1;
le++;
break;
case '\r':
case '\n':
le[0]='\0';
le++;
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));
}
goto cnt;
break;
}
}
cnt:
ln=le;
}
}
my_close(file,MYF(0));
}
return 0;
}
/* db-name is already validated when we come here */
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
......@@ -39,10 +129,10 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent
MY_DIR *dirp;
long result=1;
int error = 0;
DBUG_ENTER("mysql_create_db");
register File file;
uint create_options = create_info ? create_info->options : 0;
DBUG_ENTER("mysql_create_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
// do not create database if another thread is holding read lock
......@@ -77,43 +167,81 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent
}
}
/*
Create database options file:
Currently databse default charset is only stored there.
*/
strcat(path,"/");
unpack_dirname(path,path);
strcat(path,MY_DB_OPT_FILE);
if ((file=my_create(path,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
{
sprintf(path,"default-character-set=%s\n",
(create_info && create_info->table_charset) ?
create_info->table_charset->name : "DEFAULT");
if ((error=write_db_opt(thd,db,create_info,path)))
goto exit;
if (my_write(file,(byte*) path,strlen(path),MYF(MY_NABP+MY_WME)))
if (!silent)
{
// QQ : should we send more suitable error message?
my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
error = -1;
goto exit;
if (!thd->query)
{
thd->query = path;
thd->query_length = (uint) (strxmov(path,"create database ", db, NullS)-
path);
}
my_close(file,MYF(0));
{
mysql_update_log.write(thd,thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query);
mysql_bin_log.write(&qinfo);
}
else
}
if (thd->query == path)
{
// QQ : should we send more suitable error message?
my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
error = -1;
goto exit;
thd->query = 0; // just in case
thd->query_length = 0;
}
send_ok(&thd->net, result);
}
exit:
start_waiting_global_read_lock(thd);
exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
DBUG_RETURN(error);
}
/* db-name is already validated when we come here */
int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
{
char path[FN_REFLEN+16];
MY_DIR *dirp;
long result=1;
int error = 0;
DBUG_ENTER("mysql_create_db");
register File file;
uint create_options = create_info ? create_info->options : 0;
printf("alter database\n");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
// do not alter database if another thread is holding read lock
if (wait_if_global_read_lock(thd,0))
{
error= -1;
goto exit2;
}
/* Check directory */
(void)sprintf(path,"%s/%s", mysql_data_home, db);
strcat(path,"/");
unpack_dirname(path,path); // Convert if not unix
strcat(path,MY_DB_OPT_FILE);
if ((error=write_db_opt(thd,db,create_info,path)))
goto exit;
if (!silent)
{
if (!thd->query)
{
thd->query = path;
thd->query_length = (uint) (strxmov(path,"create database ", db, NullS)-
thd->query_length = (uint) (strxmov(path,"alter database ", db, NullS)-
path);
}
{
......@@ -139,6 +267,10 @@ exit2:
DBUG_RETURN(error);
}
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
static TYPELIB deletable_extentions=
{array_elements(del_exts)-1,"del_exts", del_exts};
......@@ -368,7 +500,6 @@ bool mysql_change_db(THD *thd,const char *name)
char path[FN_REFLEN];
uint db_access;
DBUG_ENTER("mysql_change_db");
register File file;
if (!dbname || !(db_length=strip_sp(dbname)))
{
......@@ -419,53 +550,11 @@ bool mysql_change_db(THD *thd,const char *name)
thd->db_length=db_length;
thd->db_access=db_access;
/*
Load database options file:
*/
strcat(path,"/");
unpack_dirname(path,path);
strcat(path,MY_DB_OPT_FILE);
if ((file=my_open(path,O_RDWR|O_BINARY,MYF(MY_WME))) >= 0)
{
int nbytes=my_read(file,(byte*) path,sizeof(path),MYF(0));
if ( nbytes >= 0 )
{
char *ln=path;
char *pe=path+nbytes;
load_db_opt(thd,path);
path[nbytes]='\0';
for ( ln=path; ln<pe; )
{
char *le,*val;
for ( le=ln, val=0 ; le<pe ; le++ )
{
switch(le[0])
{
case '=':
le[0]='\0';
val=le+1;
le++;
break;
case '\r':
case '\n':
le[0]='\0';
le++;
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));
}
goto cnt;
break;
}
}
cnt:
ln=le;
}
}
my_close(file,MYF(0));
}
DBUG_RETURN(0);
}
......@@ -44,7 +44,8 @@ enum enum_sql_command {
SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS,
SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB,
SQLCOM_GRANT,
SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
......
......@@ -2328,6 +2328,23 @@ mysql_execute_command(void)
res=mysql_rm_db(thd,lex->name,lex->drop_if_exists,0);
break;
}
case SQLCOM_ALTER_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=mysql_alter_db(thd,lex->name,&lex->create_info,0);
break;
}
case SQLCOM_CREATE_FUNCTION:
if (check_access(thd,INSERT_ACL,"mysql",0,1))
break;
......
......@@ -885,12 +885,7 @@ create_table_option:
table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
}
| CHARSET EQ DEFAULT
{
Lex->create_info.table_charset=NULL;
Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET;
}
| CHARSET EQ charset
| CHARSET EQ charset_or_nocharset
{
Lex->create_info.table_charset=Lex->charset;
Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET;
......@@ -1139,6 +1134,10 @@ charset:
}
};
charset_or_nocharset:
charset
| DEFAULT {Lex->charset=NULL; }
opt_binary:
/* empty */ { Lex->charset=NULL; }
| BINARY { Lex->type|=BINARY_FLAG; Lex->charset=NULL; }
......@@ -1146,7 +1145,7 @@ opt_binary:
default_charset:
/* empty */ { Lex->charset=NULL; }
| DEFAULT CHAR_SYM SET charset ;
| DEFAULT CHAR_SYM SET charset_or_nocharset ;
references:
REFERENCES table_ident
......@@ -1271,6 +1270,15 @@ alter:
}
alter_list;
| ALTER DATABASE ident default_charset
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_ALTER_DB;
lex->name=$3.str;
lex->create_info.table_charset=lex->charset;
}
alter_list:
| alter_list_item
| alter_list ',' alter_list_item;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment