Commit dd34c824 authored by msvensson@neptunus.(none)'s avatar msvensson@neptunus.(none)

Merge bk-internal:/home/bk/mysql-5.1-new

into  neptunus.(none):/home/msvensson/mysql/mysql-5.1
parents cf0f4059 b02463c1
......@@ -839,6 +839,23 @@ SHOW TABLE STATUS;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Dynamic 0 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
DROP TABLE t1;
create table t1 (a int)
partition by list (a)
(partition `s1 s2` values in (0));
drop table t1;
create table t1 (a int)
partition by list (a)
(partition `7` values in (0));
drop table t1;
create table t1 (a int)
partition by list (a)
(partition `s1 s2 ` values in (0));
ERROR HY000: Incorrect partition name
create table t1 (a int)
partition by list (a)
subpartition by hash (a)
(partition p1 values in (0) (subpartition `p1 p2 `));
ERROR HY000: Incorrect partition name
CREATE TABLE t1 (a int)
PARTITION BY LIST (a)
(PARTITION p0 VALUES IN (NULL));
......
drop schema if exists mysqltest_1;
create schema mysqltest_1;
use mysqltest_1;
create table t1 (a int) partition by list (a) (partition p1 values in (1), partition p2 values in (2), partition p3 values in (3));
insert into t1 values (1),(2);
grant select,alter on mysqltest_1.* to mysqltest_1@localhost;
show grants for current_user;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT SELECT, ALTER ON `mysqltest_1`.* TO 'mysqltest_1'@'localhost'
alter table t1 add b int;
alter table t1 drop partition p2;
ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
grant drop on mysqltest_1.* to mysqltest_1@localhost;
alter table t1 drop partition p2;
revoke alter on mysqltest_1.* from mysqltest_1@localhost;
alter table t1 drop partition p3;
ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table 't1'
revoke select,alter,drop on mysqltest_1.* from mysqltest_1@localhost;
drop user mysqltest_1@localhost;
drop table t1;
drop schema mysqltest_1;
End of 5.1 tests
......@@ -175,3 +175,4 @@ select count(*) from t2;
insert into t2 select t1.* from t1, t2 t, t3 where t1.id1 = t.id2 and t.id2 = t3.id3;
select count(*) from t2;
drop table t1,t2,t3;
......@@ -956,6 +956,30 @@ PARTITION p2 VALUES LESS THAN (30) ENGINE = MyISAM);
SHOW TABLE STATUS;
DROP TABLE t1;
#
#BUG 18750 Problems with partition names
#
create table t1 (a int)
partition by list (a)
(partition `s1 s2` values in (0));
drop table t1;
create table t1 (a int)
partition by list (a)
(partition `7` values in (0));
drop table t1;
--error ER_WRONG_PARTITION_NAME
create table t1 (a int)
partition by list (a)
(partition `s1 s2 ` values in (0));
--error ER_WRONG_PARTITION_NAME
create table t1 (a int)
partition by list (a)
subpartition by hash (a)
(partition p1 values in (0) (subpartition `p1 p2 `));
#
# BUG 18752 SHOW CREATE TABLE doesn't show NULL value in SHOW CREATE TABLE
#
......
-- source include/have_partition.inc
# Grant tests not performed with embedded server
-- source include/not_embedded.inc
--disable_warnings
drop schema if exists mysqltest_1;
--enable_warnings
#
# Bug #17139: ALTER TABLE ... DROP PARTITION should require DROP privilege
#
create schema mysqltest_1;
use mysqltest_1;
create table t1 (a int) partition by list (a) (partition p1 values in (1), partition p2 values in (2), partition p3 values in (3));
insert into t1 values (1),(2);
grant select,alter on mysqltest_1.* to mysqltest_1@localhost;
connect (conn1,localhost,mysqltest_1,,mysqltest_1);
show grants for current_user;
alter table t1 add b int;
--error ER_TABLEACCESS_DENIED_ERROR
alter table t1 drop partition p2;
disconnect conn1;
connection default;
grant drop on mysqltest_1.* to mysqltest_1@localhost;
connect (conn2,localhost,mysqltest_1,,mysqltest_1);
alter table t1 drop partition p2;
disconnect conn2;
connection default;
revoke alter on mysqltest_1.* from mysqltest_1@localhost;
connect (conn3,localhost,mysqltest_1,,mysqltest_1);
--error ER_TABLEACCESS_DENIED_ERROR
alter table t1 drop partition p3;
disconnect conn3;
connection default;
revoke select,alter,drop on mysqltest_1.* from mysqltest_1@localhost;
drop user mysqltest_1@localhost;
drop table t1;
drop schema mysqltest_1;
--echo End of 5.1 tests
......@@ -4696,8 +4696,9 @@ int ha_ndbcluster::create(const char *name,
DBUG_RETURN(my_errno);
}
int ha_ndbcluster::create_handler_files(const char *file)
int ha_ndbcluster::create_handler_files(const char *file, HA_CREATE_INFO *info)
{
char path[FN_REFLEN];
const char *name;
Ndb* ndb;
const NDBTAB *tab;
......@@ -4707,16 +4708,21 @@ int ha_ndbcluster::create_handler_files(const char *file)
DBUG_ENTER("create_handler_files");
DBUG_PRINT("enter", ("file: %s", file));
if (!(ndb= get_ndb()))
DBUG_RETURN(HA_ERR_NO_CONNECTION);
NDBDICT *dict= ndb->getDictionary();
if (!(tab= dict->getTable(m_tabname)))
if (!info->frm_only)
DBUG_RETURN(0); // Must be a create, ignore since frm is saved in create
set_dbname(file);
set_tabname(file);
DBUG_PRINT("info", ("m_dbname: %s, m_tabname: %s", m_dbname, m_tabname));
if (!(tab= dict->getTable(m_tabname)))
DBUG_RETURN(0); // Unkown table, must be temporary table
DBUG_ASSERT(get_ndb_share_state(m_share) == NSS_ALTERED);
name= table->s->normalized_path.str;
DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, name));
if (readfrm(name, &data, &length) ||
if (readfrm(file, &data, &length) ||
packfrm(data, length, &pack_data, &pack_length))
{
DBUG_PRINT("info", ("Missing frm for %s", m_tabname));
......@@ -4732,6 +4738,7 @@ int ha_ndbcluster::create_handler_files(const char *file)
my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
}
set_ndb_share_state(m_share, NSS_INITIAL);
free_share(&m_share); // Decrease ref_count
......@@ -4838,6 +4845,15 @@ int ha_ndbcluster::create_ndb_index(const char *name,
DBUG_RETURN(0);
}
/*
Prepare for an on-line alter table
*/
void ha_ndbcluster::prepare_for_alter()
{
ndbcluster_get_share(m_share); // Increase ref_count
set_ndb_share_state(m_share, NSS_ALTERED);
}
/*
Add an index on-line to a table
*/
......@@ -4850,7 +4866,7 @@ int ha_ndbcluster::add_index(TABLE *table_arg,
int error= 0;
uint idx;
DBUG_ASSERT(m_share->state == NSS_INITIAL);
DBUG_ASSERT(m_share->state == NSS_ALTERED);
for (idx= 0; idx < num_of_keys; idx++)
{
KEY *key= key_info + idx;
......@@ -4866,10 +4882,10 @@ int ha_ndbcluster::add_index(TABLE *table_arg,
if((error= create_index(key_info[idx].name, key, idx_type, idx)))
break;
}
if (!error)
if (error)
{
ndbcluster_get_share(m_share); // Increase ref_count
set_ndb_share_state(m_share, NSS_ALTERED);
set_ndb_share_state(m_share, NSS_INITIAL);
free_share(&m_share); // Decrease ref_count
}
DBUG_RETURN(error);
}
......@@ -4894,7 +4910,7 @@ int ha_ndbcluster::prepare_drop_index(TABLE *table_arg,
uint *key_num, uint num_of_keys)
{
DBUG_ENTER("ha_ndbcluster::prepare_drop_index");
DBUG_ASSERT(m_share->state == NSS_INITIAL);
DBUG_ASSERT(m_share->state == NSS_ALTERED);
// Mark indexes for deletion
uint idx;
for (idx= 0; idx < num_of_keys; idx++)
......@@ -4907,8 +4923,6 @@ int ha_ndbcluster::prepare_drop_index(TABLE *table_arg,
Thd_ndb *thd_ndb= get_thd_ndb(thd);
Ndb *ndb= thd_ndb->ndb;
renumber_indexes(ndb, table_arg);
ndbcluster_get_share(m_share); // Increase ref_count
set_ndb_share_state(m_share, NSS_ALTERED);
DBUG_RETURN(0);
}
......
......@@ -595,6 +595,7 @@ class ha_ndbcluster: public handler
const char * table_type() const;
const char ** bas_ext() const;
ulong table_flags(void) const;
void prepare_for_alter();
int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys);
int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys);
int final_drop_index(TABLE *table_arg);
......@@ -609,7 +610,7 @@ class ha_ndbcluster: public handler
int rename_table(const char *from, const char *to);
int delete_table(const char *name);
int create(const char *name, TABLE *form, HA_CREATE_INFO *info);
int create_handler_files(const char *file);
int create_handler_files(const char *file, HA_CREATE_INFO *info);
int get_default_no_partitions(ulonglong max_rows);
bool get_no_parts(const char *name, uint *no_parts);
void set_auto_partitions(partition_info *part_info);
......
......@@ -562,6 +562,7 @@ int ha_partition::rename_table(const char *from, const char *to)
SYNOPSIS
create_handler_files()
name Full path of table name
create_info Create info generated for CREATE TABLE
RETURN VALUE
>0 Error
......@@ -575,7 +576,8 @@ int ha_partition::rename_table(const char *from, const char *to)
and types of engines in the partitions.
*/
int ha_partition::create_handler_files(const char *name)
int ha_partition::create_handler_files(const char *name,
HA_CREATE_INFO *create_info)
{
DBUG_ENTER("ha_partition::create_handler_files()");
......
......@@ -179,7 +179,8 @@ public:
virtual int rename_table(const char *from, const char *to);
virtual int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info);
virtual int create_handler_files(const char *name);
virtual int create_handler_files(const char *name,
HA_CREATE_INFO *create_info);
virtual void update_create_info(HA_CREATE_INFO *create_info);
virtual char *update_table_comment(const char *comment);
virtual int change_partitions(HA_CREATE_INFO *create_info,
......
......@@ -1338,6 +1338,7 @@ public:
virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
virtual void prepare_for_alter() { return; }
virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
{ return (HA_ERR_WRONG_COMMAND); }
virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
......@@ -1378,7 +1379,8 @@ public:
virtual void drop_table(const char *name);
virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
virtual int create_handler_files(const char *name) { return FALSE;}
virtual int create_handler_files(const char *name, HA_CREATE_INFO *info)
{ return FALSE;}
virtual int change_partitions(HA_CREATE_INFO *create_info,
const char *path,
......
......@@ -696,6 +696,12 @@ bool partition_info::check_partition_info(handlerton **eng_type,
partition_element *part_elem= part_it++;
if (!is_sub_partitioned())
{
if (check_table_name(part_elem->partition_name,
strlen(part_elem->partition_name)))
{
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
goto end;
}
if (part_elem->engine_type == NULL)
part_elem->engine_type= default_engine_type;
DBUG_PRINT("info", ("engine = %d",
......@@ -709,6 +715,12 @@ bool partition_info::check_partition_info(handlerton **eng_type,
do
{
part_elem= sub_it++;
if (check_table_name(part_elem->partition_name,
strlen(part_elem->partition_name)))
{
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
goto end;
}
if (part_elem->engine_type == NULL)
part_elem->engine_type= default_engine_type;
DBUG_PRINT("info", ("engine = %u",
......
......@@ -5826,3 +5826,6 @@ ER_NDB_CANT_SWITCH_BINLOG_FORMAT
eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
ER_PARTITION_NO_TEMPORARY
eng "Cannot create temporary table with partitions"
ER_WRONG_PARTITION_NAME
eng "Incorrect partition name"
swe "Felaktigt partitionsnamn"
......@@ -2991,6 +2991,11 @@ end_with_restore_list:
#else
{
ulong priv=0;
ulong priv_needed= ALTER_ACL;
/* We also require DROP priv for ALTER TABLE ... DROP PARTITION */
if (lex->alter_info.flags & ALTER_DROP_PARTITION)
priv_needed|= DROP_ACL;
if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name);
......@@ -3015,7 +3020,7 @@ end_with_restore_list:
else
select_lex->db= first_table->db;
}
if (check_access(thd, ALTER_ACL, first_table->db,
if (check_access(thd, priv_needed, first_table->db,
&first_table->grant.privilege, 0, 0,
test(first_table->schema_table)) ||
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0,
......@@ -3026,7 +3031,7 @@ end_with_restore_list:
goto error; /* purecov: inspected */
if (grant_option)
{
if (check_grant(thd, ALTER_ACL, all_tables, 0, UINT_MAX, 0))
if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0))
goto error;
if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
{ // Rename of table
......
......@@ -1614,6 +1614,21 @@ static int add_key_partition(File fptr, List<char> field_list)
return err;
}
static int add_name_string(File fptr, const char *name)
{
int err;
String name_string("", 0, system_charset_info);
THD *thd= current_thd;
ulonglong save_options= thd->options;
thd->options= 0;
append_identifier(thd, &name_string, name,
strlen(name));
thd->options= save_options;
err= add_string_object(fptr, &name_string);
return err;
}
static int add_int(File fptr, longlong number)
{
llstr(number, buff);
......@@ -1912,7 +1927,7 @@ char *generate_partition_syntax(partition_info *part_info,
part_info->part_state_len= part_state_id+1;
}
err+= add_partition(fptr);
err+= add_string(fptr, part_elem->partition_name);
err+= add_name_string(fptr, part_elem->partition_name);
err+= add_space(fptr);
err+= add_partition_values(fptr, part_info, part_elem);
if (!part_info->is_sub_partitioned())
......@@ -1928,7 +1943,7 @@ char *generate_partition_syntax(partition_info *part_info,
{
part_elem= sub_it++;
err+= add_subpartition(fptr);
err+= add_string(fptr, part_elem->partition_name);
err+= add_name_string(fptr, part_elem->partition_name);
err+= add_space(fptr);
err+= add_partition_options(fptr, part_elem);
if (j != (no_subparts-1))
......
......@@ -753,6 +753,7 @@ mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
static const char *require_quotes(const char *name, uint name_length)
{
uint length;
bool pure_digit= TRUE;
const char *end= name + name_length;
for (; name < end ; name++)
......@@ -761,7 +762,11 @@ static const char *require_quotes(const char *name, uint name_length)
length= my_mbcharlen(system_charset_info, chr);
if (length == 1 && !system_charset_info->ident_map[chr])
return name;
if (length == 1 && (chr < '0' || chr > '9'))
pure_digit= FALSE;
}
if (pure_digit)
return name;
return 0;
}
......
......@@ -347,7 +347,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
lpt->create_info, lpt->new_create_list, lpt->key_count,
lpt->key_info_buffer, lpt->table->file)) ||
((flags & WFRM_CREATE_HANDLER_FILES) &&
lpt->table->file->create_handler_files(path)))
lpt->table->file->create_handler_files(path, lpt->create_info)))
{
error= 1;
goto end;
......@@ -3964,6 +3964,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
char index_file[FN_REFLEN], data_file[FN_REFLEN];
char path[FN_REFLEN];
char reg_path[FN_REFLEN+1];
ha_rows copied,deleted;
ulonglong next_insert_id;
......@@ -4000,6 +4001,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
new_db= db;
build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext);
build_table_filename(path, sizeof(path), db, table_name, "");
used_fields=create_info->used_fields;
......@@ -4773,6 +4775,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
KEY_PART_INFO *part_end;
DBUG_PRINT("info", ("No new_table, checking add/drop index"));
table->file->prepare_for_alter();
if (index_add_count)
{
#ifdef XXX_TO_BE_DONE_LATER_BY_WL3020_AND_WL1892
......@@ -4788,7 +4791,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error= (mysql_create_frm(thd, reg_path, db, table_name,
create_info, prepared_create_list, key_count,
key_info_buffer, table->file) ||
table->file->create_handler_files(reg_path));
table->file->create_handler_files(path, create_info));
VOID(pthread_mutex_unlock(&LOCK_open));
if (error)
goto err;
......@@ -4834,7 +4837,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error= (mysql_create_frm(thd, reg_path, db, table_name,
create_info, prepared_create_list, key_count,
key_info_buffer, table->file) ||
table->file->create_handler_files(reg_path));
table->file->create_handler_files(path, create_info));
VOID(pthread_mutex_unlock(&LOCK_open));
if (error)
goto err;
......@@ -4904,19 +4907,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
/*end of if (index_drop_count)*/
if (index_add_count || index_drop_count)
{
/*
The final .frm file is already created as a temporary file
and will be renamed to the original table name later.
*/
/*
The final .frm file is already created as a temporary file
and will be renamed to the original table name later.
*/
/* Need to commit before a table is unlocked (NDB requirement). */
DBUG_PRINT("info", ("Committing after add/drop index"));
if (ha_commit_stmt(thd) || ha_commit(thd))
goto err;
committed= 1;
}
/* Need to commit before a table is unlocked (NDB requirement). */
DBUG_PRINT("info", ("Committing before unlocking table"));
if (ha_commit_stmt(thd) || ha_commit(thd))
goto err;
committed= 1;
}
/*end of if (! new_table) for add/drop index*/
......@@ -5061,7 +5061,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
VOID(pthread_mutex_lock(&LOCK_open));
}
/* Tell the handler that a new frm file is in place. */
if (table->file->create_handler_files(reg_path))
if (table->file->create_handler_files(path, create_info))
{
VOID(pthread_mutex_unlock(&LOCK_open));
goto err;
......
......@@ -3639,7 +3639,7 @@ part_definition:
;
part_name:
ident_or_text
ident
{
LEX *lex= Lex;
partition_info *part_info= lex->part_info;
......
......@@ -330,7 +330,7 @@ int rea_create_table(THD *thd, const char *path,
// Make sure mysql_create_frm din't remove extension
DBUG_ASSERT(*fn_rext(frm_name));
if (file->create_handler_files(path))
if (file->create_handler_files(path, create_info))
goto err_handler;
if (!create_info->frm_only && ha_create_table(thd, path, db, table_name,
create_info,0))
......
......@@ -31,6 +31,7 @@ static Ndb_cluster_connection *ndb_cluster_connection= 0;
static Ndb* ndb = 0;
static const NdbDictionary::Dictionary * dic = 0;
static int _unqualified = 0;
static int _parsable = 0;
static void
fatal(char const* fmt, ...)
......@@ -76,10 +77,13 @@ list(const char * tabname,
if (dic->listIndexes(list, tabname) == -1)
fatal_dict("listIndexes");
}
if (ndb->usingFullyQualifiedNames())
ndbout_c("%-5s %-20s %-8s %-7s %-12s %-8s %s", "id", "type", "state", "logging", "database", "schema", "name");
else
ndbout_c("%-5s %-20s %-8s %-7s %s", "id", "type", "state", "logging", "name");
if (!_parsable)
{
if (ndb->usingFullyQualifiedNames())
ndbout_c("%-5s %-20s %-8s %-7s %-12s %-8s %s", "id", "type", "state", "logging", "database", "schema", "name");
else
ndbout_c("%-5s %-20s %-8s %-7s %s", "id", "type", "state", "logging", "name");
}
for (unsigned i = 0; i < list.count; i++) {
NdbDictionary::Dictionary::List::Element& elt = list.elements[i];
char type[100];
......@@ -170,9 +174,19 @@ list(const char * tabname,
}
}
if (ndb->usingFullyQualifiedNames())
ndbout_c("%-5d %-20s %-8s %-7s %-12s %-8s %s", elt.id, type, state, store, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name);
else
ndbout_c("%-5d %-20s %-8s %-7s %s", elt.id, type, state, store, elt.name);
{
if (_parsable)
ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name);
else
ndbout_c("%-5d %-20s %-8s %-7s %-12s %-8s %s", elt.id, type, state, store, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name);
}
else
{
if (_parsable)
ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, elt.name);
else
ndbout_c("%-5d %-20s %-8s %-7s %s", elt.id, type, state, store, elt.name);
}
}
}
......@@ -196,6 +210,9 @@ static struct my_option my_long_options[] =
{ "unqualified", 'u', "Use unqualified table names",
(gptr*) &_unqualified, (gptr*) &_unqualified, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "parsable", 'p', "Return output suitable for mysql LOAD DATA INFILE",
(gptr*) &_parsable, (gptr*) &_parsable, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void usage()
......
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