mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
ALTER DATABASE DEFAULT CHARACTER SET latin1;
This commit is contained in:
parent
a3d8e08695
commit
0dce493b69
5 changed files with 200 additions and 84 deletions
|
@ -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);
|
||||
|
|
237
sql/sql_db.cc
237
sql/sql_db.cc
|
@ -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,37 +167,12 @@ 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 (my_write(file,(byte*) path,strlen(path),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;
|
||||
if ((error=write_db_opt(thd,db,create_info,path)))
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
if (!silent)
|
||||
{
|
||||
if (!thd->query)
|
||||
|
@ -139,6 +204,73 @@ exit2:
|
|||
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,"alter database ", db, NullS)-
|
||||
path);
|
||||
}
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (thd->query == path)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
@ -1270,7 +1269,16 @@ alter:
|
|||
lex->simple_alter=1;
|
||||
}
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue